Skip to content

Repository files navigation

CareFrame

CareFrame is a mobile-first, patient-facing symptom-framing app. It helps a patient or caregiver organize symptoms, history, fears, medications, expectations, and key questions into a clinician-readable pre-visit brief.

CareFrame is not a symptom checker, triage tool, diagnosis engine, treatment guide, or care-setting recommender.

What This Build Contains

  • apps/web: React/Vite PWA for the patient flow.
  • apps/api: Express API for session handles, extraction, brief generation, redaction, and consented contribution records.
  • packages/content: curated complaint maps, care-setting facts, emergency warning terms, fears, expectations, and history flags.
  • packages/engine: deterministic extraction, adaptive questions, visit brief generation, safety validation, redaction, contribution minimization, and printable text output.
  • packages/schemas: shared Zod schemas and TypeScript types, including strict generated-output contracts.

Current Boundaries

CareFrame must not:

  • diagnose or rank diagnoses;
  • estimate disease probability;
  • tell a user where to go;
  • tell a user it is safe to wait;
  • recommend treatment or medication changes;
  • steer toward a sponsor, facility, plan, or vendor;
  • sell or use identifiable health data for ads.

The only directional safety language is the general emergency warning: if the user believes the situation may be life-threatening, call emergency services now.

In the PWA, hard-stop narrative language such as crushing chest pressure with trouble breathing stops the routine question flow before onset/course screens. The app shows the universal emergency banner and offers a quick emergency summary from the facts already entered.

Local Setup

pnpm install
pnpm test
pnpm build

Run the web app:

pnpm dev:web

Run the API:

pnpm dev:api

Canonical MVP API routes from GOAL.md:

POST /api/session/start
DELETE /api/session/:id
POST /api/intake/extract
POST /api/intake/questions
POST /api/brief/generate
POST /api/safety/validate
GET /api/ai/status
POST /api/speech/transcribe
POST /api/redact
POST /api/contribute
DELETE /api/contribute/:id
GET /patient-ux/evaluation-packet

The earlier local MVP routes such as /sessions, /extract, /brief, /redact, and /contributions remain available for compatibility.

The web app is local-first for the MVP. The API uses ephemeral in-memory sessions and stores only consented, minimized contribution records during a process lifetime. DELETE /api/session/:id deletes a local in-memory session created by POST /api/session/start; this is default-mode cleanup, not a production identity-linked retention policy.

POST /api/intake/extract returns the shared PatientNarrativeDraft schema. In the deterministic MVP path it extracts conservative patient-stated clues from narrative text, including timeline wording, progression, medication names, online prescription/recent-care clues, what the patient tried, fears, expectations, hard-stop signals, candidate complaint map, and normalized source notes. It does not return diagnoses or probabilities.

The API exposes a safe unavailable-by-default LLM adapter contract for future extraction candidates. /api/intake/extract consults the adapter and falls back to deterministic extraction while no provider is configured. GET /api/ai/status returns local_llm_not_configured, externalProviderUsed: false, rawPromptStored: false, rawOutputStored: false, rawInputEchoed: false, and deterministicFallbackActive: true. The readiness packet is in docs/LLM_ADAPTER_READINESS.md; no local, self-hosted, cloud, or vendor LLM provider is enabled in this MVP.

POST /api/brief/generate accepts both the internal object-shaped answer payload and the GOAL.md MVP shape with draft, an answers array, top-level attachments, and includeSettingFacts. The API normalizes that request into the shared brief engine without diagnostic image interpretation.

On the final brief screen, the PWA supports user-initiated clipboard copy, direct API-backed PDF download, text download, browser print/save-as-PDF fallback, local QR image display/download, and explicit browser-local save/delete under the careframe.localBrief.v1 localStorage key. Local save is separate from contribution consent. In browsers with Web Crypto support, the saved brief is written as an AES-GCM encrypted envelope with a same-origin browser key stored separately under careframe.localBriefKey.v1; delete removes both. This protects against casual readable localStorage inspection only and is not production key management. If Web Crypto is unavailable, the fallback record is explicitly labeled unencrypted. PDF generation is an explicit export action that posts the current answers to the configured CareFrame API, which is ephemeral in local MVP mode. The local QR image uses a fixed non-PHI payload and does not encode the health story. The optional follow-up survey is also separate from contribution consent; it creates a local de-identified preview from structured ratings only and does not collect contact details, raw story text, printable brief text, or photo names.

The web app uses VITE_CAREFRAME_API_URL for direct PDF generation when set, and otherwise defaults to http://localhost:4100.

The PWA shell includes a web manifest, mobile install metadata, and a production-only service-worker registration. The service worker is intentionally conservative: it caches the static app shell and Vite static assets only, and ignores API routes, PDF/export routes, clinician-review routes, cross-origin requests, non-GET requests, and unknown dynamic routes.

