Behind the build
Care Partners at Home
A multi-tenant operating platform for a home-care agency: operator, caregiver, and family, over one auditable workflow.
Tailored product work, designed multi-tenant from the start.
- Next.js
- PostgreSQL · RLS
- State machines
- Append-only audit
- SMS-first comms
- AI workflows
Care Partners at Home presented a very different engineering problem from a typical business website.
A home-care agency does not simply need pages describing its services.
Behind those pages is an operating system of families asking for help, caregivers applying and working shifts, coordinators making matches, incidents being reported, consent being recorded, schedules changing, payroll moving, families asking questions, and sensitive decisions that may need to be reconstructed months later.
I built the system around that reality.
This is tailored product work for Care Partners at Home. The platform is currently in its final pre-launch stage and is projected to be online very soon.
Although the first deployment is tailored around the agency’s own operation, I designed the underlying system as multi-tenant software from the beginning so the architecture is not tied permanently to one agency.
Architecture at a Glance
Care Partners OS
│
Next.js Platform
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
Operator Console Caregiver PWA Family Portal
│ │ │
└────────────────────┼────────────────────┘
│
Service Layer
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
State Machines Communications AI
+ Audit Trail + Consent Workflows
│ │ │
└────────────────────┼────────────────────┘
│
PostgreSQL
│
Tenant-scoped RLS
The important part of this diagram is not Next.js.
It is that the operator, caregiver, and family are not treated as three views of the same screen.
They are three different participants in the same care operation, with different responsibilities, permissions, and expectations.
Case Study 1: One Business Process, Three Completely Different Users
The problem
Home care is collaborative, but it is not symmetrical.
An operator may need to review a care request, evaluate caregiver matches, resolve an incident, inspect an audit trail, or manage a schedule.
A caregiver needs something much simpler:
What am I doing today?
They may also need to report an incident, review a shift, request a pay adjustment, resign, submit a referral, or update something about themselves.
The family has another perspective entirely.
They care about schedules, care notes, invoices, concerns, caregiver teams, photos, authorized representatives, lifecycle changes, and what has happened over time.
Putting all of those users into one generic authenticated application would make the system easier to code initially.
It would make the product harder to use and harder to secure.
The decision
I separated the application around the people actually using it.
Operator
↓
/dashboard
/care-requests
/matches
/schedule
/incidents
/moderation
/payroll
/audit
...
Caregiver
↓
/c/today
/c/schedule
/c/incidents
/c/pay-raise
/c/resignation
/c/profile
...
Family
↓
/f/dashboard
/f/schedule
/f/care-notes
/f/invoices
/f/concerns
/f/caregiver-team
/f/timeline
...
These are not separate products with duplicated business logic.
They meet at a shared service layer.
That allows the same event to appear differently depending on who is looking at it.
Consider an incident.
Caregiver reports concern
│
▼
Incident pipeline
│
┌────┴─────┐
▼ ▼
Operator Family
queue visibility
│
▼
resolution
│
▼
audit history
The workflow remains one business process.
The doors into it are different.
State, not buttons
I also avoided letting interface buttons define business rules.
Important workflows are represented as explicit state machines.
A transition is legal because the domain allows it, not because somebody happened to render a button that performs an update.
current state
│
▼
allowed-transition check
│
├── allowed → update + audit
│
└── denied → no mutation
That matters for workflows such as caregiver screening, matching, care requests, incidents, resignations, family lifecycle changes, and other operations where jumping directly from one database status to another could bypass a real-world control.
The outcome
The product now supports three coherent experiences while preserving one underlying business model.
The operator gets an operational console.
The caregiver gets a mobile-first work surface.
The family gets a quieter portal focused on visibility and participation in care.
And all three remain connected to the same auditable workflow rather than becoming independent islands of application state.
That distinction is what turned the project from a website into an operating platform.
Case Study 2: Designing for Trust When the Data Represents Real People
The problem
Multi-tenancy is easy to describe:
Every agency sees only its own data.
The difficult part is proving that a forgotten WHERE tenant_id = ... cannot quietly violate that promise.
For a system containing caregiver information, family information, care records, incidents, schedules, communications, and operational histories, I did not want tenant isolation to depend entirely on every future developer remembering to write the correct query.
The decision
Tenant isolation is enforced at two levels.
Every business table carries a tenant identifier.
Every normal service operation runs inside an explicit tenant scope.
PostgreSQL Row Level Security independently enforces that same tenant boundary.
Authenticated user
│
▼
Application permission
│
▼
withTenantScope(...)
│
▼
tenant-scoped transaction
│
▼
PostgreSQL RLS
│
▼
business data
The database therefore participates in authorization rather than merely storing the result of authorization decisions made elsewhere.
A query that accidentally omits its tenant filter does not automatically become a cross-customer data leak.
Audit as business evidence
I treated audit history similarly.
Important business mutations write an audit entry.
For records where history matters, deletion is deliberately restricted.
A caregiver leaving the organization, a family ending service, a consent being withdrawn, or an incident reaching resolution should not make the prior state disappear.
The architecture therefore favors:
state transition
+
append-only evidence
over destructive updates that erase the path the business took.
That audit history is useful beyond compliance.
The family timeline can reconstruct meaningful activity from the same evidence rather than requiring another parallel history system.
Consent that cannot silently change afterward
Consent documents receive another protection.
Published consent versions are immutable.
When someone accepts a consent document, the system records a cryptographic hash of the version they actually accepted.
Consent document
│
▼
immutable version
│
▼
SHA-256 body hash
│
▼
acceptance ledger
If the wording later changes, that becomes a new version.
The old acceptance does not magically become consent to the new wording.
That sounds obvious when stated in English.
It is surprisingly easy to get wrong in software if a consent document is just another editable database row.
The outcome
Trust-sensitive rules are not scattered across page components.
Tenant isolation lives at the application and database layers.
State changes produce durable evidence.
Consent is versioned and tamper-anchored.
Permissions are role-based and rechecked server-side.
The system therefore has multiple independent controls protecting the same boundaries instead of assuming one perfect layer will never make a mistake.
Where AI Fits
Care Partners uses AI, but I drew a firm boundary around what AI is allowed to become.
There are workflows where a model is genuinely useful:
family intake
→ structured summary
caregiver SMS interview
→ conversational screening
caregiver pool
→ match ranking
incident text
→ classification / summary
submitted content
→ moderation
family concern
→ writing assistance
But the model is not the system of record.
Every AI invocation passes through one service boundary and is associated with a real business entity.
Token usage and invocation identity are recorded.
More importantly, failure behavior depends on the risk of the workflow.
For content moderation, an AI failure does not mean:
Probably fine. Publish it.
It means:
AI unavailable
↓
hold for review
For a family writing-assistance feature, the opposite behavior is appropriate.
If the rewrite model fails, the family member’s original words survive and the submission continues.
AI rewrite unavailable
↓
use author's original text
↓
continue
Same technology.
Different risk.
Different failure policy.
That distinction matters much more to me than simply saying the platform “uses AI.”
Communications Are Part of the Domain
Home-care communication is another place where I avoided allowing individual pages to send messages however they wanted.
Outbound communication passes through one communications fabric.
Business event
│
▼
communication service
│
├── verify consent
├── select template version
├── choose tenant/provider configuration
├── deliver SMS or email
├── record message
└── write audit event
This means consent enforcement is not something every feature author has to remember independently.
The same boundary can eventually support different provider credentials for different agencies while preserving one application-level communication contract.
For Care Partners at Home specifically, the customer journey is intentionally SMS-first rather than pretending the agency operates a traditional phone-answering center.
That product decision is enforced throughout the application rather than appearing only in marketing copy.
Building Around People, Not Around the Database
A great deal of the design discipline in this project came from resisting technically convenient shortcuts.
The family site does not invent testimonials or staff.
The product does not pretend automated responses are human responses.
Accessibility is part of the design baseline.
The caregiver experience starts on a phone-sized viewport.
Operator actions are permission-checked again on the server even if the UI has already hidden an unavailable control.
Missing vendor integrations degrade explicitly rather than being disguised as complete functionality.
And sensitive workflows leave evidence behind.
Those are product decisions, but they become architecture once software has to guarantee them.
Current Stage
The platform is currently in its final pre-launch stage.
Core operator, caregiver, and family workflows have been built and exercised end-to-end, including a broader scenario harness covering the major operating journeys.
A small number of external-service dependencies still require production configuration, including areas such as communications verification, payment/payroll connectivity, object storage, and production observability.
I prefer to describe that boundary precisely rather than calling an alpha system fully live before those dependencies are actually complete.
Care Partners at Home is projected to be online very soon.
Why I Built It This Way
The hard part of Care Partners at Home was never creating another dashboard.
It was deciding what the software must remember, what it must never expose, who has authority to change something, which changes require history, where AI can assist safely, and how three very different groups of people participate in the same care relationship.
That led to an architecture built around explicit boundaries:
tenant isolation
role authority
state transitions
audit evidence
immutable consent
communications governance
AI failure policy
I could have built the public website first and treated the rest as later back-office work.
Instead, I built the operational system underneath it.
Because in home care, the promise on the website ultimately matters only if the operation behind it can keep that promise.
More things I've built
- ClinSupplyCompass Live · multi-tenant SaaS
Closed-loop clinical-supply planning, proven against the 130-sheet workbook it replaced.
- HeyLayla Live · free pilot
A private, verified matrimonial platform: a public site, a member PWA, and an operator console over one API.
- Hunt Planner Pro For sale · in negotiation
A productized planning-and-booking experience for guided hunts, built as a transferable commercial asset.