Add an evidence field to compliance reports

This allows us to show a page with information about what the district
is concerned about when asking the user to fill a report.
This commit is contained in:
Eli Ribble 2026-04-21 21:35:40 +00:00
parent a0ac5c0674
commit fe2041f22b
No known key found for this signature in database
7 changed files with 99 additions and 32 deletions

View file

@ -25,7 +25,7 @@ func AddRoutes(r *mux.Router) {
r.Handle("/communication", authenticatedHandlerJSON(communication.List)).Methods("GET")
compliance_request := resource.ComplianceRequest(router)
r.Handle("/compliance-request/mailer", authenticatedHandlerJSONPost(compliance_request.CreateMailer)).Methods("POST")
r.HandleFunc("/compliance-request/image/pool/{public_id}", compliance_request.ImagePoolGet).Methods("GET")
r.HandleFunc("/compliance-request/image/pool/{public_id}", compliance_request.ImagePoolGet).Methods("GET").Name("compliance-request.image.pool.ByIDGet")
//r.HandleFunc("/compliance-request/image/pool/{public_id}", getComplianceRequestImagePool).Methods("GET")
r.Handle("/configuration/integration/arcgis", authenticatedHandlerJSONPost(postConfigurationIntegrationArcgis)).Methods("POST")
r.Handle("/events", auth.NewEnsureAuth(streamEvents)).Methods("GET")

View file

@ -121,3 +121,15 @@ func ComplianceReportRequestByLeadID(ctx context.Context, lead_ids []int32) (map
}
return results, nil
}
func ComplianceReportRequestFromPublicID(ctx context.Context, public_id string) (*types.ComplianceReportRequest, error) {
row, err := models.ComplianceReportRequests.Query(
sm.Where(models.ComplianceReportRequests.Columns.PublicID.EQ(psql.Arg(public_id))),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
if err.Error() == "sql: no rows in result set" {
return nil, nil
}
return nil, fmt.Errorf("query CRR: %w", err)
}
return types.ComplianceReportRequestFromModel(row), nil
}

View file

