WeatherTool project documentation
This directory contains the working documentation for the WeatherTool modernization effort. The repository-root README.md is preserved as the original project overview; these documents describe the reviewed code, current staging environment, and changes being developed.
Current status
- 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. - Both Rocky and the VPS currently run on the free
data.gov.lvopen-data feed only. Real private FTP credentials (ftp.meteo.lv) were obtained 2026-08-23 and the code path is proven working (manual tests succeeded repeatedly, including once from Rocky as recently as 2026-08-24 morning), but enabling the scheduled fetch has failed unpredictably on both machines at different times, for reasons not yet understood — see the roadmap Phase 7 for the full timeline.ENABLE_LVGMC_FTP_JOBSstaysfalseeverywhere until the LVGMC contact can explain the account's actual connection/rate policy. DMI HARMONIE's credentials turned out not to be needed at all (DMI dropped its API key requirement — confirmed live, see the roadmap changelog) but wiring it up is deferred to a dedicated verification session, since the GRIB-parsing and map-rendering code has real, untested risk (a hardcoded crop/rotation calibration that may not match the current model grid). - A real UTC-vs-local timezone mismatch between the two sources (open-data's timestamps were UTC, FTP's already local, both stored in the same column with no conversion) was found and fixed before enabling both together; both
weathertables were backed up and wiped for a clean, consistently-timestamped restart. - The safe scheduled jobs (open-data station ingestion, GRIB cleanup) always run; the FTP and HARMONIE jobs both stay off — FTP pending the LVGMC answer above, HARMONIE pending its own implementation/verification work.
- 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.
- Faktiskā symbol placement is automatic after manual image selection and is anchored to each rendered temperature badge.
- Ūdens auto-populates its six ranges on load with real per-zone water-temperature min/max (65 LVĢMC stations classified into the 6 named zones), with manual override and reset still available. Uses separate authoritative 1920×1080 and 3840×1440 production templates; both exports have been visually validated.
- Brīdinājumi renders current LVĢMC warning polygons over a production border overlay with feathered severity fills, plus draggable/resizable per-warning weather-symbol placement. Its lon/lat-to-pixel projection is an affine fit calibrated against the same validated city pixel positions Kartes/Faktiskā already use, replacing an earlier bounding-box calibration that drifted up to ~200px on the 3840 canvas.
- Confirmed local Monda Regular/Bold files provide interface and generated-graphic typography; weather symbols use normalized transparent image assets.
- Release
b0b58d2is deployed as immutable imageweathertool:b0b58d2f1e0ed47ca13795b64595386ec2f0e0c7; release3eddf95remains the immediate application rollback. On top of the earlier frontend design pass and the timezone/upsert/scheduler-split fixes, this release replaces the hardcoded per-route static-file list with a general SPA fallback — a real, user-reported bug where refreshing/faktiskaor/udens-temperatura404ed instead of loading the app (those two routes were never added to the old list). A missing/assetsfile still 404s properly rather than silently serving HTML. - An independent fresh-eyes security review (requested against the local Rocky version only) found a live-verified CRITICAL path-traversal vulnerability plus several HIGH/MEDIUM findings — see the roadmap changelog for
6b9c7cf/8c45d8dfor the full list. All are fixed, compiled, live-verified on Rocky, and deployed to the VPS as release0be325f(imageweathertool:0be325fbbbf92b03bc8d574dc6f7b9449ef310ea); releaseb0b58d2remains the immediate application rollback. Rocky'sPOSTGRES_PASSWORDwas rotated afterward since the old value had been exposed into the review's own output via/proc/self/environ.LVGMC_PASSWORDrotation is not yet done — that needs the user's own action via the LVGMC contact. A follow-up independent review then caught that the FTP auth-bypass fix was incomplete (a sibling route,/api/show/lvgmc-forecast, had the same live-FTP-trigger issue but had only gotten the traversal fix); fixed and deployed as9bab93d. That same review flagged several open architectural/testability findings (theparMapNscheduler crash-loop pattern, per-requestSystem.gc(), an unenforced field-routing invariant, no JDBC connection pooling, and several files undersrc/main/scalathat look like tests but aren't) — not yet acted on, tracked for a future session. - Gitea Actions CI is live: a repository-scoped runner on Rocky (isolated behind its own Docker-in-Docker daemon, same pattern as HOP's Forgejo runner) runs
sbt testplus the frontend typecheck/build/audit routine on every push/PR tocodex/staging-baseline. See Continuous integration. CI-only for now — it does not deploy anywhere or touch any real credential. - FTP (
ENABLE_LVGMC_FTP_JOBS) is currentlyfalseon both Rocky and the VPS — re-testing the morning after enabling it turned up a second, unexplained failure (Rocky alone, VPS confirmed off, ~4 minutes after a successful manual test) that doesn't fit the original two-machine-collision theory. Decided to stop self-testing via trial and error and wait for the user to ask the LVGMC contact directly about theltvaccount's connection/rate policy, rather than risk repeatedly tripping an unknown limit. See the roadmap Phase 7 for the full diagnosis timeline. - The isolated VPS UAT stack is running and healthy: WeatherTool is bound to
127.0.0.1:8002, Authelia to127.0.0.1:9091, and PostgreSQL has no host port. Public access is routed through Cloudflare, Nginx, and Authelia. - Cloudflare delegation is active, strict origin TLS covers only
laikapstak.liandauth.laikapstak.li, and the public Nginx/Authelia login flow is operational without changing the existing HOP site. - The VPS
weathertable was wiped twice on 2026-08-23: first to remove the original 14-day synthetic dataset (backed up to/srv/weathertool/backups/pre-real-data-release/), then again after the UTC/local timezone fix (backed up to/srv/weathertool/backups/pre-timezone-fix-wipe/) so the two real sources it now holds — open-data (minutes 15/45) and FTP (minutes 11/13/23/30) — are consistently timestamped from a clean start. - Approved 1920×1080 and 3840×1440 PNG production bases are now the rendering source for Faktiskā and Ūdens temperatūra; code draws only the changing values, selected weather symbols, and wind data over those fixed newsroom graphics.
- Browser branding assets and Latvian Open Graph/Twitter metadata are included for favicon, Apple home-screen icon, and link-preview support. Public crawler access still depends on the Nginx/Authelia policy used for the metadata and preview image.
- Browser and API verification is complete for the deployed
3eddf95release: exact release image smoke-tested on Rocky before transfer (bundle hash and correct-local-time API responses matched the known-good local build), checksum verified on both ends, container health/loopback/public HTTPS confirmed. - Every FTP failure so far has cascaded through
parMapNinto the app's top-level error handler, crash-looping the entire app in-process (DB, HTTP server, schedulers all torn down and rebuilt every ~5s) rather than just failing the one scheduled task — caught twice by watching logs after enabling the flag rather than assuming it was safe, reverted both times within minutes. - Frontend dependency maintenance is complete: Solid runtime and Vite tooling were updated, obsolete packages were removed, TypeScript checking was added, and a clean Rocky
npm ci, typecheck, production build, full audit, and production-only audit all pass with zero known vulnerabilities. - This is not yet approved or hardened for workplace production.
Documents
- Architecture and data flow — components, data sources, data flow, and repository layout.
- Development and staging — Windows source/Git workflow, Rocky development and verification, VPS deployment, synthetic data, and rollback.
- Product workflows — the intended purpose and current status of each visible workspace.
- Update roadmap — phased technical, security, dependency, testing, and UI work.
- Continuous integration — Gitea Actions topology, isolation boundary, and the current CI workflow.
- Third-party notices — licenses and attribution for adapted interface components.
- Temporary VPS staging plan — isolation, authentication, prepared deployment bundle, release, backup, verification, and rollback model for external user testing.
Documentation rules
- Do not put passwords, API keys, workplace URLs, or production data in Git.
- Document the behavior that exists separately from behavior that is proposed.
- Update these documents in the same commit when a change alters deployment, data flow, or a user workflow.
- Keep synthetic/development instructions clearly distinguished from workplace production procedures.
- Preserve established Latvian names in operator-facing workspaces and production files even when development notes are written in English.