Files
ecw-charge-validation/docs/superpowers/specs/2026-10-19-results-portal-redesign-design.md
T
ManikandanandClaude Opus 5.5 ba15a574ab Initial import: eCW Charge Validation bot and results Portal
Snapshot of the working project as of 2026-10-23 (local 2d4d4fc), one
commit with no earlier history: the tracked files were de-identified
first (synthetic claim ids and patient data only; see Context.md
section 7). Credentials, run logs, screenshots, claim reports and client
workbooks are gitignored and not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:38:17 +05:30

4.6 KiB
Raw Blame History

Results portal redesign — design

Date: 2026-10-19. Operator requests (voice, Tanglish), choices made on the visual companion mockups (.superpowers/brainstorm/828-1792395410/).

Problem

The results page (web/, FastAPI + Jinja, 127.0.0.1:8000) opens on the newest run only. A second run (20 claims) hides the first (10 claims) behind a "Run" dropdown nobody noticed, so earlier runs look lost. The front page is three quarters claims table (24 columns, sideways slider), which the operator does not want on the home page. The look is "very basic".

What the operator chose

Question Choice
Home page Dashboard: Bot run card (Start / Stop / live progress), today's tiles, one big Claim status button
Claim status page Date cards, newest first
A date with several runs All claims of the day together (every run's rows in one list)
One day's page Short table + side panel
Colours Navy & blue (navy header, white cards on light grey, blue buttons)
Live run's claim list In the Bot run card ("Live claims" side panel)
Search one claim over all dates Yes — "Find a claim" on the Dashboard
Approach A — server pages (FastAPI + Jinja), one page per screen

Pages

All pages share base.html: navy header with the title, a mode pill (VERIFY / LIVE-WRITE from SAVE_CORRECTIONS) and a breadcrumb (Dashboard › Claim status › 16 Oct 2026). Light grey background, white cards, blue buttons; Pass green, Fail red, Review amber everywhere.

  1. Dashboard /
    • Bot run card — the existing Start / Stop / progress / live log, plus a Live claims link opening a side panel with every claim of the running (or last) run: Waiting / Checking / result. A claim with a saved result opens /day/<date of its run>?claim=<no>.
    • Today tiles: claims checked today, Pass, Fail, Review (0 when no run today).
    • Find a claim box → /claim?claim_no=….
    • Big Claim status → button → /days.
    • No claims table.
  2. Claim status /days — one card per day (last 90 days with a run), newest first: weekday + date, claims checked, number of runs, Pass / Fail / Review and a thin colour bar. A card opens /day/<date>.
  3. One day /day/YYYY-MM-DD
    • Tiles All / Pass / Fail / Review; a tile is a filter link (?category=Fail). Claim # search box (?claim_no=).
    • Short table, 10 rows a page (client-side pager): #, Claim #, Time (the run's time), Payer, Result chip, Comments (one line, cut with an ellipsis). No sideways scroll.
    • Row click → side panel with every Charge Summary field, the run's time and mode, and the conditions/changes JSON.
    • ?claim=<no> opens that claim's panel on load (on its page).
  4. Claim history /claim?claim_no=… — every saved check of claims matching the number (newest first, up to 200): date, time, mode, result, comments; each row opens /day/<date>?claim=<no>.

/?run_at=<time> (old links) redirects (303) to /day/<date of that run>. /api/runs, /api/results, /api/bot/* stay as they are.

Data

No schema change. web/repo.py gains three parameterized SELECTs:

  • days(limit=90) — GROUP BY CAST(run_at AS DATE): day, claims, runs (COUNT(DISTINCT run_at)), pass / fail / review counts, newest first.
  • day_results(day, category, claim_no) — rows with run_at >= day AND run_at < day + 1, ordered by run_at, S.No, id.
  • claim_history(claim_no) — TOP 200 … WHERE claim_no LIKE ? ordered by run_at DESC.

Rules: a run belongs to the day it started (every row of a run shares its run_at), so a run never splits over two cards. The same claim checked twice in a day shows twice, each with its time; a day's count is checks. "Not found" claims have no saved row (as today) and appear only in the live panel. A legacy driver returning the day as text is coerced to a date, like run_at already is.

Unchanged

127.0.0.1 only; Host allowlist; no-store and the other headers; DB errors reported by kind; Start / Stop need the page's Origin and token; page runs are VERIFY only. All new pages are read-only. Page text from the DB goes out escaped (Jinja autoescape; the panel's data as tojson in an attribute, rendered with textContent).

Testing

tests/test_web_app.py (fake repo, fake DB connection): each page renders with its data and links; filters and the bad-input 400s; the redirect; the three new SQL statements are parameterized and shaped as above; the hardening, API and Start / Stop cases kept. A browser check of the four pages on fixture data (Playwright, the in-app browser).