lint: remove unused rmo/ handler files

All route registrations in rmo/routes.go were commented out,
making the entire handler package dead code. Delete:
rmo/error.go, rmo/quick.go, rmo/report.go, rmo/nuisance.go,
rmo/root.go, rmo/status.go, rmo/notification.go
This commit is contained in:
Eli Ribble 2026-05-09 17:12:50 +00:00
parent b9a68aab04
commit fbb95920dc
7 changed files with 0 additions and 640 deletions

View file

@ -1,32 +0,0 @@
package rmo
import (
"net/http"
//"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/html"
)
type ContentError struct {
Code string
District *ContentDistrict
URL ContentURL
}
func getError(w http.ResponseWriter, r *http.Request) {
code := r.FormValue("code")
district, err := districtBySlug(r)
if err != nil {
//respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
district = nil
}
html.RenderOrError(
w,
"rmo/error.html",
ContentError{
Code: code,
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}

View file

@ -1 +0,0 @@
package rmo

View file

@ -1,64 +0,0 @@
package rmo
import (
"fmt"
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/Gleipnir-Technology/nidus-sync/platform/report"
//"github.com/rs/zerolog/log"
)
type ContentNuisance struct {
District *ContentDistrict
MapboxToken string
URL ContentURL
}
type ContentNuisanceSubmitComplete struct {
District *ContentDistrict
ReportID string
URL ContentURL
}
func getNuisance(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/nuisance.html",
ContentNuisance{
District: nil,
URL: makeContentURL(nil),
},
)
}
func getNuisanceDistrict(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/nuisance.html",
ContentNuisance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getSubmitComplete(w http.ResponseWriter, r *http.Request) {
report_id := r.URL.Query().Get("report")
district, err := report.DistrictForReport(r.Context(), report_id)
if err != nil {
respondError(w, fmt.Sprintf("Failed to get district for report '%s'", report_id, err), err, http.StatusInternalServerError)
return
}
html.RenderOrError(
w,
"rmo/submit-complete.html",
ContentNuisanceSubmitComplete{
District: newContentDistrict(district),
ReportID: report_id,
URL: makeContentURL(nil),
},
)
}

View file

@ -1,26 +0,0 @@
package rmo
import (
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/html"
)
type ContentRegisterNotificationsComplete struct {
ReportID string
}
type District struct {
LogoURL string
Name string
}
func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) {
report := r.URL.Query().Get("report")
html.RenderOrError(
w,
"rmo/register-notifications-complete.html",
ContentRegisterNotificationsComplete{
ReportID: report,
},
)
}

View file

@ -1,89 +0,0 @@
package rmo
import (
"encoding/json"
"net/http"
"strings"
//"github.com/Gleipnir-Technology/nidus-sync/config"
"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"
"github.com/Gleipnir-Technology/nidus-sync/lint"
//"github.com/gorilla/mux"
"github.com/stephenafamo/scan"
//"github.com/rs/zerolog/log"
)
type ReportSuggestion struct {
ID string `json:"id"`
//Type string `json:"type"`
//Location string
}
type ReportSuggestionResponse struct {
Reports []ReportSuggestion `json:"reports"`
}
func getReportSuggestion(w http.ResponseWriter, r *http.Request) {
partial_report_id := r.FormValue("r")
if partial_report_id == "" {
respondError(w, "You need at least a bit of an 'r'", nil, http.StatusBadRequest)
return
}
p := partialSearchParam(partial_report_id)
ctx := r.Context()
/*
rows, err := sql.PublicreportPublicIDSuggestion(p).All(ctx, db.PGInstance.BobDB)
if err != nil {
respondError(w, "Failed to query DB: %w", err, http.StatusInternalServerError)
return
}
*/
type _Row struct {
Location string `db:"location"`
PublicID string `db:"public_id"`
}
rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns("public_id", "location"),
sm.From("publicreport.report"),
sm.Where(
psql.Quote("public_id").Like(psql.Arg(p)),
),
), scan.StructMapper[_Row]())
var result ReportSuggestionResponse
for _, row := range rows {
/*
value, err := row.Location.Value()
if err != nil {
log.Warn().Err(err).Msg("Failed to get value")
continue
}
value_str, ok := value.(string)
if !ok {
log.Warn().Msg("Failed to get location as string")
continue
}
log.Debug().Str("location", value_str).Msg("Looking at row")
*/
result.Reports = append(result.Reports, ReportSuggestion{
//Type: row.TableName,
ID: row.PublicID,
//Location: "",
})
}
jsonBody, err := json.Marshal(result)
if err != nil {
respondError(w, "Failed to marshal JSON: %w", err, http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
lint.Write(w, jsonBody)
}
func partialSearchParam(p string) string {
result := strings.ReplaceAll(p, "-", "")
result = strings.ToUpper(result)
return result + "%"
}

View file

@ -1,123 +0,0 @@
package rmo
import (
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/lint"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/rs/zerolog/log"
)
type ContentPrivacy struct {
Address string
Company string
Site string
URLReport string
}
type ContentRoot struct {
District *ContentDistrict
URL ContentURL
}
type ContentURL struct {
Nuisance string
NuisanceSubmit string
SubmitComplete string
Status string
Tegola string
Water string
WaterSubmit string
}
func boolFromForm(r *http.Request, k string) bool {
s := r.PostFormValue(k)
if s == "on" {
return true
}
return false
}
func getPrivacy(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/privacy.html",
ContentPrivacy{
Address: "2726 S Quinn Ave, Gilbert, AZ, USA",
Company: "Gleipnir LLC",
Site: "Report Mosquitoes Online",
URLReport: config.MakeURLReport("/"),
},
)
}
func getRoot(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/root.html",
ContentRoot{
URL: makeContentURL(nil),
},
)
}
func getRootDistrict(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/root.html",
ContentRoot{
District: newContentDistrict(district),
URL: makeContentURL(district),
},
)
}
func getRobots(w http.ResponseWriter, r *http.Request) {
lint.Fprint(w, "User-agent: *\n")
lint.Fprint(w, "Allow: /\n")
}
func getTerms(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/terms.html",
ContentRoot{
URL: makeContentURL(nil),
},
)
}
func makeContentURL(district *models.Organization) ContentURL {
if district == nil || district.Slug.IsNull() {
return ContentURL{
Nuisance: makeURL("/nuisance"),
NuisanceSubmit: makeURL("/nuisance"),
Status: makeURL("/status"),
Tegola: config.MakeURLTegola("/"),
Water: makeURL("/water"),
WaterSubmit: makeURL("/water"),
}
} else {
slug := district.Slug.MustGet()
return ContentURL{
Nuisance: makeURL("/district/%s/nuisance", slug),
NuisanceSubmit: makeURL("/nuisance", slug),
Status: makeURL("/status"),
Tegola: config.MakeURLTegola("/"),
Water: makeURL("/district/%s/water", slug),
WaterSubmit: makeURL("/water"),
}
}
}
func makeURL(f string, args ...string) string {
return config.MakeURLReport(f, args...)
}
// Respond with an error that is visible to the user
func respondError(w http.ResponseWriter, m string, e error, s int) {
log.Warn().Int("status", s).Err(e).Str("user message", m).Msg("Responding with an error")
http.Error(w, m, s)
}

