package commandcenter import ( "context" "errors" "fmt" "time" "github.com/jackc/pgx/v5" "github.com/shopspring/decimal" "github.com/missionworkforce/missionmatch/internal/modules/matching/engine" "github.com/missionworkforce/missionmatch/internal/platform/tenant" ) // ErrNoDatabase is returned when no pool is configured. var ErrNoDatabase = errors.New("commandcenter: no database configured") var hundred = decimal.NewFromInt(100) // WCC composite weights (DISTINCT from the engine's per-candidate weights). Sum == 1.00 (tested). var weights = map[string]decimal.Decimal{ "clearance_coverage": decimal.RequireFromString("0.30"), "skill_coverage": decimal.RequireFromString("0.25"), "labor_category_coverage": decimal.RequireFromString("0.20"), "proposal_readiness": decimal.RequireFromString("0.15"), "availability_coverage": decimal.RequireFromString("0.10"), } var driverOrder = []struct{ key, label string }{ {"clearance_coverage", "Clearance Coverage"}, {"skill_coverage", "Skill Coverage"}, {"labor_category_coverage", "Labor Category Coverage"}, {"proposal_readiness", "Proposal Readiness"}, {"availability_coverage", "Availability Coverage"}, } var levelLabels = map[string]string{ "unknown": "Unknown", "none": "None", "confidential": "Confidential", "secret": "Secret", "top_secret": "Top Secret", "ts_sci": "TS/SCI", } // Service computes the Workforce Command Center view. type Service struct { db *tenant.DB clock func() time.Time } func NewService(db *tenant.DB) *Service { return &Service{db: db, clock: time.Now} } func levelLabel(code string) string { if l, ok := levelLabels[code]; ok { return l } return code } func pct(num, den int64) decimal.Decimal { if den <= 0 { return decimal.Zero } return decimal.NewFromInt(num).Div(decimal.NewFromInt(den)).Mul(hundred).Round(2) } func driverState(p decimal.Decimal) string { switch { case p.GreaterThanOrEqual(engine.BandGreenMin): return "ready" case p.GreaterThanOrEqual(engine.BandYellowMin): return "partial" default: return "gap" } } func colorFor(p decimal.Decimal) string { switch driverState(p) { case "ready": return "green" case "partial": return "yellow" default: return "red" } } // CommandCenter computes the full dashboard for the caller's org as-of the given date. func (s *Service) CommandCenter(ctx context.Context, asOf time.Time) (View, error) { if s.db == nil { return View{}, ErrNoDatabase } asOfStr := asOf.Format("2006-01-02") v := View{AsOf: asOfStr, GeneratedAt: asOf.UTC().Format(time.RFC3339), Meta: Meta{Notes: []string{}}} if org, ok := tenant.OrgFromContext(ctx); ok { v.OrganizationID = org } err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error { if err := buildTemps(ctx, tx, asOfStr); err != nil { return err } // ---- opportunity metadata (RLS-scoped) ---- oppMeta := map[string]oppInfo{} rows, err := tx.Query(ctx, `SELECT id::text, name, COALESCE(customer_agency,''), COALESCE(solicitation_number,''), COALESCE(to_char(due_date,'YYYY-MM-DD'),''), value, value_source FROM opportunities WHERE status='open'`) if err != nil { return fmt.Errorf("opp map: %w", err) } for rows.Next() { var id, name, cust, sol, due, src string var val *decimal.Decimal if err := rows.Scan(&id, &name, &cust, &sol, &due, &val, &src); err != nil { rows.Close() return err } oppMeta[id] = oppInfo{name: name, customer: cust, solicitation: sol, dueDate: due, value: val, valueSource: src} } rows.Close() if err := rows.Err(); err != nil { return err } // ---- assignment-based panels (each available candidate consumed at most once) ---- assigned, qualified, reqs, _, err := fetchAssignment(ctx, tx) if err != nil { return err } opps, highRisk := opportunitiesFromAssignment(reqs, assigned, oppMeta) v.ActiveOpportunities = opps gaps, suggestReq, totalGaps := gapsFromAssignment(reqs, assigned, oppMeta) v.StaffingGaps = gaps v.LaborCategoryCoverage = lcatCoverageFromAssignment(reqs, assigned) var proposalPct decimal.Decimal v.ProposalReadiness, proposalPct = proposalFromAssignment(reqs, assigned, qualified, oppMeta) // ---- drivers (clearance/skill/lcat coverage + availability via SQL; proposal from assignment) ---- drivers, availReqCov, err := s.drivers(ctx, tx) if err != nil { return err } drivers["proposal_readiness"] = proposalPct var totalCleared, availableAll, availCleared int64 if err := tx.QueryRow(ctx, `SELECT count(*) FILTER (WHERE effective AND lvl>=2), count(*) FILTER (WHERE available), count(*) FILTER (WHERE available AND effective AND lvl>=2) FROM cc_cand`). Scan(&totalCleared, &availableAll, &availCleared); err != nil { return fmt.Errorf("banner cand: %w", err) } // Proposal-ready = green slate members on slates tied to an OPEN (or standalone) opportunity, // excluding closed-opportunity slates [review EN-2]. var proposalReady, activeReqs int64 if err := tx.QueryRow(ctx, `SELECT count(DISTINCT sm.candidate_id) FROM slate_members sm JOIN slates s ON s.id = sm.slate_id JOIN requirements r ON r.id = s.requirement_id LEFT JOIN opportunities o ON o.id = r.opportunity_id WHERE sm.band='green' AND (o.id IS NULL OR o.status='open')`).Scan(&proposalReady); err != nil { return fmt.Errorf("proposal ready: %w", err) } if err := tx.QueryRow(ctx, `SELECT count(*) FROM cc_active_req`).Scan(&activeReqs); err != nil { return fmt.Errorf("active reqs: %w", err) } // ---- clearance intelligence ---- if v.ClearanceIntelligence, err = s.clearance(ctx, tx, asOfStr); err != nil { return err } // ---- win impact ---- if v.WinImpact, err = s.winImpact(ctx, tx); err != nil { return err } // ---- heat map ---- if v.HeatMap, err = s.heatMap(ctx, tx); err != nil { return err } // ---- action center badge counts ---- var openNoSlate, reqsUnscreened int64 if err := tx.QueryRow(ctx, `SELECT count(*) FROM opportunities o WHERE o.status='open' AND NOT EXISTS (SELECT 1 FROM slates s WHERE s.requirement_id IN (SELECT id FROM requirements r WHERE r.opportunity_id=o.id))`). Scan(&openNoSlate); err != nil { return fmt.Errorf("open no slate: %w", err) } if err := tx.QueryRow(ctx, `SELECT count(*) FROM cc_active_req ar WHERE NOT EXISTS (SELECT 1 FROM slates s WHERE s.requirement_id=ar.id)`). Scan(&reqsUnscreened); err != nil { return fmt.Errorf("reqs unscreened: %w", err) } // ---- assemble mission readiness ---- score := decimal.Zero drvViews := make([]Driver, 0, len(driverOrder)) for _, d := range driverOrder { p := drivers[d.key] score = score.Add(p.Mul(weights[d.key])) drvViews = append(drvViews, Driver{ Key: d.key, Label: d.label, Pct: p.StringFixed(2), State: driverState(p), Weight: weights[d.key].String(), }) } score = score.Round(2) band, status := readinessBand(score, totalCleared == 0 && activeReqs == 0) v.MissionReadiness = MissionReadiness{ Score: score.StringFixed(2), Band: band, Status: status, Drivers: drvViews, AvailabilityReqCoverage: availReqCov.StringFixed(2), Flags: []string{}, } v.Banner = Banner{ TotalClearedWorkforce: int(totalCleared), AvailableCandidates: int(availableAll), ProposalReadyCandidates: int(proposalReady), ActiveRequirements: int(activeReqs), StaffingGaps: int(totalGaps), HighRiskOpportunities: highRisk, } v.ActionCenter = buildActionCenter(suggestReq, opps, int(openNoSlate), int(reqsUnscreened)) v.Meta.Empty = totalCleared == 0 && activeReqs == 0 && availableAll == 0 return nil }) if err != nil { return View{}, err } v.AIRecommendations = buildRecommendations(v) if v.AIRecommendations == nil { v.AIRecommendations = []Recommendation{} } return v, nil } type oppInfo struct { name string customer string solicitation string dueDate string value *decimal.Decimal valueSource string // representative, operator, sam, usaspending (W2 Revenue at Risk provenance) } // isRealValueSource reports whether an opportunity value came from a cached federal source (SAM or // USASpending). A representative or operator entered dollar is not a real federal figure, so it can // never clear the representative label on Revenue at Risk. func isRealValueSource(s string) bool { return s == "sam" || s == "usaspending" } func readinessBand(score decimal.Decimal, empty bool) (band, status string) { if empty { return "red", "No Data" } switch { case score.GreaterThanOrEqual(engine.BandGreenMin): return "green", "Mission Ready" case score.GreaterThanOrEqual(engine.BandYellowMin): return "yellow", "Watch" default: return "red", "At Risk" } }