extract mermaid docs

This commit is contained in:
Aaron Po
2026-08-31 21:20:51 -04:00
parent 6a061f4e28
commit 8ac1981f81
38 changed files with 267 additions and 245 deletions

View File

@@ -0,0 +1,81 @@
# The Biergarten App — Vertical Slice Architecture
Two diagrams, split by concern: which host wires up which slice at startup, and
which projects each slice actually compiles against. Mixing DI wiring and
compile-time references in one graph is what made the old diagram unreadable.
## Host wiring
Each host (`API.Core`, `Database.Seed`) decides for itself which `Features.*`
assemblies to register — there's no shared bootstrap. `Database.Migrations`
doesn't wire up any slice; it applies schema directly.
```mermaid
--8<-- "diagrams/website/architecture/host-wiring.mmd"
```
## Project reference dependencies
Solid arrows are compile-time project references. Dashed arrows are the two
places slices talk to each other without a direct reference: the email
MediatR contract routed through `Shared.Application`, and the one place that
pattern is broken outright. Every DB-backed slice depends on the same three
foundation projects (`Shared.Contracts`, `Domain.Entities`,
`Database.Connection`) — drawn as one box instead of fifteen separate arrows;
see the notes for what else each of those foundation projects pulls in.
```mermaid
--8<-- "diagrams/website/architecture/project-references.mmd"
```
## Notes
- **API.Core**: Program.cs wiring only
- MediatR + `AddApplicationPart` per HTTP-exposed `Features.*` assembly
- Swagger/OpenAPI, health checks, JWT auth middleware, global exception filter
- Only `Features.Users` and `Features.Breweries` get `AddApplicationPart` (controllers)
- `Features.PhotoUpload` and `Features.Emails` scanned for MediatR handlers only
- `Features.Locations` and `Features.Beers` not referenced by `API.Core` at all
- **Feature slices**: each owns its own controller (where present), commands/queries + handlers, validators, and Dapper repository
- `Features.Users` covers auth (`Commands/Authentication`), account management (`Commands/Account`), and profile/avatar (`Commands/Profile`)
- internally namespaced `Features.Auth`, despite project name `Features.Users`
- `Features.Emails` and `Features.PhotoUpload` have no controller — invoked only via MediatR commands sent from other slices
- `Features.Locations` has no controller; one MediatR handler (`GetOrCreateCityHandler`) registered by `Database.Seed` only — `API.Core` never scans it
- `Features.Beers` is scaffolded (project + references only, no source files yet)
- **The one exception to slice isolation**: `Features.Users` takes a direct project reference to `Features.PhotoUpload`
- sends its `UploadPhotoCommand` via MediatR from `UploadAvatarHandler`
- unlike the email flow, the command type lives in the target slice itself, not in `Shared.Application`
- **Shared.Application**:
- `ValidationBehavior` (MediatR pipeline)
- Cross-slice email commands (`SendRegistrationEmailCommand`, `SendResendConfirmationEmailCommand`)
- MediatR command contract (not project reference)
- Every slice (including `Features.Emails`) references it for the pipeline behavior alone
- **Domain.Entities**:
- `UserAccount`, `UserCredential`, `UserVerification`, `UserProfile`, `UserAvatar`
- `BreweryPost`, `BreweryPostLocation`
- `City`, `StateProvince`, `Country`
- `BeerPost`, `BeerStyle`, `Photo` (schema tables exist for `BeerPost`/`BeerStyle`; no repository yet since `Features.Beers` has no code)
- **Database.Connection**: the shared connection-factory project
- each slice's own repository issues inline SQL via Dapper against it
- no ORM, no stored procedures
- Replaces the old `Infrastructure.Sql` project
- **Database.Migrations**: separate console app
- `schema.dbml` + SQL scripts
- applies DDL directly
- distinct from `Database.Seed`, which loads data through the feature slices' own DI extensions
- **Database.Seed**:
- calls each slice's `AddFeatures*()` DI extension directly
- builds its own MediatR registration
- no API host, no shared pipeline with `API.Core`
- **Omitted from the diagram**:
- `Domain.Exceptions` (referenced by nearly every project directly, including all of `Shared.Contracts`, `Infrastructure.Jwt`, and each feature slice)
- `Infrastructure.Configuration` (the shared options-binding project referenced by `Database.Connection`, `Infrastructure.Email`, `Infrastructure.FileUpload`, and `Features.Emails` directly)
- both are plumbing-level dependencies of nearly everything above, and drawing them would just add a second copy of the same fan-in

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Confirm User
```mermaid
--8<-- "diagrams/website/auth/confirm-user.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Delete Account
```mermaid
--8<-- "diagrams/website/auth/delete-account.mmd"
```

View File

@@ -0,0 +1,7 @@
# User Authentication Flow — Error Handling
Global exception mapping performed by `API.Core`'s `GlobalExceptionFilter`. Applies uniformly across every authentication endpoint (registration, login, refresh, confirm, resend, update-username/email/password/profile, delete-account) — see the per-flow diagrams for where each exception type is thrown.
```mermaid
--8<-- "diagrams/website/auth/error-handling.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Login
```mermaid
--8<-- "diagrams/website/auth/login.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Refresh Token
```mermaid
--8<-- "diagrams/website/auth/refresh-token.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Registration
```mermaid
--8<-- "diagrams/website/auth/registration.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Resend Confirmation Email
```mermaid
--8<-- "diagrams/website/auth/resend-confirmation.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Update Email
```mermaid
--8<-- "diagrams/website/auth/update-email.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Update Password
```mermaid
--8<-- "diagrams/website/auth/update-password.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Update Profile
```mermaid
--8<-- "diagrams/website/auth/update-profile.mmd"
```

View File

@@ -0,0 +1,5 @@
# User Authentication Flow — Update Username
```mermaid
--8<-- "diagrams/website/auth/update-username.mmd"
```

View File

@@ -0,0 +1,7 @@
# Database Schema
Every table also has a `RowVersion ROWVERSION` column (optimistic concurrency), omitted below for brevity. Tables marked `(*)` have no repository/feature slice yet.
```mermaid
--8<-- "diagrams/website/database-schema.mmd"
```

View File

@@ -0,0 +1,15 @@
# Docker Deployment Architecture
```mermaid
--8<-- "diagrams/website/deployment.mmd"
```
## Notes
- **Dev network** (`biergarten-dev`, bridge): internal DNS resolves `sql-server` and `api`. Volumes: `biergarten-dev-data`. Startup order: SQL Server (health check) → migrations (run-once) → seed (run-once) → API (long-running).
- **Test network** (`biergarten-test`, bridge): all test components isolated; fresh DB instance each run (`CLEAR_DATABASE=true`, ephemeral `biergarten-test-data` volume). All tests run in parallel, results aggregated.
- **Prod network** (`prodnet`, bridge): isolated from dev/test networks. Volumes: `sqlserverdata-prod`, `nuget-cache-prod`. No seed step in production.
- **Database-only environment**: same devnet volumes/images as `docker-compose.dev.yaml`, minus `api.core` and `mailpit` — for working against the database without running the API.
- **Minimal environment**: database + mailpit only, no API container — for frontend development against an `API.Core` process run outside Docker.
- `unit.tests` builds `Dockerfile.tests`, which restores/builds against `Core.slnx` then runs `dotnet test` for every `Features/*.Tests` project in turn (`Features.Users.Tests`, `Features.Breweries.Tests`, `Features.Emails.Tests`), mocking each handler's repository/service dependencies with Moq — no real database needed.
- `.trx` results are readable by Visual Studio, Azure DevOps, and GitHub Actions.