mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 01:54:43 +00:00
extract mermaid docs
This commit is contained in:
@@ -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
|
flowchart TD
|
||||||
Start([start]) --> ParseArgs["main.cc: ParseArguments(argc, argv)"]
|
Start([start]) --> ParseArgs["main.cc: ParseArguments(argc, argv)"]
|
||||||
ParseArgs --> ArgsValid{Arguments valid?}
|
ParseArgs --> ArgsValid{Arguments valid?}
|
||||||
@@ -77,4 +72,3 @@ flowchart TD
|
|||||||
|
|
||||||
Finalize --> CloseLog["main.cc: close log_channel, join log dispatcher thread"]
|
Finalize --> CloseLog["main.cc: close log_channel, join log dispatcher thread"]
|
||||||
CloseLog --> Stop2(["return 0 / stop"])
|
CloseLog --> Stop2(["return 0 / stop"])
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# The Biergarten Data Pipeline — Class Diagram (Current)
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
classDiagram
|
classDiagram
|
||||||
class BiergartenPipelineOrchestrator {
|
class BiergartenPipelineOrchestrator {
|
||||||
-shared_ptr~ILogger~ logger_
|
-shared_ptr~ILogger~ logger_
|
||||||
@@ -261,4 +258,3 @@ classDiagram
|
|||||||
IExportService <|.. SqliteExportService : implements
|
IExportService <|.. SqliteExportService : implements
|
||||||
SqliteExportService *-- IDateTimeProvider : owns
|
SqliteExportService *-- IDateTimeProvider : owns
|
||||||
IDateTimeProvider <|.. SystemDateTimeProvider : implements
|
IDateTimeProvider <|.. SystemDateTimeProvider : implements
|
||||||
```
|
|
||||||
@@ -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
|
flowchart TD
|
||||||
Start([start]) --> ParseArgs["Main: ParseArguments(argc, argv)"]
|
Start([start]) --> ParseArgs["Main: ParseArguments(argc, argv)"]
|
||||||
ParseArgs --> InvalidArgs{Invalid args?}
|
ParseArgs --> InvalidArgs{Invalid args?}
|
||||||
@@ -197,4 +192,3 @@ flowchart TD
|
|||||||
CloseLogCh --> MainDone["Main: spdlog::info 'Pipeline complete in X ms'"]
|
CloseLogCh --> MainDone["Main: spdlog::info 'Pipeline complete in X ms'"]
|
||||||
MainDone --> JoinLog["Main: Join Log Worker — drain guarantees no LogEntry is dropped at shutdown"]
|
MainDone --> JoinLog["Main: Join Log Worker — drain guarantees no LogEntry is dropped at shutdown"]
|
||||||
JoinLog --> Stop2([stop])
|
JoinLog --> Stop2([stop])
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# Biergarten Data Pipeline — Class Diagram (Planned)
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
classDiagram
|
classDiagram
|
||||||
namespace DomainModels {
|
namespace DomainModels {
|
||||||
class Location {
|
class Location {
|
||||||
@@ -585,9 +582,3 @@ classDiagram
|
|||||||
GeneratedRating *-- RatingResult
|
GeneratedRating *-- RatingResult
|
||||||
GeneratedRating *-- GenerationMetadata
|
GeneratedRating *-- GenerationMetadata
|
||||||
GeneratedFollow *-- 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.
|
|
||||||
59
docs/diagrams/website/architecture/host-wiring.mmd
Normal file
59
docs/diagrams/website/architecture/host-wiring.mmd
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
config:
|
||||||
|
|
||||||
|
flowchart:
|
||||||
|
|
||||||
|
curve: stepAfter
|
||||||
|
|
||||||
|
layout: elk
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
flowchart TB
|
||||||
|
|
||||||
|
API["API.Core<br/>(ASP.NET Core Web API)"]
|
||||||
|
|
||||||
|
Seed["Database.Seed<br/>(console app)"]
|
||||||
|
|
||||||
|
Migrations["Database.Migrations<br/>(console app)"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subgraph SLICES["Feature Slices"]
|
||||||
|
|
||||||
|
direction LR
|
||||||
|
|
||||||
|
UsersSlice["Features.Users<br/>(controller)"]
|
||||||
|
|
||||||
|
BrewerySlice["Features.Breweries<br/>(controller)"]
|
||||||
|
|
||||||
|
PhotoSlice["Features.PhotoUpload<br/>(MediatR only)"]
|
||||||
|
|
||||||
|
EmailsSlice["Features.Emails<br/>(MediatR only)"]
|
||||||
|
|
||||||
|
LocationsSlice["Features.Locations<br/>(plain DI service)"]
|
||||||
|
|
||||||
|
BeersSlice["Features.Beers<br/>(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
|
||||||
77
docs/diagrams/website/architecture/project-references.mmd
Normal file
77
docs/diagrams/website/architecture/project-references.mmd
Normal file
@@ -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<br>(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<br>(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<br>Tables")]
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Confirm User
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -82,4 +79,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Delete Account
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -68,4 +65,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -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
|
sequenceDiagram
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
|
|
||||||
@@ -15,4 +10,3 @@ sequenceDiagram
|
|||||||
Note over API: Domain.Exceptions.ValidationException → 400 Bad Request
|
Note over API: Domain.Exceptions.ValidationException → 400 Bad Request
|
||||||
Note over API: Microsoft.Data.SqlClient.SqlException → 503 Service Unavailable
|
Note over API: Microsoft.Data.SqlClient.SqlException → 503 Service Unavailable
|
||||||
Note over API: All others → 500 Internal Server Error
|
Note over API: All others → 500 Internal Server Error
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Login
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -96,4 +93,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Refresh Token
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -80,4 +77,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Registration
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -154,4 +151,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Resend Confirmation Email
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -74,4 +71,3 @@ sequenceDiagram
|
|||||||
API->>User: 200 OK {message: "confirmation email has been resent"}
|
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
|
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
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Update Email
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -67,4 +64,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Update Password
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -87,4 +84,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Update Profile
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -66,4 +63,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# User Authentication Flow — Update Username
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
actor User
|
actor User
|
||||||
participant API as API Controller
|
participant API as API Controller
|
||||||
@@ -71,4 +68,3 @@ sequenceDiagram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
deactivate API
|
deactivate API
|
||||||
```
|
|
||||||
@@ -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
|
erDiagram
|
||||||
User ||--o{ Cred : "has credentials"
|
User ||--o{ Cred : "has credentials"
|
||||||
User ||--o| Verify : "has verification"
|
User ||--o| Verify : "has verification"
|
||||||
@@ -165,4 +160,3 @@ erDiagram
|
|||||||
datetime CreatedAt
|
datetime CreatedAt
|
||||||
datetime UpdatedAt "nullable"
|
datetime UpdatedAt "nullable"
|
||||||
}
|
}
|
||||||
```
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# Docker Deployment Architecture
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart TB
|
flowchart TB
|
||||||
Developer(["Developer"])
|
Developer(["Developer"])
|
||||||
Host[["Docker Host"]]
|
Host[["Docker Host"]]
|
||||||
@@ -77,14 +74,3 @@ flowchart TB
|
|||||||
MinSeed -->|2. Seed data| MinDB
|
MinSeed -->|2. Seed data| MinDB
|
||||||
MinMig -.->|depends_on| MinDB
|
MinMig -.->|depends_on| MinDB
|
||||||
MinSeed -.->|depends_on| MinMig
|
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.
|
|
||||||
7
docs/pipeline/diagrams/current/activity.md
Normal file
7
docs/pipeline/diagrams/current/activity.md
Normal file
@@ -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"
|
||||||
|
```
|
||||||
5
docs/pipeline/diagrams/current/class.md
Normal file
5
docs/pipeline/diagrams/current/class.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# The Biergarten Data Pipeline — Class Diagram (Current)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/pipeline/current/class.mmd"
|
||||||
|
```
|
||||||
7
docs/pipeline/diagrams/planned/activity.md
Normal file
7
docs/pipeline/diagrams/planned/activity.md
Normal file
@@ -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"
|
||||||
|
```
|
||||||
10
docs/pipeline/diagrams/planned/class.md
Normal file
10
docs/pipeline/diagrams/planned/class.md
Normal file
@@ -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.
|
||||||
@@ -11,65 +11,7 @@ assemblies to register — there's no shared bootstrap. `Database.Migrations`
|
|||||||
doesn't wire up any slice; it applies schema directly.
|
doesn't wire up any slice; it applies schema directly.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
---
|
--8<-- "diagrams/website/architecture/host-wiring.mmd"
|
||||||
|
|
||||||
config:
|
|
||||||
|
|
||||||
flowchart:
|
|
||||||
|
|
||||||
curve: stepAfter
|
|
||||||
|
|
||||||
layout: elk
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
flowchart TB
|
|
||||||
|
|
||||||
API["API.Core<br/>(ASP.NET Core Web API)"]
|
|
||||||
|
|
||||||
Seed["Database.Seed<br/>(console app)"]
|
|
||||||
|
|
||||||
Migrations["Database.Migrations<br/>(console app)"]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
subgraph SLICES["Feature Slices"]
|
|
||||||
|
|
||||||
direction LR
|
|
||||||
|
|
||||||
UsersSlice["Features.Users<br/>(controller)"]
|
|
||||||
|
|
||||||
BrewerySlice["Features.Breweries<br/>(controller)"]
|
|
||||||
|
|
||||||
PhotoSlice["Features.PhotoUpload<br/>(MediatR only)"]
|
|
||||||
|
|
||||||
EmailsSlice["Features.Emails<br/>(MediatR only)"]
|
|
||||||
|
|
||||||
LocationsSlice["Features.Locations<br/>(plain DI service)"]
|
|
||||||
|
|
||||||
BeersSlice["Features.Beers<br/>(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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project reference dependencies
|
## 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.
|
see the notes for what else each of those foundation projects pulls in.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
---
|
--8<-- "diagrams/website/architecture/project-references.mmd"
|
||||||
|
|
||||||
config:
|
|
||||||
|
|
||||||
flowchart: {}
|
|
||||||
|
|
||||||
layout: fixed
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
flowchart TB
|
|
||||||
|
|
||||||
subgraph SLICES["Feature Slices"]
|
|
||||||
|
|
||||||
direction LR
|
|
||||||
|
|
||||||
BrewerySlice["Features.Breweries"]
|
|
||||||
|
|
||||||
LocationsSlice["Features.Locations"]
|
|
||||||
|
|
||||||
BeersSlice["Features.Beers<br>(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<br>(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<br>Tables")]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
5
docs/website/diagrams/auth/confirm-user.md
Normal file
5
docs/website/diagrams/auth/confirm-user.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Confirm User
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/confirm-user.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/delete-account.md
Normal file
5
docs/website/diagrams/auth/delete-account.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Delete Account
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/delete-account.mmd"
|
||||||
|
```
|
||||||
7
docs/website/diagrams/auth/error-handling.md
Normal file
7
docs/website/diagrams/auth/error-handling.md
Normal 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"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/login.md
Normal file
5
docs/website/diagrams/auth/login.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Login
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/login.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/refresh-token.md
Normal file
5
docs/website/diagrams/auth/refresh-token.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Refresh Token
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/refresh-token.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/registration.md
Normal file
5
docs/website/diagrams/auth/registration.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Registration
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/registration.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/resend-confirmation.md
Normal file
5
docs/website/diagrams/auth/resend-confirmation.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Resend Confirmation Email
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/resend-confirmation.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/update-email.md
Normal file
5
docs/website/diagrams/auth/update-email.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Update Email
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/update-email.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/update-password.md
Normal file
5
docs/website/diagrams/auth/update-password.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Update Password
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/update-password.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/update-profile.md
Normal file
5
docs/website/diagrams/auth/update-profile.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Update Profile
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/update-profile.mmd"
|
||||||
|
```
|
||||||
5
docs/website/diagrams/auth/update-username.md
Normal file
5
docs/website/diagrams/auth/update-username.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# User Authentication Flow — Update Username
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
--8<-- "diagrams/website/auth/update-username.mmd"
|
||||||
|
```
|
||||||
7
docs/website/diagrams/database-schema.md
Normal file
7
docs/website/diagrams/database-schema.md
Normal 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"
|
||||||
|
```
|
||||||
15
docs/website/diagrams/deployment.md
Normal file
15
docs/website/diagrams/deployment.md
Normal 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.
|
||||||
39
mkdocs.yml
39
mkdocs.yml
@@ -10,28 +10,28 @@ nav:
|
|||||||
- Architecture: architecture.md
|
- Architecture: architecture.md
|
||||||
- Diagrams:
|
- Diagrams:
|
||||||
- Website:
|
- Website:
|
||||||
- Architecture: website/diagrams-md/architecture.md
|
- Architecture: website/diagrams/architecture.md
|
||||||
- Database Schema: website/diagrams-md/database-schema.md
|
- Database Schema: website/diagrams/database-schema.md
|
||||||
- Deployment: website/diagrams-md/deployment.md
|
- Deployment: website/diagrams/deployment.md
|
||||||
- Auth Flows:
|
- Auth Flows:
|
||||||
- Registration: website/diagrams-md/auth/registration.md
|
- Registration: website/diagrams/auth/registration.md
|
||||||
- Login: website/diagrams-md/auth/login.md
|
- Login: website/diagrams/auth/login.md
|
||||||
- Refresh Token: website/diagrams-md/auth/refresh-token.md
|
- Refresh Token: website/diagrams/auth/refresh-token.md
|
||||||
- Confirm User: website/diagrams-md/auth/confirm-user.md
|
- Confirm User: website/diagrams/auth/confirm-user.md
|
||||||
- Resend Confirmation: website/diagrams-md/auth/resend-confirmation.md
|
- Resend Confirmation: website/diagrams/auth/resend-confirmation.md
|
||||||
- Update Username: website/diagrams-md/auth/update-username.md
|
- Update Username: website/diagrams/auth/update-username.md
|
||||||
- Update Email: website/diagrams-md/auth/update-email.md
|
- Update Email: website/diagrams/auth/update-email.md
|
||||||
- Update Password: website/diagrams-md/auth/update-password.md
|
- Update Password: website/diagrams/auth/update-password.md
|
||||||
- Update Profile: website/diagrams-md/auth/update-profile.md
|
- Update Profile: website/diagrams/auth/update-profile.md
|
||||||
- Delete Account: website/diagrams-md/auth/delete-account.md
|
- Delete Account: website/diagrams/auth/delete-account.md
|
||||||
- Error Handling: website/diagrams-md/auth/error-handling.md
|
- Error Handling: website/diagrams/auth/error-handling.md
|
||||||
- Pipeline:
|
- Pipeline:
|
||||||
- Current:
|
- Current:
|
||||||
- Activity: pipeline/diagrams-md/current/activity.md
|
- Activity: pipeline/diagrams/current/activity.md
|
||||||
- Class: pipeline/diagrams-md/current/class.md
|
- Class: pipeline/diagrams/current/class.md
|
||||||
- Planned:
|
- Planned:
|
||||||
- Activity: pipeline/diagrams-md/planned/activity.md
|
- Activity: pipeline/diagrams/planned/activity.md
|
||||||
- Class: pipeline/diagrams-md/planned/class.md
|
- Class: pipeline/diagrams/planned/class.md
|
||||||
- Website:
|
- Website:
|
||||||
- Getting Started: website/getting-started.md
|
- Getting Started: website/getting-started.md
|
||||||
- Database: website/database.md
|
- Database: website/database.md
|
||||||
@@ -56,3 +56,6 @@ markdown_extensions:
|
|||||||
- name: mermaid
|
- name: mermaid
|
||||||
class: mermaid
|
class: mermaid
|
||||||
format: !!python/name:pymdownx.superfences.fence_code_format
|
format: !!python/name:pymdownx.superfences.fence_code_format
|
||||||
|
- pymdownx.snippets:
|
||||||
|
base_path: [docs]
|
||||||
|
check_paths: true
|
||||||
|
|||||||
Reference in New Issue
Block a user