When browser speech recognition is available, the PWA shows a voice privacy note before dictation starts. The note says the browser or platform provider may process speech to turn it into text, and typing remains available instead.

The API exposes POST /api/speech/transcribe as the server-side STT adapter contract. In the local MVP it returns local_stt_not_configured, uses no cloud provider, stores no audio, and returns no transcript until a local or self-hosted STT engine is configured and reviewed. The readiness packet is in docs/SPEECH_STT_READINESS.md.

The PWA exposes a browser-local TTS adapter for read-aloud where speechSynthesis is available. It reports browser_speech_synthesis, careFrameServerTtsUsed: false, careFrameCloudTtsUsed: false, rawTextStored: false, and rawTextEchoed: false. On the final brief screen, read-aloud uses the same printable visit brief as copy, PDF, text download, email draft, and local-save flows. No CareFrame server-side or cloud TTS provider is configured in the local MVP. The readiness packet is in docs/TTS_READINESS.md.

The welcome screen includes high-contrast and text-size controls. Automated accessibility tests check the high-contrast toggle state, text-size scaling, and axe baseline coverage for the welcome, emergency hard-stop, and generated final-brief screens. This is an automated MVP baseline, not WCAG certification or physical-device assistive-technology signoff.

For image and document input, the PWA asks what the attachment is before adding it. OCR text entry appears only for medication labels, documents, or reports. The user reviews and confirms extracted text before CareFrame adds medication text or patient-provided document text to the brief. Symptom photos and other images remain attach-only, with no diagnostic image interpretation.

By default outside tests, consented de-identified analytics records append to:

data/deidentified-contributions.jsonl

Override this path with CAREFRAME_ANALYTICS_PATH. The JSONL record is minimized structured data only; it excludes raw narrative, medication free text, allergy free text, image names, and image data. Set CAREFRAME_ANALYTICS_ENCRYPTION_KEY to write file-backed API contribution records as AES-GCM encrypted envelopes instead of readable JSON objects. The configured key must be a random 32-byte secret encoded as hex/base64/base64url, or a high-entropy local passphrase of at least 32 characters; short and common demo keys are rejected. DELETE /api/contribute/:id deletes a stored API contribution by the contributionId returned from POST /api/contribute; this is local MVP storage behavior, not a production identity, key-management, rotation, recovery, or retention policy.

The deterministic redaction helper returns an internal receipt with removed elements and caution flags. Synthetic eval coverage includes direct identifiers, provider/facility labels, exact dates, image exclusion, small-geography clues, and rare family/condition combinations. These flags are not a Safe Harbor or Expert Determination certification; external dataset release still requires human review.

Shared generated-output schemas for PatientNarrativeDraft, VisitBrief, and RedactionResult are strict. Schema tests lock the expected output keys and reject unsafe extra fields such as diagnoses, probabilities, destination recommendations, treatment plans, or unknown redaction risk flags.

Technical audit events append to:

data/audit-events.jsonl

Override this path with CAREFRAME_AUDIT_PATH. Audit records contain route templates, event type, method, status, duration, timestamp, and explicit no-PHI/no-body/no-param flags. They do not include request bodies, response bodies, route params, session IDs, IPs, user agents, raw narrative, OCR text, medication text, or photo names.

The internal security threat model draft is in docs/SECURITY_THREAT_MODEL.md. It is a review packet for the local/demo MVP and remains pending external security review.

The internal retention, deletion, and audit policy draft is in docs/RETENTION_DELETION_AUDIT_POLICY.md. It maps current local MVP behavior to production policy questions and remains pending privacy/legal/security approval.

The browser-local save security packet is in docs/LOCAL_SAVE_SECURITY.md. It documents the MVP encrypted localStorage envelope, same-origin browser key limitation, fallback behavior, and pending production security review.

The LLM adapter readiness packet is in docs/LLM_ADAPTER_READINESS.md. It documents the unavailable-by-default model adapter seam, deterministic fallback behavior, and pending provider/privacy/security review.

The TTS readiness packet is in docs/TTS_READINESS.md. It documents browser/device read-aloud behavior, unsupported fallback, and pending production accessibility/privacy review.

The patient UX evaluation packet is in docs/PATIENT_UX_EVALUATION_PACKET.md and is also available from GET /patient-ux/evaluation-packet. It connects synthetic mobile QA and the local structured follow-up survey preview to the GOAL.md UX metrics, while keeping real patient study, physical-device QA, and assistive-technology user testing pending.

Docker Compose

docker compose up api postgres redis minio

The database, Redis, and MinIO services are scaffolding for later production hardening. The current API implementation does not persist raw PHI server-side in ephemeral mode.

