Donation Platform for a Blood-Donation Operator
Multi-tenant booking portal and staff back office for a blood-donation operator on one .NET API; donor data kept out of logs, URLs and third-party payloads.

Problem
A query that forgets its tenant filter is a cross-organization exposure, not a cosmetic bug. That was the constraint on this platform from the first day: a blood-donation operator running several organizations on one system, with records that hold identity, contact details, dates of birth, eligibility and screening notes.
Three developers had eight months to replace the operator's booking and donor-management tools with one platform for two audiences, donors booking their own visits and staff running the centers. Personal data leaks through channels most projects never close, application logs, URL query strings, error responses, cache keys and payloads sent to outside services, and sites differ in capacity rules, closures and recurring schedules; flattening those rules would have made the platform easier to build and useless to operate.
Solution
One .NET API with Entity Framework Core and one PostgreSQL database behind a Next.js portal and a staff back office, on managed AWS services.
Tenant scoping is applied by default at the data-access layer, so a forgotten filter fails safe, and automated checks in the build catch a missing filter, an unprotected mutating endpoint or personal data in the wrong place before it reaches a shared environment. Sensitive records are referenced internally by opaque identifiers, and personal data stays out of logs, URLs, error bodies and cache keys by construction.
Two rules shaped the working day more than any feature. No personal data goes to a third-party service, our own AI tooling included, without recorded sign-off. And production data never reaches a development or test environment: test datasets are generated, seeded deterministically and reloaded on every environment, so realistic testing never depends on a real person's record.


