mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-05-31 17:53:59 +00:00
34
pipeline/diagrams/biergarten-weizen-theme.puml
Normal file
34
pipeline/diagrams/biergarten-weizen-theme.puml
Normal file
@@ -0,0 +1,34 @@
|
||||
skinparam shadowing false
|
||||
skinparam backgroundColor #FCFCF7
|
||||
skinparam defaultFontName "DM Sans"
|
||||
skinparam defaultFontColor #14180C
|
||||
skinparam titleFontName "Volkhov"
|
||||
skinparam titleFontColor #14180C
|
||||
skinparam ArrowColor #656F33
|
||||
skinparam NoteBackgroundColor #DBEEDD
|
||||
skinparam NoteFontColor #14180C
|
||||
skinparam NoteBorderColor #4A5837
|
||||
skinparam SwimlaneBorderColor #4A5837
|
||||
skinparam SwimlaneBorderThickness 1
|
||||
skinparam activityStartColor #EBECE3
|
||||
skinparam activityEndColor #4A5837
|
||||
skinparam activityStopColor #4A5837
|
||||
skinparam ActivityBackgroundColor #EBECE3
|
||||
skinparam ActivityBorderColor #4A5837
|
||||
skinparam ActivityDiamondBackgroundColor #CBD2B5
|
||||
skinparam ActivityDiamondBorderColor #4A5837
|
||||
skinparam packageStyle rectangle
|
||||
skinparam packageBackgroundColor #F1F3EA
|
||||
skinparam packageBorderColor #4A5837
|
||||
skinparam packageFontColor #14180C
|
||||
skinparam classBackgroundColor #EBECE3
|
||||
skinparam classBorderColor #4A5837
|
||||
skinparam classFontColor #14180C
|
||||
skinparam classAttributeFontColor #3F4724
|
||||
skinparam classStereotypeFontColor #4A5837
|
||||
skinparam interfaceBackgroundColor #DBEEDD
|
||||
skinparam interfaceBorderColor #4A5837
|
||||
skinparam interfaceFontColor #14180C
|
||||
skinparam enumBackgroundColor #E4E6D8
|
||||
skinparam enumBorderColor #4A5837
|
||||
skinparam enumFontColor #14180C
|
||||
@@ -1,25 +1,7 @@
|
||||
@startuml biergarten_activity
|
||||
skinparam defaultFontName "DM Sans"
|
||||
!include ../biergarten-weizen-theme.puml
|
||||
skinparam defaultFontSize 13
|
||||
skinparam titleFontName "Volkhov"
|
||||
skinparam titleFontSize 20
|
||||
skinparam backgroundColor #FCFCF7
|
||||
skinparam defaultFontColor #14180C
|
||||
skinparam titleFontColor #14180C
|
||||
skinparam ArrowColor #656F33
|
||||
skinparam activityStartColor #EBECE3
|
||||
skinparam activityEndColor #4A5837
|
||||
skinparam activityStopColor #4A5837
|
||||
skinparam ActivityBackgroundColor #EBECE3
|
||||
skinparam ActivityBorderColor #4A5837
|
||||
skinparam ActivityDiamondBackgroundColor #CBD2B5
|
||||
skinparam ActivityDiamondBorderColor #4A5837
|
||||
skinparam NoteBackgroundColor #DBEEDD
|
||||
skinparam NoteFontColor #14180C
|
||||
skinparam NoteBorderColor #4A5837
|
||||
skinparam SwimlaneBorderColor #4A5837
|
||||
skinparam SwimlaneBorderThickness 1
|
||||
skinparam monochrome reverse
|
||||
|
||||
title The Biergarten Data Pipeline — Activity Diagram
|
||||
|
||||
@@ -37,8 +19,8 @@ endif
|
||||
:Initialize SqliteExportService;
|
||||
note right
|
||||
Opens SQLite connection.
|
||||
Begins a single transaction
|
||||
covering all five fixture types.
|
||||
(Transactions are now managed
|
||||
per-phase via batching).
|
||||
end note
|
||||
|
||||
:Create BoundedChannel<LogEntry> log_ch;
|
||||
@@ -126,12 +108,18 @@ fork again
|
||||
end note
|
||||
fork again
|
||||
|SQLite Worker|
|
||||
:BEGIN TRANSACTION;
|
||||
while (exp_ch has items?) is (yes)
|
||||
:Receive GeneratedUser;
|
||||
:ProcessUser(user);
|
||||
:PipelineLogger::Log(Info, UserGeneration,\n city, user_id, "sqlite");
|
||||
:Append -> user_pool_;
|
||||
if (Batch size reached?) then (yes)
|
||||
:COMMIT & BEGIN;
|
||||
else (no)
|
||||
endif
|
||||
endwhile (no)
|
||||
:COMMIT (Final);
|
||||
end fork
|
||||
|
||||
|Orchestrator|
|
||||
@@ -145,23 +133,24 @@ end fork
|
||||
|
||||
fork
|
||||
|Orchestrator|
|
||||
:Loop: Send Locations -> loc_ch;
|
||||
:Loop: Sample User from user_pool_
|
||||
and pair with Location;
|
||||
:Send BreweryTask(Location, User) -> loc_ch;
|
||||
:Close loc_ch;
|
||||
fork again
|
||||
|LLM Worker|
|
||||
while (loc_ch has items?) is (yes)
|
||||
:Receive Location;
|
||||
:Receive BreweryTask(Location, User);
|
||||
|
||||
:GetLocationContextFromCache(location);
|
||||
:GetLocationContextFromCache(task.location);
|
||||
note right
|
||||
Guaranteed cache hit from startup.
|
||||
end note
|
||||
|
||||
:GenerateBrewery(enriched_city, context)\nvia DataGenerator;
|
||||
:GenerateBrewery(enriched_city, context, task.user)\nvia DataGenerator;
|
||||
note right
|
||||
KV cache stays warm across all
|
||||
brewery generations -- system prompt
|
||||
does not change within this phase.
|
||||
KV cache stays warm.
|
||||
Brewery is linked to the sampled owner_user_id.
|
||||
end note
|
||||
:PipelineLogger::Log(Info,\n BreweryGeneration,\n city, brewery_id, "llm");
|
||||
:Send GeneratedBrewery -> exp_ch;
|
||||
@@ -169,12 +158,18 @@ fork again
|
||||
:Close exp_ch;
|
||||
fork again
|
||||
|SQLite Worker|
|
||||
:BEGIN TRANSACTION;
|
||||
while (exp_ch has items?) is (yes)
|
||||
:Receive GeneratedBrewery;
|
||||
:ProcessBrewery(brewery);
|
||||
:PipelineLogger::Log(Info,\n BreweryGeneration,\n city, brewery_id, "sqlite");
|
||||
:Append -> brewery_pool_;
|
||||
if (Batch size reached?) then (yes)
|
||||
:COMMIT & BEGIN;
|
||||
else (no)
|
||||
endif
|
||||
endwhile (no)
|
||||
:COMMIT (Final);
|
||||
end fork
|
||||
|
||||
|Orchestrator|
|
||||
@@ -218,6 +213,7 @@ fork again
|
||||
:Close exp_ch;
|
||||
fork again
|
||||
|SQLite Worker|
|
||||
:BEGIN TRANSACTION;
|
||||
while (exp_ch has items?) is (yes)
|
||||
:Receive BeersBundle;
|
||||
while (For each beer in bundle?) is (remaining)
|
||||
@@ -226,7 +222,12 @@ fork again
|
||||
:Append -> beer_pool_;
|
||||
endwhile (done)
|
||||
:PipelineLogger::Log(Info,\n BeerGeneration,\n city, brewery_id, "sqlite");
|
||||
if (Batch size reached?) then (yes)
|
||||
:COMMIT & BEGIN;
|
||||
else (no)
|
||||
endif
|
||||
endwhile (no)
|
||||
:COMMIT (Final);
|
||||
end fork
|
||||
|
||||
|Orchestrator|
|
||||
@@ -247,6 +248,7 @@ note right
|
||||
emerges from persona distribution.
|
||||
end note
|
||||
|
||||
:BEGIN TRANSACTION;
|
||||
while (For each GeneratedUser in user_pool_?) is (remaining)
|
||||
:CheckinsForUser(user, brewery_pool_.size());
|
||||
while (For each checkin index?) is (remaining)
|
||||
@@ -256,8 +258,13 @@ while (For each GeneratedUser in user_pool_?) is (remaining)
|
||||
:ProcessCheckin(checkin);
|
||||
:PipelineLogger::Log(Info, CheckinGeneration,\n nullopt, checkin_id, "sqlite");
|
||||
:Append -> checkin_pool_;
|
||||
if (Batch size reached?) then (yes)
|
||||
:COMMIT & BEGIN;
|
||||
else (no)
|
||||
endif
|
||||
endwhile (done)
|
||||
endwhile (done)
|
||||
:COMMIT (Final);
|
||||
|
||||
' ═══════════════════════════════════════════
|
||||
' PHASE 3 — RATING GENERATION
|
||||
@@ -269,33 +276,41 @@ note right
|
||||
Rating skew modulated per persona.
|
||||
end note
|
||||
|
||||
:BEGIN TRANSACTION;
|
||||
while (For each GeneratedCheckin in checkin_pool_?) is (remaining)
|
||||
:Match brewery_id, select beer from beer_pool_\n(same brewery_id, biased by persona affinities);
|
||||
if (Beer exists for brewery?) then (yes)
|
||||
:GenerateRating(user, beer, checkin_id)\nvia DataGenerator;
|
||||
:ProcessRating(rating);
|
||||
:PipelineLogger::Log(Info, RatingGeneration,\n nullopt, rating_id, "sqlite");
|
||||
if (Batch size reached?) then (yes)
|
||||
:COMMIT & BEGIN;
|
||||
else (no)
|
||||
endif
|
||||
else (no)
|
||||
:PipelineLogger::Log(Warn, RatingGeneration,\n nullopt, brewery_id, "sqlite");
|
||||
:Skip -- brewery has no beers;
|
||||
endif
|
||||
endwhile (done)
|
||||
:COMMIT (Final);
|
||||
|
||||
' ═══════════════════════════════════════════
|
||||
' TEARDOWN
|
||||
' ═══════════════════════════════════════════
|
||||
|Main|
|
||||
|Orchestrator|
|
||||
:Finalize SqliteExportService;
|
||||
note right
|
||||
COMMIT covers all five fixture types.
|
||||
Safely closes the DB connection.
|
||||
end note
|
||||
:Close log_ch;
|
||||
|
||||
|Main|
|
||||
:spdlog::info "Pipeline complete in X ms";
|
||||
:Join Log Worker;
|
||||
note right
|
||||
Drain guarantees no LogEntry is
|
||||
dropped at shutdown.
|
||||
end note
|
||||
:spdlog::info "Pipeline complete in X ms";
|
||||
stop
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
' ==========================================
|
||||
' CONFIGURATION & STYLING
|
||||
' ==========================================
|
||||
skinparam classAttributeFontSize 13
|
||||
|
||||
' --- Typography ---
|
||||
skinparam defaultFontName "DM Sans"
|
||||
skinparam defaultFontSize 20
|
||||
skinparam titleFontName "Volkhov"
|
||||
!include ../biergarten-weizen-theme.puml
|
||||
skinparam classAttributeFontSize 9
|
||||
skinparam defaultFontSize 25
|
||||
skinparam titleFontSize 30
|
||||
|
||||
package "Domain" {
|
||||
package "Domain Models" {
|
||||
package "Domain: Models" {
|
||||
|
||||
class Location {
|
||||
+ city : std::string
|
||||
@@ -126,9 +122,9 @@ package "Domain" {
|
||||
|
||||
|
||||
LocationContext *-- Completeness
|
||||
}
|
||||
}
|
||||
|
||||
package "Domain: Application Configuration"{
|
||||
package "Domain: Application Configuration"{
|
||||
class SamplingOptions {
|
||||
+ temperature : float = 1.0F
|
||||
+ top_p : float = 0.95F
|
||||
@@ -157,12 +153,9 @@ package "Domain" {
|
||||
ApplicationOptions *-- GeneratorOptions
|
||||
ApplicationOptions *-- PipelineOptions
|
||||
GeneratorOptions *-- SamplingOptions
|
||||
}
|
||||
}
|
||||
|
||||
' ==========================================
|
||||
' DOMAIN POLICY
|
||||
' ==========================================
|
||||
package "Domain Policy" {
|
||||
package "Domain: Policy" {
|
||||
|
||||
interface ContextStrategy <<interface>> {
|
||||
+ QueriesFor(loc : const Location&) : std::vector<std::string>
|
||||
@@ -211,41 +204,9 @@ package "Domain" {
|
||||
+ CheckinsForUser(user : const GeneratedUser&,\n brewery_count : size_t) : size_t
|
||||
+ TimestampFor(user : const GeneratedUser&,\n index : size_t) : std::string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
' ==========================================
|
||||
' ORCHESTRATION
|
||||
' ==========================================
|
||||
|
||||
class BiergartenPipelineOrchestrator {
|
||||
- preloader_ : std::unique_ptr<DataPreloader>
|
||||
- enrichment_service_ : std::unique_ptr<EnrichmentService>
|
||||
- generator_ : std::unique_ptr<DataGenerator>
|
||||
- logger_ : std::unique_ptr<Logger>
|
||||
- exporter_ : std::unique_ptr<ExportService>
|
||||
- brewery_context_strategy_ : std::unique_ptr<ContextStrategy>
|
||||
- sampling_strategy_ : std::unique_ptr<SamplingStrategy>
|
||||
- beer_selection_strategy_ : std::unique_ptr<BeerSelectionStrategy>
|
||||
- checkin_strategy_ : std::unique_ptr<CheckinDistributionStrategy>
|
||||
- beer_style_palette_ : std::vector<BeerStyle>
|
||||
- options_ : ApplicationOptions
|
||||
--
|
||||
- user_pool_ : std::vector<GeneratedUser>
|
||||
- brewery_pool_ : std::vector<GeneratedBrewery>
|
||||
- beer_pool_ : std::vector<GeneratedBeer>
|
||||
- checkin_pool_ : std::vector<GeneratedCheckin>
|
||||
--
|
||||
+ Run() : bool
|
||||
- RunUserPhase(locations : const std::vector<Location>&) : void
|
||||
- RunBreweryAndBeerPhase(locations : const std::vector<Location>&) : void
|
||||
- RunCheckinPhase() : void
|
||||
- RunRatingPhase() : void
|
||||
}
|
||||
|
||||
package "Infrastructure" {
|
||||
|
||||
package "Logging" {
|
||||
package "Infrastructure: Logging" {
|
||||
enum LogLevel {
|
||||
Debug
|
||||
Info
|
||||
@@ -294,9 +255,9 @@ package "Infrastructure" {
|
||||
LogEntry *-- PipelinePhase
|
||||
PipelineLogger ..> LogEntry : emits
|
||||
LogWorker ..> LogEntry : consumes
|
||||
}
|
||||
}
|
||||
|
||||
package "Pipeline Channel" {
|
||||
package "Infrastructure: Pipeline Channel" {
|
||||
|
||||
class "BoundedChannel<T>" as BoundedChannel {
|
||||
- queue_ : std::queue<T>
|
||||
@@ -310,9 +271,9 @@ package "Infrastructure" {
|
||||
+ Close() : void
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package "Data Preloading" {
|
||||
package "Infrastructure: Data Preloading" {
|
||||
|
||||
interface DataPreloader <<interface>> {
|
||||
+ LoadLocations(filepath : const std::filesystem::path&) : std::vector<Location>
|
||||
@@ -328,9 +289,9 @@ package "Infrastructure" {
|
||||
+ LoadNamesByCountry(filepath : const std::filesystem::path&) : NamesByCountry
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package "Enrichment" {
|
||||
package "Infrastructure: Enrichment" {
|
||||
|
||||
interface EnrichmentService <<interface>> {
|
||||
+ GetLocationContext(loc : const Location&,\n strategy : const ContextStrategy&) : LocationContext
|
||||
@@ -353,9 +314,9 @@ package "Infrastructure" {
|
||||
+ UrlEncode(value : const std::string&) : std::string
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package "Data Generation" {
|
||||
package "Infrastructure: Data Generation" {
|
||||
|
||||
interface DataGenerator <<interface>> {
|
||||
+ GenerateBrewery(location : const Location&,\n context : const LocationContext&) : BreweryResult
|
||||
@@ -399,9 +360,9 @@ package "Infrastructure" {
|
||||
+ ExpectedArchitecture() : std::string_view
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
package "Data Export" {
|
||||
package "Infrastructure: Data Export" {
|
||||
|
||||
interface ExportService <<interface>> {
|
||||
+ Initialize() : void
|
||||
@@ -446,12 +407,34 @@ package "Infrastructure" {
|
||||
+ GetUtcTimestamp() : std::string
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
' ==========================================
|
||||
' GLOBAL RELATIONSHIPS
|
||||
' ==========================================
|
||||
|
||||
|
||||
class BiergartenPipelineOrchestrator {
|
||||
- preloader_ : std::unique_ptr<DataPreloader>
|
||||
- enrichment_service_ : std::unique_ptr<EnrichmentService>
|
||||
- generator_ : std::unique_ptr<DataGenerator>
|
||||
- logger_ : std::unique_ptr<Logger>
|
||||
- exporter_ : std::unique_ptr<ExportService>
|
||||
- brewery_context_strategy_ : std::unique_ptr<ContextStrategy>
|
||||
- sampling_strategy_ : std::unique_ptr<SamplingStrategy>
|
||||
- beer_selection_strategy_ : std::unique_ptr<BeerSelectionStrategy>
|
||||
- checkin_strategy_ : std::unique_ptr<CheckinDistributionStrategy>
|
||||
- beer_style_palette_ : std::vector<BeerStyle>
|
||||
- options_ : ApplicationOptions
|
||||
--
|
||||
- user_pool_ : std::vector<GeneratedUser>
|
||||
- brewery_pool_ : std::vector<GeneratedBrewery>
|
||||
- beer_pool_ : std::vector<GeneratedBeer>
|
||||
- checkin_pool_ : std::vector<GeneratedCheckin>
|
||||
--
|
||||
+ Run() : bool
|
||||
- RunUserPhase(locations : const std::vector<Location>&) : void
|
||||
- RunBreweryAndBeerPhase(locations : const std::vector<Location>&) : void
|
||||
- RunCheckinPhase() : void
|
||||
- RunRatingPhase() : void
|
||||
}
|
||||
|
||||
' --- Orchestration Aggregations (Services & Strategies) ---
|
||||
BiergartenPipelineOrchestrator *-- DataPreloader
|
||||
|
||||
Reference in New Issue
Block a user