mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 09:37:23 +00:00
165 lines
4.5 KiB
Plaintext
165 lines
4.5 KiB
Plaintext
@startuml
|
|
skinparam style strictuml
|
|
skinparam defaultFontName "DM Sans"
|
|
skinparam defaultFontSize 14
|
|
skinparam titleFontName "Volkhov"
|
|
skinparam titleFontSize 20
|
|
skinparam backgroundColor #FAFCF9
|
|
skinparam defaultFontColor #28342A
|
|
skinparam titleFontColor #28342A
|
|
skinparam ArrowColor #628A5B
|
|
skinparam NoteBackgroundColor #EAF0E8
|
|
skinparam NoteBorderColor #547461
|
|
skinparam ActivityBackgroundColor #FAFCF9
|
|
skinparam ActivityBorderColor #547461
|
|
skinparam ActivityDiamondBackgroundColor #FAFCF9
|
|
skinparam ActivityDiamondBorderColor #628A5B
|
|
skinparam ActivityBarColor #628A5B
|
|
skinparam SwimlaneBorderColor #547461
|
|
skinparam SwimlaneBorderThickness 0.3
|
|
|
|
title The Biergarten Data Pipeline (Current — Synchronous Data Path)
|
|
|
|
|#F2F6F0|main.cc|
|
|
start
|
|
:Create BoundedChannel<LogEntry> log_channel;
|
|
:Spawn log dispatcher thread\n(LogDispatcher::Run());
|
|
note right
|
|
The only concurrency in the current pipeline:
|
|
a dedicated thread drains log_channel and
|
|
forwards entries to spdlog for the entire run.
|
|
Joined during shutdown after log_channel closes.
|
|
end note
|
|
:ParseArguments(argc, argv);
|
|
if (Are arguments valid?) then (no)
|
|
:Log error / usage info;
|
|
stop
|
|
else (yes)
|
|
endif
|
|
|
|
:Init OpenSSL global state & LlamaBackendState;
|
|
:di::make_injector(...);
|
|
note right
|
|
Binds ILogger, IEnrichmentService, DataGenerator,
|
|
IExportService, IPromptFormatter, WebClient based
|
|
on --mocked vs. model-backed mode.
|
|
end note
|
|
:injector.create<std::unique_ptr<BiergartenPipelineOrchestrator>>();
|
|
:BiergartenPipelineOrchestrator::Run();
|
|
note right
|
|
Run() itself is synchronous — sampling, enrichment,
|
|
generation, and export all happen on this thread.
|
|
end note
|
|
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
:Initialize SQLite export;
|
|
|
|
|#E0EAE0|SqliteExportService|
|
|
:GetUtcTimestamp() from SystemDateTimeProvider;
|
|
:Initialize();
|
|
note right
|
|
Builds a fresh biergarten_seed_<UTC datetime>.sqlite filename
|
|
Appends a numeric suffix if the timestamp already exists
|
|
Opens DB Connection
|
|
Executes Schema DDL
|
|
Begins Transaction
|
|
end note
|
|
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
:QueryCitiesWithCountries();
|
|
|
|
|#E2EBDC|JsonLoader|
|
|
:JsonLoader::LoadLocations("locations.json");
|
|
:std::ranges::sample(all_locations, --location-count);
|
|
note right
|
|
--location-count defaults to 10.
|
|
end note
|
|
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
while (For each sampled Location?) is (Remaining cities)
|
|
|#DCE8D8|IEnrichmentService|
|
|
:GetLocationContext(loc);
|
|
note right
|
|
WikipediaEnrichmentService fetches a generic
|
|
"brewing" extract and a "beer in {country}" extract
|
|
(not a city/region-specific page). MockEnrichmentService
|
|
(--mocked) returns an empty string instead.
|
|
end note
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
if (Lookup failed?) then (yes)
|
|
:Log warning, skip city;
|
|
else (no)
|
|
:Store EnrichedCity{Location, region_context};
|
|
endif
|
|
endwhile (Done)
|
|
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
:GenerateBreweries(enriched_cities);
|
|
|
|
|#E5EDE1|DataGenerator|
|
|
while (For each EnrichedCity?) is (Remaining cities)
|
|
if (Generator Mode) then (MockGenerator)
|
|
:DeterministicHash & Format;
|
|
else (LlamaGenerator)
|
|
:PrepareRegionContext;
|
|
:prompt_directory_->Load("BREWERY_GENERATION");
|
|
note right
|
|
Resolves to BREWERY_GENERATION.md inside --prompt-dir.
|
|
end note
|
|
repeat
|
|
:Infer(system_prompt, user_prompt, max_tokens, kBreweryJsonGrammar);
|
|
:ValidateBreweryJson(raw, brewery);
|
|
if (Is JSON Valid?) then (yes)
|
|
break
|
|
else (no)
|
|
:Attempt++;
|
|
:Append validation error to retry prompt;
|
|
endif
|
|
repeat while (Attempt < 3?) is (yes)
|
|
note right
|
|
max_tokens is fixed across retries —
|
|
it is not raised on truncation.
|
|
end note
|
|
endif
|
|
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
if (Generation successful?) then (yes)
|
|
|#E0EAE0|SqliteExportService|
|
|
:ProcessRecord(GeneratedBrewery);
|
|
if (Location in cache?) then (yes)
|
|
:Reuse location_id;
|
|
else (no)
|
|
:Insert Location & Cache ID;
|
|
endif
|
|
:Insert Brewery (FK: location_id);
|
|
|
|
if (Exception caught during insert?) then (yes)
|
|
|#EAF0E8|BiergartenPipelineOrchestrator|
|
|
:Log warning "SQLite export failed";
|
|
note right
|
|
Data loss is prevented per-record.
|
|
The pipeline continues running.
|
|
end note
|
|
else (no)
|
|
endif
|
|
else (no)
|
|
:Log warning "Generation failed, skipping...";
|
|
endif
|
|
|#E5EDE1|DataGenerator|
|
|
endwhile (Done)
|
|
|
|
|#E0EAE0|SqliteExportService|
|
|
:Finalize();
|
|
note right
|
|
Commits Transaction
|
|
Closes Database Connection
|
|
end note
|
|
|
|
|#F2F6F0|main.cc|
|
|
:Close log_channel;
|
|
:Join log dispatcher thread;
|
|
:Return 0;
|
|
stop
|
|
|
|
@enduml
|