Verification

pnpm verify

Run browser-based mobile visual QA:

pnpm exec playwright install chromium
pnpm qa:mobile

The install command is only needed when Chromium is not already present. pnpm qa:mobile builds the PWA, serves it locally, drives synthetic patient flows through Chromium at phone-sized viewports, and writes screenshots plus report.json under docs/qa/mobile-visual/.

Current test coverage checks:

  • eleven GOAL.md starter complaint maps plus other;
  • five neutral care-setting fact cards including specialty care, capability questions, and information-to-have guidance;
  • non-diagnostic, clinician-reviewable content;
  • no more than five default adaptive questions;
  • emergency hard-stop detection;
  • categorized synthetic safety eval fixture set with 104 cases across the eight GOAL.md section 22.1 scenario categories;
  • output safety blocking for diagnosis, destination, treatment, false reassurance, and commercial steering;
  • prompt-injection evals that block instruction override, hidden-prompt requests, and diagnosis-list forcing before generated briefs can repeat them;
  • installable PWA shell metadata and static-only service-worker caching boundaries;
  • PWA emergency hard-stop behavior before routine clarification screens;
  • routine-screen mobile controls for Skip, I don't know, and Show final brief, including unknown timeline handling and emergency hard-stop shortcut guarding;
  • deterministic brief generation;
  • strict output-schema snapshots for PatientNarrativeDraft, VisitBrief, and RedactionResult, including rejection of unsafe extra fields and unknown redaction risk flags;
  • synthetic clinician-review sample export set with routine, emergency-hard-stop, and caregiver/low-clarity generated briefs for utility rating;
  • synthetic PHI redaction, including provider/facility labels and internal risk flags for exact dates, small geography, rare combinations, and images;
  • consent-only minimized contribution records;
  • JSONL persistence of consented de-identified analytics without raw PHI;
  • AES-GCM encrypted JSONL envelopes for API contribution records when a validated CAREFRAME_ANALYTICS_ENCRYPTION_KEY is configured;
  • AES-GCM encrypted browser-local saved brief envelopes with separate same-origin browser key storage when Web Crypto is available;
  • readiness documentation guardrails for the internal threat-model draft and no-go production status;
  • readiness documentation guardrails for the internal retention/deletion/audit policy draft;
  • readiness documentation guardrails for the synthetic patient UX evaluation packet;
  • readiness documentation guardrails for the API-side STT adapter contract;
  • readiness documentation guardrails for the browser-local TTS adapter contract;
  • readiness documentation guardrails for the browser-local saved-brief security packet;
  • readiness documentation guardrails for the unavailable-by-default LLM adapter contract;
  • API deletion of stored consented contribution records by returned contribution id;
  • PHI-safe technical audit logging without request bodies, route params, or session IDs;
  • GOAL.md /api/... route aliases for session start/delete, intake extraction/questions, brief generation, safety validation, AI capability status, redaction, and contribution;
  • shared PatientNarrativeDraft validation for /api/intake/extract, including deterministic narrative-derived medication, prescription/recent-care, tried-at-home, fear, expectation, hard-stop, and source-note fields;
  • safe API-side LLM adapter contract with deterministic fallback and no external provider configured;
  • spec-compatible /api/brief/generate request handling for draft, answer arrays, top-level attachments, and setting facts;
  • GOAL.md home input choices for speak, type, camera/photo, quick checklist, and caregiver mode;
  • explicit browser speech privacy disclosure before dictation starts;
  • safe API-side STT adapter contract with local STT explicitly unconfigured;
  • browser-local TTS adapter for read-aloud without CareFrame server/cloud TTS;
  • image-kind selection before attachment, OCR only for labels/documents/reports, and confirmation before extracted text is used;
  • in-app plain-language privacy choices for no-storage restart, browser-local save, de-identified contribution preview, and unavailable institution sharing in the public MVP;
  • separate optional follow-up survey preview for confidence, readability, trust, commercial-bias concern, and accessibility helpfulness, without raw story text or contact collection;
  • explicit email-to-self export disclosure with a user-opened email draft and no collected email address;
  • direct final-brief PDF download through the ephemeral local API, with browser print fallback;
  • local QR display/download on the final brief without browser-local save or contribution side effects;
  • final-brief copy, explicit encrypted browser-local save, and delete behavior without enabling contribution consent;
  • automated accessibility baseline coverage for welcome, emergency hard-stop, and final-brief screens, plus high-contrast and text-size control semantics;
  • API endpoint behavior;
  • core web patient flow;
  • browser-rendered mobile welcome, routine-control, brief, and emergency screens without horizontal overflow.

Reference Prototype

The original static prototype remains untouched in Prototype development request/. It is the reference design and interaction spec, not the production codebase.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages