Use these notes when working in this backend. Keep changes small, follow existing controller and EF patterns, and prefer linking to code over duplicating generated documentation.
- ASP.NET Core Web API targeting
net10.0; main startup, DI, middleware, seeding, auth, OpenAPI, and migration-on-startup logic live in src/Program.cs. - EF Core uses SQLite through
ConnectionStrings:Sqlitein appsettings.json, defaulting toData Source=app.db. SplitzDbContextextendsIdentityDbContext<SplitzUser>and exposes the app aggregate sets in src/SplitzDbContext.cs.- Controllers in src/Controllers contain most request workflow and authorization logic. Services in src/Services are focused helpers for invoice debt calculation, image processing, and S3-compatible storage.
- Entities and DTOs are colocated in src/Models. Validation attributes on DTOs/entities are part of the API contract.
Run from the SplitzBackend folder unless noted otherwise.
dotnet restore
dotnet build
dotnet run --project SplitzBackend.csproj
dotnet format SplitzBackend.sln --verify-no-changesThere is currently no backend test project. Do not claim dotnet test validates backend behavior unless a test project has been added.
- The
httplaunch profile binds tohttp://0.0.0.0:5119; local clients on Windows should callhttp://localhost:5119. - Development startup applies pending EF migrations automatically and seeds sample users/groups only when no users exist.
- OpenAPI is served only in Development. Swashbuckle is the active generator at
/openapi/{documentName}.json; Scalar UI is mapped byMapScalarApiReference(). appsettings.jsoncontains placeholder S3 values. Image upload and signed photo URLs require realStorageconfig.
- Custom endpoints use
[Authorize],[ApiController], and[Route("[controller]")]; Identity minimal APIs are mounted under/accountin src/Program.cs. - Access control is usually based on the current Identity user plus group membership/ownership checks, not roles. Preserve required
Include(...)calls before membership or balance mutations. - Use AutoMapper mappings in src/MapperProfile.cs. Photo fields may store owned object keys such as
users/...,groups/...,transactions/..., ordrafts/...;SignedPhotoUrlResolverconverts them to signed relative URLs. - Swashbuckle filters in src/OpenAPIGen/Filter customize the frontend contract: authorized operations get Bearer security, decimals are emitted as string format
decimal, and enums are emitted as strings. - Do not hand-edit generated frontend OpenAPI files in
SplitzFrontend/src/backend/openapi; regenerate them from the backend OpenAPI contract after API changes.
- Migrations live in src/Migrations.
- Add migrations from the backend root with:
dotnet ef migrations add <Name> --output-dir src/Migrations
dotnet build- Normal app startup runs
db.Database.MigrateAsync(), so usedotnet ef database updateonly when a manual database update is specifically needed.
- Development seeding does not refresh an existing
app.dbonce any user exists. - Use
DateTime.UtcNowfor server-generated timestamps.Group.LastActivityTimeis persisted and used for sorting in clients, so local-time values can produce incorrect ordering across time zones. Group.TransactionCountandGroup.LastActivityTimeare denormalized search/sort hints; keep them in sync when changing transaction or group workflows.