2026-01-31 20:08:08 +00:00
|
|
|
package report
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
2026-02-10 04:31:57 +00:00
|
|
|
"time"
|
2026-01-31 20:08:08 +00:00
|
|
|
|
2026-02-01 02:37:35 +00:00
|
|
|
"github.com/Gleipnir-Technology/bob"
|
2026-01-31 20:08:08 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/db"
|
2026-02-01 02:37:35 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
2026-02-10 04:07:59 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform/email"
|
2026-01-31 20:57:34 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform/text"
|
2026-03-16 19:52:29 +00:00
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
|
|
|
|
|
"github.com/aarondl/opt/omit"
|
|
|
|
|
"github.com/aarondl/opt/omitnull"
|
2026-04-08 17:49:32 +00:00
|
|
|
//"github.com/rs/zerolog/log"
|
2026-01-31 20:08:08 +00:00
|
|
|
)
|
|
|
|
|
|
2026-02-01 02:37:35 +00:00
|
|
|
func DistrictForReport(ctx context.Context, report_id string) (*models.Organization, error) {
|
2026-03-18 15:36:20 +00:00
|
|
|
report, err := reportByPublicID(ctx, db.PGInstance.BobDB, report_id)
|
2026-02-01 02:37:35 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Failed to find report %s: %w", report_id, err)
|
|
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
result, e := models.FindOrganization(ctx, db.PGInstance.BobDB, report.OrganizationID)
|
2026-02-01 02:37:35 +00:00
|
|
|
if e != nil {
|
2026-03-18 15:36:20 +00:00
|
|
|
return nil, fmt.Errorf("Failed to load organization %d: %w", report.OrganizationID, e)
|
2026-02-01 02:37:35 +00:00
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 17:49:32 +00:00
|
|
|
func RegisterNotificationEmail(ctx context.Context, txn bob.Executor, report_id string, destination string) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
report, e := reportByPublicID(ctx, db.PGInstance.BobDB, report_id)
|
|
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to find report: %w", e)
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
e = email.EnsureInDB(ctx, destination)
|
2026-02-10 04:07:59 +00:00
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to ensure phone is in DB: %w", e)
|
2026-02-10 04:07:59 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
err := addNotificationEmail(ctx, txn, report, destination)
|
2026-01-31 20:08:08 +00:00
|
|
|
if err != nil {
|
2026-01-31 20:57:34 +00:00
|
|
|
return err
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|
2026-03-16 19:52:29 +00:00
|
|
|
email.SendReportConfirmation(ctx, destination, report_id)
|
2026-01-31 20:57:34 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 17:49:32 +00:00
|
|
|
func RegisterNotificationPhone(ctx context.Context, txn bob.Executor, report_id string, phone types.E164) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
report, e := reportByPublicID(ctx, db.PGInstance.BobDB, report_id)
|
|
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to find report: %w", e)
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
e = text.EnsureInDB(ctx, db.PGInstance.BobDB, phone)
|
2026-02-10 04:07:59 +00:00
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to ensure phone is in DB: %w", e)
|
2026-02-10 04:07:59 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
err := addNotificationPhone(ctx, txn, report, phone)
|
2026-01-31 20:57:34 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
text.ReportSubscriptionConfirmationText(ctx, db.PGInstance.BobDB, phone, report.PublicID)
|
2026-01-31 20:08:08 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 17:49:32 +00:00
|
|
|
func RegisterSubscriptionEmail(ctx context.Context, txn bob.Executor, destination string) error {
|
2026-02-10 04:31:57 +00:00
|
|
|
e := email.EnsureInDB(ctx, destination)
|
|
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to ensure email is in DB: %w", e)
|
2026-02-10 04:31:57 +00:00
|
|
|
}
|
|
|
|
|
setter := models.PublicreportSubscribeEmailSetter{
|
|
|
|
|
Created: omit.From(time.Now()),
|
|
|
|
|
Deleted: omitnull.FromPtr[time.Time](nil),
|
|
|
|
|
//DistrictID: omit.FromPtr[int32](nil),
|
|
|
|
|
EmailAddress: omit.From(destination),
|
|
|
|
|
}
|
|
|
|
|
_, err := models.PublicreportSubscribeEmails.Insert(&setter).Exec(ctx, txn)
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to save new subscription email row: %w", err)
|
2026-02-10 04:31:57 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-31 20:08:08 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func RegisterSubscriptionPhone(ctx context.Context, txn bob.Executor, phone types.E164) error {
|
2026-02-14 05:05:31 +00:00
|
|
|
e := text.EnsureInDB(ctx, db.PGInstance.BobDB, phone)
|
2026-02-10 04:31:57 +00:00
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to ensure phone is in DB: %w", e)
|
2026-02-10 04:31:57 +00:00
|
|
|
}
|
|
|
|
|
setter := models.PublicreportSubscribePhoneSetter{
|
|
|
|
|
Created: omit.From(time.Now()),
|
|
|
|
|
Deleted: omitnull.FromPtr[time.Time](nil),
|
|
|
|
|
//DistrictID: omitnull.FromPtr[int32](nil),
|
2026-03-16 19:52:29 +00:00
|
|
|
PhoneE164: omit.From(phone.PhoneString()),
|
2026-02-10 04:31:57 +00:00
|
|
|
}
|
|
|
|
|
_, err := models.PublicreportSubscribePhones.Insert(&setter).Exec(ctx, txn)
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to save new subscription phone row: %w", err)
|
2026-02-10 04:31:57 +00:00
|
|
|
}
|
2026-01-31 20:08:08 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 17:49:32 +00:00
|
|
|
func SaveReporter(ctx context.Context, txn bob.Executor, report_id string, name string, email string, phone *types.E164, has_consent bool) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
report, e := reportByPublicID(ctx, db.PGInstance.BobDB, report_id)
|
|
|
|
|
if e != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to find report: %w", e)
|
2026-02-06 15:39:49 +00:00
|
|
|
}
|
|
|
|
|
if name != "" {
|
2026-03-18 15:36:20 +00:00
|
|
|
err := updateReporterName(ctx, txn, report, name)
|
2026-02-06 15:39:49 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if phone != nil {
|
2026-03-18 15:36:20 +00:00
|
|
|
err := updateReporterPhone(ctx, txn, report, *phone)
|
2026-02-06 15:39:49 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if email != "" {
|
2026-03-18 15:36:20 +00:00
|
|
|
err := updateReporterEmail(ctx, txn, report, email)
|
2026-02-06 15:39:49 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
err := updateReporterConsent(ctx, txn, report, has_consent)
|
2026-02-06 15:39:49 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
func reportByPublicID(ctx context.Context, txn bob.Executor, public_id string) (*models.PublicreportReport, error) {
|
|
|
|
|
return models.PublicreportReports.Query(
|
|
|
|
|
models.SelectWhere.PublicreportReports.PublicID.EQ(public_id),
|
|
|
|
|
).One(ctx, txn)
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func addNotificationEmail(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, email string) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
setter := models.PublicreportNotifyEmailSetter{
|
|
|
|
|
Created: omit.From(time.Now()),
|
|
|
|
|
Deleted: omitnull.FromPtr[time.Time](nil),
|
|
|
|
|
EmailAddress: omit.From(email),
|
|
|
|
|
ReportID: omit.From(report.ID),
|
|
|
|
|
}
|
|
|
|
|
_, err := models.PublicreportNotifyEmails.Insert(&setter).Exec(ctx, txn)
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to save new notification email row: %w", err)
|
2026-02-06 15:39:49 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func addNotificationPhone(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, phone types.E164) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
var err error
|
|
|
|
|
setter := models.PublicreportNotifyPhoneSetter{
|
|
|
|
|
Created: omit.From(time.Now()),
|
|
|
|
|
Deleted: omitnull.FromPtr[time.Time](nil),
|
|
|
|
|
PhoneE164: omit.From(phone.PhoneString()),
|
|
|
|
|
ReportID: omit.From(report.ID),
|
|
|
|
|
}
|
|
|
|
|
_, err = models.PublicreportNotifyPhones.Insert(&setter).Exec(ctx, txn)
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to save new notification phone row: %w", err)
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|
2026-03-18 15:36:20 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func updateReporterConsent(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, has_consent bool) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
return updateReportCol(ctx, txn, report, &models.PublicreportReportSetter{
|
|
|
|
|
ReporterContactConsent: omitnull.From(has_consent),
|
|
|
|
|
})
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func updateReporterEmail(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, email string) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
return updateReportCol(ctx, txn, report, &models.PublicreportReportSetter{
|
|
|
|
|
ReporterEmail: omit.From(email),
|
|
|
|
|
})
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func updateReporterName(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, name string) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
return updateReportCol(ctx, txn, report, &models.PublicreportReportSetter{
|
|
|
|
|
ReporterName: omit.From(name),
|
|
|
|
|
})
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func updateReportCol(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, setter *models.PublicreportReportSetter) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
err := report.Update(ctx, txn, setter)
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to update nuisance report in the database: %w", err)
|
2026-03-18 15:36:20 +00:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
func updateReporterPhone(ctx context.Context, txn bob.Executor, report *models.PublicreportReport, phone types.E164) error {
|
2026-03-18 15:36:20 +00:00
|
|
|
err := report.Update(ctx, txn, &models.PublicreportReportSetter{
|
|
|
|
|
ReporterPhone: omit.From(phone.PhoneString()),
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
2026-04-08 17:49:32 +00:00
|
|
|
return fmt.Errorf("Failed to update report: %w", err)
|
2026-03-18 15:36:20 +00:00
|
|
|
}
|
|
|
|
|
return nil
|
2026-01-31 20:08:08 +00:00
|
|
|
}
|