Operator Spreadsheet Access to Westside Data
story: Operator Spreadsheet Access to Westside Data
Role
Westside Operator — Marcus initially (Lucas's brother, coach candidate, active player), with coaches and other Westside staff as the expansion audience in later phases.
Key
spreadsheet-accessWant
As a Westside operator, I want to view all Westside basketball data in a spreadsheet-style interface with sort, filter, search, and copy-to-clipboard capabilities — without any AI, developer, or admin in the loop.
So That
So that I can independently accomplish the manual operational tasks I own — chasing unsigned contracts, verifying jersey orders, collecting missing waivers, contacting cohorts of parents, pulling lists for GroupMe messages, tracking sponsor outreach, and responding to whatever ad-hoc operational question comes up this week — without waiting for anyone to build a view for me or query the database on my behalf.
Paradigm (why this story exists)
AI should never be a blocker. The current state is that Marcus cannot see or use Westside data directly — his options are "ask Lucas" or "ask an AI agent to query for him." Both of those make a human or AI a dependency in the operator's critical path. That's the pattern this story eliminates. Direct, immediate, unfiltered access to production data (read-only, through a defense-in-depth restricted role) is the correct state. AI becomes an accelerator for tasks like "draft this email" or "summarize this cohort" — it does not become the sole path to the data.
Acceptance Criteria
- [ ] Marcus can navigate to
https://westside-ops.tail5b443a.ts.netfrom his phone (Tailscale-private) and log in via Keycloak using his existing westside realm account - [ ] After login, Marcus sees a sidebar of pages covering every major data surface: Players, Parents, Teams & Rosters, Contracts, Jerseys & Orders, Email Log, Schedule, Coaches, Sponsors
- [ ] Every page renders the full relevant dataset in a Streamlit
st.data_editorgrid with: column header sort, per-column filter, full-text search, row selection, cell selection, Ctrl+C copy-to-clipboard - [ ] Marcus can filter to "all Kings" by clicking the division column filter — no developer involvement, no new page required
- [ ] Marcus can copy the email column of a filtered view and paste it into Gmail or GroupMe without reformatting
- [ ] The underlying data is live — changes made via westside-app's admin (or by basketball-api workflows) appear on Marcus's next page refresh
- [ ] westside-ops is read-only in v1 — no accidental edits, no production data corruption risk
- [ ] Security-critical tables (
oauth_tokens,password_reset_tokens,outbox) are not reachable at the Postgres role level — not just hidden in the UI, literallypermission deniedif a bug tried to query them - [ ] The tool works on Marcus's phone (iOS Safari, 390px viewport) — grids are scrollable and readable on mobile
- [ ] Marcus does not need to learn a query language, a view-builder grammar, or any developer tooling — only the standard spreadsheet UX he already knows
Success Metric
After 1 week of westside-ops being live, Marcus has independently completed at least 5 operational tasks (e.g., "emailed all Kings parents," "pulled a list of unsigned contracts," "copied practice-schedule info for a coach") without asking Lucas, Ava, or any AI agent to query or navigate data on his behalf. Measured by conversation review (if Marcus's Westside-related messages to Lucas drop by >50% while his operational output stays constant or increases, the story is fulfilled).
Related Architecture
arch-deployment-westside-ops— how westside-ops runs (Streamlit pod + private Tailscale + Keycloak OIDC + restricted Postgres role)arch-domain-westside-ops— the subset of basketball-api tables exposed through thewestside_ops_readerrole and how they're grouped into the 9 Streamlit pagesarch-dataflow-westside-ops— the runtime flow: Marcus → Tailscale → Keycloak OIDC → Streamlit → read-only Postgres →st.data_editorgrid
Related
board-westside-ops— project board where tickets serving this story livenocodb-basketball-api-scoping— archived scoping research (NocoDB was evaluated and deferred in favor of Streamlit for tighter stack fit; the schema audit, GRANT allowlist, and workflow analysis in that note remain authoritative)feedback_paldocs_first,feedback_basketball_hands_off,feedback_marcus_plain_language,feedback_discovered_scope_always_tracked— relevant memoriesproject_marcus_second_tryout,project_marcus_doordash_onboarding,user_brother_marcus— Marcus context memoriessession_2026_04_03_email_overhaul— basketball-api's existing email blast endpoint that future cohort-action tickets will integrate with
Explicitly out of scope for v1
- Write access — v1 is read-only. Editing rows comes later, gated on Marcus wanting it and on a backup/undo story.
- Cohort-action buttons (e.g., "email all selected") — v1 uses copy-to-clipboard as the bridge to Gmail/GroupMe. Integrated action buttons come after Marcus has validated the read-only shape.
- Parent-facing or coach-facing filtered views — v1 is Marcus only. Row-level access for other roles comes in a later story.
- Marcus's personal DoorDash/LLC data — distinct dataset, distinct schema, deferred to a future story that reuses the same tool.
- Any changes to westside-app — the existing SvelteKit admin stays untouched. westside-ops is purely additive.