Actually update reports when a subscriber subscribes

This commit is contained in:
Eli Ribble 2026-01-31 20:57:34 +00:00
parent 1d7484ef4d
commit f20067b323
No known key found for this signature in database
4 changed files with 106 additions and 38 deletions

View file

@ -12,12 +12,10 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/background"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/sql"
"github.com/nyaruka/phonenumbers"
"github.com/Gleipnir-Technology/nidus-sync/platform/text"
"github.com/rs/zerolog/log"
)
type E164 = phonenumbers.PhoneNumber
type ErrorWithCode struct {
code string
err error
@ -32,8 +30,63 @@ func (e *ErrorWithCode) Error() string {
}
type SomeReport struct {
report_id string
type_ string
reportID string
tableName string
}
func (sr SomeReport) updateReporterEmail(ctx context.Context, email string) *ErrorWithCode {
table := um.Table("so-such-table")
switch sr.tableName {
case "nuisance":
table = um.Table("publicreport.nuisance")
case "pool":
table = um.Table("publicreport.pool")
default:
return newErrorWithCode("internal-error", "Programmer error: unrecognized table")
}
result, err := psql.Update(
table,
um.SetCol("reporter_email").ToArg(email),
um.Where(psql.Quote("public_id").EQ(psql.Arg(sr.reportID))),
).Exec(ctx, db.PGInstance.BobDB)
if err != nil {
return newErrorWithCode("internal-error", "Failed to update report: %w", err)
}
rowcount, err := result.RowsAffected()
if err != nil {
return newErrorWithCode("internal-error", "Failed to get rows affected: %w", err)
}
if rowcount != 1 {
log.Warn().Str("report_id", sr.reportID).Msg("updated more than one row, which is a programmer error")
}
return nil
}
func (sr SomeReport) updateReporterPhone(ctx context.Context, phone text.E164) *ErrorWithCode {
table := um.Table("so-such-table")
switch sr.tableName {
case "nuisance":
table = um.Table("publicreport.nuisance")
case "pool":
table = um.Table("publicreport.pool")
default:
return newErrorWithCode("internal-error", "Programmer error: unrecognized table")
}
result, err := psql.Update(
table,
um.SetCol("reporter_phone").ToArg(text.PhoneString(phone)),
um.Where(psql.Quote("public_id").EQ(psql.Arg(sr.reportID))),
).Exec(ctx, db.PGInstance.BobDB)
if err != nil {
return newErrorWithCode("internal-error", "Failed to update report: %w", err)
}
rowcount, err := result.RowsAffected()
if err != nil {
return newErrorWithCode("internal-error", "Failed to get rows affected: %w", err)
}
if rowcount != 1 {
log.Warn().Str("report_id", sr.reportID).Msg("updated more than one row, which is a programmer error")
}
return nil
}
// GenerateReportID creates a 12-character random string using only unambiguous
@ -61,29 +114,29 @@ func GenerateReportID() (string, error) {
return builder.String(), nil
}
func RegisterNotifications(ctx context.Context, report_id string, email string, phone *E164) *ErrorWithCode {
result, err := psql.Update(
um.Table("publicreport.quick"),
um.SetCol("reporter_email").ToArg(email),
um.SetCol("reporter_phone").ToArg(phone),
um.Where(psql.Quote("public_id").EQ(psql.Arg(report_id))),
).Exec(ctx, db.PGInstance.BobDB)
func RegisterNotificationEmail(ctx context.Context, report_id string, email string) *ErrorWithCode {
some_report, err := findSomeReport(ctx, report_id)
if err != nil {
return newErrorWithCode("internal-error", "Failed to update report: %w", err)
return err
}
rowcount, err := result.RowsAffected()
err = some_report.updateReporterEmail(ctx, email)
if err != nil {
return newErrorWithCode("internal-error", "Failed to get rows affected: %w", err)
return err
}
if rowcount != 1 {
log.Warn().Str("report_id", report_id).Msg("updated more than one row, which is a programmer error")
background.ReportSubscriptionConfirmationEmail(email, report_id)
return nil
}
func RegisterNotificationPhone(ctx context.Context, report_id string, phone text.E164) *ErrorWithCode {
some_report, err := findSomeReport(ctx, report_id)
if err != nil {
return err
}
if email != "" {
background.ReportSubscriptionConfirmationEmail(email, report_id)
}
if phone != nil {
background.ReportSubscriptionConfirmationText(*phone, report_id)
err = some_report.updateReporterPhone(ctx, phone)
if err != nil {
return err
}
background.ReportSubscriptionConfirmationText(phone, report_id)
return nil
}
@ -91,7 +144,7 @@ func RegisterSubscriptionEmail(ctx context.Context, email string) *ErrorWithCode
log.Warn().Msg("RegisterSubscription not implemented yet")
return nil
}
func RegisterSubscriptionPhone(ctx context.Context, phone *E164) *ErrorWithCode {
func RegisterSubscriptionPhone(ctx context.Context, phone text.E164) *ErrorWithCode {
log.Warn().Msg("RegisterSubscription not implemented yet")
return nil
}
@ -109,6 +162,9 @@ func findSomeReport(ctx context.Context, report_id string) (result SomeReport, e
default:
return result, newErrorWithCode("internal-error", "More than one report with the provided ID, which shouldn't happen")
}
row := rows[0]
result.reportID = report_id
result.tableName = row.FoundInTables[0]
return result, nil
}

View file

@ -23,6 +23,10 @@ import (
type E164 = phonenumbers.PhoneNumber
func PhoneString(p E164) string {
return phonenumbers.Format(&p, phonenumbers.E164)
}
func HandleTextMessage(src string, dst string, body string) {
ctx := context.Background()

View file

@ -31,31 +31,39 @@ func postRegisterNotifications(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, fmt.Sprintf("/submit-complete?report=%s", report_id), http.StatusFound)
return
}
phone, err := text.ParsePhoneNumber(phone_str)
if err != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=invalid-phone&report=%s", report_id), http.StatusFound)
return
var phone *text.E164
if phone_str != "" {
phone, err = text.ParsePhoneNumber(phone_str)
if err != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=invalid-phone&report=%s", report_id), http.StatusFound)
return
}
}
ctx := r.Context()
if subscribe != nil && *subscribe {
if email != "" {
if email != "" {
if subscribe != nil && *subscribe {
e := report.RegisterSubscriptionEmail(ctx, email)
if e != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=%s&report=%s", report_id, e.Code()), http.StatusFound)
}
}
if phone_str != "" {
e := report.RegisterSubscriptionPhone(ctx, phone)
e := report.RegisterNotificationEmail(ctx, report_id, email)
if e != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=%s&report=%s", report_id, e.Code()), http.StatusFound)
}
}
if phone != nil {
if subscribe != nil && *subscribe {
e := report.RegisterSubscriptionPhone(ctx, *phone)
if e != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=%s&report=%s", report_id, e.Code()), http.StatusFound)
}
}
e := report.RegisterNotificationPhone(ctx, report_id, *phone)
if e != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=%s&report=%s", report_id, e.Code()), http.StatusFound)
}
}
e := report.RegisterNotifications(ctx, report_id, email, phone)
if e != nil {
http.Redirect(w, r, fmt.Sprintf("/error?code=%s&report=%s", report_id, e.Code()), http.StatusFound)
} else {
http.Redirect(w, r, fmt.Sprintf("/register-notifications-complete?report=%s", report_id), http.StatusFound)
}
http.Redirect(w, r, fmt.Sprintf("/register-notifications-complete?report=%s", report_id), http.StatusFound)
}

View file

@ -114,5 +114,5 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
return
}
log.Info().Str("public_id", public_id).Int32("id", nuisance.ID).Msg("Created nuisance report")
http.Redirect(w, r, fmt.Sprintf("/nuisance-submit-complete?report=%s", public_id), http.StatusFound)
http.Redirect(w, r, fmt.Sprintf("/submit-complete?report=%s", public_id), http.StatusFound)
}