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>
97 lines
4.6 KiB
Markdown
97 lines
4.6 KiB
Markdown
# 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).
|