diff --git a/db/gen/nidus-sync/publicreport/model/report.go b/db/gen/nidus-sync/publicreport/model/report.go index e1d330e6..351c5699 100644 --- a/db/gen/nidus-sync/publicreport/model/report.go +++ b/db/gen/nidus-sync/publicreport/model/report.go @@ -36,5 +36,5 @@ type Report struct { AddressGid string ClientUUID *uuid.UUID ReporterPhoneCanSms bool - ReporterContactID *int32 + ReporterContactID int32 } diff --git a/db/query/comms/contact.go b/db/query/comms/contact.go index b8c55315..c4b506ef 100644 --- a/db/query/comms/contact.go +++ b/db/query/comms/contact.go @@ -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))) 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 { statement := table.Contact.UPDATE(). diff --git a/platform/publicreport.go b/platform/publicreport.go index f4792f52..43e82293 100644 --- a/platform/publicreport.go +++ b/platform/publicreport.go @@ -13,7 +13,6 @@ import ( "github.com/Gleipnir-Technology/jet/postgres" "github.com/rs/zerolog/log" "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" 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" @@ -235,18 +234,8 @@ func PublicReportUpdateCompliance(ctx context.Context, public_id string, report_ } } if reporter != nil { - if report.ReporterContactID == nil { - contact := modelcomms.Contact{ - 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 reporter.Name != "" { + err = querycomms.ContactUpdateName(ctx, txn, int64(report.ReporterContactID), reporter.Name) if err != nil { return fmt.Errorf("update contact: %w", err) } @@ -397,7 +386,7 @@ func publicReportCreate(ctx context.Context, setter_report modelpublicreport.Rep if err != nil { return result, fmt.Errorf("contact empty: %w", err) } - setter_report.ReporterContactID = &contact.ID + setter_report.ReporterContactID = contact.ID if addr != nil { setter_report.AddressID = addr.ID } diff --git a/platform/publicreport/contact.go b/platform/publicreport/contact.go new file mode 100644 index 00000000..b27ba275 --- /dev/null +++ b/platform/publicreport/contact.go @@ -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 +} diff --git a/platform/publicreport/notification.go b/platform/publicreport/notification.go index 8a9f1661..80e34144 100644 --- a/platform/publicreport/notification.go +++ b/platform/publicreport/notification.go @@ -78,30 +78,45 @@ func RegisterSubscriptionPhone(ctx context.Context, txn db.Ex, contact modelcomm return nil } -func SaveReporter(ctx context.Context, txn db.Ex, report modelpublicreport.Report, name string) (contact modelcomms.Contact, err error) { - if report.ReporterContactID == nil { - contact = modelcomms.Contact{ - Created: time.Now(), - Name: name, - OrganizationID: report.OrganizationID, - } - contact, err = querycomms.ContactInsert(ctx, txn, contact) +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) { + 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 insert: %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) - } + 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 } diff --git a/platform/publicreport/report.go b/platform/publicreport/report.go index a93c3be2..a2165d53 100644 --- a/platform/publicreport/report.go +++ b/platform/publicreport/report.go @@ -79,9 +79,12 @@ func byID(ctx context.Context, public_id string, is_public bool) (*types.PublicR return &reports[0], nil } func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, is_public bool) ([]types.PublicReport, error) { + txn := db.PGInstance.PGXPool address_ids := make([]int64, 0) + contact_ids := make([]int64, len(reports)) report_ids := make([]int32, len(reports)) for i, report := range reports { + contact_ids[i] = int64(report.ReporterContactID) report_ids[i] = report.ID if report.AddressID != nil { address_ids = append(address_ids, int64(*report.AddressID)) @@ -97,7 +100,7 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, if err != nil { 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 { 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 { 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)) for i, row := range reports { @@ -137,6 +148,7 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, Raw: row.AddressRaw, } } + contact := contact_by_id[int64(row.ReporterContactID)] results[i] = types.PublicReport{ Address: *address, Concerns: nil, @@ -148,17 +160,10 @@ func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, DistrictID: &row.OrganizationID, District: nil, PublicID: row.PublicID, - Reporter: types.ContactSimple{ - Email: row.ReporterEmail, - Name: row.ReporterName, - Phone: types.PhoneSimple{ - CanSMS: row.ReporterPhoneCanSms, - Number: row.ReporterPhone, - }, - }, - Status: row.Status.String(), - Type: row.ReportType.String(), - URI: "", + Reporter: contact, + Status: row.Status.String(), + Type: row.ReportType.String(), + URI: "", } } return results, nil diff --git a/platform/publicreport_notification.go b/platform/publicreport_notification.go index e2a4e0c0..14d95fa1 100644 --- a/platform/publicreport_notification.go +++ b/platform/publicreport_notification.go @@ -21,6 +21,7 @@ type PublicreportNotification struct { Name string Notification bool Phone *types.E164 + PhoneCanSms bool ReportID string Subscription bool } @@ -40,7 +41,7 @@ func PublicreportNotificationCreate(ctx context.Context, pn PublicreportNotifica 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 { return fmt.Errorf("save reporter: %w", err) } diff --git a/platform/types/contact.go b/platform/types/contact.go index 8ab714b3..01852482 100644 --- a/platform/types/contact.go +++ b/platform/types/contact.go @@ -12,6 +12,7 @@ type Contact struct { } type ContactSimple struct { Email string `json:"email"` + ID int32 `json:"-"` Name string `json:"name"` Phone PhoneSimple `json:"phone"` } diff --git a/resource/publicreport_notification.go b/resource/publicreport_notification.go index e7a3406d..f60ba707 100644 --- a/resource/publicreport_notification.go +++ b/resource/publicreport_notification.go @@ -46,6 +46,7 @@ func (res *publicreportNotificationR) Create(ctx context.Context, r *http.Reques Name: n.Name, Notification: n.Notification, Phone: phone, + PhoneCanSms: n.CanSMS, ReportID: n.ReportID, Subscription: n.Subscription, })