mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Pipeline: rename Location to City, wire postal code into breweries
This commit is contained in:
@@ -54,7 +54,9 @@ architecture needs.
|
||||
(present per-forename in the source data) is never discarded the way a
|
||||
pre-flattened `{first_name, last_name}` list would lose it; see §2.
|
||||
- [ ] Extend `GeneratedBrewery` with `brewery_id`, `context_completeness`,
|
||||
`metadata` (currently just `{location, brewery}`).
|
||||
`metadata` (currently `{location, address, brewery}` — see the
|
||||
`Location`→`City` rename and `Address` struct added in the
|
||||
`postal_regex`/§9 entries below).
|
||||
- [ ] Add `GeneratedBeer`, `GeneratedCheckin`, `GeneratedRating`,
|
||||
`GeneratedFollow` aggregate structs.
|
||||
- [x] Add `UserRecord` (`location`, `user : UserResult`, `email`,
|
||||
@@ -70,6 +72,30 @@ architecture needs.
|
||||
holding `generated_users_` in memory. Still missing vs. the planned
|
||||
`GeneratedUser`: `user_id`, `password`, and `metadata`.
|
||||
- [x] Add `UserPersona` (`name`, `description`, `style_affinities`).
|
||||
- [x] Add `postal_regex` (`std::vector<std::string>`) and
|
||||
`postal_code_examples` (`std::vector<std::string>`) to `Location`
|
||||
(now `City` — see below), sourced from each `cities.json` entry's
|
||||
`postal_code.city_regex` / `postal_code.examples`. Not part of the
|
||||
originally planned `Location` shape in `diagrams/planned/class.puml` —
|
||||
added ahead of postal code generation work; see §9.
|
||||
- [x] Renamed `Location` → `City` throughout the pipeline (struct, all
|
||||
parameter/return types, `LocationsList`→`CityList`,
|
||||
`LoadLocations()`→`LoadCities()`) so the domain vocabulary matches the
|
||||
web backend's `City`/`CityId`. Field/variable names that merely hold a
|
||||
`City` instance (e.g. `EnrichedCity::location`, `BreweryRecord::location`)
|
||||
were left as-is — `City` itself has a `city` field (the city name
|
||||
string), so renaming the container field too would read as
|
||||
`enriched_city.city.city`. The SQLite export layer's own vocabulary
|
||||
(`locations` table, `location_id` column, `location_cache_`, etc.) was
|
||||
renamed to `cities`/`city_id` to match, since it's this pipeline's own
|
||||
throwaway export, not the backend's SQL Server schema (see §5).
|
||||
- [x] Added a new `Address` struct (`postal_code` only, for now) and a
|
||||
`BreweryRecord::address` member, mirroring the web backend's
|
||||
`BreweryPostLocation` (`AddressLine1`, `AddressLine2`, `PostalCode`,
|
||||
`CityId`). Only `postal_code` is populated — `address_line1`/
|
||||
`address_line2` generation has no fixture data or service yet. Users
|
||||
do not get an `Address`: the backend's `UserAccount` has no address
|
||||
fields, only `BreweryPostLocation` does.
|
||||
|
||||
## 2. Data Preloading
|
||||
|
||||
@@ -78,7 +104,7 @@ architecture needs.
|
||||
- [x] Extract an interface; have `CuratedJsonDataService` implement it.
|
||||
Landed as `ICuratedDataService`
|
||||
(`services/curated_data/curated_data_service.h`), not `DataPreloader`
|
||||
— `LoadLocations()`, `LoadPersonas()`, `LoadForenamesByCountry()`, and
|
||||
— `LoadCities()`, `LoadPersonas()`, `LoadForenamesByCountry()`, and
|
||||
`LoadSurnamesByCountry()` are all virtual methods returning `const&`
|
||||
and take no arguments. `CuratedJsonDataService`
|
||||
(`services/curated_data/curated_json_data_service.h`, originally
|
||||
@@ -101,7 +127,7 @@ architecture needs.
|
||||
and is already copied into the Docker image
|
||||
(`runpod/Dockerfile`), but no loader reads it yet, and the native
|
||||
CMake build doesn't copy it into `build/` at all — `CMakeLists.txt`'s
|
||||
"Runtime Assets" step only copies `locations.json` and `prompts/`.
|
||||
"Runtime Assets" step only copies `cities.json` and `prompts/`.
|
||||
- [x] Add `LoadPersonas()` and author `personas.json` (doesn't exist yet).
|
||||
- [x] Add name-by-country loading, parsing
|
||||
`tooling/pipeline/forenames-by-country.json` and
|
||||
@@ -116,10 +142,16 @@ architecture needs.
|
||||
`sigpwned/popular-names-by-country-dataset` (CC0) — see
|
||||
ETHICS-AND-KNOWN-ISSUES.md's Names-by-Country Dataset section for
|
||||
provenance. Deliberately not pre-paired or filtered down to just the
|
||||
countries in `locations.json`: keeping the source shape (including
|
||||
countries in `cities.json`: keeping the source shape (including
|
||||
per-forename gender) intact means the loader can support more
|
||||
countries later, or gender-aware persona/bio generation, without
|
||||
re-sourcing data.
|
||||
- [x] Parse `postal_code.city_regex` and `postal_code.examples` out of each
|
||||
`cities.json` entry's nested `postal_code` object in
|
||||
`CuratedJsonDataService::LoadCities()`, into `City::postal_regex`
|
||||
/ `City::postal_code_examples` (see §1). `MockCuratedDataService`'s
|
||||
4 fixed locations carry matching values pulled from the corresponding
|
||||
`cities.json` entries.
|
||||
|
||||
## 3. Policy / Strategy Layer
|
||||
|
||||
@@ -174,17 +206,20 @@ Entirely new — no `includes/policy/` (or equivalent) directory exists today.
|
||||
`kCreateUsersTableSql` / `kInsertUserSql` in
|
||||
`includes/services/database/sqlite_statement_helpers.h`) are
|
||||
implemented — `GenerateUsers()` exports every successful user
|
||||
alongside its resolved `location_id`.
|
||||
alongside its resolved `city_id`.
|
||||
- [x] `ProcessRecord(const BreweryRecord&)` now also binds
|
||||
`BreweryRecord::address.postal_code` into a `postal_code` column on
|
||||
`breweries` (see §9).
|
||||
- [ ] Extend `IExportService` with `ProcessBeer`, `ProcessCheckin`,
|
||||
`ProcessRating`, `ProcessFollow` (today `ProcessRecord(const
|
||||
BreweryRecord&)` and `ProcessRecord(const UserRecord&)` exist).
|
||||
- [ ] Add `beers`, `checkins`, `ratings`, `follows` tables to
|
||||
`SqliteExportService::InitializeSchema()` (`locations`, `breweries`,
|
||||
and `users` already exist) — see `kCreateLocationsTableSql` /
|
||||
`SqliteExportService::InitializeSchema()` (`cities`, `breweries`,
|
||||
and `users` already exist) — see `kCreateCitiesTableSql` /
|
||||
`kCreateBreweriesTableSql` / `kCreateUsersTableSql` in
|
||||
`includes/services/database/sqlite_statement_helpers.h` for the
|
||||
existing pattern to follow.
|
||||
- [ ] Add a `brewery_cache_` alongside the existing `location_cache_`, and
|
||||
- [ ] Add a `brewery_cache_` alongside the existing `city_cache_`, and
|
||||
move from one open transaction for the whole run to per-phase batched
|
||||
commits (`BEGIN` / `COMMIT & BEGIN` on a batch-size threshold), as
|
||||
shown in the planned activity diagram.
|
||||
@@ -233,6 +268,36 @@ Entirely new — no `includes/policy/` (or equivalent) directory exists today.
|
||||
Assets" `configure_file` step in `CMakeLists.txt` so native builds and
|
||||
the Docker image agree on what's available at runtime.
|
||||
|
||||
## 9. Postal Code Generation
|
||||
|
||||
`tooling/pipeline/includes/services/postal_code/`. Not part of the original
|
||||
`diagrams/planned/class.puml` sketch — added once `Location` (now `City`)
|
||||
gained `postal_regex`/`postal_code_examples` (§1, §2).
|
||||
|
||||
- [x] Add the `IPostalCodeService` interface —
|
||||
`GeneratePostalCode(location : const City&) : std::string`.
|
||||
- [x] Add `MockPostalCodeService`: ignores `location.postal_regex` entirely
|
||||
and returns `location.postal_code_examples.front()`.
|
||||
- [ ] **Implement a real, xeger-based `IPostalCodeService`.** A xeger
|
||||
generator turns a regex pattern (here, one of
|
||||
`City::postal_regex`) into a random string that matches it — the
|
||||
inverse of matching a string against a regex. Without it, every
|
||||
generated postal code is either a hardcoded mock value or absent
|
||||
entirely; a real implementation is required before postal codes can
|
||||
vary per generated brewery instead of always reusing the same
|
||||
curated example.
|
||||
- [x] Wire `IPostalCodeService` into `main.cc`'s Boost.DI injector — bound
|
||||
unconditionally to `MockPostalCodeService` (no `--mocked` branch yet,
|
||||
since a real implementation doesn't exist to switch to; add one once
|
||||
the xeger-based generator above lands, mirroring `IEnrichmentService`)
|
||||
— and into `BiergartenPipelineOrchestrator::GenerateBreweries()`,
|
||||
which calls `GeneratePostalCode(location)` per brewery and stores the
|
||||
result on `BreweryRecord::address` (a new `Address` struct — see §1),
|
||||
exported to the `breweries.postal_code` SQLite column (§5).
|
||||
Postal-code generation is per-brewery, not per-city or per-user: users
|
||||
don't have an address concept in the web backend, only breweries do
|
||||
(`BreweryPostLocation`), so `UserRecord` was deliberately not extended.
|
||||
|
||||
---
|
||||
|
||||
## Suggested build order
|
||||
@@ -250,3 +315,7 @@ populated. Phase 1b may begin.", etc.) imply a dependency order. Roughly:
|
||||
planned diagrams.
|
||||
5. Enrichment cache pre-warming and the city/region query decision (§7) —
|
||||
useful at any point, but most valuable once phases run concurrently.
|
||||
6. Postal code generation (§9) is independent of the phases above — the
|
||||
xeger-based generator just needs `City::postal_regex`, already in
|
||||
place. Wiring the mock into brewery output has already landed (§9); the
|
||||
real generator can be swapped in once built.
|
||||
|
||||
Reference in New Issue
Block a user