4.6 KiB
MilkyShots – Agent Guide
Gitea repo owner: MilkyShots
Prerequisites
- .NET 10 SDK (pinned in
global.json;allowPrerelease: true) - PostgreSQL with pgvector extension
- Sass CLI for SCSS compilation (see SCSS section)
- Run
dotnet tool restorebefore first migration — installsdotnet-ef
Projects (4 in solution)
| Project | Role | Entrypoint |
|---|---|---|
| Butter | Shared class library (DTOs, enums, MIME types) | — |
| Lactose | ASP.NET Core Web API — controllers, EF Core, repos, background jobs | Lactose/Program.cs |
| MilkStream | Blazor WASM host — serves WASM files + dynamic /appsettings.json |
MilkStream/Program.cs |
| MilkStream.Client | Blazor WASM client — Razor components, SCSS, frontend services | MilkStream.Client/Program.cs |
Build & run
dotnet build MilkyShots.sln # .NET 10, C# 12
dotnet run --project Lactose # API on :5162 (host) / :8080 (container)
dotnet run --project MilkStream # WASM host on :5269 (host) / :8080 (container)
Database: Default credentials in appsettings.json. Docker compose spins up all services.
Port gotcha: appsettings.json defaults DatabaseAddress:Port to 3306 (legacy MySQL port). PostgreSQL runs on 5432. The raw connection string must be overridden, or use docker-compose.yml which maps host 3306 → container 5432 automatically.
Infrastructure gotchas
- Npgsql legacy timestamps:
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true)is set inLactose/Program.cs. Do not remove without understanding the timestamp implications. - MilkStream
/appsettings.json: Dynamically generated from server config — maps beforeUseStaticFiles, so it shadows the static file inMilkStream.Client/wwwroot/. This endpoint providesLactoseBaseUrlto the WASM client. - Auth requires claims transformation:
RefreshTokenTransformation(registered asIClaimsTransformation) must succeed on every authenticated request, or all endpoints return 403. - EF Core Tools v8.0.15 vs EF Core Design v10.0.9: Version mismatch may cause
dotnet efCLI quirks. - WASM client DI:
LoginServiceis Singleton; all other services areScoped. TwoHttpClientregistrations: one unauthenticated (default) for login, and one named"MilkstreamClient"which hasJwtTokenRefresheras aDelegatingHandler. The handler transparently refreshes expired tokens pre-flight and retries once on 401 — authenticated services must never handle token refreshes manually. Do not addSendWithRefreshAsyncor similar wrappers; rely solely on the named client. - HTTPS redirection is commented out in Lactose — API does not enforce HTTPS.
XML docs enforced
Directory.Build.props at solution root enables GenerateDocumentationFile and treats CS1591 (missing XML comment) as error. All public APIs must have XML docs. Repo implementations use <inheritdoc /> — keep interface docs in sync.
Conventions
HttpPut= create,HttpPost("{id}")= update — not REST-idiomatic; do not "fix" without team buy-in- Soft delete only — set
DeletedAt, never hard-delete (models: Asset, User, Person) - Repository
Save()must be called explicitly after insert/update/delete - Enum prefix
E(e.g.EAccessLevel,EAssetType,EJobStatus) - JWT access token: 10 min, refresh token: 60 min (constants in
LactoseAuthService.cs) - Conventional Commits enforced via
cliff.toml; changelog generated withgit-cliff - Granular commits — commit each logical change separately (e.g., DTO change, controller logic, UI component) with a descriptive commit message
- Reuse API endpoints — prefer adding optional query parameters to existing endpoints over creating new routes. New endpoints are a last resort when the existing ones fundamentally cannot serve the need.
Modularity
Reusable UI components live in MilkStream.Client/Components/Shared/.
When a markup pattern appears in 2+ places, extract it into a shared component.
See issue #52 for the tracking list of candidate components.
CORS gotchas
CorsAllowedOriginsenv var replaces the JSON array entirely (semicolon-separated)- MilkStream browser origin must be listed in Lactose's CORS
LactoseBaseUrlon MilkStream = URL the browser uses to reach Lactose
EF Core / Migrations
Migrations in Lactose/Migrations/ — generated, do not hand-edit.
dotnet ef migrations add <Name> --project Lactose
dotnet ef database update --project Lactose
Tests
No test project found in solution.