Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / cmd/opp-sync/main.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 1675031db74316e100782d063e9eda1a597fe3a1 |
| Branch | workstream-a-opportunity-intelligence |
| Path or archive member | cmd/opp-sync/main.go |
| Original SHA-256 | e379fdba3244a55031ce2560117ae609239a5375cf598295af1913adb59b2822 |
| Git blob SHA | ea1685f461c54d47de0ca16d9b428b3aaf6f3895 |
| Reading-copy SHA-256 | 51b18c61b5776df0ed318a8b73c29954c606e6f4012bc298a0282a8d4cfa3686 |
Recovered source transcript
Download complete source text ↓96 lines · 3.5 KB
Credential-bearing and unrelated personal details were removed from this reading copy. The source identity and original checksum remain recorded.
// Command opp-sync runs the Opportunity Intelligence ingestion. It pulls the configured federal feeds
// (SAM active solicitations and USASpending contract awards) through the OpportunitySource adapters and
// upserts them into the unified opportunity_records catalog, retaining each raw payload to object
// storage and writing one audit event per source. It runs as the migrator role and is safe to rerun:
// every upsert is idempotent.
//
// Env: MM_MIGRATOR_DATABASE_URL (or MM_DATABASE_URL), SAM_API_KEY, SAM_API_BASE (optional),
// USASPENDING_BASE (optional), MM_OPP_RAW_DIR (object storage root, default ./data/opp-raw).
package main
import (
"context"
"log"
"os"
"strings"
"time"
"github.com/jackc/pgx/v5/pgxpool"
oppintel "github.com/missionworkforce/missionmatch/internal/modules/opportunity_intelligence"
"github.com/missionworkforce/missionmatch/internal/modules/opportunity_intelligence/adapters"
"github.com/missionworkforce/missionmatch/internal/platform/audit"
"github.com/missionworkforce/missionmatch/internal/platform/marketintel"
"github.com/missionworkforce/missionmatch/internal/platform/samgov"
"github.com/missionworkforce/missionmatch/internal/platform/storage"
"github.com/missionworkforce/missionmatch/internal/platform/tenant"
)
func main() {
dsn := firstNonEmpty(os.Getenv("MM_MIGRATOR_DATABASE_URL"), os.Getenv("MM_DATABASE_URL"))
if dsn == "" {
log.Fatal("opp-sync: set MM_MIGRATOR_DATABASE_URL (the migrator DSN)")
}
samKey := strings.TrimSpace(os.Getenv("SAM_API_KEY"))
if samKey == "" {
log.Fatal("opp-sync: SAM_API_KEY is [credential removed]")
}
rawDir := firstNonEmpty(os.Getenv("MM_OPP_RAW_DIR"), "./data/opp-raw")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
pool, err := pgxpool.New(ctx, dsn)
if err != nil {
log.Fatalf("opp-sync: connect: %v", err)
}
defer pool.Close()
store, err := storage.NewLocal(rawDir)
if err != nil {
log.Fatalf("opp-sync: storage: %v", err)
}
ing := oppintel.NewIngester(store, oppintel.NewDBWriter(pool), audit.New(tenant.New(pool)))
sources := []oppintel.OpportunitySource{
adapters.NewSAMSource(samgov.New(os.Getenv("SAM_API_BASE"), samKey), samgov.Galapagos, 5),
adapters.NewUSASpendingSource(marketintel.NewUSASpending(os.Getenv("USASPENDING_BASE")), galapagosAwardQuery(), 5),
}
var grand int
for _, src := range sources {
res, ierr := ing.Ingest(ctx, src)
if ierr != nil {
log.Fatalf("opp-sync: ingest %s: %v", src.Name(), ierr)
}
log.Printf("opp-sync: %s fetched %d upserted %d by_kind %v", res.Source, res.Fetched, res.Upserted, res.ByKind)
grand += res.Upserted
}
log.Printf("opp-sync: done, %d records upserted into opportunity_records", grand)
}
// galapagosAwardQuery is the market intelligence pull (DoD, the Galapagos NAICS family, HI and NM, the
// last three years of contract actions). It mirrors the standalone awards-sync market pass.
func galapagosAwardQuery() marketintel.AwardQuery {
now := time.Now().UTC()
start := now.AddDate(-3, 0, 0)
return marketintel.AwardQuery{
NAICS: samgov.Galapagos.NAICS,
States: samgov.Galapagos.States,
AwardTypeCodes: []string{"A", "B", "C", "D"},
AwardingToptier: "Department of Defense",
TimePeriods: []marketintel.TimePeriod{{Start: start.Format("2006-01-02"), End: now.Format("2006-01-02")}},
Limit: 100,
}
}
func firstNonEmpty(vals ...string) string {
for _, v := range vals {
if s := strings.TrimSpace(v); s != "" {
return s
}
}
return ""
}