Skip to content

Spike: rebuild M4 review screen in Streamlit (1-day time-box) #154

Closed

Description

@amar-python

Spike

Rebuild the M4 review screen in Streamlit, as a learning exercise. Decide the real frontend direction based on what the spike teaches.

Resolves the "spike, then decide" plan from #152.

Why the M4 review screen

Most interactive screen in the current frontend (csv-table-hub-main/src/components/review-table.tsx):

  • Paging through stored rows (100 at a time)
  • Cell edits with validation errors shown inline
  • Required-reason dialog, Save disabled until a reason is entered
  • Role-based conditional UI (reviewers/tenant_admin see edit controls; others see read-only)
  • Row history popup with who/when/why
  • Red cell tinting for invalid, blue for edited, with original value in a tooltip

If Streamlit handles this comfortably, it'll handle every simpler screen. If it strains or needs ugly workarounds, Streamlit isn't the fit.

Time-box

1 day. If a working review page isn't up by end of day two, Streamlit isn't the right tool — stop and reconsider.

Scope

  • One screen (M4 review), not the whole app
  • Reads from the existing FastAPI API — no new backend code
  • Must support: paging, cell edit dialog with reason, exclude/include, history view, role gating (uploader sees read-only)
  • Does not need to: match the exact styling, support offline-only operation, replace the React screen in production

The React implementation stays live. This spike is a parallel exploration, not a migration.

Done when

The spike yields one of these three outcomes, documented in a comment on this issue:

  1. "Streamlit was fine, I prefer this." Follow-up issue filed for staged migration plan.
  2. "Streamlit was limiting but Python-native felt right." Follow-up issue filed for a NiceGUI spike (or commit to Reflex).
  3. "Python-native felt wrong." This issue closed, Option 1 from Decide: frontend architecture after ending Lovable relationship #152 wins (keep React code), no follow-up.

In all three cases, this issue closes.

Pre-conditions

  • Python 3.11+ already on dev machine (used for FastAPI)
  • pip install streamlit on the dev machine (one-time)
  • Local FastAPI running (same workflow as current frontend dev)

No air-gap concerns for the spike itself.

Timing

When the product owner picks it up. No fixed date. Current priorities (as of 2026-11-02): #60 offline install dry run due 15 Nov, then this.

Related

Activity

  1. added
    decisionNeeds a product-owner decision before work starts
    on Nov 2, 2026
  2. added a commit that references this issue on Nov 9, 2026
  3. amar-python commented on Nov 9, 2026

    @amar-python
    OwnerAuthor

    Outcome 1: Streamlit was fine, I prefer this

    The spike (#205, merged as 78ca648) rebuilt the M4 review screen in Streamlit against the existing API with no backend changes. Paging, cell edit and exclude/include with a required reason, history, and role gating (uploader read-only) all worked. Findings are in spikes/streamlit_review/README.md.

    Strains to plan around in the migration (none were blockers):

    1. No click-to-edit on a cell: select the row, then pick the column.
    2. Save enables on Enter or blur in the reason field, not per keystroke. The API still rejects an empty reason.
    3. No per-cell tooltips; the original value shows in the row detail panel.
    4. The script reruns on every interaction.
    5. Styling is limited to colours and backgrounds.
    6. It adds a Streamlit server to deploy. Offline packaging for 2026-11-15: ship air-gapped install procedure or keep interim wording #60 is untested.

    What this means for the parked issues

    Issue Effect
    #176 localStorage leak Moot once the React screen is replaced; Streamlit keeps session state on the server
    #179 lint baseline Moot with the React code
    #186 header mapping API side still needs a decision; the UI control is rebuilt or dropped
    #187 failed uploads unreachable The spike's upload picker already lists every attempt, failed ones included
    #188 misleading Cancel Don't build Cancel without server-side cancellation (#110)
    #190 T&E errors Backend fix already merged (#203)

    Next

    Follow-up issue for the staged migration plan, per the outcome-1 path in the description.


    Generated by Claude Code

  4. amar-python commented on Nov 9, 2026

    @amar-python
    OwnerAuthor

    Follow-up filed: #212 (staged migration plan). Closing as completed with outcome 1.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    decisionNeeds a product-owner decision before work starts

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions