Story: Contract Triage

story-westside-streamlit-triage Doc

active user-story

Story: Contract Triage

Key: triage · Label: story:triage · Role: Ops (Lucas / Ava)

Story

As ops, I need to see at a glance which players have not yet signed their contract, so I can prioritize who to chase without drilling into individual player cards.

Why

The admin UI in westside-app shows one player at a time. When 50+ players are mid-roster, one-at-a-time navigation buries the signal. Marcus and Lucas need the "who is still open" list to be the default view, not something you have to click through to find.

Acceptance criteria

  • Dashboard top shows 4 metrics: signed, offered, declined, none (the current counts from players.contract_status).
  • An "Offered — the action pool" section lists every contract_status = 'offered' player with: name, program (Kings/Queens), teams, fee, parent email, parent phone, jersey details, contract version, and custom notes.
  • Filters: program, team multi-select, fee tier, "has phone", "custom deal only".
  • The filtered view shows a count: "Showing X of Y offered".
  • Total page load time < 2s (cold cache), < 500ms (warm).

Current implementation

Already built in app.py lines 15–75. Matches all acceptance criteria. This story is captured primarily for traceability — any future work touching the triage view should reference story:triage in its ticket.

Out of scope

  • Mutating contract status from this view (all writes go through the admin UI).
  • Sending outreach messages directly (see story:blast for the copy-paste export workflow).
  • Historical trend lines (how many were signed last week vs this week) — future story if requested.