package oppintel import ( "context" "time" "github.com/jackc/pgx/v5/pgtype" "github.com/missionworkforce/missionmatch/internal/platform/database/dbgen" ) // dbWriter is the production RecordWriter: it upserts a normalized record into opportunity_records via // the generated query. The ingest sync (cmd/opp-sync) runs it under the migrator role; the global // catalog is outside RLS so no tenant transaction is involved. type dbWriter struct{ q *dbgen.Queries } // NewDBWriter builds a RecordWriter over a dbgen capable handle (a pool or a transaction). func NewDBWriter(db dbgen.DBTX) RecordWriter { return &dbWriter{q: dbgen.New(db)} } func (w *dbWriter) Upsert(ctx context.Context, rec OpportunityRecord, rawObjectKey, rawSHA256 string) error { return w.q.UpsertOpportunityRecord(ctx, dbgen.UpsertOpportunityRecordParams{ SourceName: rec.SourceName, SourceRecordID: rec.SourceRecordID, DedupeKey: rec.DedupeKey, RecordKind: string(rec.Kind), Title: rec.Title, Agency: rec.Agency, SubAgency: rec.SubAgency, Naics: rec.NAICS, Psc: rec.PSC, PopCity: rec.Place.City, PopState: rec.Place.State, PopCountry: rec.Place.Country, PopZip: rec.Place.Zip, SetAside: rec.SetAside, SetAsideCode: rec.SetAsideCode, ContractVehicle: rec.ContractVehicle, EstimatedValue: rec.EstimatedValue, ValueSource: rec.ValueSource, IncumbentName: rec.IncumbentName, IncumbentUei: rec.IncumbentUEI, PostedDate: toPgDate(rec.Posted), ResponseDeadline: rec.ResponseDeadline, AwardDate: toPgDate(rec.AwardDate), EstimatedAwardDate: toPgDate(rec.EstimatedAwardDate), PopStartDate: toPgDate(rec.PopStart), PopEndDate: toPgDate(rec.PopEnd), UiLink: rec.UILink, IsPlanning: rec.IsPlanning, RawObjectKey: rawObjectKey, RawSha256: rawSHA256, FetchedAt: rec.FetchedAt, }) } // toPgDate maps an optional civil date to the pgtype.Date the generated params expect. A nil time is // the SQL NULL (an unset, not zero, date). func toPgDate(t *time.Time) pgtype.Date { if t == nil { return pgtype.Date{} } return pgtype.Date{Time: *t, Valid: true} }