diff --git a/api/handler.go b/api/handler.go index 6bfd15eb..8267db29 100644 --- a/api/handler.go +++ b/api/handler.go @@ -23,6 +23,7 @@ type ErrorAPI struct { var decoder = schema.NewDecoder() +type handlerBase func(context.Context, http.ResponseWriter, *http.Request) *nhttp.ErrorWithStatus type handlerFunctionDelete func(context.Context, *http.Request, platform.User) *nhttp.ErrorWithStatus type handlerFunctionGet[T any] func(context.Context, *http.Request, resource.QueryParams) (*T, *nhttp.ErrorWithStatus) type handlerFunctionGetAuthenticated[T any] func(context.Context, *http.Request, platform.User, resource.QueryParams) (*T, *nhttp.ErrorWithStatus) @@ -190,6 +191,16 @@ func authenticatedHandlerPostMultipart[ResponseType any](f handlerFunctionPostAu w.Write(body) }) } +func handlerBasic(f handlerBase) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + e := f(ctx, w, r) + if e != nil { + respondErrorStatus(w, e) + return + } + } +} func handlerJSON[T any](f handlerFunctionGet[T]) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/api/routes.go b/api/routes.go index 79f13c16..c406af72 100644 --- a/api/routes.go +++ b/api/routes.go @@ -81,7 +81,7 @@ func AddRoutes(r *mux.Router) { r.Handle("/geocode/reverse", handlerJSONPost(geocode.Reverse)).Methods("POST") r.Handle("/geocode/suggestion", handlerJSONSlice(geocode.SuggestionList)).Methods("GET") publicreport := resource.Publicreport(router) - r.Handle("/publicreport/{id}", handlerJSON(publicreport.ByID)).Methods("GET").Name("publicreport.ByIDGet") + r.Handle("/publicreport/{id}", handlerBasic(publicreport.ByID)).Methods("GET").Name("publicreport.ByIDGet") r.Handle("/publicreport/compliance/{id}/image", handlerFormPost(publicreport.ImageCreate)).Methods("POST") r.Handle("/publicreport/compliance/{id}", handlerJSON(compliance.ByID)).Methods("GET").Name("publicreport.compliance.ByIDGet") r.Handle("/publicreport/compliance/{id}", handlerJSONPut(compliance.Update)).Methods("PUT") diff --git a/platform/publicreport.go b/platform/publicreport.go index e4490acb..717b73f6 100644 --- a/platform/publicreport.go +++ b/platform/publicreport.go @@ -219,6 +219,15 @@ func PublicReportWaterCreate(ctx context.Context, setter_report models.Publicrep return nil }) } +func PublicReportTypeByID(ctx context.Context, public_id string) (string, error) { + report, err := models.PublicreportReports.Query( + models.SelectWhere.PublicreportReports.PublicID.EQ(public_id), + ).One(ctx, db.PGInstance.BobDB) + if err != nil { + return "", fmt.Errorf("query report '%s': %w", public_id, err) + } + return report.ReportType.String(), nil +} type funcSetReportDetail = func(context.Context, bob.Executor, int32) error diff --git a/resource/publicreport.go b/resource/publicreport.go index 6acdec44..42c90fc5 100644 --- a/resource/publicreport.go +++ b/resource/publicreport.go @@ -23,19 +23,22 @@ func Publicreport(r *router) *publicreportR { } } -func (res *publicreportR) ByID(ctx context.Context, r *http.Request, query QueryParams) (*types.PublicReport, *nhttp.ErrorWithStatus) { +func (res *publicreportR) ByID(ctx context.Context, w http.ResponseWriter, r *http.Request) *nhttp.ErrorWithStatus { vars := mux.Vars(r) public_id := vars["id"] if public_id == "" { - return nil, nhttp.NewBadRequest("You must provid an ID") + return nhttp.NewBadRequest("You must provide an ID") } - report, err := platform.PublicreportByID(ctx, public_id) + report_type, err := platform.PublicReportTypeByID(ctx, public_id) if err != nil { - return nil, nhttp.NewError("get report: %w", err) + return nhttp.NewError("get report '%s': %w", public_id, err) } - populateDistrictURI(report, res.router) - populateReportURI(report, res.router) - return report, nil + path, err := reportURI(res.router, report_type, public_id) + if err != nil { + return nhttp.NewError("get uri '%s': %w", public_id, err) + } + http.Redirect(w, r, path, http.StatusFound) + return nil } type image struct { @@ -72,8 +75,16 @@ func populateDistrictURI(report *types.PublicReport, r *router) error { return nil } func populateReportURI(report *types.PublicReport, r *router) error { + uri, err := reportURI(r, report.Type, report.PublicID) + if err != nil { + return fmt.Errorf("report uri: %w", err) + } + report.URI = uri + return nil +} +func reportURI(r *router, report_type string, public_id string) (string, error) { var route_name string - switch report.Type { + switch report_type { case "compliance": route_name = "publicreport.compliance.ByIDGet" case "nuisance": @@ -81,12 +92,11 @@ func populateReportURI(report *types.PublicReport, r *router) error { case "water": route_name = "publicreport.water.ByIDGet" default: - return fmt.Errorf("Unrecognized report type '%s'", report.Type) + return "", fmt.Errorf("Unrecognized report type '%s'", report_type) } - uri, err := r.IDStrToURI(route_name, report.PublicID) + uri, err := r.IDStrToURI(route_name, public_id) if err != nil { - return nhttp.NewError("uri: %w", err) + return "", fmt.Errorf("id str to uri '%s' '%s': %w", route_name, public_id, err) } - report.URI = uri - return nil + return uri, nil }