Slogan candidates considered
- "Your appeal, written and verified." ← shipping this on the landing page
- "Cited or it doesn't ship."
- "Prior auth, undone."
Greenlight is a multi-agent platform for prior-authorization appeals. Built for LA Hacks 2026 (Catalyst for Care track).
The product is two layers, both wired end-to-end:
- Agent pipeline. Five Python specialist agents (Policy Reader, Clinical Extractor, Literature Retriever, Letter Drafter, Verifier) + Orchestrator on uAgents/Agentverse. Reads chart + denial + payer policy, drafts a cited appeal letter, refuses to ship if any claim is ungrounded. Live in
agents/and exposed over HTTP via the REST + SSE bridge atagents/api/server.py. - Web platform. Next.js dashboard at the repo root (
app/). Doctors, medical assistants, and patients all use it to manage appeals. Live-wired to the agent pipeline throughlib/api.tsand theuseCaseStreamSSE hook — runs against the real orchestrator, persists to MongoDB, surfaces verifier failures, disables Send-to-insurer when claims are ungrounded.
See INTEGRATION_NOTES.md for the full live-wiring design — endpoints, SSE event flow, MongoDB schema, and what's still mocked (auth only).
You'll need MONGODB_URI, ANTHROPIC_API_KEY, and AWS_* Bedrock credentials in .env (see .env.example).
In one terminal — start the API bridge:
source venv/bin/activate
uvicorn agents.api.server:app --port 8000 --reloadIn another — start the web app:
npm install
npm run dev
# open http://localhost:3000Then log in (any seeded account, e.g. rchen@ucla.example / demo123), click New case → Run flagship example → Run pipeline. The agent reasoning trace ticks over for ~3 minutes at real LLM speeds; the verifier flags ungrounded claims and disables Send-to-insurer when it does. See INTEGRATION_NOTES section "Test checkpoints" for the exact per-agent timings.
If you want to iterate on UI without the LLM cost, the lib/store.ts mock layer still ships seeded data (3 hospitals, 3 doctors, 3 medical assistants, 8 patients, 11 cases — including the polished flagship semaglutide / Aetna Better Health case) for pages that haven't been migrated to the live API. The dashboard and case-detail pages are API-only; everything else falls back to seed.
All seeded users share the password demo123:
| Role | What you'll see | |
|---|---|---|
| Doctor | rchen@ucla.example |
UCLA Health queue · hours-saved counter · Send-to-insurer button |
| Medical assistant | drivera@ucla.example |
Only cases they drafted · Mark-ready-for-review button |
| Patient | john.sample@example.com |
Just their own case · status text only, no draft contents |
MOCK AUTH: passwords are stored plaintext via
lib/store.ts. Do not ship as-is — replace with NextAuth + bcrypt before any real PHI. Explicit out-of-scope for the hackathon submission.
- Greenlight palette — single green ramp from light mint (
brand-50) → deep forest (brand-900). Neutrals (slate) do most of the work; green is reserved for primary CTAs, status approved/sent, and brand affordances. Defined as CSS vars + Tailwind theme tokens inapp/globals.css. - Status colors are reserved.
brand-500= approved/sent. Amber-500 = drafting / ready-for-review. Red-500 = denied/rejected. Slate-500 = submitted/waiting. - Dark mode by default, light-mode toggle. Driven by
next-themeswith a class strategy (<html class="dark">). - Aesthetic targets — Linear / Raycast / Cursor density. Geist for UI; Source Serif 4 for the hero wordmark and section headers. Subtle borders over heavy shadows.
rounded-md. One tastefulbrand-50 → transparentgradient on the landing page.
app/
(public)/ landing, about, login, signup — TopNav layout
(auth)/ dashboard, cases/[id], patients/[id], appeals/[id]
— Sidebar layout, redirects to /login if no session
forbidden/ 403 page for failed permission checks
layout.tsx root — fonts, theme provider, tooltip provider
globals.css Tailwind 4 import + brand palette + dark mode
components/
brand/ Logo, StatusBadge, InsuranceLogo, ThemeProvider, ThemeToggle, SeedBoot
ui/ shadcn primitives — Button, Card, Sheet, Tabs, Input, Label,
Textarea, Select, Avatar, Tooltip
layout/ Sidebar, TopNav
case/ CaseTable, CaseDetailSheet, AgentTrace, StatusTimeline
lib/
types.ts User (discriminated union by role), Case, AppealLetter,
Citation, AuditEvent, ChartEvidenceItem, AgentTraceStep
store.ts localStorage-backed mock persistence — collection-shaped API
seed-data.ts 3 hospitals, 3 doctors, 3 assistants, 8 patients, 11 cases
permissions.ts canViewCase, canSendAppeal, canMarkReady, canEditDraft
utils.ts cn(), formatDate, formatRelative, nowIso
public/insurance/
Placeholder SVG logos for Aetna, Aetna Better Health, BCBS, Cigna,
UnitedHealthcare, Humana, Kaiser, Medicare, Medicare Advantage.
NOT licensed trademarks — replace before any real deployment.
agents/ Python multi-agent pipeline
orchestrator.py + 5 agent modules + shared/
api/server.py FastAPI bridge — REST + SSE + MongoDB persistence
(hosts `POST /api/cases`, `GET /api/cases/{id}/stream`, etc.)
hooks/ useCaseStream — SSE consumer for live agent progress
lib/api.ts typed client for the bridge
scripts/ Citation ingest. (scripts/api_server.py is now a re-export
shim for back-compat; canonical bridge is agents/api/server.py.)
data/ Synthetic charts, denial letters, payer policies, citation corpus
Implemented in lib/permissions.ts. Every protected page calls one of these and redirects to /forbidden on a hard fail.
| Role | What they can see |
|---|---|
| Patient | Only their own case(s). Cannot view appeal draft contents — only status text. Cannot reach /patients/[id]. |
| Doctor | Every case at their hospital. Hours-saved counter. "Send to insurer" appears on ready_to_send cases. |
| Medical assistant | Only cases they are listed as assistantId on. "Mark ready for doctor review" appears on drafting cases. |
After npm run dev, go through these as real users to verify nothing regressed:
/— landing renders, slogan visible,Log inabove the fold,Learn morescrolls to about teaser/about— four sections (Why · What we do differently · Who it's for · The team)/login— three role tiles → form reveals on click → demo creds work- Log in as
rchen@ucla.example→ dashboard shows UCLA Health cases only · hours-saved card visible - Log in as
drivera@ucla.example→ dashboard shows only cases where Daniel is the drafter - Log in as
john.sample@example.com→ dashboard shows only flagship case · clicking it opens slide-over with status text only - As
john.sample@example.com, navigating to/cases/case-david1(David's case) → redirects to/forbidden - As doctor, click flagship case row → slide-over with "Open full case" + "Send to insurer" (status
draftingso Send isn't available; switch test case tocase-amelia1for the Send button) /cases/case-flagshipopens — three columns, four tabs, agent trace shows 5 done steps with green checks- As assistant, on
case-flagship(drafting), the "Mark ready for doctor review" button is the visible action; "Send to insurer" is not - As doctor on
case-amelia1(ready_to_send), clicking "Send to insurer" flips status tosentand adds an audit event - As patient on
/cases/case-flagship, the Appeal-draft tab shows status text only — no letter body /patients/pat-john— doctor + assistant only · profile picture, insurance logo, history, cases list, notes textarea/signup— pick a role from query → role-specific fields render → submitting creates the account and logs in- Login with an unknown email → inline "Create an account" link pre-filled with that email
- Refresh the browser → session persists
- Theme toggle in the sidebar / top nav switches dark ↔ light cleanly
LA Hacks 2026 · Catalyst for Care track. Multi-agent on Agentverse. MongoDB Atlas Vector Search for the literature retriever. ElevenLabs voice in MVP 3. Built with Claude Code throughout.
Rishabh Chhabra, Aafreen Nazimuddin, Ainesh Basu — University of Illinois Urbana-Champaign.