View file

@ -1,305 +0,0 @@
package rmo
import (
"context"
"fmt"
"net/http"
"strconv"
"strings"
"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"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/google/uuid"
"github.com/gorilla/mux"
//"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
type ContentStatus struct {
District *ContentDistrict
Error string
ReportID string
URL ContentURL
}
type ContentStatusByID struct {
District *ContentDistrict
Report Report
Timeline []TimelineEntry
URL ContentURL
}
type DetailEntry struct {
Name string
Value string
}
type Report struct {
Address string
Comments string
Created time.Time
Details []DetailEntry
ID string
ImageCount int
Location string // GeoJSON
Status string
Type string
}
type TimelineEntry struct {
At time.Time
Detail string
Title string
}
func formatReportID(s string) string {
// truncate down if too long
if len(s) > 12 {
s = s[:12]
}
// If less than 4 characters, return as is
if len(s) < 4 {
return s
}
// If at least 8 characters, add hyphens at positions 4 and 8
if len(s) >= 8 {
return s[0:4] + "-" + s[4:8] + "-" + s[8:]
}
// If at least 4 characters but less than 8, add hyphen only at position 4
return s[0:4] + "-" + s[4:]
}
func getStatus(w http.ResponseWriter, r *http.Request) {
report_id_str := r.URL.Query().Get("report")
content := ContentStatus{
Error: "",
ReportID: "",
URL: makeContentURL(nil),
}
if report_id_str == "" {
html.RenderOrError(w, "rmo/status.html", content)
return
}
report_id := sanitizeReportID(report_id_str)
report_id_str = formatReportID(report_id)
//some_report, e := report.FindSomeReport(r.Context(), report_id)
content.Error = "Sorry, we can't find that report"
html.RenderOrError(w, "rmo/status.html", content)
}
func contentFromReport(ctx context.Context, report *models.PublicreportReport) (result ContentStatusByID, err error) {
org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, report.OrganizationID)
if err != nil {
return result, fmt.Errorf("Failed to get district information: %w", err)
}
type _Row struct {
ID int32 `db:"id"`
ContentType string `db:"content_type"`
Created time.Time `db:"created"`
Location string `db:"location"`
LocationJSON string `db:"location_json"`
ResolutionX int32 `db:"resolution_x"`
ResolutionY int32 `db:"resolution_y"`
StorageUUID uuid.UUID `db:"storage_uuid"`
StorageSize int32 `db:"storage_size"`
UploadedFilename string `db:"uploaded_filename"`
}
images, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
"id",
"content_type",
"created",
"location",
"COALESCE(ST_AsGeoJSON(location), '{}') AS location_json",
"resolution_x",
"resolution_y",
"storage_uuid",
"storage_size",
"uploaded_filename",
),
sm.From("publicreport.image"),
sm.InnerJoin("publicreport.report_image").OnEQ(
psql.Quote("publicreport", "image", "id"),
psql.Quote("publicreport", "report_image", "image_id"),
),
sm.Where(
psql.Quote("publicreport", "report_image", "report_id").EQ(psql.Arg(report.ID)),
),
), scan.StructMapper[_Row]())
if err != nil {
return result, fmt.Errorf("Failed to get images: %w", err)
}
result.District = newContentDistrict(org)
result.Report.ID = report.PublicID
result.Report.Address = report.AddressRaw
result.Report.Created = report.Created
result.Report.ImageCount = len(images)
result.Report.Status = cases.Title(language.AmericanEnglish).String(report.Status.String())
result.Timeline = []TimelineEntry{
TimelineEntry{
At: report.Created,
Detail: "Initial report was submitted",
Title: "Created",
},
}
type LocationGeoJSON struct {
Location string
}
location, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
psql.F("ST_AsGeoJSON", "location"),
),
sm.From("publicreport.report"),
sm.Where(psql.Quote("id").EQ(psql.Arg(report.ID))),
), scan.SingleColumnMapper[string])
if err != nil {
return result, fmt.Errorf("Failed to query location of report %d: %w", report.ID, err)
}
result.Report.Location = location
nuisance, err := models.PublicreportNuisances.Query(
models.SelectWhere.PublicreportNuisances.ReportID.EQ(report.ID),
).One(ctx, db.PGInstance.BobDB)
if err == nil {
result.Report.Type = "Mosquito Nuisance"
addContentFromNuisance(&result, nuisance)
}
water, err := models.PublicreportWaters.Query(
models.SelectWhere.PublicreportWaters.ReportID.EQ(report.ID),
).One(ctx, db.PGInstance.BobDB)
if err == nil {
result.Report.Type = "Standing Water"
addContentFromWater(&result, water)
}
return result, nil
}
func addContentFromNuisance(result *ContentStatusByID, nuisance *models.PublicreportNuisance) {
result.Report.Type = "Mosquito Nuisance"
result.Report.Details = []DetailEntry{
DetailEntry{
Name: "Active early morning (5a-8a)?",
Value: strconv.FormatBool(nuisance.TodEarly),
},
DetailEntry{
Name: "Active daytime (8a-5p)?",
Value: strconv.FormatBool(nuisance.TodDay),
},
DetailEntry{
Name: "Active evening (5p-9p)?",
Value: strconv.FormatBool(nuisance.TodEvening),
},
DetailEntry{
Name: "Active night (9p-5a)?",
Value: strconv.FormatBool(nuisance.TodNight),
},
DetailEntry{
Name: "Duration",
Value: nuisance.Duration.String(),
},
DetailEntry{
Name: "Active in backyard?",
Value: strconv.FormatBool(nuisance.IsLocationBackyard),
},
DetailEntry{
Name: "Active in frontyard?",
Value: strconv.FormatBool(nuisance.IsLocationFrontyard),
},
DetailEntry{
Name: "Active in garden?",
Value: strconv.FormatBool(nuisance.IsLocationGarden),
},
DetailEntry{
Name: "Active in other location?",
Value: strconv.FormatBool(nuisance.IsLocationOther),
},
DetailEntry{
Name: "Active in pool area?",
Value: strconv.FormatBool(nuisance.IsLocationPool),
},
DetailEntry{
Name: "Stagnant Water",
Value: strconv.FormatBool(nuisance.SourceStagnant),
},
DetailEntry{
Name: "Container",
Value: strconv.FormatBool(nuisance.SourceContainer),
},
DetailEntry{
Name: "Sprinklers & Gutters",
Value: strconv.FormatBool(nuisance.SourceGutter),
},
}
}
func addContentFromWater(result *ContentStatusByID, water *models.PublicreportWater) {
result.Report.Details = []DetailEntry{
DetailEntry{
Name: "Has a gate that affects access?",
Value: strconv.FormatBool(water.AccessGate),
},
DetailEntry{
Name: "Has dog that affects access?",
Value: strconv.FormatBool(water.AccessDog),
},
DetailEntry{
Name: "Has a fence that affects access?",
Value: strconv.FormatBool(water.AccessFence),
},
DetailEntry{
Name: "Has a locked entrace that affects access?",
Value: strconv.FormatBool(water.AccessLocked),
},
DetailEntry{
Name: "Reporter observed larvae (wigglers)?",
Value: strconv.FormatBool(water.HasLarvae),
},
DetailEntry{
Name: "Reporter observed pupae (tumblers)?",
Value: strconv.FormatBool(water.HasPupae),
},
DetailEntry{
Name: "Reporter observed adult mosquitoes?",
Value: strconv.FormatBool(water.HasAdult),
},
}
}
func getStatusByID(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
report_id := vars["report_id"]
ctx := r.Context()
report, err := models.PublicreportReports.Query(
models.SelectWhere.PublicreportReports.PublicID.EQ(report_id),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
respondError(w, "Failed to find report", err, http.StatusBadRequest)
return
}
content, err := contentFromReport(ctx, report)
if err != nil {
respondError(w, "Failed to generate report content", err, http.StatusInternalServerError)
return
}
content.URL = makeContentURL(nil)
html.RenderOrError(
w,
"rmo/status-by-id.html",
content,
)
}
func sanitizeReportID(r string) string {
result := ""
for _, char := range r {
if char != '-' {
result += string(char)
}
}
return strings.ToUpper(result)
}