Initial pattern for populating different report types

This commit is contained in:
Eli Ribble 2026-04-12 17:53:25 +00:00
parent c8f74d3c26
commit ae10e4fee8
No known key found for this signature in database
14 changed files with 218 additions and 68 deletions

View file

@ -26,7 +26,18 @@ import (
)
func PublicreportByID(ctx context.Context, report_id string) (*types.PublicReport, error) {
return publicreport.Report(ctx, report_id)
return publicreport.ByID(ctx, report_id)
}
func PublicreportByIDCompliance(ctx context.Context, report_id string) (*types.PublicReportCompliance, error) {
return publicreport.ByIDCompliance(ctx, report_id)
}
func PublicreportByIDNuisance(ctx context.Context, report_id string) (*types.PublicReportNuisance, error) {
//return publicreport.ByIDNuisance(ctx, report_id)
return nil, nil
}
func PublicreportByIDWater(ctx context.Context, report_id string) (*types.PublicReportWater, error) {
//return publicreport.ByIDWater(ctx, report_id)
return nil, nil
}
func PublicreportInvalid(ctx context.Context, user User, report_id string) error {
report, err := publicReportFromID(ctx, report_id)
@ -120,7 +131,7 @@ func PublicReportUpdate(ctx context.Context, report_id string, report_setter mod
}
}
txn.Commit(ctx)
return publicreport.Report(ctx, report_id)
return publicreport.ByID(ctx, report_id)
}
func PublicReportReporterUpdated(ctx context.Context, org_id int32, report_id string) {
event.Updated(event.TypeRMOReport, org_id, report_id)

View file

@ -0,0 +1,57 @@
package publicreport
import (
"context"
"fmt"
"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/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
//"github.com/google/uuid"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
)
func compliance(ctx context.Context, public_id string, report *types.PublicReport) (*types.PublicReportCompliance, error) {
row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
"access_instructions",
"availability_notes",
"comments",
"gate_code",
"has_dog",
"permission_type",
"report_id",
"report_phone_can_text",
"wants_scheduled",
),
sm.From("publicreport.compliance"),
sm.Where(psql.Quote("report_id").EQ(
psql.Arg(report.ID),
)),
), scan.StructMapper[types.PublicReportCompliance]())
if err != nil {
return nil, fmt.Errorf("query compliance: %w", err)
}
copyReportContent(report, &row.PublicReport)
return &row, nil
}
func copyReportContent(src *types.PublicReport, dst *types.PublicReport) {
dst.Address = src.Address
dst.Created = src.Created
dst.ID = src.ID
dst.Images = src.Images
dst.Location = src.Location
dst.Log = src.Log
dst.DistrictID = src.DistrictID
dst.District = src.District
dst.PublicID = src.PublicID
dst.Reporter = src.Reporter
dst.Status = src.Status
dst.Type = src.Type
dst.URI = src.URI
}

View file

@ -1,6 +1,7 @@
package publicreport
import (
/*
"context"
"fmt"
@ -13,8 +14,10 @@ import (
//"github.com/google/uuid"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
*/
)
/*
func nuisancesByReportID(ctx context.Context, report_ids []int32) (map[int32]*types.Nuisance, error) {
rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
@ -65,3 +68,4 @@ func nuisancesByReportID(ctx context.Context, report_ids []int32) (map[int32]*ty
}
return results, nil
}
*/

View file

