Some engagements come with real compliance stakes attached — get the workflow wrong and it’s not just a bug, it’s a regulatory problem. This is a look at one of those: a white-label background-screening platform we built for a US-based provider. (Client name withheld per engagement terms.)
The problem
Our client ran background screening under their own brand but needed a modern platform to replace manual, fragmented processes — one that could:
- Support two very different intake paths: enterprise clients inviting individuals to be screened, and individuals self-serving their own screening and paying online
- Route each screening to the right verification path — a third-party screening API for most checks, and a state fingerprinting system for the ones that still require manual results entry
- Give internal operations staff a work queue to manage exceptions, enter manual results, and run FCRA-compliant adverse-action workflows when a result required one
- Produce a single branded report per individual, regardless of which paths fed into it
- Stay multi-tenant and white-label from day one, so the same platform could serve multiple client brands without ever mixing their data
Architecture & stack
We split the system into three applications sharing one backend:
Client portal — React 19 and Vite, with RTK Query for data fetching. Handles both the enterprise-invite flow and the self-serve flow: sign-up, consent capture, document upload, package selection, live status, and branded report access.
Back-office portal — a second React 19 application, role-gated between Operations and Administrator. Operations gets a work queue with manual result entry, exception handling, and the adverse-action workflow. Administrators get cross-tenant tooling: tenant and branding management, package configuration, user management, and billing summaries.
Shared backend — NestJS on PostgreSQL (via Drizzle), with AWS Cognito for authentication and CASL for policy-based authorization. Every request carries a tenant ID resolved from the JWT and threaded through the data layer, so tenant isolation is enforced at the query level, not just the UI.
A few details we’re glad we got right:
- An immutable, hash-chained audit log. Every action — user or system — is written to an append-only chain that can be verified offline, so “did anyone touch this record” always has a provable answer.
- Real-time status via SSE. Operations and clients both see status transitions the moment they happen, without polling.
- One report renderer, two consumers. The same branded report component is shared between the operator-facing detail view and the client-facing report page, so there’s exactly one place that formats a result.
Where it stands
All three applications are feature-complete against the agreed requirements — enterprise and self-serve intake, the full operations work queue, tenant and branding administration, billing summaries, and audit reporting. The individual-booking scheduling flow (calendar and time-slot selection) is the one piece still ahead of us; the underlying capacity-configuration system that will power it is already built.
Working in a regulated-data space and need a platform that treats compliance as a first-class requirement, not an afterthought? Get in touch.