Ticket: Streamlit st.data_editor UX veto spike (local, 30 min)

ticket-westside-ops-streamlit-spike Doc

active backlog westside-ops ticket spike

Ticket: Streamlit st.data_editor UX veto spike

Story: story-westside-ops-spreadsheet-access
Architecture: arch-deployment-westside-ops, arch-dataflow-westside-ops
Labels: story:spreadsheet-access,arch:streamlit-app,type:spike,track:research,scope:planned
Estimated effort: 30 minutes
Blocks: every other ticket in this project. Blocked by: nothing.

Purpose

This is the veto gate. Before any infrastructure work starts, Lucas needs to see st.data_editor rendering real basketball-api data and decide whether the grid UX is acceptable. If the grid feels wrong, we pivot to NocoDB (per the archived nocodb-basketball-api-scoping note) — no production resources get created in the meantime.

Scope

  • Create a throwaway Python venv locally (~/tmp/westside-ops-spike or similar)
  • pip install streamlit pandas psycopg2-binary
  • Port-forward the basketball-api Postgres pod: kubectl port-forward -n basketball-api postgres-9b5b87b5-5nccx 5432:5432 (in a separate shell — use the running pod name from kubectl get pods -n basketball-api -l app=postgres, not this exact name)
  • Write a ~50-line spike.py with one Streamlit page: "Players" — full join of players, parents, teams, filtered to tenant_id=1, rendered with st.data_editor(df, disabled=True, use_container_width=True)
  • Connect as the existing basketball role (read the password from ~/secrets/basketball-api/postgres-password). The westside_ops_reader role does NOT exist yet — that's a later ticket. For this spike, we just need to see the grid.
  • streamlit run spike.py, open in browser, verify: sort by clicking column headers, per-column filter UI, search box, row selection, Ctrl+C copy of a cell range
  • Take 2-3 screenshots: full grid, filtered grid (e.g., division='boys'), and a selected-and-copied cell range

Acceptance Criteria

  • [ ] streamlit run spike.py opens a browser tab showing the Players grid with 66 rows
  • [ ] Sort works on every column (click header to cycle asc/desc)
  • [ ] Per-column filter works (click the filter icon, filter by value)
  • [ ] Search box filters across the whole grid
  • [ ] Cell selection + Ctrl+C copies tabular text to clipboard (verify by pasting into a text editor)
  • [ ] Screenshots captured and shared with Lucas
  • [ ] Lucas gives explicit thumbs up OR thumbs down on the UX

Verification

Lucas looks at the screenshots (or runs it himself via the spike.py file) and says one of:
  • "Yes, this works" — all other tickets in board-westside-ops become reviewable. Ava can start the review-ticket loop to promote them to todo.
  • "No, UX is wrong" — this ticket is marked done-with-pivot, and we unarchive the nocodb-basketball-api-scoping note, start a parallel NocoDB scoping effort on a separate spike ticket.

Files touched

  • Local only — no repos touched
  • ~/tmp/westside-ops-spike/spike.py (throwaway)
  • ~/tmp/westside-ops-spike/.venv/ (throwaway)

Rollback

Delete the throwaway directory. No cluster changes, no repo changes, no state to unwind.

Out of scope

  • Keycloak OIDC integration — not needed for veto gate, added in the main ticket
  • Multiple pages — one page is enough to judge the grid component
  • Styling or branding — defaults are fine, we're evaluating the grid, not the chrome
  • Write access — disabled=True for the spike
  • Any pod, service, or ingress work

Dependencies

None. This is the first thing that happens.