@ -57,7 +57,23 @@ func PublicreportByID(ctx context.Context, report_id string) (*types.PublicRepor
return publicreport.ByID(ctx, report_id)
}
func PublicreportByIDCompliance(ctx context.Context, report_id string) (*types.PublicReportCompliance, error) {
return publicreport.ByIDCompliance(ctx, report_id)
result, err := publicreport.ByIDCompliance(ctx, report_id)
if err != nil {
return nil, fmt.Errorf("byidcompliance: %w", err)
}
// Check for evidence if this is a mailer-based compliance request
crr, err := ComplianceReportRequestFromPublicID(ctx, result.PublicID)
if err != nil {
return nil, fmt.Errorf("compliance report request by public id: %w", err)
}
if crr != nil {
result.Evidence = []*types.EvidenceComplianceReportRequest{
&types.EvidenceComplianceReportRequest{
ComplianceReportRequestPublicID: crr.PublicID,
},
}
}
return result, nil
}
func PublicreportByIDNuisance(ctx context.Context, report_id string) (*types.PublicReportNuisance, error) {
return publicreport.ByIDNuisance(ctx, report_id)

View file

@ -9,6 +9,7 @@ import (
"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/db/models"
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
//"github.com/google/uuid"
//"github.com/rs/zerolog/log"
@ -18,18 +19,18 @@ import (
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",
models.PublicreportCompliances.Columns.AccessInstructions,
models.PublicreportCompliances.Columns.AvailabilityNotes,
models.PublicreportCompliances.Columns.Comments,
models.PublicreportCompliances.Columns.GateCode,
models.PublicreportCompliances.Columns.HasDog,
models.PublicreportCompliances.Columns.PermissionType,
models.PublicreportCompliances.Columns.ReportID,
models.PublicreportCompliances.Columns.ReportPhoneCanText,
models.PublicreportCompliances.Columns.WantsScheduled,
),
sm.From("publicreport.compliance"),
sm.Where(psql.Quote("report_id").EQ(
sm.From(models.PublicreportCompliances.Name()),
sm.Where(models.PublicreportCompliances.Columns.ReportID.EQ(
psql.Arg(report.ID),
)),
), scan.StructMapper[types.PublicReportCompliance]())
@ -37,6 +38,7 @@ func compliance(ctx context.Context, public_id string, report *types.PublicRepor
return nil, fmt.Errorf("query compliance: %w", err)
}
copyReportContent(report, &row.PublicReport)
return &row, nil
}

View file

@ -0,0 +1,32 @@
package types
import (
"fmt"
"github.com/gorilla/mux"
"github.com/rs/zerolog/log"
)
type Evidence interface {
PopulateURL(*mux.Router) error
}
type EvidenceComplianceReportRequest struct {
ComplianceReportRequestPublicID string
URL string
}
func (e *EvidenceComplianceReportRequest) PopulateURL(r *mux.Router) error {
route_name := "compliance-request.image.pool.ByIDGet"
handler := r.Get(route_name)
if handler == nil {
return fmt.Errorf("failed to get handler '%s'", route_name)
}
uri, err := handler.URL("public_id", e.ComplianceReportRequestPublicID)
if err != nil {
return fmt.Errorf("failed to create uri from '%s'", e.ComplianceReportRequestPublicID)
}
uri.Scheme = "https"
e.URL = uri.String()
log.Debug().Str("url", e.URL).Msg("populated evidence URL")
return nil
}

View file

@ -5,19 +5,20 @@ import (
)
type PublicReport struct {
Address Address `db:"address" json:"address"`
Created time.Time `db:"created" json:"created"`
ID int32 `db:"id" json:"-"`
Images []Image `db:"images" json:"images"`
Location *Location `db:"location" json:"location"`
Log []LogEntry `db:"-" json:"log"`
DistrictID *int32 `db:"organization_id" json:"-"`
District *string `db:"-" json:"district"`
PublicID string `db:"public_id" json:"public_id"`
Reporter Contact `db:"reporter" json:"reporter"`
Status string `db:"status" json:"status"`
Type string `db:"report_type" json:"type"`
URI string `db:"-" json:"uri"`
Address Address `db:"address" json:"address"`
Created time.Time `db:"created" json:"created"`
Evidence []*EvidenceComplianceReportRequest `db:"-" json:"evidence"`
ID int32 `db:"id" json:"-"`
Images []Image `db:"images" json:"images"`
Location *Location `db:"location" json:"location"`
Log []LogEntry `db:"-" json:"log"`
DistrictID *int32 `db:"organization_id" json:"-"`
District *string `db:"-" json:"district"`
PublicID string `db:"public_id" json:"public_id"`
Reporter Contact `db:"reporter" json:"reporter"`
Status string `db:"status" json:"status"`
Type string `db:"report_type" json:"type"`
URI string `db:"-" json:"uri"`
}
type PublicReportCompliance struct {
PublicReport

View file

@ -55,9 +55,7 @@ func (res *complianceR) ByID(ctx context.Context, r *http.Request, query QueryPa
if err != nil {
return nil, nhttp.NewError("get report: %w", err)
}
populateDistrictURI(&report.PublicReport, res.router)
populateReportURI(&report.PublicReport, res.router)
return report, nil
return res.complianceHydrate(report)
}
func (res *complianceR) Create(ctx context.Context, r *http.Request, n publicreportComplianceForm) (*types.PublicReportCompliance, *nhttp.ErrorWithStatus) {
if n.District.IsUnset() {
@ -112,9 +110,7 @@ func (res *complianceR) Create(ctx context.Context, r *http.Request, n publicrep
if err != nil {
return nil, nhttp.NewError("get report after creation: %w", err)
}
populateDistrictURI(&result.PublicReport, res.router)
populateReportURI(&result.PublicReport, res.router)
return result, nil
return res.complianceHydrate(result)
}
func (res *complianceR) Update(ctx context.Context, r *http.Request, prf publicreportComplianceForm) (*types.PublicReportCompliance, *nhttp.ErrorWithStatus) {
vars := mux.Vars(r)
@ -188,5 +184,13 @@ func (res *complianceR) Update(ctx context.Context, r *http.Request, prf publicr
if err != nil {
return nil, nhttp.NewError("get report after update: %w", err)
}
return res.complianceHydrate(report)
}
func (res *complianceR) complianceHydrate(report *types.PublicReportCompliance) (*types.PublicReportCompliance, *nhttp.ErrorWithStatus) {
populateDistrictURI(&report.PublicReport, res.router)
populateReportURI(&report.PublicReport, res.router)
for _, e := range report.Evidence {
e.PopulateURL(res.router.router)
}
return report, nil
}