Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/matching/slate_service.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 |
| Branch | master |
| Path or archive member | internal/modules/matching/slate_service.go |
| Original SHA-256 | 2ee357687e08e6c68b6350ab3b7a16cb0d93ab7de9292ecc2f50609d5b270722 |
| Git blob SHA | 13825ee80b4c761473bdb0fba81e3b977893316b |
| Reading-copy SHA-256 | 2ee357687e08e6c68b6350ab3b7a16cb0d93ab7de9292ecc2f50609d5b270722 |
Every recorded occurrence
These 51 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/modules/matching/slate_service.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-d-missionmatch | 3be46ba89edb737182075a2b320509b42dc916f8 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-e-dataflow-deploy | 433815a042f9741411e60fa553fe72143e9b10db | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | w3-ai-staffing-recommendations | 43d56387270ef4da4cabd794d97ca6a49909bc7d | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws3-clearance | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-c-slatematch | 5cd60c918301b46ecd6ed3e03e20c395da0062e2 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ai-intelligence-layer | 5d5ddff70393a197c5f54a45280bb5dd42b24755 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws6-retrieval | 6c56e29231ec05735927fa265c97d517499dfeaf | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | per-tenant-routing | 9bde0f9a74b89d01980fa658e5253acda7528d0c | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ai-brain-live | aac32fc49c878cc5bca099459307611562d0bac1 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws1-ontology-sync | b596f449a32a1016fbd403c36505cc00a1ac9ee6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | deploy-and-ops | bdacd9d0b4d5998d25fc74bf4007f4c3ec538c7a | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | phase2-eval-fairness | d361af254701975fe239927656ababb56374655e | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws2-alias-relationship | e4dada4601c6eb101830f9d223a9655dfa120616 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | per-tenant-routing | 9bde0f9a74b89d01980fa658e5253acda7528d0c | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws6-retrieval | 6c56e29231ec05735927fa265c97d517499dfeaf | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-c-slatematch | 5cd60c918301b46ecd6ed3e03e20c395da0062e2 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws1-ontology-sync | b596f449a32a1016fbd403c36505cc00a1ac9ee6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | w3-ai-staffing-recommendations | 43d56387270ef4da4cabd794d97ca6a49909bc7d | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws3-clearance | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | phase2-eval-fairness | d361af254701975fe239927656ababb56374655e | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-e-dataflow-deploy | 433815a042f9741411e60fa553fe72143e9b10db | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ai-intelligence-layer | 5d5ddff70393a197c5f54a45280bb5dd42b24755 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | deploy-and-ops | bdacd9d0b4d5998d25fc74bf4007f4c3ec538c7a | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws2-alias-relationship | e4dada4601c6eb101830f9d223a9655dfa120616 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | ai-brain-live | aac32fc49c878cc5bca099459307611562d0bac1 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | workstream-d-missionmatch | 3be46ba89edb737182075a2b320509b42dc916f8 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_service.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓290 lines · 9.0 KB
package matching
import (
"context"
"encoding/csv"
"encoding/json"
"errors"
"strconv"
"strings"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/shopspring/decimal"
"github.com/missionworkforce/missionmatch/internal/modules/matching/engine"
"github.com/missionworkforce/missionmatch/internal/platform/audit"
"github.com/missionworkforce/missionmatch/internal/platform/database/dbgen"
)
// ListSlates returns the slates generated for one requirement, newest first, with a member count
// (slateMATCH slate list). It reads the stored slates, it does not rescore.
func (s *Service) ListSlates(ctx context.Context, requirementID uuid.UUID) ([]SlateSummaryView, error) {
if s.db == nil {
return nil, ErrNoDatabase
}
var out []SlateSummaryView
err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error {
q := dbgen.New(tx)
slates, e := q.ListSlatesForRequirement(ctx, requirementID)
if e != nil {
return e
}
out = make([]SlateSummaryView, 0, len(slates))
for _, sl := range slates {
members, e := q.ListSlateMembers(ctx, sl.ID)
if e != nil {
return e
}
out = append(out, SlateSummaryView{
SlateID: sl.ID.String(),
Name: sl.Name,
Status: sl.Status,
MemberCount: len(members),
CreatedAt: sl.CreatedAt.Format("2006-01-02"),
})
}
return nil
})
return out, err
}
// SlateDetail returns one slate with its ranked members (read from the persisted slate_members, never
// rescored) and the proposal readiness rollup. ErrNotFound when the slate is not in the caller's org.
func (s *Service) SlateDetail(ctx context.Context, slateID uuid.UUID) (SlateDetailView, error) {
if s.db == nil {
return SlateDetailView{}, ErrNoDatabase
}
var view SlateDetailView
err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error {
q := dbgen.New(tx)
sl, e := q.GetSlate(ctx, slateID)
if errors.Is(e, pgx.ErrNoRows) {
return ErrNotFound
}
if e != nil {
return e
}
members, e := q.ListSlateMembersWithNames(ctx, slateID)
if e != nil {
return e
}
title := ""
if rq, e := q.GetRequirement(ctx, sl.RequirementID); e == nil {
title = rq.Title
} else if !errors.Is(e, pgx.ErrNoRows) {
// A missing requirement leaves the title blank; a real error must not be swallowed into a
// silently blank Requirement line on a branded export.
return e
}
view = SlateDetailView{
SlateID: sl.ID.String(),
RequirementID: sl.RequirementID.String(),
RequirementTitle: title,
Name: sl.Name,
Status: sl.Status,
Members: make([]SlateMemberDetailView, len(members)),
Readiness: computeReadiness(sl.ID.String(), sl.RequirementID.String(), members),
}
for i, m := range members {
view.Members[i] = slateMemberDetailView(m)
}
return nil
})
return view, err
}
// ProposalReadiness returns the readiness rollup for one slate (GET /proposal-readiness): the band and
// human decision mix across its members, computed from the stored slate and never by rescoring.
func (s *Service) ProposalReadiness(ctx context.Context, slateID uuid.UUID) (ProposalReadinessView, error) {
if s.db == nil {
return ProposalReadinessView{}, ErrNoDatabase
}
var out ProposalReadinessView
err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error {
q := dbgen.New(tx)
sl, e := q.GetSlate(ctx, slateID)
if errors.Is(e, pgx.ErrNoRows) {
return ErrNotFound
}
if e != nil {
return e
}
members, e := q.ListSlateMembersWithNames(ctx, slateID)
if e != nil {
return e
}
out = computeReadiness(sl.ID.String(), sl.RequirementID.String(), members)
return nil
})
return out, err
}
// ExportSlate renders a slate as a branded CSV (the proposal candidate slate a capture team submits).
// It reads the persisted member scores and decisions, so the export always matches the frozen slate.
func (s *Service) ExportSlate(ctx context.Context, slateID uuid.UUID) (string, error) {
if s.db == nil {
return "", ErrNoDatabase
}
var out string
err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error {
q := dbgen.New(tx)
sl, e := q.GetSlate(ctx, slateID)
if errors.Is(e, pgx.ErrNoRows) {
return ErrNotFound
}
if e != nil {
return e
}
members, e := q.ListSlateMembersWithNames(ctx, slateID)
if e != nil {
return e
}
title := ""
if rq, e := q.GetRequirement(ctx, sl.RequirementID); e == nil {
title = rq.Title
} else if !errors.Is(e, pgx.ErrNoRows) {
// A missing requirement leaves the title blank; a real error must not be swallowed into a
// silently blank Requirement line on a branded export.
return e
}
out = renderSlateCSV(sl, title, members)
// The export is a bulk egress of candidate PII (names, scores, decisions). Record it in the
// append-only audit with the slate and the actor only, NEVER the reviewer note text or scores.
payload, _ := json.Marshal(map[string]any{"members": len(members)})
return s.auditOnTx(ctx, tx, audit.Event{Action: "aedt.slate.exported", EntityType: "slate", EntityID: sl.ID.String(), NewValues: payload})
})
return out, err
}
// computeReadiness rolls a slate's persisted members into the proposal readiness view: the band mix,
// the human decision mix, the approved and proposal ready count, and an overall label. Pure.
func computeReadiness(slateID, requirementID string, members []dbgen.ListSlateMembersWithNamesRow) ProposalReadinessView {
r := ProposalReadinessView{SlateID: slateID, RequirementID: requirementID, TotalMembers: len(members)}
for _, m := range members {
switch m.Decision {
case "approved":
r.Approved++
case "rejected":
r.Rejected++
default:
r.Pending++
}
switch m.Band {
case "green":
r.ProposalReady++
case "yellow":
r.Potential++
default:
r.Recruiting++
}
if m.Decision == "approved" && m.Band == "green" {
r.ApprovedReady++
}
}
r.ReadinessPct = "0"
if r.TotalMembers > 0 {
// Approved share as a percent, decimal so the rollup carries no float64.
pct := decimal.NewFromInt(int64(r.Approved)).
Div(decimal.NewFromInt(int64(r.TotalMembers))).
Mul(decimal.NewFromInt(100))
r.ReadinessPct = pct.StringFixed(0)
}
r.Status = readinessStatus(r)
return r
}
func readinessStatus(r ProposalReadinessView) string {
switch {
case r.TotalMembers == 0:
return "Empty"
case r.Pending > 0:
return "In Review"
case r.Approved == 0:
return "Needs Recruiting"
default:
return "Proposal Ready"
}
}
func slateMemberDetailView(m dbgen.ListSlateMembersWithNamesRow) SlateMemberDetailView {
rank := 0
if m.Rank != nil {
rank = int(*m.Rank)
}
note := ""
if m.DecisionNote != nil {
note = *m.DecisionNote
}
var gaps []string
if len(m.GapSummary) > 0 {
_ = json.Unmarshal(m.GapSummary, &gaps)
}
return SlateMemberDetailView{
CandidateID: m.CandidateID.String(),
FullName: m.FullName,
Rank: rank,
Total: m.TotalScore.StringFixed(2),
Band: m.Band,
BandLabel: bandLabel(m.Band),
Components: map[string]string{
"Clearance": m.ClearanceScore.StringFixed(2),
"Skills": m.SkillsScore.StringFixed(2),
"Certifications": m.CertsScore.StringFixed(2),
"CustomerExperience": m.CustomerScore.StringFixed(2),
"Experience": m.ExperienceScore.StringFixed(2),
"LocationAvailability": m.LocationScore.StringFixed(2),
},
Explanation: m.Explanation,
GapSummary: gaps,
Decision: m.Decision,
DecisionNote: note,
}
}
// bandLabel maps a stored band code to its human label, defaulting safely on an unknown code.
func bandLabel(code string) string {
if b, err := engine.ParseBand(code); err == nil {
return b.Label()
}
return code
}
// renderSlateCSV writes a branded proposal candidate slate. The header carries the product and slate
// identity and the standing clearance disclaimer; the rows are the ranked, frozen members with their
// human decisions. encoding/csv quotes any name or note that contains a comma.
func renderSlateCSV(sl dbgen.Slate, requirementTitle string, members []dbgen.ListSlateMembersWithNamesRow) string {
var b strings.Builder
b.WriteString("missionMATCH slateMATCH Proposal Candidate Slate\n")
b.WriteString("Slate," + csvField(sl.Name) + "\n")
b.WriteString("Requirement," + csvField(requirementTitle) + "\n")
b.WriteString("Clearance shown is a self reported indicator, never verified.\n")
b.WriteString("\n")
w := csv.NewWriter(&b)
_ = w.Write([]string{"Rank", "Candidate", "Total Score", "Band", "Decision", "Reviewer Note", "Explanation"})
for _, m := range members {
rank := ""
if m.Rank != nil {
rank = strconv.Itoa(int(*m.Rank))
}
note := ""
if m.DecisionNote != nil {
note = *m.DecisionNote
}
_ = w.Write([]string{
rank, m.FullName, m.TotalScore.StringFixed(2), bandLabel(m.Band), m.Decision, note, m.Explanation,
})
}
w.Flush()
return b.String()
}
// csvField quotes a single header value that may contain a comma (the csv writer handles the rows).
func csvField(s string) string {
if strings.ContainsAny(s, ",\"\n") {
return "\"" + strings.ReplaceAll(s, "\"", "\"\"") + "\""
}
return s
}