Two Audiences, One System: An Offline-First Family App With a Facility Cloud Behind It
CareReady serves two audiences with opposite needs — a family that must use it with zero login and fully offline, and a facility that needs authenticated, isolated data. I designed one system that gives each what it needs, bridged by a capability code, and hardened it through a real closed-pilot safety gate.
larai-w/careready-belongings-checker (pilot-gate issues #6/#7)
Context
CareReady helps families prepare belongings for care transitions (short stays, admissions). A facility creates a checklist template and hands the family a short share code / QR; the family redeems it on a phone and keeps it — offline. It runs in production at a public URL, in a closed pilot.
The design tension is the whole problem: the family should never have to create an account or be online, but the facility's data must be authenticated and scoped. One system, two audiences with opposite constraints.
Constraints
- Family side: no login, offline-first. Care happens on the move, on cheap phones, with weak connectivity; a login wall would kill it.
- Facility side: real auth + tenant isolation. Staff data must be authenticated and scoped per facility.
- Health-adjacent + privacy. OCR of paper lists must not capture names or room numbers by design.
- Public repository, solo, part-time. No pool IDs/secrets in the repo; governance via issues, tests, and sanitised runbooks.
Architecture & key decisions
I deliberately gave the two audiences different trust models, bridged by a capability:
- Family (unauthenticated, capability-scoped). Redeeming a template is a public endpoint keyed by a short share code, resolved through a DynamoDB GSI (
GSI1PK = CODE#<shareCode>). No account, no PII — the code is the capability. The frontend is an offline-first PWA (service worker + on-device storage), so once redeemed it works with no network and nothing sensitive leaves the device. - Facility (authenticated, tenant-scoped). Template CRUD sits behind an Amazon Cognito JWT authorizer on an API Gateway HTTP API. Templates are scoped by
facilityId, so one facility never sees another's. Self-signup is disabled — an admin provisions facility users — a deliberate choice for a controlled pilot.
Supporting decisions: single-table DynamoDB with a GSI purely to serve the public share-code lookup; one Lambda, boto3-only with an internal router and RemovalPolicy.RETAIN on the table; an OCR provider seam (OpenAI Vision default, Textract switchable) with the key in Secrets Manager and images processed synchronously and not stored; infrastructure as AWS CDK v2, with CI running pytest + moto on every push.
Delivery & governance (the pilot safety gate)
Before inviting real households, I defined an M1 safety gate as GitHub issues and turned it into repeatable, owner-executed artifacts:
- A real-device end-to-end walkthrough (facility sign-in → template + QR → phone redeem → offline retention → prepare/return/print) with a PII/PHI-free defect-recording template and a "no critical defect" sign-off (issue #6).
- A credential-rotation and recovery runbook (issue #7) that explicitly distinguishes the email sign-in alias from Cognito's internal
Username— a real operational footgun — procedure only, no secrets.
Outcomes
- One system genuinely serves both audiences: family gets zero-login, offline, no-PII; facility gets authenticated, per-tenant isolation — bridged by a capability code rather than forcing families through auth.
- The pilot has a written, repeatable safety gate, so "is it safe to invite people?" is answered by evidence, not vibes.
- Privacy is a design property: on-device family data, no stored OCR images, secrets in Secrets Manager, per-facility scoping.
Honest limitations
- Still a closed pilot, not general release; the M1 gate is defined and partly executed, and some steps need the owner's real devices/AWS.
- The share-code model trades a little security for a lot of family convenience; right for low-sensitivity belongings data, but not for higher-sensitivity records without rethinking.
- Rate limits and abuse controls on public endpoints are on the backlog before scaling beyond the pilot.
Lessons
- Match the trust model to each audience, not to the system. Forcing families through facility-grade auth would have been "secure" and unused.
- Design DynamoDB from access patterns. The GSI existed only because a public code redeem needed it.
- A pilot needs a written gate. An E2E checklist + rotation runbook made "are we ready for real users?" testable and safe.
Evidence
Repo: github.com/larai-w/careready-belongings-checker — pilot-gate issues #6 (real-device E2E) and #7 (credential rotation/recovery). backend/ (CDK v2, single-Lambda API, DynamoDB + GSI, Cognito, pytest+moto) and the M1 walkthrough / rotation-runbook docs.
Need a system two audiences can both trust?
Architecture-aware technical project management for cloud builds — where the trade-offs actually have to ship.
Book a Free Consultation