01Public demo available
Policy Operations API
A policy changes state, belongs to an organization and must never lose a concurrent edit. The API guarantees it with the token, the row version and an audit written alongside the change.

Context
A policy's lifecycle looks simple: draft, active, cancelled. The hard part is around it: that one organization never sees or touches another's policies, that every transition leaves a trace of who made it and why, and that two operators editing at once never overwrite each other unknowingly.
The project solves those three things in a .NET API on SQL Server, built as a public demonstration with synthetic data. A draft can be activated or cancelled; an active policy can be cancelled; cancelled is a final state. Every accepted transition records the actor, the time, the correlation id and the reason.
Architecture
The Vue interface, served as a static site, calls the API. The API requires a JWT token, takes the organization from one of its claims and exposes each policy's row version as an ETag; any change must carry that version in the If-Match header. The application layer runs the transition on the domain and the infrastructure saves the policy and its audit entry in a single transaction.
Decisions
- Modular monolith in four projects. Domain, application, infrastructure and API, on the long-term support version of .NET. The single-project layout could not demonstrate the boundaries the documentation promised; now architecture tests verify them.
- The organization comes from the token, not from the request. Every repository method requires the organization id and policy numbers are unique within it. A policy of another organization answers as missing, not as forbidden, so its existence is never revealed.
- Optimistic concurrency with a row version. Without an If-Match header the API asks for the precondition; with a stale version it answers with a concurrency conflict. Errors follow the Problem Details format with a stable code and a trace id, and the audit is written in the same transaction as the change.
- Public demo on a free tier, with its limits in plain sight. A single anonymous, rate-limited endpoint runs the whole scenario without sharing credentials. When the database wakes up after a pause, the API answers that the service is unavailable and says when to retry, instead of an opaque error. Continuous integration tests against a real SQL Server in a container.
What you can verify in the demo
- Run the five-step scenario with one click: create a draft, activate it, watch an edit with a stale version get rejected, cancel and read the audit with its two transitions.
- Follow each step on the architecture blueprint, which lights up the answering layer and marks the concurrency rejection in red.
- Tell whether the run was real against SQL Server or simulated in the browser: the interface labels each case.
- Copy the reproducible command to repeat the scenario from the terminal.