The context
This project is a focused build of a full stack Insurance Management System, designed to reflect how real applications are structured and delivered. It brings together frontend, backend, and database concerns into a single cohesive system, with a strong emphasis on clean architecture and long term maintainability.
The goal is not just to build features, but to build them properly. Every part of the system is designed with intention, from how data flows through the application to how responsibilities are separated across layers. This is about building something that can scale and be clearly understood by other developers.
Why an insurance system?
The domain was chosen because of my past experience working in the insurance industry. It was always frustrating when a clients details were not always on one system. The project also naturally introduces meaningful relationships between entities. Clients, policies, and claims are connected in ways that require proper structure and logic. A client can have multiple policies, and each policy can have multiple claims. Those relationships directly influence how the system behaves, including things like risk calculation.
Building within a domain like this forces careful thinking around data modelling and system design. Instead of simple isolated features, the focus is on representing real world relationships accurately and ensuring the system remains consistent as it grows.
Architecture: the layered approach
The backend follows a structured layered architecture that separates concerns clearly across the application. Each layer has a defined responsibility and communicates with the next in a predictable way.
Controllers handle routing and validation. Services contain business logic. Repositories handle data access. Keeping these responsibilities separate makes the system easier to understand, extend, and test.
Interfaces are defined first, with implementations registered through
dependency injection in
Program.cs. This keeps the system flexible and allows components to be swapped
or extended without affecting other parts of the application.
Technology decisions
React Query over plain fetch
Data fetching on the frontend is handled using React Query. Instead of manually managing loading states, caching, and refetching logic, React Query provides a consistent and scalable way to work with server state.
This allows components to stay focused on rendering while data management is handled in a clean and predictable way.
PostgreSQL over SQLite
PostgreSQL is used as the database to reflect a production ready setup. It supports concurrent usage, strong data integrity, and more advanced querying capabilities than file based solutions.
Using a full database server ensures the system behaves more like a real deployed application from the start.
DTOs to separate concerns
The API is structured around Data Transfer Objects rather than exposing database models directly. Each operation has its own DTO, which keeps the API contract clear and avoids leaking internal structures.
Response DTOs also include computed values such as
RiskLevel
and
TotalClaims, which are calculated within the service layer.
Tailwind CSS v4
The frontend uses Tailwind CSS v4, which keeps styling fast and simple. The setup is minimal, allowing styles to be applied directly without unnecessary configuration.
This keeps the focus on building the interface while maintaining a consistent design system.
Database design
The schema is built around four tables: Users, Clients, Policies, and Claims. These tables reflect the core structure of the system and how data is connected.
- A Client has many Policies (one-to-many)
- A Policy has many Claims (one-to-many)
- Cascade delete is used to keep related data consistent
- Unique indexes prevent duplicate records at the database level
- Decimal precision is used for currency values
Entity Framework Core is used to generate and manage the database through migrations. The schema evolves directly from the C# models, keeping everything aligned.
Project setup and tooling
The project is structured as a monorepo with a clear separation between backend and frontend. Each part of the system is organised to keep responsibilities clear and easy to navigate.
- InsuranceApp.Api the ASP.NET Core 10 Web API backend
- InsuranceApp.Client the Vite + React + TypeScript frontend
The backend is organised into Controllers, Services, Repositories, Models, DTOs, and Data. This structure keeps the codebase clean and makes it easy to understand where logic belongs.
The frontend uses React Query, React Router, Axios, and Lucide React to handle data, routing, HTTP communication, and UI elements.
Sensitive values such as database connections and authentication keys are stored in environment specific files and excluded from version control.
What's coming next
The next phase focuses on expanding the service and controller layers, followed by building out the full frontend experience.
Authentication, risk calculation, and deployment will follow. The aim is to continue building out the system in a way that stays consistent with the architecture and keeps the codebase clean and understandable.
Follow the build
The full source code is on GitHub. More updates will be added as the project progresses.
View on GitHub