Update storage of reporter in contact

I failed to retrieve the data correctly before as part of the changeover
to contact records.

Issue: #13
This commit is contained in:
Eli Ribble 2026-05-21 16:59:44 +00:00
parent b9f2107c79
commit e3cc1e99d1
No known key found for this signature in database
9 changed files with 132 additions and 50 deletions

View file

@ -36,5 +36,5 @@ type Report struct {
AddressGid string AddressGid string
ClientUUID *uuid.UUID ClientUUID *uuid.UUID
ReporterPhoneCanSms bool ReporterPhoneCanSms bool
ReporterContactID *int32 ReporterContactID int32
} }

View file

@ -60,6 +60,20 @@ func ContactFromID(ctx context.Context, txn db.Ex, id int64) (model.Contact, err
WHERE(table.Contact.ID.EQ(postgres.Int(id))) WHERE(table.Contact.ID.EQ(postgres.Int(id)))
return db.ExecuteOne[model.Contact](ctx, statement) return db.ExecuteOne[model.Contact](ctx, statement)
} }
func ContactsFromIDs(ctx context.Context, txn db.Ex, contact_ids []int64) ([]model.Contact, error) {
if len(contact_ids) == 0 {
return []model.Contact{}, nil
}
sql_ids := make([]postgres.Expression, len(contact_ids))
for i, contact_id := range contact_ids {
sql_ids[i] = postgres.Int(contact_id)
}
statement := table.Contact.SELECT(
table.Contact.AllColumns,
).FROM(table.Contact).
WHERE(table.Contact.ID.IN(sql_ids...))
return db.ExecuteManyTx[model.Contact](ctx, txn, statement)
}
func ContactUpdateName(ctx context.Context, txn db.Ex, id int64, name string) error { func ContactUpdateName(ctx context.Context, txn db.Ex, id int64, name string) error {
statement := table.Contact.UPDATE(). statement := table.Contact.UPDATE().

View file

@ -13,7 +13,6 @@ import (
"github.com/Gleipnir-Technology/jet/postgres" "github.com/Gleipnir-Technology/jet/postgres"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"source.gleipnir.technology/Gleipnir/nidus-sync/db" "source.gleipnir.technology/Gleipnir/nidus-sync/db"
modelcomms "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/comms/model"
"source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/public/model" "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/public/model"
tablepublic "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/public/table" tablepublic "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/public/table"
modelpublicreport "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/publicreport/model" modelpublicreport "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/publicreport/model"
@ -235,18 +234,8 @@ func PublicReportUpdateCompliance(ctx context.Context, public_id string, report_
} }
} }
if reporter != nil { if reporter != nil {
if report.ReporterContactID == nil { if reporter.Name != "" {
contact := modelcomms.Contact{ err = querycomms.ContactUpdateName(ctx, txn, int64(report.ReporterContactID), reporter.Name)
Created: time.Now(),
Name: reporter.Name,
OrganizationID: report.OrganizationID,
}
_, err = querycomms.ContactInsert(ctx, txn, contact)
if err != nil {
return fmt.Errorf("insert contact: %w", err)
}
} else if reporter.Name != "" {
err = querycomms.ContactUpdateName(ctx, txn, int64(*report.ReporterContactID), reporter.Name)
if err != nil { if err != nil {
return fmt.Errorf("update contact: %w", err) return fmt.Errorf("update contact: %w", err)
} }
@ -397,7 +386,7 @@ func publicReportCreate(ctx context.Context, setter_report modelpublicreport.Rep
if err != nil { if err != nil {
return result, fmt.Errorf("contact empty: %w", err) return result, fmt.Errorf("contact empty: %w", err)
} }
setter_report.ReporterContactID = &contact.ID setter_report.ReporterContactID = contact.ID
if addr != nil { if addr != nil {
setter_report.AddressID = addr.ID setter_report.AddressID = addr.ID
} }

View file

@ -0,0 +1,56 @@
package publicreport
import (
"context"
"fmt"
"source.gleipnir.technology/Gleipnir/nidus-sync/db"
querycomms "source.gleipnir.technology/Gleipnir/nidus-sync/db/query/comms"
"source.gleipnir.technology/Gleipnir/nidus-sync/platform/types"
)
func ContactSimplesFromIDs(ctx context.Context, txn db.Ex, contact_ids []int64) ([]types.ContactSimple, error) {
contacts, err := querycomms.ContactsFromIDs(ctx, txn, contact_ids)
if err != nil {
return nil, fmt.Errorf("contacts from ids: %w", err)
}
contact_emails, err := querycomms.ContactEmailByContactIDs(ctx, txn, contact_ids)
if err != nil {
return nil, fmt.Errorf("contact emails from ids: %w", err)
}
contact_phones, err := querycomms.ContactPhoneByContactIDs(ctx, txn, contact_ids)
if err != nil {
return nil, fmt.Errorf("contact phones from ids: %w", err)
}
results := make([]types.ContactSimple, len(contact_ids))
for i, contact := range contacts {
emails, ok := contact_emails[int64(contact.ID)]
if !ok {
return nil, fmt.Errorf("no emails for contact %d", contact.ID)
}
phones, ok := contact_phones[int64(contact.ID)]
if !ok {
return nil, fmt.Errorf("no phones for contact %d", contact.ID)
}
email_string := ""
if len(emails) > 0 {
email_string = emails[0].Address
}
phone_simple := types.PhoneSimple{}
if len(phones) > 0 {
phone := phones[0]
phone_simple = types.PhoneSimple{
CanSMS: phone.CanSms,
Number: phone.E164,
}
}
results[i] = types.ContactSimple{
Email: email_string,
ID: contact.ID,
Name: contact.Name,
Phone: phone_simple,
}
}
return results, nil
}

View file

@ -78,30 +78,45 @@ func RegisterSubscriptionPhone(ctx context.Context, txn db.Ex, contact modelcomm
return nil return nil
} }
func SaveReporter(ctx context.Context, txn db.Ex, report modelpublicreport.Report, name string) (contact modelcomms.Contact, err error) { func SaveReporter(ctx context.Context, txn db.Ex, report modelpublicreport.Report, name string, email_address string, phone *types.E164, can_sms bool) (contact modelcomms.Contact, err error) {
if report.ReporterContactID == nil { contact, err = querycomms.ContactFromID(ctx, txn, int64(report.ReporterContactID))
contact = modelcomms.Contact{ if err != nil {
Created: time.Now(), return contact, fmt.Errorf("contact query: %w", err)
Name: name, }
OrganizationID: report.OrganizationID, log.Debug().Str("name", name).Str("old name", contact.Name).Int32("id", contact.ID).Msg("contact updated")
} if name != "" && contact.Name != name {
contact, err = querycomms.ContactInsert(ctx, txn, contact) err = querycomms.ContactUpdateName(ctx, txn, int64(contact.ID), name)
if err != nil { if err != nil {
return contact, fmt.Errorf("contact insert: %w", err) return contact, fmt.Errorf("contact update name: %w", err)
}
log.Debug().Str("name", name).Int32("id", contact.ID).Msg("new contact inserted")
} else {
contact, err = querycomms.ContactFromID(ctx, txn, int64(*report.ReporterContactID))
if err != nil {
return contact, fmt.Errorf("contact query: %w", err)
}
log.Debug().Str("name", name).Str("old name", contact.Name).Int32("id", contact.ID).Msg("contact updated")
if name != "" && contact.Name != name {
err = querycomms.ContactUpdateName(ctx, txn, int64(contact.ID), name)
if err != nil {
return contact, fmt.Errorf("contact update name: %w", err)
}
} }
} }
if email_address != "" {
e, err := querycomms.ContactEmailInsert(ctx, txn, modelcomms.ContactEmail{
Address: email_address,
Confirmed: false,
ContactID: contact.ID,
//ID
IsSubscribed: false,
})
if err != nil {
return contact, fmt.Errorf("contact add email: %w", err)
}
log.Info().Str("address", e.Address).Msg("Created contact email")
}
if phone != nil {
p, err := querycomms.ContactPhoneInsert(ctx, txn, modelcomms.ContactPhone{
CanSms: can_sms,
ConfirmedMessageID: nil,
ContactID: contact.ID,
E164: phone.PhoneString(),
IsSubscribed: false,
StopMessageID: nil,
})
if err != nil {
return contact, fmt.Errorf("contact add phone: %w", err)
}
log.Info().Str("e164", p.E164).Msg("Created contact phone")
}
return contact, nil return contact, nil
} }

View file

@ -79,9 +79,12 @@ func byID(ctx context.Context, public_id string, is_public bool) (*types.PublicR
return &reports[0], nil return &reports[0], nil
} }
func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, is_public bool) ([]types.PublicReport, error) { func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, is_public bool) ([]types.PublicReport, error) {
txn := db.PGInstance.PGXPool
address_ids := make([]int64, 0) address_ids := make([]int64, 0)
contact_ids := make([]int64, len(reports))
report_ids := make([]int32, len(reports)) report_ids := make([]int32, len(reports))
for i, report := range reports { for i, report := range reports {
contact_ids[i] = int64(report.ReporterContactID)
report_ids[i] = report.ID report_ids[i] = report.ID
if report.AddressID != nil { if report.AddressID != nil {
address_ids = append(address_ids, int64(*report.AddressID)) address_ids = append(address_ids, int64(*report.AddressID))
@ -97,7 +100,7 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report,
if err != nil { if err != nil {
return nil, fmt.Errorf("log entries for reports: %w", err) return nil, fmt.Errorf("log entries for reports: %w", err)
} }
addresses, err := querypublic.AddressesFromIDs(ctx, db.PGInstance.PGXPool, address_ids) addresses, err := querypublic.AddressesFromIDs(ctx, txn, address_ids)
if err != nil { if err != nil {
return nil, fmt.Errorf("addresses for reports: %w", err) return nil, fmt.Errorf("addresses for reports: %w", err)
} }
@ -105,6 +108,14 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report,
for _, address := range addresses { for _, address := range addresses {
addresses_by_id[int64(address.ID)] = address addresses_by_id[int64(address.ID)] = address
} }
contacts, err := ContactSimplesFromIDs(ctx, txn, contact_ids)
if err != nil {
return nil, fmt.Errorf("contact simples from ids: %w", err)
}
contact_by_id := make(map[int64]types.ContactSimple, 0)
for _, contact := range contacts {
contact_by_id[int64(contact.ID)] = contact
}
results := make([]types.PublicReport, len(reports)) results := make([]types.PublicReport, len(reports))
for i, row := range reports { for i, row := range reports {
@ -137,6 +148,7 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report,
Raw: row.AddressRaw, Raw: row.AddressRaw,
} }
} }
contact := contact_by_id[int64(row.ReporterContactID)]
results[i] = types.PublicReport{ results[i] = types.PublicReport{
Address: *address, Address: *address,
Concerns: nil, Concerns: nil,
@ -148,17 +160,10 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report,
DistrictID: &row.OrganizationID, DistrictID: &row.OrganizationID,
District: nil, District: nil,
PublicID: row.PublicID, PublicID: row.PublicID,
Reporter: types.ContactSimple{ Reporter: contact,
Email: row.ReporterEmail, Status: row.Status.String(),
Name: row.ReporterName, Type: row.ReportType.String(),
Phone: types.PhoneSimple{ URI: "",
CanSMS: row.ReporterPhoneCanSms,
Number: row.ReporterPhone,
},
},
Status: row.Status.String(),
Type: row.ReportType.String(),
URI: "",
} }
} }
return results, nil return results, nil

View file

@ -21,6 +21,7 @@ type PublicreportNotification struct {
Name string Name string
Notification bool Notification bool
Phone *types.E164 Phone *types.E164
PhoneCanSms bool
ReportID string ReportID string
Subscription bool Subscription bool
} }
@ -40,7 +41,7 @@ func PublicreportNotificationCreate(ctx context.Context, pn PublicreportNotifica
return fmt.Errorf("no such report '%s'", pn.ReportID) return fmt.Errorf("no such report '%s'", pn.ReportID)
} }
contact, err := publicreport.SaveReporter(ctx, txn, *report, pn.Name) contact, err := publicreport.SaveReporter(ctx, txn, *report, pn.Name, pn.Email, pn.Phone, pn.PhoneCanSms)
if err != nil { if err != nil {
return fmt.Errorf("save reporter: %w", err) return fmt.Errorf("save reporter: %w", err)
} }

View file

@ -12,6 +12,7 @@ type Contact struct {
} }
type ContactSimple struct { type ContactSimple struct {
Email string `json:"email"` Email string `json:"email"`
ID int32 `json:"-"`
Name string `json:"name"` Name string `json:"name"`
Phone PhoneSimple `json:"phone"` Phone PhoneSimple `json:"phone"`
} }

View file

@ -46,6 +46,7 @@ func (res *publicreportNotificationR) Create(ctx context.Context, r *http.Reques
Name: n.Name, Name: n.Name,
Notification: n.Notification, Notification: n.Notification,
Phone: phone, Phone: phone,
PhoneCanSms: n.CanSMS,
ReportID: n.ReportID, ReportID: n.ReportID,
Subscription: n.Subscription, Subscription: n.Subscription,
}) })