Files
ecw-charge-validation/docs/superpowers/plans/2026-10-19-results-portal-redesign.md
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

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=<iso> → 303 to /day/<date> (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/<results_run_at date>?claim=<id>), 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.