@ -15,6 +15,34 @@ import (
"github.com/stephenafamo/scan"
)
func ByID(ctx context.Context, public_id string) (*types.PublicReport, error) {
query := reportQuery()
query.Apply(
sm.Where(psql.Quote("publicreport", "report", "public_id").EQ(psql.Arg(public_id))),
)
reports, err := reportQueryToRows(ctx, query)
if err != nil {
return nil, fmt.Errorf("query to rows: %w", err)
}
if len(reports) != 1 {
return nil, fmt.Errorf("reports returned: %d", len(reports))
}
return reports[0], nil
}
func ByIDCompliance(ctx context.Context, public_id string) (*types.PublicReportCompliance, error) {
query := reportQuery()
query.Apply(
sm.Where(psql.Quote("publicreport", "report", "public_id").EQ(psql.Arg(public_id))),
)
reports, err := reportQueryToRows(ctx, query)
if err != nil {
return nil, fmt.Errorf("query to rows: %w", err)
}
if len(reports) != 1 {
return nil, fmt.Errorf("reports returned: %d", len(reports))
}
return compliance(ctx, public_id, reports[0])
}
func ReportsForOrganization(ctx context.Context, org_id int32) ([]*types.PublicReport, error) {
query := reportQuery()
query.Apply(
@ -74,20 +102,6 @@ func reportQueryToRows(ctx context.Context, query bob.BaseQuery[*dialect.SelectQ
}
return results, nil
}
func Report(ctx context.Context, public_id string) (*types.PublicReport, error) {
query := reportQuery()
query.Apply(
sm.Where(psql.Quote("publicreport", "report", "public_id").EQ(psql.Arg(public_id))),
)
reports, err := reportQueryToRows(ctx, query)
if err != nil {
return nil, fmt.Errorf("query to rows: %w", err)
}
if len(reports) != 1 {
return nil, fmt.Errorf("reports returned: %d", len(reports))
}
return reports[0], nil
}
func Reports(ctx context.Context, org_id int32, ids []int32) ([]*types.PublicReport, error) {
query := reportQuery()
query.Apply(

View file

@ -1,6 +1,7 @@
package publicreport
import (
/*
"context"
"fmt"
@ -14,8 +15,10 @@ import (
//"github.com/google/uuid"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
*/
)
/*
func watersByReportID(ctx context.Context, report_ids []int32) (map[int32]*types.Water, error) {
rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
@ -67,3 +70,4 @@ func watersByReportID(ctx context.Context, report_ids []int32) (map[int32]*types
}
return results, nil
}
*/

View file

@ -1,20 +0,0 @@
package types
type Nuisance struct {
AdditionalInfo string `db:"additional_info" json:"additional_info"`
Duration string `db:"duration" json:"duration"`
IsLocationBackyard bool `db:"is_location_backyard" json:"is_location_backyard"`
IsLocationFrontyard bool `db:"is_location_frontyard" json:"is_location_frontyard"`
IsLocationGarden bool `db:"is_location_garden" json:"is_location_garden"`
IsLocationOther bool `db:"is_location_other" json:"is_location_other"`
IsLocationPool bool `db:"is_location_pool" json:"is_location_pool"`
ReportID int32 `db:"report_id" json:"-"`
SourceContainer bool `db:"source_container" json:"source_container"`
SourceDescription string `db:"source_description" json:"source_description"`
SourceGutter bool `db:"source_gutter" json:"source_gutter"`
SourceStagnant bool `db:"source_stagnant" json:"source_stagnant"`
TODDay bool `db:"tod_day" json:"time_of_day_day"`
TODEarly bool `db:"tod_early" json:"time_of_day_early"`
TODEvening bool `db:"tod_evening" json:"time_of_day_evening"`
TODNight bool `db:"tod_night" json:"time_of_day_night"`
}

View file

@ -19,3 +19,54 @@ type PublicReport struct {
Type string `db:"report_type" json:"type"`
URI string `db:"-" json:"uri"`
}
type PublicReportCompliance struct {
PublicReport
AccessInstructions string `db:"access_instructions" json:"access_instructions"`
AvailabilityNotes string `db:"availability_notes" json:"availability_notes"`
Comments string `db:"comments" json:"comments"`
GateCode string `db:"gate_code" json:"gate_code"`
HasDog *bool `db:"has_dog" json:"has_dog"`
PermissionType string `db:"permission_type" json:"permission_type"`
ReportID int32 `db:"report_id" json:"-"`
ReportPhoneCanText *bool `db:"report_phone_can_text" json:"can_text"`
WantsScheduled *bool `db:"wants_scheduled" json:"wants_scheduled"`
}
type PublicReportNuisance struct {
PublicReport
AdditionalInfo string `db:"additional_info" json:"additional_info"`
Duration string `db:"duration" json:"duration"`
IsLocationBackyard bool `db:"is_location_backyard" json:"is_location_backyard"`
IsLocationFrontyard bool `db:"is_location_frontyard" json:"is_location_frontyard"`
IsLocationGarden bool `db:"is_location_garden" json:"is_location_garden"`
IsLocationOther bool `db:"is_location_other" json:"is_location_other"`
IsLocationPool bool `db:"is_location_pool" json:"is_location_pool"`
ReportID int32 `db:"report_id" json:"-"`
SourceContainer bool `db:"source_container" json:"source_container"`
SourceDescription string `db:"source_description" json:"source_description"`
SourceGutter bool `db:"source_gutter" json:"source_gutter"`
SourceStagnant bool `db:"source_stagnant" json:"source_stagnant"`
TODDay bool `db:"tod_day" json:"time_of_day_day"`
TODEarly bool `db:"tod_early" json:"time_of_day_early"`
TODEvening bool `db:"tod_evening" json:"time_of_day_evening"`
TODNight bool `db:"tod_night" json:"time_of_day_night"`
}
type PublicReportWater struct {
PublicReport
AccessComments string `db:"access_comments" json:"access_comments"`
AccessGate bool `db:"access_gate" json:"access_gate"`
AccessFence bool `db:"access_fence" json:"access_fence"`
AccessLocked bool `db:"access_locked" json:"access_locked"`
AccessDog bool `db:"access_dog" json:"access_dog"`
AccessOther bool `db:"access_other" json:"access_other"`
Comments string `db:"comments" json:"comments"`
HasAdult bool `db:"has_adult" json:"has_adult"`
HasBackyardPermission bool `db:"has_backyard_permission" json:"has_backyard_permission"`
HasLarvae bool `db:"has_larvae" json:"has_larvae"`
HasPupae bool `db:"has_pupae" json:"has_pupae"`
IsReporterConfidential bool `db:"is_reporter_confidential" json:"is_reporter_confidential"`
IsReporterOwner bool `db:"is_reporter_owner" json:"is_reporter_owner"`
Owner Contact `db:"owner" json:"owner"`
ReportID int32 `db:"report_id" json:"-"`
}

View file

@ -1,19 +0,0 @@
package types
type Water struct {
AccessComments string `db:"access_comments" json:"access_comments"`
AccessGate bool `db:"access_gate" json:"access_gate"`
AccessFence bool `db:"access_fence" json:"access_fence"`
AccessLocked bool `db:"access_locked" json:"access_locked"`
AccessDog bool `db:"access_dog" json:"access_dog"`
AccessOther bool `db:"access_other" json:"access_other"`
Comments string `db:"comments" json:"comments"`
HasAdult bool `db:"has_adult" json:"has_adult"`
HasBackyardPermission bool `db:"has_backyard_permission" json:"has_backyard_permission"`
HasLarvae bool `db:"has_larvae" json:"has_larvae"`
HasPupae bool `db:"has_pupae" json:"has_pupae"`
IsReporterConfidential bool `db:"is_reporter_confidential" json:"is_reporter_confidential"`
IsReporterOwner bool `db:"is_reporter_owner" json:"is_reporter_owner"`
Owner Contact `db:"owner" json:"owner"`
ReportID int32 `db:"report_id" json:"-"`
}

View file

@ -56,7 +56,7 @@ func (res *communicationR) List(ctx context.Context, r *http.Request, user platf
comms[i] = communication{
Created: report.Created,
ID: report.PublicID,
PublicReport: report,
PublicReport: *report,
Type: "publicreport." + string(report.Type),
}
}

View file

@ -67,7 +67,7 @@ func (res *complianceR) Create(ctx context.Context, r *http.Request, n publicrep
ReportPhoneCanText: omitnull.FromPtr[bool](nil),
WantsScheduled: omitnull.FromPtr[bool](nil),
}
report, err := platform.ReportComplianceCreate(ctx, setter_report, setter_compliance)
report, err := platform.PublicReportComplianceCreate(ctx, setter_report, setter_compliance)
if err != nil {
return nil, nhttp.NewError("create compliance report: %w", err)
}

View file

@ -122,7 +122,7 @@ func (res *nuisanceR) Create(ctx context.Context, r *http.Request, n nuisanceFor
TodEvening: omit.From(n.TODEvening),
TodNight: omit.From(n.TODNight),
}
report, err := platform.ReportNuisanceCreate(ctx, setter_report, setter_nuisance, n.Location, address, uploads)
report, err := platform.PublicReportNuisanceCreate(ctx, setter_report, setter_nuisance, n.Location, address, uploads)
if err != nil {
return nil, nhttp.NewError("create nuisance report: %w", err)
}

View file

@ -36,15 +36,50 @@ func (res *publicreportR) ByID(ctx context.Context, r *http.Request, query Query
if err != nil {
return nil, nhttp.NewError("get report: %w", err)
}
var district_uri string
if report.DistrictID != nil {
district_uri, err = res.router.IDToURI("district.ByIDGet", int(*report.DistrictID))
if err != nil {
return nil, nhttp.NewError("district uri: %w", err)
}
}
populateDistrictURI(report, res.router)
populateReportURI(report, res.router)
report.District = &district_uri
return report, nil
}
func (res *publicreportR) ByIDCompliance(ctx context.Context, r *http.Request, query QueryParams) (*types.PublicReportCompliance, *nhttp.ErrorWithStatus) {
vars := mux.Vars(r)
public_id := vars["id"]
if public_id == "" {
return nil, nhttp.NewBadRequest("You must provid an ID")
}
report, err := platform.PublicreportByIDCompliance(ctx, public_id)
if err != nil {
return nil, nhttp.NewError("get report: %w", err)
}
populateDistrictURI(&report.PublicReport, res.router)
populateReportURI(&report.PublicReport, res.router)
return report, nil
}
func (res *publicreportR) ByIDNuisance(ctx context.Context, r *http.Request, query QueryParams) (*types.PublicReportNuisance, *nhttp.ErrorWithStatus) {
vars := mux.Vars(r)
public_id := vars["id"]
if public_id == "" {
return nil, nhttp.NewBadRequest("You must provid an ID")
}
report, err := platform.PublicreportByIDNuisance(ctx, public_id)
if err != nil {
return nil, nhttp.NewError("get report: %w", err)
}
populateDistrictURI(&report.PublicReport, res.router)
populateReportURI(&report.PublicReport, res.router)
return report, nil
}
func (res *publicreportR) ByIDWater(ctx context.Context, r *http.Request, query QueryParams) (*types.PublicReportWater, *nhttp.ErrorWithStatus) {
vars := mux.Vars(r)
public_id := vars["id"]
if public_id == "" {
return nil, nhttp.NewBadRequest("You must provid an ID")
}
report, err := platform.PublicreportByIDWater(ctx, public_id)
if err != nil {
return nil, nhttp.NewError("get report: %w", err)
}
populateDistrictURI(&report.PublicReport, res.router)
populateReportURI(&report.PublicReport, res.router)
return report, nil
}
@ -65,7 +100,7 @@ func (res *publicreportR) ImageCreate(ctx context.Context, r *http.Request, n nu
return nil, nhttp.NewError("Failed to extract image uploads: %w", err)
}
platform.ReportImageCreate(ctx, public_id, uploads)
platform.PublicReportImageCreate(ctx, public_id, uploads)
return &image{Status: "ok"}, nil
}
@ -115,6 +150,18 @@ func (res *publicreportR) Update(ctx context.Context, r *http.Request, prf publi
return report, nil
}
func populateDistrictURI(report *types.PublicReport, r *router) error {
var district_uri string
var err error
if report.DistrictID != nil {
district_uri, err = r.IDToURI("district.ByIDGet", int(*report.DistrictID))
if err != nil {
return nhttp.NewError("district uri: %w", err)
}
}
report.District = &district_uri
return nil
}
func populateReportURI(report *types.PublicReport, r *router) error {
var route_name string
switch report.Type {

View file

@ -111,7 +111,7 @@ func (res *waterR) Create(ctx context.Context, r *http.Request, w waterForm) (*w
OwnerPhone: omit.From(w.OwnerPhone),
//ReportID omit.Val[int32]
}
report, err := platform.ReportWaterCreate(ctx, setter_report, setter_water, w.Location, address, uploads)
report, err := platform.PublicReportWaterCreate(ctx, setter_report, setter_water, w.Location, address, uploads)
if err != nil {
return nil, nhttp.NewError("Failed to save new report: %w", err)
}

View file

@ -151,6 +151,7 @@ async function fetchExistingReport(report_uri: string) {
return;
}
const body = await resp.json();
report.value.comments = body.comments;
report.value.id = body.id;
report.value.images = body.images;
report.value.uri = body.uri;