// Package marketintel fetches federal award market intelligence (incumbents, competitors, and own // past performance) behind a small swappable Provider interface, so a paid data provider can replace // the free USASpending source per client without a refactor. It has no database dependency: it // fetches and normalizes; the sync (cmd/awards-sync) writes the cache. package marketintel import ( "context" "encoding/json" "time" "github.com/shopspring/decimal" ) // Award is a normalized federal award, provider independent. type Award struct { GeneratedInternalID string // unique award id (upsert key) AwardID string // PIID RecipientName string RecipientUEI string RecipientID string AwardAmount *decimal.Decimal AwardingAgency string AwardingSubAgency string POPStart *time.Time POPEnd *time.Time NAICSCode string NAICSDescription string Description string IsGalapagos bool Raw json.RawMessage } // TimePeriod is an award action date window. type TimePeriod struct { Start string // YYYY-MM-DD End string // YYYY-MM-DD } // AwardQuery is the provider independent request. Either set NAICS plus States plus AwardingToptier // for a market pull, or set RecipientSearch (for example a UEI) for own past performance. type AwardQuery struct { NAICS []string States []string // place of performance state codes AwardTypeCodes []string // A B C D for contracts AwardingToptier string // for example "Department of Defense" TimePeriods []TimePeriod RecipientSearch []string // matches recipient name, UEI, or DUNS Limit int // page size Page int // 1 based } // Provider fetches award market intelligence. FetchAwards returns one page plus whether another page // exists. Implementations map a 429 to ErrThrottled (see usaspending.go). type Provider interface { FetchAwards(ctx context.Context, q AwardQuery) (awards []Award, hasNext bool, err error) Name() string }