# Results Portal Redesign Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the one-page results table with a Dashboard → Claim status (date cards) → One day (short table + side panel) portal, plus a claim history search, in a navy & blue theme. **Architecture:** Server-rendered FastAPI + Jinja pages sharing `base.html`. Three new read-only queries in `web/repo.py` group the existing `CV_ChargeSummary` rows by the day a run started. The Bot run card and `/api/*` stay as they are; old `/?run_at=` links redirect to the day page. **Tech Stack:** FastAPI, Jinja2, pyodbc (SQL Server), vanilla JS, standalone test scripts (`python tests\test_web_app.py`). **Spec:** `docs/superpowers/specs/2026-10-19-results-portal-redesign-design.md` ## Global Constraints - Bound to 127.0.0.1; Host allowlist, `no-store` headers, DB errors by kind — unchanged. - Start / Stop need the page Origin and `X-Run-Token`; page runs are VERIFY only. - All new pages read-only; every SQL statement parameterized; values never in SQL text. - DB text is escaped: Jinja autoescape, panel data via `tojson` in an attribute, written with `textContent`. - No claim ids or patient data in tracked docs; tests use made-up ids. - No git commits unless the operator asks. --- ### Task 1: Day-wise queries in the repo **Files:** Modify `web/repo.py`; Test `tests/test_web_app.py` **Interfaces — Produces:** - `SqlResultsRepo.days(limit: int = 90) -> list[dict]` — keys `day` (date), `claims`, `runs`, `pass_count`, `fail_count`, `review_count`; newest first. - `SqlResultsRepo.day_results(day: date, category=None, claim_no=None) -> list[dict]` — full rows (`_SELECT_COLUMNS`) with `run_at >= day AND run_at < day+1`, ordered `run_at, s_no, id`. - `SqlResultsRepo.claim_history(claim_no: str) -> list[dict]` — `TOP 200` full rows `WHERE claim_no LIKE ?` ordered `run_at DESC, s_no, id`. - `_coerce` also turns a text `day` into a `date`. - [ ] Tests: each query's SQL is a parameterized SELECT with the clauses above and the expected params (`[datetime(day), datetime(day)+1 day]`, `["%no%"]`); text `day` coerced. - [ ] Implement; run `python tests\test_web_app.py`. ### Task 2: Routes **Files:** Modify `web/app.py`; Test `tests/test_web_app.py` **Interfaces — Consumes:** Task 1. **Produces:** routes - `GET /` → `dashboard.html` with `today` (days() row for `date.today()` or zero counts), `mode` ("VERIFY"/"LIVE-WRITE"), `run_token`. `GET /?run_at=` → 303 to `/day/` (keeps `category`, `claim_no`); bad `run_at` → 400. - `GET /days` → `days.html` with `days`. - `GET /day/{day}` (`YYYY-MM-DD`, else 400) with `category`, `claim_no`, `claim` → `day.html` with `day`, `counts` (from `days()` row or computed from the unfiltered rows), `rows` (each with `fields` = list of `[header, display text]` and `details_pretty`), filters. - `GET /claim?claim_no=` → `claim.html` with `rows` (history) and `claim_no`; empty search → page with the box only. - FakeRepo in tests gains `days`, `day_results`, `claim_history`. - [ ] Tests for each route (data shown, links, filters passed, 400s, redirect, DB down 503, hardening incl. new paths). - [ ] Implement; run tests. ### Task 3: Templates and theme **Files:** Create `web/templates/base.html`, `dashboard.html`, `days.html`, `day.html`, `claim.html`; delete `web/templates/index.html`. - `base.html`: `:root` navy palette, header (title, mode pill, breadcrumb block), `{% block content %}`, `{% block scripts %}`, footer PHI note. - `dashboard.html`: Bot run card (moved from index.html, with the Live claims panel replacing the old Claim status panel; a saved claim opens `/day/?claim=`), today tiles, Find a claim form, big Claim status button. - `days.html`: date cards grid with counts and colour bar; empty state. - `day.html`: tiles as filter links, claim search, short table (#, Claim #, Time, Payer, Result, Comments), 10-a-page pager, side panel from `data-fields` (`tojson`) via `textContent`; `?claim=` opens it. - `claim.html`: search box and history table linking to day pages. - [ ] Tests on rendered HTML (ids, links, no inline `style=`, theme vars, panel wiring, one-scroll lock, Live claims link target). - [ ] Run `python tests\test_web_app.py` and `python tests\test_run_status.py`. ### Task 4: Browser check - [ ] Serve the app on a fake repo with sample data (scratch script, made-up ids), open each page in the in-app browser, screenshot, check pager, panel, filters, empty states, narrow width. - [ ] Full suite.