238 lines
19 KiB
Markdown
238 lines
19 KiB
Markdown
# Spec: RPA dashboard skills (no-AI and AI)
|
||
|
||
Status: ready-for-agent
|
||
|
||
## Problem Statement
|
||
|
||
Every new RPA project at Ecare needs a dashboard: what the bot is doing now, how many batches finished or failed, a log people can read, and a report they can export. For projects that use AI extraction, it also needs a way for a person to review low-confidence fields and approve them, plus a view of what the AI is costing.
|
||
|
||
Today, each dashboard is built from scratch. Two good dashboards already exist, Tebra ERA (no AI) and Superbill Review (AI), but their designs, colours and data plumbing sit inside those projects. They can't be reused without hours of copy-and-strip work.
|
||
|
||
As a result:
|
||
- Each new project looks different.
|
||
- Each one re-learns the same lessons: never hide error lines, run the bot in its own process, poll only while busy, enforce the approval gate on the server.
|
||
- Developers spend days on UI instead of on the automation.
|
||
|
||
## Solution
|
||
|
||
Build two Claude skills that a developer runs inside any new RPA project to produce a working dashboard page:
|
||
|
||
- **`rpa-dashboard-no-ai`** for plain RPA bots. Based on the Tebra ERA dashboard.
|
||
- **`rpa-dashboard-ai`** for RPA bots that use an LLM or OCR. Based on Superbill Review. It includes everything in the no-AI skill, plus confidence bands, a review-and-approve screen, and a cost/ROI page.
|
||
|
||
When the developer runs a skill, it:
|
||
1. Scans the project.
|
||
2. Tells them whether a frontend already exists: where it is, what stack it uses, and what colours it uses.
|
||
3. Asks whether to keep that look or restyle it.
|
||
4. Asks for colours: a preset (Tebra Sky or Superbill Ember) or their own brand colour.
|
||
5. Asks desktop or web, if there's no frontend.
|
||
6. Asks which optional sections they want.
|
||
7. Builds the page and wires it to the bot using one standard data contract. If no bot exists yet, it uses sample data so the page works on day one.
|
||
|
||
## User Stories
|
||
|
||
1. As an RPA developer, I want to run one skill in a new project and get a working dashboard page, so that I don't build the UI from scratch.
|
||
2. As an RPA developer, I want to choose between a no-AI skill and an AI skill, so that the dashboard matches what my bot actually does.
|
||
3. As an RPA developer, I want the skill to scan my project before asking anything, so that it doesn't ask questions the code already answers.
|
||
4. As an RPA developer, I want the skill to tell me whether a frontend already exists, with its location, stack and colours, so that I know what it found before it changes anything.
|
||
5. As an RPA developer with an existing frontend, I want to choose between keeping its look and restyling it, so that the skill never overwrites my brand without asking.
|
||
6. As an RPA developer who keeps the existing look, I want the new dashboard page to match the existing tokens, fonts and components, so that it feels like part of the same app.
|
||
7. As an RPA developer who restyles, I want the skill to replace only the theme tokens, so that my layout and logic stay untouched.
|
||
8. As an RPA developer with no frontend, I want to pick the Tebra Sky preset, so that I get the blue glassmorphism look quickly.
|
||
9. As an RPA developer with no frontend, I want to pick the Superbill Ember preset, so that I get the red-orange brand gradient look quickly.
|
||
10. As an RPA developer, I want to give one brand hex and have the skill derive the rest of the palette, so that a client-branded dashboard needs no design work.
|
||
11. As an RPA developer, I want every palette to come with a matching dark mode, so that dark mode never looks broken.
|
||
12. As an RPA developer, I want the skill to check text contrast for a custom palette, so that the dashboard stays readable.
|
||
13. As an RPA developer with no frontend, I want to choose desktop (PyQt with an embedded web page) or web, so that the dashboard fits how the bot is deployed.
|
||
14. As an RPA developer on desktop, I want the page to talk to Python through a bridge, so that I don't need a web server.
|
||
15. As an RPA developer on web, I want the same page to poll the backend, so that one design serves both deployment styles.
|
||
16. As an RPA developer, I want to choose which optional sections get built (checkpoint tracker, admin/roles, login), so that I don't delete unused code afterwards.
|
||
17. As an RPA developer, I want the sidebar, top bar, dark toggle and status dot built every time, so that every dashboard has the same shell.
|
||
18. As an RPA developer, I want KPI cards for total, completed, in-progress and not-completed batches, so that the overview always answers "how are we doing?".
|
||
19. As an RPA developer, I want a status donut with a legend, so that the batch split is visible at a glance.
|
||
20. As an RPA developer, I want a run panel with a progress bar, a step list and a live log, so that operators can watch a run happen.
|
||
21. As an RPA developer, I want a report table with search and Excel export, so that results can be handed to the billing team.
|
||
22. As an RPA developer, I want one documented data contract (events in, actions out), so that I know exactly what my bot must send.
|
||
23. As an RPA developer, I want the skill to wire the contract to my existing bot, so that the dashboard shows real data immediately.
|
||
24. As an RPA developer without a bot yet, I want the page to ship with sample data, so that I can demo and style it before the bot exists.
|
||
25. As an RPA developer, I want my bot's raw output lines turned into friendly log messages by a rules table, so that operators see plain English.
|
||
26. As an RPA developer, I want error lines always shown even when no friendly rule matches, so that a real failure is never invisible.
|
||
27. As an RPA developer, I want step progress driven by specific markers in the bot's output, so that progress doesn't jump on unrelated lines.
|
||
28. As an RPA developer on desktop, I want the bot to run in its own process with its output tailed, so that UI automation reads stay reliable.
|
||
29. As an RPA developer on web, I want polling to speed up only while a run is busy, so that an idle dashboard doesn't hammer the backend.
|
||
30. As an operator, I want a status dot that says ready, running, done or error, so that I know at a glance whether the bot is working.
|
||
31. As an operator, I want a Run button that disables itself while a run is going, so that I can't start two runs by accident.
|
||
32. As an operator, I want my dark-mode choice remembered, so that I don't toggle it every time.
|
||
33. As an operator, I want each report row to show a coloured success, attention or failed pill, so that I can spot problems fast.
|
||
34. As an operator, I want the dashboard to stay usable on a narrow window, so that it works on a small laptop screen.
|
||
35. As an admin, I want an optional roles screen (admin/operator), so that only the right people see admin features.
|
||
36. As an AI-project developer, I want the AI skill to include everything from the no-AI skill, so that I don't have to merge two outputs.
|
||
37. As an AI-project developer, I want confidence bands (green ≥0.95, amber 0.90–0.95, red <0.90), so that reviewers only look at fields that need them.
|
||
38. As an AI-project developer, I want a field's band to come from its worst word score, so that one shaky word can't hide inside a clean-looking field.
|
||
39. As an AI-project developer, I want a blank mandatory field always flagged, so that a missing code never passes silently.
|
||
40. As an AI-project developer, I want the band caveat shown in the UI ("colour reflects print clarity, not correctness"), so that reviewers don't over-trust green.
|
||
41. As a reviewer, I want the source document next to the extracted fields, so that I can check each value against the original.
|
||
42. As a reviewer, I want to filter fields by band (all, red, amber, missing, unscored), so that I work the riskiest fields first.
|
||
43. As a reviewer, I want to correct a value and keep it as a draft until I save, so that I don't commit half-finished edits.
|
||
44. As a reviewer, I want a warning if I leave with unsaved edits, so that I don't lose work.
|
||
45. As a reviewer, I want to verify each field, so that there's a record of who checked what.
|
||
46. As a reviewer, I want a "verify remaining" action, so that I can finish a clean document quickly.
|
||
47. As a reviewer, I want approval to be refused by the server until every required field is verified, so that the gate can't be bypassed from the browser.
|
||
48. As a reviewer, I want to see "page X of Y" while extraction runs, so that I know how long to wait.
|
||
49. As a reviewer, I want to retry a failed run on the same or a different model, so that a quota or overload error doesn't block me.
|
||
50. As an AI-project developer, I want an optional model picker, so that users can choose a cheaper or stronger model per batch.
|
||
51. As a manager, I want a cost page with input, output and thinking tokens and cost per run, so that I know what the AI spends.
|
||
52. As a manager, I want this month's spend and a month-by-month breakdown, so that I can track the budget.
|
||
53. As a manager, I want a coverage pill ("N of M documents priced"), so that I know whether the totals are complete.
|
||
54. As a manager, I want an "against doing it by hand" panel with editable assumptions, clearly labelled as assumptions, so that the ROI story is honest.
|
||
55. As an AI-project developer, I want a pricing table with a clear error when a model is missing, so that cost is never silently wrong.
|
||
56. As an AI-project developer on desktop, I want the AI sections available as plain HTML, so that a PyQt AI project gets them too.
|
||
57. As an AI-project developer on web, I want the AI dashboard built in React with Vite and Tailwind, adapted from the Superbill components, so that it matches the proven design.
|
||
58. As a skill maintainer, I want the reference code bundled inside each skill, so that the skills work on any PC even if the source projects move.
|
||
59. As a skill maintainer, I want the bundled references free of patient data, internal IPs and keys, so that the skills are safe to share.
|
||
60. As a skill maintainer, I want project-specific names (ECW, Tebra, table prefixes, patient/ticket wording) stripped or clearly marked, so that new projects don't inherit them.
|
||
61. As a skill maintainer, I want an automated check that the generated page renders contract events correctly, so that I can change templates without fear.
|
||
62. As a skill maintainer, I want an eval that runs each skill on small fixture projects, so that I know the question flow and output still work.
|
||
63. As a team member, I want to install the skills by copying their folders into Claude's skills directory, so that setup is trivial.
|
||
|
||
## Implementation Decisions
|
||
|
||
**Modules**
|
||
- **Two skills, each self-contained:** a skill file holding the workflow and trigger description, plus a templates folder. The AI skill's desktop path reuses the no-AI dashboard page, so both skills must be installed together.
|
||
- **No-AI templates:**
|
||
- a single-file dashboard page (theme tokens, shell, KPI, donut, run panel, report);
|
||
- a minimal PyQt host with bridge and process tailing;
|
||
- the data contract;
|
||
- theme presets;
|
||
- raw Tebra extracts as reference.
|
||
- **AI templates:**
|
||
- an AI data contract that extends the no-AI one;
|
||
- plain-HTML AI sections for desktop (band legend, review split pane, ROI tiles);
|
||
- theme presets;
|
||
- Superbill reference components, styles, band logic and the pricing/cost function.
|
||
|
||
**Workflow order, identical in both skills**
|
||
1. Scan.
|
||
2. Report the existing frontend, then ask keep or restyle.
|
||
3. Ask colours. Skipped if the user keeps the existing theme.
|
||
4. Ask the stack question. Only when there's no frontend.
|
||
5. Ask for optional sections.
|
||
6. Build.
|
||
7. Wire the data.
|
||
8. Verify.
|
||
|
||
**Theme rules**
|
||
- The theme lives only in the token blocks, light plus dark. Restyling swaps tokens and nothing else.
|
||
- Presets:
|
||
- **Tebra Sky:** sky gradient, glass cards, accent `#3d9bd0`, Segoe UI.
|
||
- **Superbill Ember:** flat surfaces, gradient `#ff3049`→`#f26b21`, used only on the header, primary buttons, the active nav row and the progress fill; Sora and IBM Plex fonts.
|
||
- **Custom:** derived from one brand hex.
|
||
- Band colours are semantic only and never used on buttons or headings.
|
||
|
||
**Transport**
|
||
- One envelope in both directions: `{event, data}`.
|
||
- **Desktop:** Python pushes envelopes into the page; the page calls named bridge slots.
|
||
- **Web:** the page polls a dashboard endpoint and a run-status endpoint. Run-status returns `{running, events[]}`. Polling is fast (≈2s) only while running, otherwise slow.
|
||
- The same page file detects which transport is present.
|
||
|
||
**No-AI contract (events to the page)**
|
||
- `status {state: ready|running|done|error, msg}`
|
||
- `step {label, pct}`
|
||
- `log {msg, type: info|success|warn|error}`
|
||
- `dashboard_data {batches: [{batch_id, date, state: completed|inprogress|notcompleted|cleared, items_total, items_done}]}`
|
||
- `report_data {rows: [... , status, bucket: success|attention|failed]}`
|
||
- `set_user {username, emp_id, role}`
|
||
- `apply_dark {on}`
|
||
- Optional: `cpstate {kind: pending|active|done|stuck, cp}`
|
||
|
||
**No-AI contract (actions from the page)**
|
||
- `load_dashboard`, `start_automation`, `request_stop`, `load_latest_report`, `download_report`, `set_dark`, `logout`
|
||
|
||
**Derived rules**
|
||
- A Pending batch from today is `inprogress`; one from an older day is `notcompleted`.
|
||
- Report buckets map {processed successfully, posted, completed} to success and {error, failed} to failed; everything else is attention.
|
||
|
||
**AI contract additions.** These type shapes came from the Superbill prototype; trimmed:
|
||
|
||
```
|
||
Run { job_id, status: pending|queued|running|done|failed, model,
|
||
pages_done, pages_total, summary: { green, amber, red, unscored } }
|
||
ReviewRow { row_id, field, value, band: green|amber|red|blank|unscored,
|
||
score, reason, verified, corrected_value }
|
||
RoiRun { model, input_tokens, output_tokens, thinking_tokens, total_cost }
|
||
```
|
||
|
||
The AI skill adds these actions: patch one review row (corrected value, verified), approve a run (the server enforces the gate), and fetch ROI. While a single run is busy, it's polled every ≈1.5s.
|
||
|
||
**Banding**
|
||
- Green ≥0.95, amber 0.90–0.95, red <0.90.
|
||
- A multi-word field takes the minimum word score.
|
||
- A blank mandatory field is always flagged.
|
||
- The caveat text is shown next to the legend.
|
||
|
||
**Cost**
|
||
- Cost per call = input tokens × input rate + (output + thinking tokens) × output rate, per million tokens.
|
||
- The pricing table records its source and its as-of date. An unknown model raises an error naming the known models; it never defaults to zero.
|
||
|
||
**Bot integration on desktop**
|
||
- The bot runs as a child process, and its stdout is tailed.
|
||
- The raw line is kept for audit.
|
||
- The step-marker table and the friendly-rules table use specific substrings, and the first match wins.
|
||
- Unmatched non-error lines are hidden; unmatched error lines are always shown.
|
||
|
||
**Fill-in points**
|
||
- Template placeholders are filled by the skill: app name, subtitle, logo, steps, report columns, API base, bot module.
|
||
- Python templates must stay valid Python before they're filled, so placeholders go inside string literals. The current host template breaks this rule and is known lint debt.
|
||
|
||
**Safety**
|
||
- Bundled references contain no PHI, internal IPs, credentials or keys.
|
||
- Project-specific names are removed or marked as examples.
|
||
|
||
## Testing Decisions
|
||
|
||
- **Good tests check external behaviour only:** what the user sees on the page for a given set of contract events, and what files and questions a skill produces for a given project. They don't check internal function names, CSS class names or the template's internal structure.
|
||
- **Seam 1: the data contract (primary).**
|
||
- Load a generated dashboard page in a headless browser with no backend.
|
||
- Push contract envelopes through the page's public entry point.
|
||
- Assert on the visible result. KPI numbers match the batch states; donut segments and legend counts match; the active and done steps match the step label; log lines appear with the right type; error lines from an unmatched bot line appear; report rows filter on search and show the right bucket pill; dark mode flips the theme.
|
||
- The AI variant also checks: band counts and legend; review rows filtered by band; approve stays blocked while rows are unverified (server stub returns refusal); ROI tiles sum the runs; a missing-price model surfaces an error.
|
||
- Run each case in light and dark, and at a narrow width (≤820px).
|
||
- **Seam 2: skill eval.**
|
||
- Run each skill against small fixture projects:
|
||
- (a) empty project, no frontend, no bot;
|
||
- (b) PyQt project with a bot that prints step markers;
|
||
- (c) web project with an existing frontend and its own colours;
|
||
- (d) for the AI skill, a project with an LLM extraction call.
|
||
- Assert that the skill reports the existing frontend only when there is one, and asks keep-or-restyle in that case.
|
||
- Assert that it asks for colours and stack only when appropriate, and asks for optional sections.
|
||
- Assert that it produces a page that passes Seam 1 with sample data, or with the fixture bot's real output in case (b).
|
||
- Use the skill-creator eval tooling, or `claude plugin eval`.
|
||
- **Python logic tests:** the pure Python pieces bundled in the templates get a small assert-based self-check: line classification and friendly-rule matching, band assignment, and cost calculation. The prior art is the band and cost functions in Superbill and Tebra's pytest suite for report categorisation and batch state.
|
||
- **Prior art:** Tebra has pytest files covering batch clear, report scope and status categorisation. Superbill's band thresholds and its server-enforced approval gate define the expected AI behaviour.
|
||
|
||
## Out of Scope
|
||
|
||
- **Backend generation:** database tables, stored procedures, worker queues, and auth/login services. The skills wire to what exists or ship sample data; they don't build the backend. (The optional login page is UI only.)
|
||
- **The automation itself:** UI automation steps, SOAP/API posting, and extraction prompts and templates.
|
||
- **Deployment:** the auto-update launcher and Dokploy.
|
||
- **Frameworks other than plain HTML (desktop/web) and React (AI web).** For an existing Vue/Angular frontend, the skill ports sections using the HTML as reference, best effort, with no dedicated template.
|
||
- **Exact ports of every original feature:** PDF zoom/fullscreen polish, drag-to-stage in the sidebar, the animated extraction progress, demography and insurance lookups, and the batch-clear approval flow.
|
||
- **Installing the skills into Claude.** The user copies the folders.
|
||
|
||
## Further Notes
|
||
|
||
- **Source projects:** Tebra ERA, a PyQt6 desktop app whose dashboard is one embedded HTML page; and Superbill Review, FastAPI with a React 19 + Vite + Tailwind v4 front end and Gemini on Vertex AI. Their design docs (Superbill's design and product notes, Tebra's context notes) explain the reasoning behind the visual rules and should be read before changing presets.
|
||
- **Already done in this folder:**
|
||
- the no-AI dashboard page, the PyQt host and the no-AI contract;
|
||
- reference extracts for both skills.
|
||
- **Still to do:**
|
||
- both skill files;
|
||
- both theme preset files;
|
||
- the AI contract;
|
||
- the AI desktop sections;
|
||
- stripping project names from the AI references;
|
||
- fixing the host template's placeholder lint;
|
||
- both test seams.
|
||
- **Plan:** the planning record with every grill decision is the plan file at the repo root.
|
||
- No glossary or ADRs exist yet for this folder.
|