CASE STUDY
Insurance Management API
Business rules and predictable writes in a personal .NET API.
The task
Manage customers and policy lifecycles while handling duplicate requests and conflicting updates.
My role
I implemented the backend, business rules and API tests in this personal project.
The solution
A .NET 8 API for managing customers and the lifecycle of car, health and life policies. Built around business rules, predictable errors and reliable writes.
See it in action
Insurance
Management API
A .NET 8 API for managing customers and the lifecycle of car, health and life policies. Built around business rules, predictable errors and reliable writes.
Personal project · Backend implementation, business rules and API tests.
Try the interactive example View repositoryA repeated request returns the same policy. Conflicting changes are flagged, and policy actions remain traceable.
Technical details
- 01APIValidation · authentication · HTTP
- 02Domain & servicesPolicy rules · lifecycle · idempotency
- 03PersistenceEF Core · SQL invariants · audit events
409Stale writes and conflicting requests get explicit errors.
Engineering decisions
Safe retries
Issue and cancel endpoints accept an idempotency key. The same key and payload replay the original result; a changed payload returns a conflict.
Rules at two levels
A customer can have at most one active car policy. Service checks and a filtered unique SQL index both enforce that rule.
Concurrent changes
A row-version token detects stale policy updates, returning a conflict instead of silently replacing another change.
Traceable lifecycle
Issuing, updating and cancelling policies create audit events. Cancellation retains the record, and cancelled policies cannot be updated.
Tests & contracts
xUnit endpoint tests cover conflicting idempotency keys, replay behavior, validation, JWT permissions and rate limits.
See the code behind a safe retry
Before creating another policy, the service checks for the existing operation and key. It validates the request fingerprint, then returns the original entity.
var existingIdempotency = await GetIdempotencyAsync(operation, idempotencyKey, cancellationToken);
if (existingIdempotency is not null)
{
// Same operation+key should return the original result unless payload changed.
ValidateFingerprint(existingIdempotency, idempotencyFingerprint);
return await GetByIdAsync(existingIdempotency.ResponseEntityId, cancellationToken);
}Read the complete serviceExcerpt from PolicyService.cs. The full service also handles conflicting payloads and concurrent inserts.
A SMALL ENGINEERING CHALLENGE
You click “Save” twice. What should happen?
The first request succeeded, but its response was lost. You retry with the same key and the same information.
Choose an answer, then see the behavior in action.
Illustrative simulation using sample data. No live API calls.
View the retry example
INTERACTIVE ENGINEERING EXAMPLE
Retry safely.
Avoid duplicate policies.
If a response gets lost, a client may send the same request again. This example returns the existing policy instead of creating a duplicate.
Illustrative simulation of the project’s idempotency rule. Uses sample data; no live API calls.
Watch the request travel
Create a policy, retry or change the premium to follow the result.
Policies created 0
POST /api/customers/{id}/policies{
"type": "Health",
"premium": 100
}
Send the first request to create a sample policy.
An identical retry should return the original policy.
Evidence & limitations
The interactive example is a browser simulation. It does not call a hosted API, and the full SQL Server deployment was not verified in this portfolio preview.