diff --git a/docs/pipeline/diagrams-md/current/activity.md b/docs/diagrams/pipeline/current/activity.mmd
similarity index 93%
rename from docs/pipeline/diagrams-md/current/activity.md
rename to docs/diagrams/pipeline/current/activity.mmd
index 0054a3b9..0e011519 100644
--- a/docs/pipeline/diagrams-md/current/activity.md
+++ b/docs/diagrams/pipeline/current/activity.mmd
@@ -1,8 +1,3 @@
-# The Biergarten Data Pipeline (Current — Synchronous Data Path)
-
-The only concurrency in the current pipeline is a dedicated log dispatcher thread that drains `log_channel` and forwards entries to spdlog for the entire run (joined during shutdown after `log_channel` closes). `BiergartenPipelineOrchestrator::Run()` itself is synchronous — sampling, enrichment, generation, and export all happen on the main thread.
-
-```mermaid
flowchart TD
Start([start]) --> ParseArgs["main.cc: ParseArguments(argc, argv)"]
ParseArgs --> ArgsValid{Arguments valid?}
@@ -77,4 +72,3 @@ flowchart TD
Finalize --> CloseLog["main.cc: close log_channel, join log dispatcher thread"]
CloseLog --> Stop2(["return 0 / stop"])
-```
diff --git a/docs/pipeline/diagrams-md/current/class.md b/docs/diagrams/pipeline/current/class.mmd
similarity index 99%
rename from docs/pipeline/diagrams-md/current/class.md
rename to docs/diagrams/pipeline/current/class.mmd
index 3ead5e4a..f970cb72 100644
--- a/docs/pipeline/diagrams-md/current/class.md
+++ b/docs/diagrams/pipeline/current/class.mmd
@@ -1,6 +1,3 @@
-# The Biergarten Data Pipeline — Class Diagram (Current)
-
-```mermaid
classDiagram
class BiergartenPipelineOrchestrator {
-shared_ptr~ILogger~ logger_
@@ -261,4 +258,3 @@ classDiagram
IExportService <|.. SqliteExportService : implements
SqliteExportService *-- IDateTimeProvider : owns
IDateTimeProvider <|.. SystemDateTimeProvider : implements
-```
diff --git a/docs/pipeline/diagrams-md/planned/activity.md b/docs/diagrams/pipeline/planned/activity.mmd
similarity index 95%
rename from docs/pipeline/diagrams-md/planned/activity.md
rename to docs/diagrams/pipeline/planned/activity.mmd
index e6c4e5f5..ab92df72 100644
--- a/docs/pipeline/diagrams-md/planned/activity.md
+++ b/docs/diagrams/pipeline/planned/activity.mmd
@@ -1,8 +1,3 @@
-# The Biergarten Data Pipeline — Activity Diagram (Planned)
-
-Each generation phase runs a producer/consumer trio concurrently: an **Orchestrator** producer feeds a bounded channel, an **LLM Worker** consumes it and generates records (closing its output channel when the input is drained and closed), and a **SQLite Worker** consumes that output channel and commits in batches. The Checkin and Follow phases run in parallel with each other once the user and brewery pools are populated.
-
-```mermaid
flowchart TD
Start([start]) --> ParseArgs["Main: ParseArguments(argc, argv)"]
ParseArgs --> InvalidArgs{Invalid args?}
@@ -197,4 +192,3 @@ flowchart TD
CloseLogCh --> MainDone["Main: spdlog::info 'Pipeline complete in X ms'"]
MainDone --> JoinLog["Main: Join Log Worker — drain guarantees no LogEntry is dropped at shutdown"]
JoinLog --> Stop2([stop])
-```
diff --git a/docs/pipeline/diagrams-md/planned/class.md b/docs/diagrams/pipeline/planned/class.mmd
similarity index 96%
rename from docs/pipeline/diagrams-md/planned/class.md
rename to docs/diagrams/pipeline/planned/class.mmd
index ff6b7b1a..c0fcc5c1 100644
--- a/docs/pipeline/diagrams-md/planned/class.md
+++ b/docs/diagrams/pipeline/planned/class.mmd
@@ -1,6 +1,3 @@
-# Biergarten Data Pipeline — Class Diagram (Planned)
-
-```mermaid
classDiagram
namespace DomainModels {
class Location {
@@ -585,9 +582,3 @@ classDiagram
GeneratedRating *-- RatingResult
GeneratedRating *-- GenerationMetadata
GeneratedFollow *-- GenerationMetadata
-```
-
-## Notes
-
-- `Logger`, `PipelineLogger`, and `LogWorker` are referenced only in relationships in the source PlantUML (not given their own class blocks there either) — they appear here as implicit nodes for the same reason.
-- Package grouping from the PlantUML source (`Domain: Models`, `Domain: Application Configuration`, `Domain: Policy`, `Infrastructure: Logging`, `Infrastructure: Pipeline Channel`, `Infrastructure: Data Preloading`, `Infrastructure: Enrichment`, `Infrastructure: Prompting`, `Infrastructure: Data Generation`, `Infrastructure: Data Export`) is preserved as Mermaid `namespace` blocks.
diff --git a/docs/diagrams/website/architecture/host-wiring.mmd b/docs/diagrams/website/architecture/host-wiring.mmd
new file mode 100644
index 00000000..7e49191d
--- /dev/null
+++ b/docs/diagrams/website/architecture/host-wiring.mmd
@@ -0,0 +1,59 @@
+---
+
+config:
+
+flowchart:
+
+curve: stepAfter
+
+layout: elk
+
+---
+
+flowchart TB
+
+API["API.Core
(ASP.NET Core Web API)"]
+
+Seed["Database.Seed
(console app)"]
+
+Migrations["Database.Migrations
(console app)"]
+
+
+
+subgraph SLICES["Feature Slices"]
+
+direction LR
+
+UsersSlice["Features.Users
(controller)"]
+
+BrewerySlice["Features.Breweries
(controller)"]
+
+PhotoSlice["Features.PhotoUpload
(MediatR only)"]
+
+EmailsSlice["Features.Emails
(MediatR only)"]
+
+LocationsSlice["Features.Locations
(plain DI service)"]
+
+BeersSlice["Features.Beers
(scaffolded, no code yet)"]
+
+end
+
+
+
+API -->|AddApplicationPart + MediatR scan| UsersSlice
+
+API -->|AddApplicationPart + MediatR scan| BrewerySlice
+
+API -->|MediatR scan only| PhotoSlice
+
+API -->|MediatR scan only| EmailsSlice
+
+
+
+Seed -->|AddFeaturesUsers| UsersSlice
+
+Seed -->|AddFeaturesBreweries| BrewerySlice
+
+Seed -->|AddFeaturesPhotoUpload| PhotoSlice
+
+Seed -->|AddFeaturesLocations| LocationsSlice
diff --git a/docs/diagrams/website/architecture/project-references.mmd b/docs/diagrams/website/architecture/project-references.mmd
new file mode 100644
index 00000000..3fea620b
--- /dev/null
+++ b/docs/diagrams/website/architecture/project-references.mmd
@@ -0,0 +1,77 @@
+---
+
+config:
+
+flowchart: {}
+
+layout: fixed
+
+---
+
+flowchart TB
+
+subgraph SLICES["Feature Slices"]
+
+direction LR
+
+BrewerySlice["Features.Breweries"]
+
+LocationsSlice["Features.Locations"]
+
+BeersSlice["Features.Beers
(scaffolded)"]
+
+PhotoSlice["Features.PhotoUpload"]
+
+UsersSlice["Features.Users"]
+
+EmailsSlice["Features.Emails"]
+
+end
+
+subgraph FOUNDATION["Foundation (every DB-backed slice depends on all three)"]
+
+direction LR
+
+SharedContracts["Shared.Contracts"]
+
+Domain["Domain.Entities"]
+
+DBConn["Database.Connection"]
+
+end
+
+subgraph INFRA["Slice-specific Infrastructure"]
+
+direction LR
+
+JWT["Infrastructure.Jwt"]
+
+PwdHash["Infrastructure.PasswordHashing"]
+
+FileUpload["Infrastructure.FileUpload"]
+
+Email["Infrastructure.Email"]
+
+EmailTemplates["Infrastructure.Email.Templates"]
+
+end
+
+UsersSlice == project ref, sends UploadPhotoCommand ==> PhotoSlice
+
+UsersSlice -. sends email commands .-> SharedApp["Shared.Application
(email command contract)"]
+
+EmailsSlice -. handles email commands .-> SharedApp
+
+BrewerySlice --> FOUNDATION
+
+LocationsSlice --> FOUNDATION
+
+BeersSlice --> FOUNDATION
+
+PhotoSlice --> FOUNDATION & FileUpload
+
+UsersSlice --> FOUNDATION & JWT & PwdHash
+
+EmailsSlice --> Email & EmailTemplates
+
+DBConn -- Dapper SQL, no ORM --> Tables[("SQL Server
Tables")]
diff --git a/docs/website/diagrams-md/auth/confirm-user.md b/docs/diagrams/website/auth/confirm-user.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/confirm-user.md
rename to docs/diagrams/website/auth/confirm-user.mmd
index 2e7532d5..f340267c 100644
--- a/docs/website/diagrams-md/auth/confirm-user.md
+++ b/docs/diagrams/website/auth/confirm-user.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Confirm User
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -82,4 +79,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/delete-account.md b/docs/diagrams/website/auth/delete-account.mmd
similarity index 97%
rename from docs/website/diagrams-md/auth/delete-account.md
rename to docs/diagrams/website/auth/delete-account.mmd
index 6b3b1caa..b80b396a 100644
--- a/docs/website/diagrams-md/auth/delete-account.md
+++ b/docs/diagrams/website/auth/delete-account.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Delete Account
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -68,4 +65,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/error-handling.md b/docs/diagrams/website/auth/error-handling.mmd
similarity index 64%
rename from docs/website/diagrams-md/auth/error-handling.md
rename to docs/diagrams/website/auth/error-handling.mmd
index ebf53d5d..e4ef9a36 100644
--- a/docs/website/diagrams-md/auth/error-handling.md
+++ b/docs/diagrams/website/auth/error-handling.mmd
@@ -1,8 +1,3 @@
-# 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
sequenceDiagram
participant API as API Controller
@@ -15,4 +10,3 @@ sequenceDiagram
Note over API: Domain.Exceptions.ValidationException → 400 Bad Request
Note over API: Microsoft.Data.SqlClient.SqlException → 503 Service Unavailable
Note over API: All others → 500 Internal Server Error
-```
diff --git a/docs/website/diagrams-md/auth/login.md b/docs/diagrams/website/auth/login.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/login.md
rename to docs/diagrams/website/auth/login.mmd
index 6cf6cfa1..e6d87273 100644
--- a/docs/website/diagrams-md/auth/login.md
+++ b/docs/diagrams/website/auth/login.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Login
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -96,4 +93,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/refresh-token.md b/docs/diagrams/website/auth/refresh-token.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/refresh-token.md
rename to docs/diagrams/website/auth/refresh-token.mmd
index c0156c5b..ca1273b9 100644
--- a/docs/website/diagrams-md/auth/refresh-token.md
+++ b/docs/diagrams/website/auth/refresh-token.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Refresh Token
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -80,4 +77,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/registration.md b/docs/diagrams/website/auth/registration.mmd
similarity index 99%
rename from docs/website/diagrams-md/auth/registration.md
rename to docs/diagrams/website/auth/registration.mmd
index b77159c1..c8f58484 100644
--- a/docs/website/diagrams-md/auth/registration.md
+++ b/docs/diagrams/website/auth/registration.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Registration
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -154,4 +151,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/resend-confirmation.md b/docs/diagrams/website/auth/resend-confirmation.mmd
similarity index 97%
rename from docs/website/diagrams-md/auth/resend-confirmation.md
rename to docs/diagrams/website/auth/resend-confirmation.mmd
index e7b9e2f6..2c2e271e 100644
--- a/docs/website/diagrams-md/auth/resend-confirmation.md
+++ b/docs/diagrams/website/auth/resend-confirmation.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Resend Confirmation Email
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -74,4 +71,3 @@ sequenceDiagram
API->>User: 200 OK {message: "confirmation email has been resent"}
Note right of API: Always 200 OK regardless of outcome above — same user-enumeration precaution as a not-found user or an already-confirmed account
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/update-email.md b/docs/diagrams/website/auth/update-email.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/update-email.md
rename to docs/diagrams/website/auth/update-email.mmd
index 53a3f953..f7f875b5 100644
--- a/docs/website/diagrams-md/auth/update-email.md
+++ b/docs/diagrams/website/auth/update-email.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Update Email
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -67,4 +64,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/update-password.md b/docs/diagrams/website/auth/update-password.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/update-password.md
rename to docs/diagrams/website/auth/update-password.mmd
index a47a75fa..8f249c4d 100644
--- a/docs/website/diagrams-md/auth/update-password.md
+++ b/docs/diagrams/website/auth/update-password.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Update Password
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -87,4 +84,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/update-profile.md b/docs/diagrams/website/auth/update-profile.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/update-profile.md
rename to docs/diagrams/website/auth/update-profile.mmd
index 14adfe5f..1d91cb72 100644
--- a/docs/website/diagrams-md/auth/update-profile.md
+++ b/docs/diagrams/website/auth/update-profile.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Update Profile
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -66,4 +63,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/auth/update-username.md b/docs/diagrams/website/auth/update-username.mmd
similarity index 98%
rename from docs/website/diagrams-md/auth/update-username.md
rename to docs/diagrams/website/auth/update-username.mmd
index 6baf2a51..07b0d5d8 100644
--- a/docs/website/diagrams-md/auth/update-username.md
+++ b/docs/diagrams/website/auth/update-username.mmd
@@ -1,6 +1,3 @@
-# User Authentication Flow — Update Username
-
-```mermaid
sequenceDiagram
actor User
participant API as API Controller
@@ -71,4 +68,3 @@ sequenceDiagram
end
end
deactivate API
-```
diff --git a/docs/website/diagrams-md/database-schema.md b/docs/diagrams/website/database-schema.mmd
similarity index 95%
rename from docs/website/diagrams-md/database-schema.md
rename to docs/diagrams/website/database-schema.mmd
index be309cb9..4b250607 100644
--- a/docs/website/diagrams-md/database-schema.md
+++ b/docs/diagrams/website/database-schema.mmd
@@ -1,8 +1,3 @@
-# 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
erDiagram
User ||--o{ Cred : "has credentials"
User ||--o| Verify : "has verification"
@@ -165,4 +160,3 @@ erDiagram
datetime CreatedAt
datetime UpdatedAt "nullable"
}
-```
diff --git a/docs/website/diagrams-md/deployment.md b/docs/diagrams/website/deployment.mmd
similarity index 68%
rename from docs/website/diagrams-md/deployment.md
rename to docs/diagrams/website/deployment.mmd
index ced7d8e9..09f7b70d 100644
--- a/docs/website/diagrams-md/deployment.md
+++ b/docs/diagrams/website/deployment.mmd
@@ -1,6 +1,3 @@
-# Docker Deployment Architecture
-
-```mermaid
flowchart TB
Developer(["Developer"])
Host[["Docker Host"]]
@@ -77,14 +74,3 @@ flowchart TB
MinSeed -->|2. Seed data| MinDB
MinMig -.->|depends_on| MinDB
MinSeed -.->|depends_on| MinMig
-```
-
-## 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.
diff --git a/docs/pipeline/diagrams/current/activity.md b/docs/pipeline/diagrams/current/activity.md
new file mode 100644
index 00000000..331c06d6
--- /dev/null
+++ b/docs/pipeline/diagrams/current/activity.md
@@ -0,0 +1,7 @@
+# The Biergarten Data Pipeline (Current — Synchronous Data Path)
+
+The only concurrency in the current pipeline is a dedicated log dispatcher thread that drains `log_channel` and forwards entries to spdlog for the entire run (joined during shutdown after `log_channel` closes). `BiergartenPipelineOrchestrator::Run()` itself is synchronous — sampling, enrichment, generation, and export all happen on the main thread.
+
+```mermaid
+--8<-- "diagrams/pipeline/current/activity.mmd"
+```
diff --git a/docs/pipeline/diagrams/current/class.md b/docs/pipeline/diagrams/current/class.md
new file mode 100644
index 00000000..6f1e68a2
--- /dev/null
+++ b/docs/pipeline/diagrams/current/class.md
@@ -0,0 +1,5 @@
+# The Biergarten Data Pipeline — Class Diagram (Current)
+
+```mermaid
+--8<-- "diagrams/pipeline/current/class.mmd"
+```
diff --git a/docs/pipeline/diagrams/planned/activity.md b/docs/pipeline/diagrams/planned/activity.md
new file mode 100644
index 00000000..cbeb22ca
--- /dev/null
+++ b/docs/pipeline/diagrams/planned/activity.md
@@ -0,0 +1,7 @@
+# The Biergarten Data Pipeline — Activity Diagram (Planned)
+
+Each generation phase runs a producer/consumer trio concurrently: an **Orchestrator** producer feeds a bounded channel, an **LLM Worker** consumes it and generates records (closing its output channel when the input is drained and closed), and a **SQLite Worker** consumes that output channel and commits in batches. The Checkin and Follow phases run in parallel with each other once the user and brewery pools are populated.
+
+```mermaid
+--8<-- "diagrams/pipeline/planned/activity.mmd"
+```
diff --git a/docs/pipeline/diagrams/planned/class.md b/docs/pipeline/diagrams/planned/class.md
new file mode 100644
index 00000000..837e1c91
--- /dev/null
+++ b/docs/pipeline/diagrams/planned/class.md
@@ -0,0 +1,10 @@
+# Biergarten Data Pipeline — Class Diagram (Planned)
+
+```mermaid
+--8<-- "diagrams/pipeline/planned/class.mmd"
+```
+
+## Notes
+
+- `Logger`, `PipelineLogger`, and `LogWorker` are referenced only in relationships in the source PlantUML (not given their own class blocks there either) — they appear here as implicit nodes for the same reason.
+- Package grouping from the PlantUML source (`Domain: Models`, `Domain: Application Configuration`, `Domain: Policy`, `Infrastructure: Logging`, `Infrastructure: Pipeline Channel`, `Infrastructure: Data Preloading`, `Infrastructure: Enrichment`, `Infrastructure: Prompting`, `Infrastructure: Data Generation`, `Infrastructure: Data Export`) is preserved as Mermaid `namespace` blocks.
diff --git a/docs/website/diagrams-md/architecture.md b/docs/website/diagrams/architecture.md
similarity index 65%
rename from docs/website/diagrams-md/architecture.md
rename to docs/website/diagrams/architecture.md
index f4e91347..64d1ab7c 100644
--- a/docs/website/diagrams-md/architecture.md
+++ b/docs/website/diagrams/architecture.md
@@ -11,65 +11,7 @@ assemblies to register — there's no shared bootstrap. `Database.Migrations`
doesn't wire up any slice; it applies schema directly.
```mermaid
----
-
-config:
-
-flowchart:
-
-curve: stepAfter
-
-layout: elk
-
----
-
-flowchart TB
-
-API["API.Core
(ASP.NET Core Web API)"]
-
-Seed["Database.Seed
(console app)"]
-
-Migrations["Database.Migrations
(console app)"]
-
-
-
-subgraph SLICES["Feature Slices"]
-
-direction LR
-
-UsersSlice["Features.Users
(controller)"]
-
-BrewerySlice["Features.Breweries
(controller)"]
-
-PhotoSlice["Features.PhotoUpload
(MediatR only)"]
-
-EmailsSlice["Features.Emails
(MediatR only)"]
-
-LocationsSlice["Features.Locations
(plain DI service)"]
-
-BeersSlice["Features.Beers
(scaffolded, no code yet)"]
-
-end
-
-
-
-API -->|AddApplicationPart + MediatR scan| UsersSlice
-
-API -->|AddApplicationPart + MediatR scan| BrewerySlice
-
-API -->|MediatR scan only| PhotoSlice
-
-API -->|MediatR scan only| EmailsSlice
-
-
-
-Seed -->|AddFeaturesUsers| UsersSlice
-
-Seed -->|AddFeaturesBreweries| BrewerySlice
-
-Seed -->|AddFeaturesPhotoUpload| PhotoSlice
-
-Seed -->|AddFeaturesLocations| LocationsSlice
+--8<-- "diagrams/website/architecture/host-wiring.mmd"
```
## Project reference dependencies
@@ -83,83 +25,7 @@ foundation projects (`Shared.Contracts`, `Domain.Entities`,
see the notes for what else each of those foundation projects pulls in.
```mermaid
----
-
-config:
-
-flowchart: {}
-
-layout: fixed
-
----
-
-flowchart TB
-
-subgraph SLICES["Feature Slices"]
-
-direction LR
-
-BrewerySlice["Features.Breweries"]
-
-LocationsSlice["Features.Locations"]
-
-BeersSlice["Features.Beers
(scaffolded)"]
-
-PhotoSlice["Features.PhotoUpload"]
-
-UsersSlice["Features.Users"]
-
-EmailsSlice["Features.Emails"]
-
-end
-
-subgraph FOUNDATION["Foundation (every DB-backed slice depends on all three)"]
-
-direction LR
-
-SharedContracts["Shared.Contracts"]
-
-Domain["Domain.Entities"]
-
-DBConn["Database.Connection"]
-
-end
-
-subgraph INFRA["Slice-specific Infrastructure"]
-
-direction LR
-
-JWT["Infrastructure.Jwt"]
-
-PwdHash["Infrastructure.PasswordHashing"]
-
-FileUpload["Infrastructure.FileUpload"]
-
-Email["Infrastructure.Email"]
-
-EmailTemplates["Infrastructure.Email.Templates"]
-
-end
-
-UsersSlice == project ref, sends UploadPhotoCommand ==> PhotoSlice
-
-UsersSlice -. sends email commands .-> SharedApp["Shared.Application
(email command contract)"]
-
-EmailsSlice -. handles email commands .-> SharedApp
-
-BrewerySlice --> FOUNDATION
-
-LocationsSlice --> FOUNDATION
-
-BeersSlice --> FOUNDATION
-
-PhotoSlice --> FOUNDATION & FileUpload
-
-UsersSlice --> FOUNDATION & JWT & PwdHash
-
-EmailsSlice --> Email & EmailTemplates
-
-DBConn -- Dapper SQL, no ORM --> Tables[("SQL Server
Tables")]
+--8<-- "diagrams/website/architecture/project-references.mmd"
```
## Notes
diff --git a/docs/website/diagrams/auth/confirm-user.md b/docs/website/diagrams/auth/confirm-user.md
new file mode 100644
index 00000000..827995e5
--- /dev/null
+++ b/docs/website/diagrams/auth/confirm-user.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Confirm User
+
+```mermaid
+--8<-- "diagrams/website/auth/confirm-user.mmd"
+```
diff --git a/docs/website/diagrams/auth/delete-account.md b/docs/website/diagrams/auth/delete-account.md
new file mode 100644
index 00000000..2ac44f0b
--- /dev/null
+++ b/docs/website/diagrams/auth/delete-account.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Delete Account
+
+```mermaid
+--8<-- "diagrams/website/auth/delete-account.mmd"
+```
diff --git a/docs/website/diagrams/auth/error-handling.md b/docs/website/diagrams/auth/error-handling.md
new file mode 100644
index 00000000..0baf659f
--- /dev/null
+++ b/docs/website/diagrams/auth/error-handling.md
@@ -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"
+```
diff --git a/docs/website/diagrams/auth/login.md b/docs/website/diagrams/auth/login.md
new file mode 100644
index 00000000..da366c53
--- /dev/null
+++ b/docs/website/diagrams/auth/login.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Login
+
+```mermaid
+--8<-- "diagrams/website/auth/login.mmd"
+```
diff --git a/docs/website/diagrams/auth/refresh-token.md b/docs/website/diagrams/auth/refresh-token.md
new file mode 100644
index 00000000..2103f635
--- /dev/null
+++ b/docs/website/diagrams/auth/refresh-token.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Refresh Token
+
+```mermaid
+--8<-- "diagrams/website/auth/refresh-token.mmd"
+```
diff --git a/docs/website/diagrams/auth/registration.md b/docs/website/diagrams/auth/registration.md
new file mode 100644
index 00000000..5acde69e
--- /dev/null
+++ b/docs/website/diagrams/auth/registration.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Registration
+
+```mermaid
+--8<-- "diagrams/website/auth/registration.mmd"
+```
diff --git a/docs/website/diagrams/auth/resend-confirmation.md b/docs/website/diagrams/auth/resend-confirmation.md
new file mode 100644
index 00000000..26c77906
--- /dev/null
+++ b/docs/website/diagrams/auth/resend-confirmation.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Resend Confirmation Email
+
+```mermaid
+--8<-- "diagrams/website/auth/resend-confirmation.mmd"
+```
diff --git a/docs/website/diagrams/auth/update-email.md b/docs/website/diagrams/auth/update-email.md
new file mode 100644
index 00000000..53b25b02
--- /dev/null
+++ b/docs/website/diagrams/auth/update-email.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Update Email
+
+```mermaid
+--8<-- "diagrams/website/auth/update-email.mmd"
+```
diff --git a/docs/website/diagrams/auth/update-password.md b/docs/website/diagrams/auth/update-password.md
new file mode 100644
index 00000000..a52c1751
--- /dev/null
+++ b/docs/website/diagrams/auth/update-password.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Update Password
+
+```mermaid
+--8<-- "diagrams/website/auth/update-password.mmd"
+```
diff --git a/docs/website/diagrams/auth/update-profile.md b/docs/website/diagrams/auth/update-profile.md
new file mode 100644
index 00000000..001bd140
--- /dev/null
+++ b/docs/website/diagrams/auth/update-profile.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Update Profile
+
+```mermaid
+--8<-- "diagrams/website/auth/update-profile.mmd"
+```
diff --git a/docs/website/diagrams/auth/update-username.md b/docs/website/diagrams/auth/update-username.md
new file mode 100644
index 00000000..245ea4dc
--- /dev/null
+++ b/docs/website/diagrams/auth/update-username.md
@@ -0,0 +1,5 @@
+# User Authentication Flow — Update Username
+
+```mermaid
+--8<-- "diagrams/website/auth/update-username.mmd"
+```
diff --git a/docs/website/diagrams/database-schema.md b/docs/website/diagrams/database-schema.md
new file mode 100644
index 00000000..86697361
--- /dev/null
+++ b/docs/website/diagrams/database-schema.md
@@ -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"
+```
diff --git a/docs/website/diagrams/deployment.md b/docs/website/diagrams/deployment.md
new file mode 100644
index 00000000..35802e1c
--- /dev/null
+++ b/docs/website/diagrams/deployment.md
@@ -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.
diff --git a/mkdocs.yml b/mkdocs.yml
index e01d8bca..c36e3e91 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -10,28 +10,28 @@ nav:
- Architecture: architecture.md
- Diagrams:
- Website:
- - Architecture: website/diagrams-md/architecture.md
- - Database Schema: website/diagrams-md/database-schema.md
- - Deployment: website/diagrams-md/deployment.md
+ - Architecture: website/diagrams/architecture.md
+ - Database Schema: website/diagrams/database-schema.md
+ - Deployment: website/diagrams/deployment.md
- Auth Flows:
- - Registration: website/diagrams-md/auth/registration.md
- - Login: website/diagrams-md/auth/login.md
- - Refresh Token: website/diagrams-md/auth/refresh-token.md
- - Confirm User: website/diagrams-md/auth/confirm-user.md
- - Resend Confirmation: website/diagrams-md/auth/resend-confirmation.md
- - Update Username: website/diagrams-md/auth/update-username.md
- - Update Email: website/diagrams-md/auth/update-email.md
- - Update Password: website/diagrams-md/auth/update-password.md
- - Update Profile: website/diagrams-md/auth/update-profile.md
- - Delete Account: website/diagrams-md/auth/delete-account.md
- - Error Handling: website/diagrams-md/auth/error-handling.md
+ - Registration: website/diagrams/auth/registration.md
+ - Login: website/diagrams/auth/login.md
+ - Refresh Token: website/diagrams/auth/refresh-token.md
+ - Confirm User: website/diagrams/auth/confirm-user.md
+ - Resend Confirmation: website/diagrams/auth/resend-confirmation.md
+ - Update Username: website/diagrams/auth/update-username.md
+ - Update Email: website/diagrams/auth/update-email.md
+ - Update Password: website/diagrams/auth/update-password.md
+ - Update Profile: website/diagrams/auth/update-profile.md
+ - Delete Account: website/diagrams/auth/delete-account.md
+ - Error Handling: website/diagrams/auth/error-handling.md
- Pipeline:
- Current:
- - Activity: pipeline/diagrams-md/current/activity.md
- - Class: pipeline/diagrams-md/current/class.md
+ - Activity: pipeline/diagrams/current/activity.md
+ - Class: pipeline/diagrams/current/class.md
- Planned:
- - Activity: pipeline/diagrams-md/planned/activity.md
- - Class: pipeline/diagrams-md/planned/class.md
+ - Activity: pipeline/diagrams/planned/activity.md
+ - Class: pipeline/diagrams/planned/class.md
- Website:
- Getting Started: website/getting-started.md
- Database: website/database.md
@@ -56,3 +56,6 @@ markdown_extensions:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
+ - pymdownx.snippets:
+ base_path: [docs]
+ check_paths: true