DEV Community

Jason Michael
Jason Michael

Posted on

Pulza: Splitting a Monorepo Along a Compliance Boundary, Not Just a Feature Boundary

We Split Our Turborepo Apps by HIPAA Exposure, Not by Team Ownership

Most monorepo app-splitting advice centers on team ownership or deploy cadence. For Pulza, the deciding factor was different: which apps might touch protected health information (PHI), and which provably never do.

The structure

Pulza is a Turborepo + pnpm workspace monorepo. apps/web, apps/portal, and apps/marketing are Next.js 15 apps on Vercel. apps/workers is a separate Node/TS service running background jobs (via pg-boss over Postgres) on Railway. Database access goes through Drizzle ORM, with packages/db as the single schema source of truth. Auth is Supabase Auth plus Row-Level Security.

Why workers live on a different platform entirely

This wasn't a scaling decision — it's a compliance boundary decision, documented explicitly in the project's architecture notes as the "PHI boundary."

Each infrastructure vendor has its own path to HIPAA compliance via a Business Associate Agreement (BAA), and each is priced and gated differently: Vercel's BAA is a Pro-plan add-on, Supabase requires a Team plan plus a separate HIPAA add-on, and Railway requires a committed Enterprise spend to unlock BAA coverage at all. None of these are active yet in Pulza's current build phase.

Because Railway's BAA tier isn't funded, apps/workers is deliberately restricted to non-PHI jobs only — a constraint enforced by discipline and documentation right now, not yet by a hard technical barrier, though that's worth flagging as a real limitation of the current approach.

The tradeoff this creates

Any background job that would need to touch a client record — a reminder about an upcoming session, say — can't run on apps/workers yet, because that would mean PHI flowing through infrastructure that isn't compliance-covered. So those jobs either wait for the Railway tier to be funded, or need to be redesigned to avoid touching PHI directly (e.g., triggering a notification without the job itself reading the sensitive payload).

Why I think this is the right call, with a caveat

Segmenting compliance-sensitive infrastructure from general-purpose infrastructure, before you have real compliance-sensitive data flowing through the system, is cheaper than retrofitting it under pressure later. I'd rather over-architect this boundary early than discover, post-launch, that a "small" background job has been quietly processing PHI on infrastructure that was never covered for it.

The caveat: right now this boundary is enforced by team discipline and code review, not by an automated technical guardrail that would catch a violation before it ships. That's a real gap I'm aware of, not a solved problem — and I'd be interested in how others have automated enforcement of similar data-boundary rules within a monorepo, rather than relying on developers remembering the rule.

Top comments (0)