{"id":50391020,"url":"https://github.com/hallelx2/enyata-project","last_synced_at":"2026-05-30T18:01:36.458Z","repository":{"id":347363156,"uuid":"1184745006","full_name":"hallelx2/enyata-project","owner":"hallelx2","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-27T22:36:29.000Z","size":150,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T00:57:38.899Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hallelx2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-17T22:27:28.000Z","updated_at":"2026-03-27T22:36:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hallelx2/enyata-project","commit_stats":null,"previous_names":["hallelx2/enyata-project"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hallelx2/enyata-project","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hallelx2%2Fenyata-project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hallelx2%2Fenyata-project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hallelx2%2Fenyata-project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hallelx2%2Fenyata-project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hallelx2","download_url":"https://codeload.github.com/hallelx2/enyata-project/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hallelx2%2Fenyata-project/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33703065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T18:01:35.825Z","updated_at":"2026-05-30T18:01:36.441Z","avatar_url":"https://github.com/hallelx2.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AuraHealth — Enyata × Interswitch Buildathon Submission\n\n\u003e **Powered by Interswitch QuickTeller — eliminating Nigeria's hospital payment queues through AI triage and escrow-backed care**\n\n**Live Link:** https://aurahealth-five.vercel.app\n\n---\n\n## Interswitch APIs Used\n\n| API | Endpoint | Purpose |\n|-----|----------|---------|\n| OAuth 2.0 | `POST /passport/oauth/token` | Authenticate server-side requests (Basic auth, client_credentials) |\n| Pay Bill API | `POST /collections/api/v1/pay-bill` | Create server-side payment link — returns a `paymentUrl` to redirect to |\n| Hosted payment page | `newwebpay.qa.interswitchng.com/collections/w/pay` | Patient pays escrow — card, bank transfer, USSD, or wallet |\n| Transaction verification | `GET /collections/api/v1/gettransaction.json` | Confirm payment succeeded before marking escrow as held |\n| Payouts | `POST /api/v1/payouts` | Disburse held escrow funds to hospital bank account on release |\n| *(Next)* Identity verification | Interswitch KYC API | Verify patient and hospital identity at onboarding |\n\n**Sandbox:** `qa.interswitchng.com` (API) + `newwebpay.qa.interswitchng.com` (payment page)\n**Production:** `webpay.interswitchng.com` (API) + `newwebpay.interswitchng.com` (payment page)\n\nThe integration code is in [`src/lib/interswitch.ts`](src/lib/interswitch.ts) and [`src/app/api/escrow/callback/route.ts`](src/app/api/escrow/callback/route.ts).\n\n---\n\n## The Problem\n\nA patient in a Nigerian emergency faces a payment queue at every stage of care:\n\n- Admission desk — pay to register\n- Ward allocation — pay for bed\n- Diagnostics — pay for labs and imaging\n- Pharmacy — pay for each medication\n- Procedures — pay per intervention\n\nEach payment is separate, often requires cash, and must be settled *before* care is delivered. This costs time — and lives.\n\nAuraHealth eliminates this queue entirely. A single voice call to our AI agent covers the full episode of care in advance, routed to the right hospital with the right resources.\n\n---\n\n## How It Works\n\n### Step 1 — The Hospital Gets Ready\n\nA hospital signs up at [/signup](https://aurahealth-five.vercel.app/signup) and is **auto-approved** — their dashboard opens immediately. A setup modal prompts them to fill in:\n\n- Description, specialties, emergency phone number\n- Number of general beds, ICU slots\n- A resource inventory — each item with a name, category, available count, and price in ₦ (e.g. General Bed ₦15,000/night, ICU ₦80,000/night, CT Scan ₦25,000)\n\nThis resource inventory is what feeds the AI agent. When a patient calls, Aura already knows exactly what the hospital has available and at what price — before she asks a single question.\n\nThe hospital also registers their bank account. This is where Interswitch disburses the escrow balance when the hospital marks treatment complete.\n\n---\n\n### Step 2 — The Patient Signs Up and Links to a Hospital\n\nA patient signs up at [/signup](https://aurahealth-five.vercel.app/signup). They are automatically matched to an available hospital, or they can search and request a specific one from their dashboard at [/dashboard/patient](https://aurahealth-five.vercel.app/dashboard/patient).\n\nThe patient also links a payment source — a debit card, bank account, or HMO/insurance policy. AuraHealth stores a reference to this source (not the raw card data). This is the account that gets charged when they confirm payment during a triage call.\n\n---\n\n### Step 3 — The Patient Calls Aura\n\nThe patient opens their dashboard and taps **\"Start Voice Triage\"** — a live browser call starts immediately via VAPI. Or they can call directly on `+17622204588`.\n\n**Aura answers.** She runs on GPT-4o (conversation), Deepgram nova-3-medical (clinical-grade transcription), and ElevenLabs (voice synthesis).\n\nAura asks: *\"Hi, I am Aura. What brings you in today?\"*\n\nThe patient describes their symptoms in plain speech. Aura listens, assesses severity (critical / high / medium / low), and decides it is time to route.\n\n---\n\n### Step 4 — Aura Contacts Our Server (The Tool Call)\n\nWhen Aura has enough information, she internally triggers a **server tool call** — VAPI sends a POST request to our webhook at `/api/vapi/webhook` with the symptoms and severity. Our server then does four things:\n\n1. **Creates a triage record** in the database — patient, symptoms, severity, timestamp\n2. **Fetches the hospital's live resource inventory** — what is available and at what price right now\n3. **Sends everything to Gemini 2.5 Pro** (via Google Vertex AI) — symptoms, severity, hospital resources — and asks it to generate:\n   - A warm routing message to read aloud to the patient\n   - 3–5 differential diagnoses (medical terms for the doctor)\n   - A clinical summary paragraph for the receiving doctor\n4. **Saves the differentials and clinical summary** back to the triage record\n\nOur server returns the routing message as plain text. VAPI reads it aloud to the patient immediately.\n\n---\n\n### Step 5 — Payment Pre-Authorisation via Interswitch\n\nRight after routing, Aura asks: *\"Shall I pre-authorise ₦5,000 for your care? This guarantees you will not face any payment queues on arrival.\"*\n\nThe patient says **\"Yes\"**. VAPI fires a second tool call — `createEscrow`. Our server:\n\n1. Creates an escrow record in the database\n2. Gets an **OAuth 2.0 Bearer token** from Interswitch (`POST /passport/oauth/token`)\n3. Builds a **SHA-512 signed redirect URL** for the Interswitch hosted payment page\n4. Charges the patient's linked payment source via Interswitch\n5. Interswitch redirects the patient back to `/api/escrow/callback`\n6. We verify the transaction (`GET /collections/api/v1/gettransaction.json`) — response code `\"00\"` means success\n7. Escrow is marked **\"held\"** — money is locked with AuraHealth until the hospital releases it\n\nAura reads back the confirmation and reference number. The patient is done — no browser, no card entry, no queues.\n\n---\n\n### Step 6 — The Hospital Dashboard Lights Up\n\nWhile all of this is happening, the hospital dashboard is **listening via SSE** (Server-Sent Events). Our stream endpoint at `/api/triage/stream` polls the database every 5 seconds and pushes any new or updated triages to the connected hospital browser.\n\nThe moment the triage is created, a new card appears in the hospital's **Triage** tab showing:\n- Patient name and symptoms\n- Severity badge (CRITICAL / HIGH / MEDIUM / LOW)\n- **Clinical AI Assessment** — the differential diagnoses and clinical summary Gemini generated\n\nThe doctor reads the AI assessment **before the patient walks through the door.**\n\n---\n\n### Step 7 — The Patient Arrives, No Payment Friction\n\nThe patient arrives. The doctor already knows what is likely wrong. There is no admission desk payment, no pharmacy queue, no diagnostic payment. The escrow covers everything.\n\nThe doctor opens the triage card and clicks **\"Mark In Progress\"**. The patient's dashboard updates in real time via their own SSE stream — their triage card flips to \"In Progress.\"\n\n---\n\n### Step 8 — Treatment Complete, Escrow Released\n\nWhen treatment is done, the hospital clicks **\"Release Escrow\"** on the triage card. AuraHealth triggers Interswitch to disburse the held funds directly to the hospital's registered bank account. The patient's dashboard updates to \"Resolved.\"\n\nThe full episode of care — from first symptom description to final payment — is settled without the patient ever stopping to pay.\n\n---\n\n## Payment Architecture\n\nAuraHealth sits at the centre of every transaction — not as a bank, but as a **payment orchestrator**. Here is how money flows:\n\n```text\nPatient payment source          AuraHealth Escrow           Hospital bank account\n──────────────────────          ─────────────────           ─────────────────────\n Card / Bank account  ───────►  Holds funds until  ──────►  Registered Interswitch\n HMO / Insurer                  treatment confirmed          merchant account\n```\n\n**Why this works:**\n\n1. **Hospital registers a bank account** with AuraHealth at onboarding. Interswitch has this account on file as the merchant destination for escrow disbursements. The hospital never handles card data.\n\n2. **Patient links a payment source** — a debit card, a bank account (direct debit), or an HMO/insurance policy number. AuraHealth stores the source reference, not the raw card data.\n\n3. **During a voice triage**, Aura confirms the estimated cost and the patient says \"Yes\". AuraHealth debits the patient's linked source via Interswitch's hosted payment page and holds the funds in escrow.\n\n4. **At each stage of in-hospital care** — bed, labs, pharmacy, procedures — the hospital can draw from the escrow balance. No cash, no new queue.\n\n5. **When care is complete**, the hospital clicks Release Escrow. Interswitch transfers the balance from the escrow hold to the hospital's registered bank account. The patient receives an itemised receipt.\n\n6. **If the patient has HMO coverage**, the insurer is billed instead of (or alongside) the patient's bank account. The hospital still receives the same guaranteed payment — the source is abstracted away.\n\n---\n\n## Full Sequence Diagram\n\n```mermaid\nsequenceDiagram\n    participant P as Patient\n    participant V as VAPI\n    participant W as Webhook\n    participant G as Gemini\n    participant DB as Database\n    participant I as Interswitch\n    participant H as Hospital\n\n    P-\u003e\u003eV: Start voice call\n    V-\u003e\u003eP: Hi, I am Aura. Describe your symptoms\n    P-\u003e\u003eV: Describes symptoms\n    V-\u003e\u003eW: Tool call routeToHospital\n    W-\u003e\u003eDB: Save triage request\n    W-\u003e\u003eDB: Fetch hospital resources and prices\n    W-\u003e\u003eG: Generate routing and clinical assessment\n    G--\u003e\u003eW: Routing message, differentials, summary\n    W-\u003e\u003eDB: Save clinical assessment to triage\n    W--\u003e\u003eV: Return routing message text\n    V-\u003e\u003eP: Aura reads routing message aloud\n    V-\u003e\u003eP: Shall I pre-authorise NGN 5000?\n    P-\u003e\u003eV: Yes\n    V-\u003e\u003eW: Tool call createEscrow\n    W-\u003e\u003eI: POST oauth token request\n    I--\u003e\u003eW: Bearer token\n    W-\u003e\u003eI: Redirect to hosted payment page\n    P-\u003e\u003eI: Patient pays on Interswitch page\n    I--\u003e\u003eW: Redirect callback with txn ref\n    W-\u003e\u003eI: GET transaction status to verify\n    I--\u003e\u003eW: ResponseCode 00 confirmed\n    W-\u003e\u003eDB: Mark escrow as held\n    W--\u003e\u003eV: Confirmation with reference number\n    V-\u003e\u003eP: Aura reads payment confirmation\n    DB--\u003e\u003eH: SSE stream detects new triage\n    H-\u003e\u003eH: Display triage with AI differentials\n    Note over H: Doctor reviews before patient arrives\n    H-\u003e\u003eDB: Mark triage as in_progress\n    DB--\u003e\u003eP: SSE detects status update\n    Note over P: Dashboard shows In Progress\n    Note over H: Doctor treats patient\n    H-\u003e\u003eDB: Click Release Escrow\n    DB-\u003e\u003eI: Disburse funds to hospital bank\n    H-\u003e\u003eDB: Mark triage as resolved\n    DB--\u003e\u003eP: SSE detects resolved\n    Note over P: Dashboard shows Resolved\n```\n\n---\n\n## Architecture\n\n```\nPatient Browser\n  └── VoiceTriage.tsx (@vapi-ai/web WebRTC)\n        └── VAPI Cloud (GPT-4o + Deepgram nova-3-medical + ElevenLabs)\n              └── POST /api/vapi/webhook\n                    ├── createTriageRequest()       → DB\n                    ├── getHospitalResources()      → DB\n                    ├── generateText(gemini-2.5-pro)→ Vertex AI\n                    │     returns: routingMessage + differentials + clinicalSummary\n                    └── initializeEscrow()          → Interswitch Pay Bill API\n\nHospital Browser\n  └── TriageInbox.tsx (EventSource)\n        └── GET /api/triage/stream?hospitalId=...\n              └── DB poll every 5s → push new + updated triages\n\nPatient Browser\n  └── PatientDashboardView (EventSource)\n        └── GET /api/events/patient-stream?patientId=...\n              └── DB poll → push link approval + triage status changes\n```\n\n---\n\n## APIs Used\n\n### Interswitch QuickTeller Business — Payments, Escrow \u0026 Payouts\n\n\u003e **Sandbox:** `qa.interswitchng.com` (API) + `newwebpay.qa.interswitchng.com` (payment page)\n\nAuraHealth uses **five Interswitch API surfaces** across the full payment lifecycle. Every API call below runs in production code — not mocked.\n\n---\n\n#### API 1 — OAuth 2.0 Authentication\n\nEvery server-side Interswitch call starts by getting a Bearer token.\n\n| Detail | Value |\n|--------|-------|\n| Endpoint | `POST /passport/oauth/token?grant_type=client_credentials` |\n| Auth header | `Basic base64(CLIENT_ID:SECRET)` |\n| Returns | `{ access_token, token_type, expires_in }` |\n| Code | [`src/lib/interswitch.ts`](src/lib/interswitch.ts) — `getAccessToken()` |\n\n```ts\n// Simplified — actual code in src/lib/interswitch.ts\nconst res = await fetch(`${apiBase}/passport/oauth/token?grant_type=client_credentials`, {\n  method: \"POST\",\n  headers: {\n    Authorization: `Basic ${Buffer.from(`${clientId}:${secret}`).toString(\"base64\")}`,\n    \"Content-Type\": \"application/x-www-form-urlencoded\",\n  },\n  body: new URLSearchParams({ grant_type: \"client_credentials\" }),\n});\n```\n\n---\n\n#### API 2 — Pay Bill (Server-Side Payment Link)\n\nWhen a patient clicks **\"Pre-authorize ₦5,000 care\"** on their dashboard, our server creates a payment link via the Pay Bill API. Interswitch returns a `paymentUrl` and we redirect the patient there.\n\n| Detail | Value |\n|--------|-------|\n| Endpoint | `POST /collections/api/v1/pay-bill` |\n| Body | `{ merchantCode, payableCode, amount, redirectUrl, customerId, currencyCode, customerEmail }` |\n| Returns | `{ paymentUrl, reference }` |\n| Code | [`src/lib/interswitch.ts`](src/lib/interswitch.ts) — `createPayBillLink()` |\n| Called from | [`src/modules/escrow/actions.ts`](src/modules/escrow/actions.ts) — `initializeEscrow()` |\n| Patient UI | [`src/modules/dashboard/patient/views/PatientDashboardView.tsx`](src/modules/dashboard/patient/views/PatientDashboardView.tsx) — `handlePreAuthorize()` |\n\nThe patient is redirected to the Interswitch hosted payment page where they can pay via card, bank transfer, USSD, or wallet. After payment, Interswitch redirects back to our callback URL.\n\n---\n\n#### API 3 — Transaction Verification\n\nAfter Interswitch redirects the patient back to `/api/escrow/callback`, our server verifies the payment server-side before marking the escrow as held.\n\n| Detail | Value |\n|--------|-------|\n| Endpoint | `GET /collections/api/v1/gettransaction.json?merchantcode=...\u0026transactionreference=...\u0026amount=...` |\n| Success | `ResponseCode === \"00\"` |\n| Code | [`src/lib/interswitch.ts`](src/lib/interswitch.ts) — `queryTransactionStatus()` |\n| Called from | [`src/modules/escrow/actions.ts`](src/modules/escrow/actions.ts) — `verifyAndHoldEscrow()` |\n| Route | [`src/app/api/escrow/callback/route.ts`](src/app/api/escrow/callback/route.ts) |\n\nWe always verify **two things**: ResponseCode is `\"00\"` AND the Amount matches what we originally charged. If either fails, we do not mark the escrow as held.\n\n---\n\n#### API 4 — Webhook Notifications\n\nInterswitch POSTs transaction status changes to our webhook endpoint. This works even if the patient closes their browser before the redirect.\n\n| Detail | Value |\n|--------|-------|\n| Our endpoint | `POST /api/interswitch/webhook` |\n| Signature verification | HMAC-SHA-512 using webhook secret from dashboard |\n| Signature header | `x-interswitch-signature` |\n| Code | [`src/app/api/interswitch/webhook/route.ts`](src/app/api/interswitch/webhook/route.ts) |\n| Dashboard config | Settings → Webhooks → enable Transactions + Payout toggles |\n\n---\n\n#### API 5 — Payouts (Escrow Disbursement)\n\nWhen the hospital clicks **\"Release Escrow\"** after treatment, our server calls the Payouts API to transfer funds from our QuickTeller wallet to the hospital's bank account.\n\n| Detail | Value |\n|--------|-------|\n| Endpoint | `POST /api/v1/payouts` |\n| Channel | `BANK_TRANSFER` |\n| Body | `{ transactionReference, amount, walletDetails: { walletId, pin }, recipient: { recipientAccount, recipientBank }, singleCall: true }` |\n| Code | [`src/lib/interswitch.ts`](src/lib/interswitch.ts) — `createPayout()` |\n| Called from | [`src/modules/escrow/actions.ts`](src/modules/escrow/actions.ts) — `releaseEscrow()` |\n\n---\n\n#### End-to-End Payment Flow (How Money Moves)\n\n```text\nPatient clicks \"Pre-authorize ₦5,000\"\n  |\n  v\nOur server: POST /collections/api/v1/pay-bill\n  |\n  v\nInterswitch returns paymentUrl --\u003e Patient redirected to payment page\n  |\n  v\nPatient pays (card / bank transfer / USSD)\n  |\n  v\nInterswitch redirects to /api/escrow/callback?txnRef=AUR...\n  |\n  v\nOur server: GET /collections/api/v1/gettransaction.json (verify ResponseCode \"00\")\n  |\n  v\nEscrow marked \"held\" in database --- money sits in our QuickTeller wallet\n  |\n  v\nHospital treats patient (zero payment friction)\n  |\n  v\nHospital clicks \"Release Escrow\"\n  |\n  v\nOur server: POST /api/v1/payouts (BANK_TRANSFER to hospital account)\n  |\n  v\nEscrow marked \"released\" --- hospital bank account credited\n```\n\n**Coming next — Interswitch Identity Verification:** We will integrate Interswitch's identity verification API to KYC patients and hospitals at onboarding, ensuring that the person pre-authorising payment is who they claim to be. This is especially important for HMO-linked accounts where a patient's insurer covers the escrow amount.\n\n---\n\n### VAPI — Voice AI Platform\n\n\u003e **Docs:** https://docs.vapi.ai\n\nVAPI hosts the Aura voice agent and manages the full WebRTC session.\n\n| Component | Value |\n|-----------|-------|\n| Model | GPT-4o (conversation) |\n| Transcription | Deepgram nova-3-medical (clinical accuracy) |\n| Voice synthesis | ElevenLabs — \"Burt\" voice |\n| Phone number | `+17622204588` |\n| HIPAA compliant | Yes |\n\nVAPI calls our server at `/api/vapi/webhook` when the agent decides to invoke a tool (`routeToHospital`, `createEscrow`). We return a text string that VAPI reads aloud to the patient.\n\n---\n\n### Google Vertex AI — Gemini 2.5 Pro\n\n\u003e **Project:** `ai-projects-481815` · **Region:** `us-central1`\n\nUsed inside the VAPI webhook to generate three things per triage:\n\n1. **Routing message** — warm, personalised sentence the voice agent reads aloud\n2. **Differential diagnoses** — 3–5 likely clinical diagnoses as a JSON array\n3. **Clinical summary** — one-paragraph reasoning for the receiving doctor\n\nGemini receives: patient symptoms, severity score, hospital specialties, and live resource availability (beds, ICU, prices). It returns structured JSON.\n\n**SDK:** `@ai-sdk/google-vertex` via Vercel AI SDK `generateText()`. Auth via service account JSON in `GOOGLE_VERTEX_CREDENTIALS`.\n\n---\n\n### VAPI Webhook — Server Tools\n\nOur `/api/vapi/webhook` (Next.js Route Handler) implements two VAPI server tools:\n\n**`routeToHospital`**\n```\nInput:  { symptoms: string, severity: \"critical\"|\"high\"|\"medium\"|\"low\" }\nAction: createTriageRequest() → getHospitalResources() → Gemini generateText()\nOutput: routing message string (read aloud by Aura)\n```\n\n**`createEscrow`**\n```\nInput:  { amountNaira: number }\nAction: getLatestTriageForPatient() → initializeEscrow() → linkEscrowToTriage()\nOutput: confirmation string with transaction reference\n```\n\n---\n\n### Neon PostgreSQL — Database\n\n\u003e **Driver:** `@neondatabase/serverless` (HTTP, edge-compatible)\n\nAll data is stored in a single Neon database. Tables:\n\n| Table | Purpose |\n|-------|---------|\n| `user` | Patients, hospitals, and admin accounts |\n| `session` / `account` | Better Auth session management |\n| `patient_hospital_link` | Hospital–patient relationship (pending/approved) |\n| `emr_record` | Imported EMR records per hospital |\n| `hospital_profile` | Description, specialties, bed count, ICU count |\n| `hospital_resource` | Resource inventory with prices |\n| `triage_request` | Full triage record incl. differentials + clinical summary |\n| `escrow_transaction` | Payment escrow lifecycle |\n\n---\n\n### Better Auth — Authentication\n\n\u003e **Version:** 1.5.6\n\nHandles signup, login, session management, and password reset. Custom fields (`role`, `phoneNumber`, `isApproved`) are passed via `inferAdditionalFields`. All auth routes live at `/api/auth/[...all]`.\n\n---\n\n## Tech Stack\n\n| Layer      | Technology                                                     |\n| ------------| ----------------------------------------------------------------|\n| Framework  | Next.js 16.2 (App Router, Partial Prerender, Cache Components) |\n| Runtime    | Bun 1.x                                                        |\n| Auth       | Better Auth 1.5.6 with Drizzle adapter                         |\n| Database   | Neon PostgreSQL (serverless HTTP)                              |\n| ORM        | Drizzle ORM 0.45                                               |\n| Styling    | Tailwind CSS v4                                                |\n| Voice AI   | VAPI (GPT-4o, Deepgram nova-3-medical, ElevenLabs)             |\n| AI Routing | Vercel AI SDK + @ai-sdk/google-vertex (Gemini 2.5 Pro)         |\n| Payments   | Interswitch QuickTeller sandbox (escrow lifecycle)             |\n| Real-time  | Server-Sent Events (triage alerts + patient updates)           |\n\n---\n\n## Features\n\n- [x] Hospital auto-approval on signup — profile setup modal opens on first login\n- [x] Hospital profile: description, specialties, bed count, ICU count, emergency phone\n- [x] Hospital resource inventory: name, category, available count, price in ₦ (feeds AI routing)\n- [x] Hospital sidebar dashboard — Overview, Triage, Patients, Resources, Profile tabs\n- [x] Patient registration with EMR-based hospital matching\n- [x] Patient payment source linking: card, bank account, or HMO/insurer\n- [x] Voice triage agent — Aura (VAPI, browser WebRTC + phone `+17622204588`)\n- [x] Text-based triage fallback\n- [x] Severity assessment (critical / high / medium / low)\n- [x] AI clinical differentials and clinical summary per triage case (Gemini 2.5 Pro)\n- [x] Hospital resource availability factored into AI routing\n- [x] Real-time triage alerts to hospital dashboard (SSE, poll every 5s)\n- [x] Real-time triage status updates to patient dashboard (SSE)\n- [x] Real-time patient-approval event to hospital dashboard (SSE)\n- [x] Triage status lifecycle: pending → in_progress → resolved\n- [x] Escrow pre-authorisation via Interswitch Pay Bill API (sandbox)\n- [x] Escrow release with Interswitch Payouts API (wallet to hospital bank account)\n- [x] Transaction verification via Interswitch gettransaction API\n- [x] EMR import (fake FHIR dataset, 15 patients)\n- [x] Linked patients panel (AuraHealth + EMR tabs)\n- [x] Admin dashboard for hospital approvals (manual override available)\n- [x] Password visibility toggle on all auth forms\n- [x] Responsive UI — mobile bottom nav on patient + hospital dashboards\n\n---\n\n## Pages\n\n| URL | Who uses it |\n|-----|------------|\n| [/](https://aurahealth-five.vercel.app/) | Landing page |\n| [/signup](https://aurahealth-five.vercel.app/signup) | Patient or hospital registration |\n| [/login](https://aurahealth-five.vercel.app/login) | Patient or hospital login |\n| [/dashboard/patient](https://aurahealth-five.vercel.app/dashboard/patient) | Patient dashboard — voice triage, history, escrow |\n| [/dashboard/hospital](https://aurahealth-five.vercel.app/dashboard/hospital) | Hospital dashboard — triage inbox, patients, resources |\n| [/admin](https://aurahealth-five.vercel.app/admin) | Admin — approve/reject hospital registrations |\n| [/admin/login](https://aurahealth-five.vercel.app/admin/login) | Admin login |\n| [/pending](https://aurahealth-five.vercel.app/pending) | Hospital awaiting admin approval |\n\n---\n\n## Getting Started\n\n### Prerequisites\n\n- [Bun](https://bun.sh) \u003e= 1.0\n- PostgreSQL database ([Neon](https://neon.tech) recommended)\n- [VAPI](https://vapi.ai) account + assistant\n- Google Cloud project with Vertex AI API enabled\n\n### Environment Variables\n\n```env\n# Database\nDATABASE_URL=postgresql://...\n\n# Better Auth\nBETTER_AUTH_URL=http://localhost:3000\nBETTER_AUTH_SECRET=your_32_char_secret_here\n\n# App\nNEXT_PUBLIC_APP_URL=http://localhost:3000\n\n# VAPI — Voice AI\nVAPI_API_KEY=your_vapi_private_key\nNEXT_PUBLIC_VAPI_PUBLIC_KEY=your_vapi_public_key\nNEXT_PUBLIC_VAPI_ASSISTANT_ID=your_assistant_id\nNEXT_PUBLIC_VAPI_PHONE_NUMBER=+17622204588\n\n# Google Vertex AI — Gemini 2.5 Pro\nGOOGLE_VERTEX_PROJECT=your_gcp_project_id\nGOOGLE_VERTEX_LOCATION=us-central1\nGOOGLE_VERTEX_CREDENTIALS={\"type\":\"service_account\",...}\n\n# Interswitch QuickTeller Business (Sandbox)\nNEXT_PUBLIC_INTERSWITCH_ENV=sandbox\nINTERSWITCH_CLIENT_ID=your_client_id\nINTERSWITCH_SECRET=your_secret_key\nINTERSWITCH_MERCHANT_CODE=your_merchant_code\nINTERSWITCH_PAY_ITEM_ID=your_pay_item_id\n# Wallet for payouts (from QuickTeller Business → Wallets)\nINTERSWITCH_WALLET_ID=your_wallet_id\nINTERSWITCH_WALLET_PIN=your_wallet_pin\n```\n\n### Installation\n\n```bash\nbun install\nbunx drizzle-kit push   # push schema to database\nbun dev                 # start dev server at http://localhost:3000\n```\n\n### Production Build\n\n```bash\nbun run build\nbun start\n```\n\n---\n\n## Project Structure\n\n```\nsrc/\n├── app/\n│   ├── admin/                   # Admin dashboard\n│   ├── api/\n│   │   ├── auth/                # Better Auth handler\n│   │   ├── escrow/callback/     # Interswitch payment callback\n│   │   ├── events/patient-stream/ # SSE — patient dashboard updates\n│   │   ├── triage/stream/       # SSE — hospital triage alerts\n│   │   └── vapi/webhook/        # VAPI tool call handler\n│   ├── dashboard/\n│   │   ├── hospital/            # Hospital dashboard\n│   │   └── patient/             # Patient dashboard\n│   └── page.tsx                 # Landing page\n├── components/\n│   └── VoiceTriage.tsx          # VAPI browser voice widget\n├── lib/\n│   ├── auth.ts                  # Better Auth server config\n│   ├── db/schema.ts             # Full database schema\n│   └── interswitch.ts           # Interswitch payment utilities\n└── modules/\n    ├── dashboard/hospital/      # Triage inbox, patients, profile, resources\n    ├── dashboard/patient/       # Voice triage, history, escrow\n    ├── escrow/                  # Escrow actions\n    ├── hospital/                # Hospital profile + resource actions\n    └── triage/                  # Triage CRUD + severity scoring\n```\n\n---\n\n## Team\n\n**Halleluyah Darasimi Oludele** — Team Lead \u0026 Software Engineer\nFull-stack engineer responsible for the entire technical implementation: Next.js 16.2 architecture, VAPI voice integration, Gemini 2.5 Pro routing via Vertex AI, Interswitch escrow lifecycle, real-time SSE infrastructure, database schema design, and authentication.\n\n**Theophilus Ayomide Olayiwola** — Product Manager \u0026 Product Designer\nResponsible for product strategy, user research, UX design, and defining the problem space. Shaped the product vision from the patient and hospital perspective — particularly the insight that payment friction at every care stage is the core problem to solve.\n\n---\n\n## The Core Insight\n\n\u003e Nigerian hospitals collect payment at every queue. AuraHealth collapses all of those queues into a single pre-authorised escrow created during a 90-second voice call.\n\nThe patient never stops to pay again. The hospital is guaranteed payment at every stage. AuraHealth sits in the middle — routing intelligently, settling atomically, and giving doctors AI-generated clinical context before the patient even arrives.\n\n---\n\n*Built with Next.js 16.2, VAPI, Gemini 2.5 Pro (Vertex AI), Interswitch, and Neon PostgreSQL*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhallelx2%2Fenyata-project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhallelx2%2Fenyata-project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhallelx2%2Fenyata-project/lists"}