Bring architecture/workflow docs current with real-data ingestion
ARCHITECTURE.md, PRODUCT_WORKFLOWS.md, DEVELOPMENT_AND_STAGING.md, and README.md still described the removed synthetic-seed staging setup and Ūdens as pure manual entry. Updates this session (open-data station ingestion, the scheduler split, water-temperature auto-populate) weren't reflected outside UPDATE_ROADMAP.md's changelog.
This commit is contained in:
+26
-21
@@ -5,23 +5,28 @@
|
|||||||
WeatherTool is a Scala backend, SolidJS frontend, and PostgreSQL database used to inspect Latvian weather observations and prepare map-based newsroom graphics.
|
WeatherTool is a Scala backend, SolidJS frontend, and PostgreSQL database used to inspect Latvian weather observations and prepare map-based newsroom graphics.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
External providers Local/staging workflow
|
External providers
|
||||||
LVGMC station FTP/CSV ----+ Synthetic SQL seed
|
LVĢMC open-data station/hydro feeds (data.gov.lv) --+
|
||||||
LVGMC forecast CSV -------+ |
|
LVGMC station FTP/CSV (legacy, gated off) ----------+
|
||||||
DMI HARMONIE APIs --------+ v
|
LVGMC forecast CSV (legacy, gated off) --------------+
|
||||||
v PostgreSQL
|
DMI HARMONIE APIs (legacy, gated off) --------------+
|
||||||
Scala ingestion |
|
v
|
||||||
| |
|
Scala ingestion
|
||||||
+---------> Scala/http4s API
|
|
|
||||||
|
|
v
|
||||||
v
|
PostgreSQL
|
||||||
SolidJS web UI
|
|
|
||||||
|
|
v
|
||||||
v
|
Scala/http4s API
|
||||||
Canvas preview and PNG export
|
|
|
||||||
|
v
|
||||||
|
SolidJS web UI
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Canvas preview and PNG export
|
||||||
```
|
```
|
||||||
|
|
||||||
Staging currently exercises the PostgreSQL → API → frontend path with synthetic observations. It does not emulate LVGMC forecast files or HARMONIE GRIB files.
|
Staging exercises the PostgreSQL → API → frontend path with real LVĢMC open-data observations (station temperatures, water temperatures, warnings) as of 2026-08-23. The private FTP station feed and the DMI HARMONIE forecast feed still exist in code but are gated behind `ENABLE_LEGACY_PROVIDER_JOBS` (default off) pending real credentials — see `docs/UPDATE_ROADMAP.md` Phase 7.
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
@@ -29,10 +34,10 @@ Staging currently exercises the PostgreSQL → API → frontend path with synthe
|
|||||||
|
|
||||||
- Serves JSON API routes and the built frontend from `web/dist`.
|
- Serves JSON API routes and the built frontend from `web/dist`.
|
||||||
- Queries and aggregates station observations in PostgreSQL.
|
- Queries and aggregates station observations in PostgreSQL.
|
||||||
- Contains ingestion/parsing code for LVGMC station and forecast data, both the private FTP feed (`fetch.lvgmc.FetchService`) and, as of 2026-08-23, a free/keyless open-data alternative (`fetch.lvgmc.OpenDataStationService`) that pivots LVĢMC's public `data.gov.lv` station-observation feed into the same `weather` table — the two run in parallel during evaluation; see `docs/UPDATE_ROADMAP.md` Phase 7.
|
- Contains ingestion/parsing code for LVGMC station data: a free/keyless open-data path (`fetch.lvgmc.OpenDataStationService`) that pivots LVĢMC's public `data.gov.lv` station-observation feed into the `weather` table, and the original private FTP feed (`fetch.lvgmc.FetchService`), kept but gated off pending real credentials.
|
||||||
- Fetches LVĢMC open hydrometeorological-warning metadata and polygon coordinates on request, with a 5-minute in-memory cache and stale-data fallback if the upstream call fails.
|
- Fetches LVĢMC open hydrometeorological-warning metadata and polygon coordinates on request (`fetch.warnings.WarningService`), and water temperatures per named zone (`fetch.lvgmc.WaterTemperatureService`) — both free/keyless `data.gov.lv` reads with a short in-memory cache and stale-data fallback if the upstream call fails; neither persists to PostgreSQL.
|
||||||
- Contains HARMONIE discovery, download, GRIB parsing, and rendering support.
|
- Contains HARMONIE discovery, download, GRIB parsing, and rendering support, gated off pending real DMI credentials.
|
||||||
- Starts scheduled ingestion/cleanup tasks unless `ENABLE_SCHEDULED_JOBS=false`.
|
- Starts the safe scheduled ingestion/cleanup tasks (open-data stations, GRIB cleanup) unless `ENABLE_SCHEDULED_JOBS=false`. The legacy FTP station fetch and HARMONIE fetch are scheduled independently and only run if `ENABLE_LEGACY_PROVIDER_JOBS=true` — kept separate so placeholder credentials on the legacy path can't crash-loop the whole app (both paths use `cats.effect.IO`'s `parMapN`, which cancels and fails every sibling task the instant one throws).
|
||||||
|
|
||||||
### SolidJS frontend
|
### SolidJS frontend
|
||||||
|
|
||||||
@@ -49,7 +54,7 @@ Staging currently exercises the PostgreSQL → API → frontend path with synthe
|
|||||||
|
|
||||||
## Main observation-data flow
|
## Main observation-data flow
|
||||||
|
|
||||||
1. An ingestion job parses provider station data, or the development seed inserts synthetic rows.
|
1. A scheduled ingestion job parses provider station data (the open-data path by default; the legacy FTP path only if `ENABLE_LEGACY_PROVIDER_JOBS=true`).
|
||||||
2. Observations are stored in the `weather` table.
|
2. Observations are stored in the `weather` table.
|
||||||
3. The frontend requests an API route containing cities, time range, granularity, field, and aggregate key.
|
3. The frontend requests an API route containing cities, time range, granularity, field, and aggregate key.
|
||||||
4. The backend performs the database query and returns JSON.
|
4. The backend performs the database query and returns JSON.
|
||||||
@@ -79,7 +84,7 @@ The renderer attaches each normalized 256×256 weather image to the measured edg
|
|||||||
|
|
||||||
### Ūdens
|
### Ūdens
|
||||||
|
|
||||||
Ūdens is an independent fixed-template renderer. Its six ranges are manual editorial inputs rather than station-query results. The 1920×1080 and 3840×1440 products use separate authoritative templates and six separately measured value rectangles. Canvas `TextMetrics` visible-glyph bounds center the Monda text optically inside each rectangle. Preview scaling never changes native export geometry, and both output sizes have been visually validated against the supplied newsroom templates.
|
Ūdens is an independent fixed-template renderer. As of 2026-08-23 its six ranges auto-populate from `fetch.lvgmc.WaterTemperatureService` on load — real per-zone min/max, not station-query results from PostgreSQL — with manual override and a per-zone "Atiestatīt" reset still fully available, mirroring the auto-load/override/reset pattern Faktiskā already used. Each of the six named zones (Jūra, Līcis, Kurzeme, Zemgale, Vidzeme, Latgale) is a geographic grouping of every currently-reporting LVĢMC hydrological station in that area (56 inland `WTEMD` + 9 coastal `SEDUT` stations nationwide, classified by approximate historical-region boundaries — the mapping isn't derived from an authoritative region field, since the open-data portal doesn't publish one), so the displayed range reflects genuine spread across that zone's stations rather than one station's value shown twice. Readings older than 12h are dropped so one stuck sensor can't skew a zone's range. The 1920×1080 and 3840×1440 products use separate authoritative templates and six separately measured value rectangles. Canvas `TextMetrics` visible-glyph bounds center the Monda text optically inside each rectangle. Preview scaling never changes native export geometry, and both output sizes have been visually validated against the supplied newsroom templates.
|
||||||
|
|
||||||
Monda Regular and Bold are bundled locally and used by the interface and generated text. Weather symbols are bundled as independent transparent PNG assets.
|
Monda Regular and Bold are bundled locally and used by the interface and generated text. Weather symbols are bundled as independent transparent PNG assets.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
| Environment | Purpose | Address |
|
| Environment | Purpose | Address |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Windows | Source editing, review, and Git operations only; no compile, build, runtime, dependency installation, or application testing | Not applicable |
|
| Windows | Source editing, review, and Git operations only; no compile, build, runtime, dependency installation, or application testing | Not applicable |
|
||||||
| Rocky Linux | Sole development runtime: compile, build, run, seed, test, and production-like staging | `http://192.168.1.101:9190` |
|
| Rocky Linux | Sole development runtime: compile, build, run, test, and production-like staging | `http://192.168.1.101:9190` |
|
||||||
| Ubuntu VPS | Deployment target and month-long user-acceptance environment; never a development or build host | Public UAT operational at `https://laikapstak.li` with temporary synthetic data |
|
| Ubuntu VPS | Deployment target and month-long user-acceptance environment; never a development or build host | Public UAT operational at `https://laikapstak.li` with temporary synthetic data |
|
||||||
| Workplace production | Out of scope until reviewed and approved | Not documented here |
|
| Workplace production | Out of scope until reviewed and approved | Not documented here |
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ codex/staging-baseline
|
|||||||
## Safety boundaries
|
## Safety boundaries
|
||||||
|
|
||||||
- Do not commit `.env`, credentials, database data, `web/node_modules`, or `web/dist`.
|
- Do not commit `.env`, credentials, database data, `web/node_modules`, or `web/dist`.
|
||||||
- Keep `ENABLE_SCHEDULED_JOBS=false` with placeholder or development credentials.
|
- Keep `ENABLE_LEGACY_PROVIDER_JOBS=false` wherever the private LVGMC FTP or DMI HARMONIE credentials are still placeholders — that path uses `parMapN`, which cancels and fails every scheduled task the instant one throws, so a placeholder credential there crash-loops the whole app. `ENABLE_SCHEDULED_JOBS` gates only the free/keyless open-data station fetch and GRIB cleanup, and is safe to leave on.
|
||||||
- Do not publish the staging PostgreSQL port.
|
- Do not publish the staging PostgreSQL port.
|
||||||
- Do not run `npm audit fix` without reviewing the proposed dependency changes.
|
- Do not run `npm audit fix` without reviewing the proposed dependency changes.
|
||||||
- Do not change ownership or permissions of the container-managed `postgres/` directory as a deployment workaround.
|
- Do not change ownership or permissions of the container-managed `postgres/` directory as a deployment workaround.
|
||||||
@@ -40,7 +40,7 @@ codex/staging-baseline
|
|||||||
|
|
||||||
Use Windows only to edit and review source files and perform Git operations. Do not
|
Use Windows only to edit and review source files and perform Git operations. Do not
|
||||||
run Node/npm dependency installation, TypeScript checks, Vite builds, SBT/Scala
|
run Node/npm dependency installation, TypeScript checks, Vite builds, SBT/Scala
|
||||||
compilation, Docker/Podman commands, the application, synthetic-data operations,
|
compilation, Docker/Podman commands, the application,
|
||||||
or browser application tests on Windows. All compile, build, development-runtime,
|
or browser application tests on Windows. All compile, build, development-runtime,
|
||||||
and test work belongs on Rocky. The Ubuntu VPS only receives a release artifact
|
and test work belongs on Rocky. The Ubuntu VPS only receives a release artifact
|
||||||
that has already been built and verified on Rocky.
|
that has already been built and verified on Rocky.
|
||||||
@@ -97,11 +97,11 @@ At minimum, verify:
|
|||||||
1. `docker compose ps` reports PostgreSQL healthy and Scala running.
|
1. `docker compose ps` reports PostgreSQL healthy and Scala running.
|
||||||
2. `/` returns HTTP 200.
|
2. `/` returns HTTP 200.
|
||||||
3. The home navigation loads.
|
3. The home navigation loads.
|
||||||
4. Kartes can query synthetic observations.
|
4. Kartes can query real station observations (fed by the open-data ingestion job).
|
||||||
5. Each map resolution renders and downloads.
|
5. Each map resolution renders and downloads.
|
||||||
6. Faktiskā automatically loads the latest fixed-station temperatures, allows overrides, assigns normalized image symbols, supports exceptions, and downloads a 3840×1440 PNG.
|
6. Faktiskā automatically loads the latest fixed-station temperatures, allows overrides, assigns normalized image symbols, supports exceptions, and downloads a 3840×1440 PNG.
|
||||||
7. Faktiskā symbols remain automatically attached to their corresponding temperature badges when several different image assets are tested.
|
7. Faktiskā symbols remain automatically attached to their corresponding temperature badges when several different image assets are tested.
|
||||||
8. Ūdens accepts all six manual ranges and exports its independently calibrated 1920×1080 and 3840×1440 templates with optically centered values.
|
8. Ūdens auto-populates all six ranges from real water-temperature data, accepts manual correction and reset, and exports its independently calibrated 1920×1080 and 3840×1440 templates with optically centered values.
|
||||||
9. Browser developer tools show no new runtime errors.
|
9. Browser developer tools show no new runtime errors.
|
||||||
|
|
||||||
For frontend dependency maintenance, validate the committed lockfile from a clean install rather than relying on an already-mutated `node_modules` tree:
|
For frontend dependency maintenance, validate the committed lockfile from a clean install rather than relying on an already-mutated `node_modules` tree:
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Completed Faktiskā checkpoint:
|
|||||||
- automatic badge-relative image placement using consistent 256×256 asset geometry;
|
- automatic badge-relative image placement using consistent 256×256 asset geometry;
|
||||||
- guarded 3840×1440 export using the fixed wind production artwork.
|
- guarded 3840×1440 export using the fixed wind production artwork.
|
||||||
|
|
||||||
Valmiera is included in the development seed so all 13 fixed positions can be exercised. Confirmed Monda Regular/Bold files are now bundled and used. The export dimensions are locked, but final pixel-level placement must still be compared against the production masters after the font change.
|
Confirmed Monda Regular/Bold files are now bundled and used. The export dimensions are locked, but final pixel-level placement must still be compared against the production masters after the font change. As of 2026-08-23 the 12 other fixed positions load real station data; Valmiera has no matching real open-data station yet, so it currently still shows the last synthetic row generated before synthetic data generation was stopped (increasingly stale, since nothing refreshes it). Once the old synthetic rows are wiped from `weather` (a still-pending step — see `docs/UPDATE_ROADMAP.md` Phase 7), Valmiera will show no data until a real source is found.
|
||||||
|
|
||||||
## Ūdens
|
## Ūdens
|
||||||
|
|
||||||
@@ -92,13 +92,13 @@ Purpose: prepare the fixed water-temperature newsroom map as a separate producti
|
|||||||
Authoritative references:
|
Authoritative references:
|
||||||
|
|
||||||
- `UDENS_TEMPERATURA.png` defines the finished on-air composition;
|
- `UDENS_TEMPERATURA.png` defines the finished on-air composition;
|
||||||
- `UDENS_TEMP_NOSAUKUMI.png` defines the operator-facing names of the manually entered water areas/fields.
|
- `UDENS_TEMP_NOSAUKUMI.png` defines the operator-facing names of the water areas/fields.
|
||||||
|
|
||||||
Required behavior:
|
Required behavior:
|
||||||
|
|
||||||
1. Open the dedicated **Ūdens** workspace.
|
1. Open the dedicated **Ūdens** workspace.
|
||||||
2. Display the fixed set of Latvian-named water-temperature fields.
|
2. The six Latvian-named water-temperature fields auto-populate on load with the real current min/max for each zone (as of 2026-08-23), fetched from LVĢMC's open hydrological data — no manual entry needed for a normal, working day.
|
||||||
3. Enter or correct every water temperature manually.
|
3. Any field can still be corrected manually if needed; editing a zone marks it "Manuāli" and an "Atiestatīt" button restores the fetched value. An "Atjaunot datus" action re-fetches all six.
|
||||||
4. Place values automatically at their locked production positions.
|
4. Place values automatically at their locked production positions.
|
||||||
5. Preview and download either a 1920×1080 or 3840×1440 PNG.
|
5. Preview and download either a 1920×1080 or 3840×1440 PNG.
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ The 1920×1080 and 3840×1440 products are independent authoritative canvases. N
|
|||||||
|
|
||||||
The renderer uses canvas `TextMetrics` visible-glyph bounds (`actualBoundingBoxLeft`, `actualBoundingBoxRight`, `actualBoundingBoxAscent`, and `actualBoundingBoxDescent`) to optically center Monda text inside each rectangle. The browser preview scales the complete canvas only; downloaded PNGs retain their native dimensions.
|
The renderer uses canvas `TextMetrics` visible-glyph bounds (`actualBoundingBoxLeft`, `actualBoundingBoxRight`, `actualBoundingBoxAscent`, and `actualBoundingBoxDescent`) to optically center Monda text inside each rectangle. The browser preview scales the complete canvas only; downloaded PNGs retain their native dimensions.
|
||||||
|
|
||||||
Implementation status: both native exports are implemented and visually validated against the supplied production templates. Later newsroom feedback can still tune the per-template rectangles without changing the manual-entry workflow.
|
Implementation status: both native exports are implemented and visually validated against the supplied production templates. Later newsroom feedback can still tune the per-template rectangles without changing the auto-load/manual-override workflow.
|
||||||
|
|
||||||
## Brīdinājumi
|
## Brīdinājumi
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ This directory contains the working documentation for the WeatherTool modernizat
|
|||||||
|
|
||||||
- Windows is restricted to source editing, review, and Git operations. Rocky is the sole compile, build, development-runtime, and test environment. The Ubuntu VPS is a deployment target only.
|
- Windows is restricted to source editing, review, and Git operations. Rocky is the sole compile, build, development-runtime, and test environment. The Ubuntu VPS is a deployment target only.
|
||||||
- A production-like staging copy runs through Docker Compose on Rocky Linux at `http://192.168.1.101:9190`.
|
- A production-like staging copy runs through Docker Compose on Rocky Linux at `http://192.168.1.101:9190`.
|
||||||
- Staging uses deterministic synthetic observations for the repository station set plus Valmiera, required by Faktiskā.
|
- Staging ingests real LVĢMC station and water-temperature observations from the free `data.gov.lv` open-data feeds; synthetic data generation was removed once real ingestion was verified. The private LVGMC FTP feed and DMI HARMONIE forecast feed still exist in code but stay gated behind `ENABLE_LEGACY_PROVIDER_JOBS` (default off) pending real credentials.
|
||||||
- Scheduled external-provider jobs are disabled in development and staging.
|
- The safe scheduled jobs (open-data station ingestion, GRIB cleanup) run in staging; the legacy FTP/HARMONIE jobs stay off by default so placeholder credentials can't crash-loop the app.
|
||||||
- PostgreSQL is private to the project Compose network; only the Scala application publishes a host port.
|
- PostgreSQL is private to the project Compose network; only the Scala application publishes a host port.
|
||||||
- The operator-facing workspaces now use the Latvian workflow names **Stacijas**, **Kartes**, **Faktiskā**, **Ūdens**, **Brīdinājumi**, **Apskats**, **Arhīvs**, **Harmonie**, and **LVĢMC**. Kartes retains custom analytical map outputs, while Faktiskā is a fixed 13-position, latest-temperature newsroom workflow with a locked 3840×1440 export.
|
- The operator-facing workspaces now use the Latvian workflow names **Stacijas**, **Kartes**, **Faktiskā**, **Ūdens**, **Brīdinājumi**, **Apskats**, **Arhīvs**, **Harmonie**, and **LVĢMC**. Kartes retains custom analytical map outputs, while Faktiskā is a fixed 13-position, latest-temperature newsroom workflow with a locked 3840×1440 export.
|
||||||
- Faktiskā symbol placement is automatic after manual image selection and is anchored to each rendered temperature badge.
|
- Faktiskā symbol placement is automatic after manual image selection and is anchored to each rendered temperature badge.
|
||||||
|
|||||||
Reference in New Issue
Block a user