cat ./projects/wardcare-plus.md
[SOURCE AVAILABLE]05 /
WardCare+
POPIA-audited hospital ward management, deployed on Azure.

// stack
- ASP.NET Core 8
- MVC
- EF Core
- Azure App Service
- Azure SQL
- GitHub Actions (OIDC)
- xUnit
- Moq
- Agile/Scrum
// THE PROBLEM
Hospital ward management in SA operates under POPIA — every patient record access, update, or deletion is a legal event that must be traceable. The team of 4 needed a system where no developer could accidentally bypass auditing, even under time pressure. The cloud pipeline also needed zero stored credentials: no API keys, no connection strings kept in GitHub Secrets.
// WHAT I BUILT
An Azure-deployed MVC application with 7-role RBAC and policy-based authorization. I solely owned the cloud pipeline: Azure App Service + Azure SQL + GitHub Actions CI/CD using OIDC workload identity federation — GitHub authenticates to Azure via a federated identity token, no secrets stored anywhere. POPIA compliance via EF Core SaveChangesInterceptor: before/after JSON snapshots captured on every INSERT, UPDATE, and DELETE across 25+ entities, with soft-delete on every table. Validated with xUnit 2.6 + Moq 4.20.
// THE KEY DECISION
EF Core SaveChangesInterceptor over application-layer logging. If you log at the application layer, any developer who bypasses the service — calling the repository or DbContext directly — silently breaks the audit trail. An interceptor sits at the DbContext level: it cannot be bypassed without removing it from DI registration. That architectural constraint is the POPIA guarantee.
// WHAT IT TAUGHT ME
Compliance is an architectural decision, not a feature. It needs to be impossible to break, not just easy to follow. OIDC workload identity was unfamiliar territory — the mental model of "GitHub proves it is GitHub by presenting a JWT signed by GitHub’s OIDC provider" took time to properly internalise. Understanding it properly means I can apply it to any Azure-integrated CI/CD pipeline.
// REAL-WORLD IMPACT
Every patient record change has a before/after JSON snapshot in the audit table — a complete forensic trail. Zero credentials are stored in GitHub: if the repository were ever compromised, there are no secrets to rotate. The xUnit test suite validates the interceptor contract, so a refactor that accidentally removed the audit behaviour would surface immediately in CI.