diff --git a/api/review_task.go b/api/review_task.go index 2e192cb8..0ceb9715 100644 --- a/api/review_task.go +++ b/api/review_task.go @@ -135,3 +135,13 @@ func listReviewTaskPool(ctx context.Context, r *http.Request, user platform.User Total: row_total.Total, }, nil } +func userOrNil(usersByID map[int32]*platform.User, id *int32) *platform.User { + if id == nil { + return nil + } + u, ok := usersByID[*id] + if !ok { + return nil + } + return u +} diff --git a/api/signal.go b/api/signal.go index 16e8c64f..266bc5e1 100644 --- a/api/signal.go +++ b/api/signal.go @@ -3,142 +3,26 @@ package api import ( "context" "net/http" - "time" - "github.com/Gleipnir-Technology/bob" - "github.com/Gleipnir-Technology/bob/dialect/psql" - "github.com/Gleipnir-Technology/bob/dialect/psql/sm" - "github.com/Gleipnir-Technology/nidus-sync/db" nhttp "github.com/Gleipnir-Technology/nidus-sync/http" "github.com/Gleipnir-Technology/nidus-sync/platform" - "github.com/Gleipnir-Technology/nidus-sync/platform/types" //"github.com/aarondl/opt/null" - "github.com/stephenafamo/scan" ) -type signal struct { - Address types.Address `json:"address"` - Addressed *time.Time `json:"addressed"` - Addressor *platform.User `json:"addressor"` - Created time.Time `json:"created"` - Creator platform.User `json:"creator"` - ID int32 `json:"id"` - Location types.Location `json:"location"` - Species string `json:"species"` - Title string `json:"title"` - Type string `json:"type"` -} type contentListSignal struct { - Signals []signal `json:"signals"` + Signals []platform.Signal `json:"signals"` } func listSignal(ctx context.Context, r *http.Request, user platform.User, query queryParams) (*contentListSignal, *nhttp.ErrorWithStatus) { - type _Row struct { - Address types.Address `db:"address"` - Addressed *time.Time `db:"addressed"` - Addressor *int32 `db:"addressor"` - Created time.Time `db:"created"` - Creator int32 `db:"creator_id"` - ID int32 `db:"id"` - Latitude float64 `db:"latitude"` - Longitude float64 `db:"longitude"` - Location types.Location `db:"location"` - Species *string `db:"species"` - Title string `db:"title"` - Type string `db:"type"` - } limit := 20 if query.Limit != nil { limit = *query.Limit } - rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( - sm.Columns( - "signal.addressed AS addressed", - "signal.addressor AS addressor", - "signal.created AS created", - "signal.creator AS creator_id", - "signal.id AS id", - "signal.species AS species", - "signal.title AS title", - "signal.type_ AS type", - "address.country AS \"address.country\"", - "address.locality AS \"address.locality\"", - "address.number_ AS \"address.number\"", - "address.postal_code AS \"address.postal_code\"", - "address.region AS \"address.region\"", - "address.street AS \"address.street\"", - "address.unit AS \"address.unit\"", - "ST_Y(address.geom) AS latitude", - "ST_X(address.geom) AS longitude", - ), - sm.From("signal"), - sm.InnerJoin("signal_pool").OnEQ( - psql.Quote("signal", "id"), - psql.Quote("signal_pool", "signal_id"), - ), - sm.InnerJoin("pool").OnEQ( - psql.Quote("signal_pool", "pool_id"), - psql.Quote("pool", "id"), - ), - sm.InnerJoin("site").On( - psql.Quote("pool", "site_id").EQ(psql.Quote("site", "id")), - ), - sm.InnerJoin("address").OnEQ( - psql.Quote("site", "address_id"), - psql.Quote("address", "id"), - ), - sm.Where(psql.Quote("signal", "organization_id").EQ(psql.Arg(user.Organization.ID()))), - sm.Where(psql.Quote("signal", "addressed").IsNull()), - sm.Limit(limit), - ), scan.StructMapper[_Row]()) - - /* - rows, err := models.Signals.Query( - models.SelectWhere.Signals.OrganizationID.EQ(org.ID()), - sm.OrderBy("created").Desc(), - ).All(ctx, db.PGInstance.BobDB) - */ + signals, err := platform.SignalList(ctx, user, limit) if err != nil { - return nil, nhttp.NewError("failed to get signals: %w", err) - } - users_by_id, err := platform.UsersByOrg(ctx, user.Organization) - if err != nil { - return nil, nhttp.NewError("users by id: %w", err) - } - signals := make([]signal, len(rows)) - for i, row := range rows { - var species string = "" - if row.Species != nil { - species = *row.Species - } - signals[i] = signal{ - Address: row.Address, - Addressed: row.Addressed, - Addressor: userOrNil(users_by_id, row.Addressor), - Created: row.Created, - Creator: *users_by_id[row.Creator], - ID: row.ID, - Location: types.Location{ - Latitude: row.Latitude, - Longitude: row.Longitude, - }, - Species: species, - Title: row.Title, - Type: row.Type, - } + return nil, nhttp.NewError("list signals: %w", err) } return &contentListSignal{ Signals: signals, }, nil } - -func userOrNil(usersByID map[int32]*platform.User, id *int32) *platform.User { - if id == nil { - return nil - } - u, ok := usersByID[*id] - if !ok { - return nil - } - return u -} diff --git a/platform/signal.go b/platform/signal.go index 1cc8e06d..f3c44b59 100644 --- a/platform/signal.go +++ b/platform/signal.go @@ -6,19 +6,35 @@ import ( "fmt" "time" - //"github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/bob/dialect/psql/um" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/platform/types" //"github.com/Gleipnir-Technology/nidus-sync/platform/geocode" //"github.com/Gleipnir-Technology/nidus-sync/platform/geom" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" + "github.com/stephenafamo/scan" //"github.com/rs/zerolog/log" ) +type Signal struct { + Address *types.Address `db:"address" json:"address"` + Addressed *time.Time `db:"addressed" json:"addressed"` + Addressor *int32 `db:"addressor" json:"addressor"` + Created time.Time `db:"created" json:"created"` + Creator int32 `db:"creator" json:"creator"` + ID int32 `db:"id" json:"id"` + Location types.Location `db:"location" json:"location"` + Species *string `db:"species" json:"species"` + Title string `db:"title" json:"title"` + Type string `db:"type" json:"type"` +} + // Create a lead from the given signal and site func SignalCreateFromPublicreport(ctx context.Context, user User, report_id string) (*int32, error) { txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) @@ -106,3 +122,50 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri return &signal.ID, nil } + +func SignalList(ctx context.Context, user User, limit int) ([]Signal, error) { + rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( + sm.Columns( + "signal.addressed AS addressed", + "signal.addressor AS addressor", + "signal.created AS created", + "signal.creator AS creator", + "signal.id AS id", + "signal.species AS species", + "signal.title AS title", + "signal.type_ AS type", + "address.country AS \"address.country\"", + "address.locality AS \"address.locality\"", + "address.number_ AS \"address.number\"", + "address.postal_code AS \"address.postal_code\"", + "address.region AS \"address.region\"", + "address.street AS \"address.street\"", + "address.unit AS \"address.unit\"", + "ST_Y(address.location) AS \"location.latitude\"", + "ST_X(address.location) AS \"location.longitude\"", + ), + sm.From("signal"), + sm.LeftJoin("site").OnEQ( + psql.Quote("signal", "site_id"), + psql.Quote("site", "id"), + ), + sm.LeftJoin("address").OnEQ( + psql.Quote("site", "address_id"), + psql.Quote("address", "id"), + ), + sm.Where(psql.Quote("signal", "organization_id").EQ(psql.Arg(user.Organization.ID()))), + sm.Where(psql.Quote("signal", "addressed").IsNull()), + sm.Limit(limit), + ), scan.StructMapper[Signal]()) + + /* + rows, err := models.Signals.Query( + models.SelectWhere.Signals.OrganizationID.EQ(org.ID()), + sm.OrderBy("created").Desc(), + ).All(ctx, db.PGInstance.BobDB) + */ + if err != nil { + return nil, fmt.Errorf("failed to get signals: %w", err) + } + return rows, nil +}