Commit Graph
19 Commits
Author SHA1 Message Date
grabowski 7befc82ff5 feat: database stats on the dashboard via GET /api/stats
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 23s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 14s
Documentation / Validate Documentation (push) Failing after 8s
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Build Sphinx Documentation (push) Successful in 17s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
Documentation / Documentation Summary (push) Successful in 3s
New SQLAdapter.get_database_stats() aggregates totals, station count,
date range, and hourly-slot coverage in one query per dialect. The
endpoint follows the existing 503-guard/to_thread/TTL-cache pattern;
the dashboard gains a five-tile stats strip on the existing refresh
cadence. Coverage denominator is hour-truncated so off-hour endpoints
cannot push it past 100%; MySQL slot expression avoids % characters
that would break under pyformat bind interpolation.
2026-08-10 23:27:36 +07:00
grabowski 410faeddd5 fix: protect admin API endpoints; stop rejecting flood-peak measurements
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 25s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 12s
Documentation / Validate Documentation (push) Failing after 9s
Documentation / Generate API Documentation (push) Successful in 10s
Documentation / Build Sphinx Documentation (push) Successful in 16s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 0s
Documentation / Documentation Summary (push) Successful in 2s
Security: POST/PUT/DELETE /stations, POST /scrape/trigger and GET
/config now require an X-API-Key header matching ADMIN_API_KEY.
Secure by default - with no key configured those endpoints return 503
instead of being open. Comparison via secrets.compare_digest. Dashboard
and read endpoints stay public.

Data: the validator rejected any measurement whose discharge_percent
exceeded 200 - which silently deleted the Oct 2024 record-flood peaks
(the river genuinely ran at 201-226% of channel capacity). The cap is
now 500%, and an out-of-range percent nulls that auxiliary field
instead of discarding the whole row (water level and discharge are the
data that matter). Surfaced by the user's historical backfill log.
2026-08-10 18:47:08 +07:00
grabowski 9cac9c4d2a style: apply black/isort across the repo; make CI mypy advisory
The push-CI gates (black/isort/mypy) had never actually run before the
branch-trigger fix, and the codebase predates them. Formatting is now
black/isort clean repo-wide. mypy keeps running but non-blocking: 86
pre-existing errors are a separate cleanup, not a gate to hold hostage.
2026-08-10 15:57:00 +07:00
grabowski 4358d52d55 feat: ML flood-event forecasting from 8 years of gauge history
Security & Dependency Updates / Dependency Security Scan (push) Successful in 1m8s
Security & Dependency Updates / License Compliance (push) Successful in 25s
Security & Dependency Updates / Check for Dependency Updates (push) Successful in 20s
Security & Dependency Updates / Code Quality Metrics (push) Successful in 17s
Security & Dependency Updates / Security Summary (push) Successful in 9s
Add src/ml/ package predicting, per station and per 6/12/24 h horizon,
the probability of exceeding warning (3.0 m) and danger (4.5 m) levels
plus expected peak level, trained on the 592k-row PostgreSQL history:

- features.py: hourly grid with coverage gating and no future leakage;
  upstream stations enter at empirically measured travel-time lags
  (P.20 +17h ... P.103 +1h vs P.1); hour-of-day deliberately excluded
  (it encodes the scrape schedule, not hydrology)
- train.py: HistGradientBoosting regression + warn/danger classifier
  heads per station x horizon, >=30-positives gate with calibrated
  sigmoid-on-regression fallback, strict temporal splits, per-event
  lead-time evaluation; guards against sklearn 1.9.0 crash on
  degenerate feature columns
- predict.py: bundle loading with feature-name checks, heuristic
  fallback tier, get_latest_forecasts() for the API; raises when no
  models are trained so the endpoint 503s instead of serving
  persistence output as forecasts
- data.py: Postgres-first loader (FLOOD_ML_DB_URL override), HTTP API
  fallback (flagged: that path backfills synthetic discharge), csv.gz
  cache
- /forecast endpoint (15-min TTL cache) + dashboard flood-risk panel
  (hidden until models exist)
- docs/FLOOD_FORECASTING.md: full system doc with measured deployment
  numbers (~335 MB RSS, CPU negligible, ~6 min full retrain) and
  retraining policy

Validation: out-of-sample backtest of the record 2024 flood season
(train <= Aug 2024) alerted 24-48 h ahead of the Oct 5 peak; 2025-26
test split: P.1 6h PR-AUC 0.974, recall 98.3% at 1% false-alarm rate.

Also: fix P.81 station coordinates (was Ban Pong/Ratchaburi, 493 km
out of basin; now 18.6936 N 99.0819 E per RID station page), pin
scikit-learn==1.9.0 and numpy<2, gitignore model artifacts (~100 MB,
train on the server via scripts/train_flood_model.py).
2026-08-10 12:49:47 +07:00
grabowski 49a3de0087 fix: restore station telemetry and make river flow visualization data-driven
Station selection showed no history since 21ca844: Chart.js v4 datasets
had parsing:false with plain number arrays, drawing empty axes. Remove
the flag so the chart parses values again.

Backend hardening for the same flow:
- /measurements/history/{code} no longer 503s on non-Postgres configs;
  it falls back to the configured adapter (reversed to ascending order)
- DB_TYPE defaults to postgresql when POSTGRES_CONNECTION_STRING is set
  and DB_TYPE is unset, so the .env psql wins over the sqlite default
- zero readings (0.0) are no longer coerced to None, which would fail
  MeasurementResponse validation and 500 /measurements/latest

Map visualization:
- river segments are now colored, widened and dash-speed-animated by
  the discharge at the nearest gauge (same scale as the marker legend)
- fix z-order bug that drew the animated flow line behind its casing
- legend entries for river lines, reduced-motion fallback

River geometry: rebuild ping-river-network.geojson from Overpass
(110 -> 202 features), restoring missing Ping mainstem reaches through
the Bhumibol reservoir and the Tak-Kamphaeng Phet braided section
(unnamed waterway=river ways in OSM), with short synthetic connectors
(connector: true) bridging remaining sub-8 km holes.
2026-08-10 10:30:05 +07:00
grabowski 9f26b32c86 fix: bump history limits to 100k so all-time shows full dataset 2026-08-09 17:41:14 +07:00
grabowski bbbf548d66 fix: align web API limit cap with 10k and clean up postgres_history imports 2026-08-09 17:36:58 +07:00
grabowski 2fe1dcf4da feat: add 5-minute TTL cache for PostgreSQL history queries 2026-08-09 17:15:47 +07:00
grabowski 6f2a8a0d8f feat: add all-time history option and increase limit to 10k 2026-08-09 17:11:26 +07:00
grabowski ae5d0a13d7 [verified] feat: add live river dashboard
Add mapped river and ThaiWater sensor layers, PostgreSQL history charts, API endpoints, and dashboard tests.
2026-08-09 16:59:25 +07:00
grabowski e5936d5717 Move dashboard HTML out of web_api into a static file
Extract the inline root() dashboard markup into src/static/dashboard.html,
loaded once at import. Keeps HTML out of the Python module (web_api 616 -> 576
lines) with a defensive fallback if the file is missing.

Full <500 compliance for web_api still needs the endpoints split into
APIRouter modules; tracked as remaining #4 work.
2026-07-22 14:28:34 +07:00
grabowski ad7f7b8c76 Extract API Pydantic models into schemas.py
Move the seven request/response models out of web_api.py into a dedicated
src/schemas.py (separation of concerns; first step of the file-size cleanup).
web_api.py imports them back, so behaviour is unchanged.

Note: web_api.py is still over the 500-line guideline; the remaining bulk is
the inline HTML dashboard in root(), to be extracted in a follow-up.
2026-07-22 14:07:31 +07:00
grabowski 4bc3d82773 Persist station CRUD across restarts via JSON config
Station CRUD via the API previously mutated the scraper's in-memory
station_mapping only, so changes were lost on restart (and the systemd
service auto-restarts).

- Extract the 130-line hardcoded station_mapping into bundled defaults at
  src/data/stations.json; the scraper loads from a runtime-writable config
  file (STATION_CONFIG_PATH, default stations.json) and falls back to the
  bundled defaults to seed it.
- Add scraper.save_stations() with an atomic temp-file + os.replace write.
- create/update/delete station endpoints now persist and roll back the
  in-memory change if the write fails; re-raise HTTPException so persistence
  errors surface as real 500s instead of being swallowed.
- Backend-agnostic (works for the VictoriaMetrics deployment, which has no
  relational stations table). Runtime stations.json is gitignored.

Also clears pre-existing flake8 debt in water_scraper_v3.py (unused imports,
long lines, duplicate logging import) and dedupes the User-Agent to
Config.USER_AGENT.
2026-07-22 12:51:29 +07:00
grabowski 6e78225d00 Fix optional-discharge crashes and dedupe measurement mapping
- MeasurementResponse.discharge is now Optional[float]; measurements with a
  null discharge no longer raise a Pydantic ValidationError (HTTP 500) on the
  /measurements/latest and /measurements/station endpoints.
- InfluxDB save_measurements guards float(discharge) against None instead of
  crashing with TypeError.
- Extract the duplicated measurement->response mapping into a single
  _to_measurement_response helper used by both measurement endpoints.
2026-07-22 12:34:46 +07:00
grabowski f4c63cabef Fix Matrix message formatting and harden security
Matrix alerts:
- Send HTML formatted_body (org.matrix.custom.html) so **bold** and URLs
  render instead of showing literal Markdown; add plain-text body fallback.
  Add dependency-free markdown_to_matrix_html/strip_markdown helpers with
  HTML escaping of station/message data.

Security:
- InfluxDB: bind untrusted station_codes as query params and cast limit to
  int (was f-string interpolation / injection risk).
- VictoriaMetrics: escape Prometheus label values and coerce metric values
  to float, preventing exposition-format injection and None crashes.
- web_api: run blocking scrape cycle via run_in_executor so it no longer
  freezes the event loop; make CORS origins configurable and only allow
  credentials with explicit origins ("*" + credentials is invalid/unsafe).
- config: remove hardcoded root/postgres password fallbacks (raise instead)
  and stop defaulting VM_HOST to a real infrastructure hostname.

Also remove unused imports and wrap long lines to satisfy flake8.
2026-07-22 12:07:05 +07:00
grabowski 17a716fcd0 Version bump: 3.1.2 3.1.3 (Force new build)
Release - Northern Thailand Ping River Monitor / Create Release (push) Successful in 7s
Security & Dependency Updates / Dependency Security Scan (push) Successful in 35s
Security & Dependency Updates / Check for Dependency Updates (push) Has been cancelled
Security & Dependency Updates / Code Quality Metrics (push) Has been cancelled
Security & Dependency Updates / Security Summary (push) Has been cancelled
Security & Dependency Updates / License Compliance (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.11) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.12) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.9) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Build Release Images (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Security Scan (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Deploy Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Validate Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Notify Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.10) (push) Has been cancelled
Version Updates:
- Core application: src/__init__.py, src/main.py, src/web_api.py
- Package configuration: setup.py
- Documentation: README.md, docs/GITEA_WORKFLOWS.md
- Workflows: .gitea/workflows/docs.yml, .gitea/workflows/release.yml
- Scripts: generate_badges.py, init_git scripts
- Tests: test_integration.py
- Deployment docs: GITEA_SETUP_SUMMARY.md, DEPLOYMENT_CHECKLIST.md

 Purpose:
- Force new build process after workflow fixes
- Test updated security.yml without YAML errors
- Verify setup.py robustness improvements
- Trigger clean CI/CD pipeline execution

 All version references synchronized at v3.1.3
 Ready for new build and deployment testing
2025-08-12 17:47:26 +07:00
grabowski 40aef686af Fix: Replace GitHub checkout with Gitea checkout + Version bump
Release - Northern Thailand Ping River Monitor / Create Release (push) Failing after 1s
Release - Northern Thailand Ping River Monitor / Build Release Images (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Test Release Build (3.10) (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Test Release Build (3.11) (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Test Release Build (3.12) (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Test Release Build (3.9) (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Security Scan (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Deploy Release (push) Has been skipped
Release - Northern Thailand Ping River Monitor / Validate Release (push) Has been skipped
Security & Dependency Updates / Dependency Security Scan (push) Failing after 1s
Security & Dependency Updates / Docker Security Scan (push) Failing after 1s
Security & Dependency Updates / License Compliance (push) Failing after 1s
Security & Dependency Updates / Check for Dependency Updates (push) Failing after 1s
Security & Dependency Updates / Code Quality Metrics (push) Failing after 1s
Release - Northern Thailand Ping River Monitor / Notify Release (push) Successful in 1s
Security & Dependency Updates / Security Summary (push) Failing after 3s
Checkout Action Migration:
- Replace all 'actions/checkout@v4' with 'https://gitea.com/actions/checkout'
- Fixes 'Bad credentials' errors when workflows try to access GitHub API
- Native Gitea checkout action eliminates authentication issues
- Applied across all 4 workflow files (CI, Security, Release, Docs)

 Version Increment: 3.1.1  3.1.2
- Core application version updates
- Web API version synchronization
- Documentation version alignment
- Badge and release example updates

 Problem Solved:
- Workflows no longer attempt GitHub API calls
- Gitea-native checkout action handles repository access properly
- Eliminates 'Retrieving the default branch name' failures
- Cleaner workflow execution without authentication errors

 Files Updated:
- 4 workflow files: checkout action replacement
- 13 files: version number updates
- Consistent v3.1.2 across all components

 Benefits:
- Workflows will now run successfully in Gitea
- No more GitHub API authentication failures
- Native Gitea action compatibility
- Ready for successful CI/CD pipeline execution
2025-08-12 17:06:20 +07:00
grabowski 19e182c53b Version bump: 3.1.0 3.1.1
Release - Northern Thailand Ping River Monitor / Create Release (push) Successful in 6s
Security & Dependency Updates / Dependency Security Scan (push) Successful in 19s
Security & Dependency Updates / Docker Security Scan (push) Successful in 1m12s
Security & Dependency Updates / License Compliance (push) Successful in 11s
Security & Dependency Updates / Check for Dependency Updates (push) Successful in 14s
Security & Dependency Updates / Code Quality Metrics (push) Successful in 9s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.10) (push) Failing after 1m17s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.11) (push) Failing after 23s
Release - Northern Thailand Ping River Monitor / Test Release Build (3.9) (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Build Release Images (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Security Scan (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Deploy Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Validate Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Notify Release (push) Has been cancelled
Release - Northern Thailand Ping River Monitor / Test Release Build (3.12) (push) Has been cancelled
Security & Dependency Updates / Security Summary (push) Has been cancelled
Version Updates:
- Core application version (src/__init__.py)
- Web API version (src/web_api.py)
- Main application logging (src/main.py)
- Package setup version (setup.py)
- Documentation generation (docs workflow)
- Release workflow example version
- Badge generation script
- Integration test version display
- README.md badge version
- Setup and deployment documentation
- Git initialization scripts

 Patch Release (3.1.1):
- Workflow token migration fixes (GITHUB_TOKEN  GH_TOKEN)
- Pip installation warning elimination
- Improved workflow reliability and logging
- Better Gitea compatibility
- Enhanced error handling and validation

 Files Updated:
- 13 files with version references updated
- Consistent versioning across all components
- Ready for release tagging and deployment
2025-08-12 16:52:39 +07:00
grabowski af62cfef0b Initial commit: Northern Thailand Ping River Monitor v3.1.0
Security & Dependency Updates / Dependency Security Scan (push) Successful in 29s
Security & Dependency Updates / Docker Security Scan (push) Failing after 53s
Security & Dependency Updates / License Compliance (push) Successful in 13s
Security & Dependency Updates / Check for Dependency Updates (push) Successful in 19s
Security & Dependency Updates / Code Quality Metrics (push) Successful in 11s
Security & Dependency Updates / Security Summary (push) Successful in 7s
Features:
- Real-time water level monitoring for Ping River Basin (16 stations)
- Coverage from Chiang Dao to Nakhon Sawan in Northern Thailand
- FastAPI web interface with interactive dashboard and station management
- Multi-database support (SQLite, MySQL, PostgreSQL, InfluxDB, VictoriaMetrics)
- Comprehensive monitoring with health checks and metrics collection
- Docker deployment with Grafana integration
- Production-ready architecture with enterprise-grade observability

 CI/CD & Automation:
- Complete Gitea Actions workflows for CI/CD, security, and releases
- Multi-Python version testing (3.9-3.12)
- Multi-architecture Docker builds (amd64, arm64)
- Daily security scanning and dependency monitoring
- Automated documentation generation
- Performance testing and validation

 Production Ready:
- Type safety with Pydantic models and comprehensive type hints
- Data validation layer with range checking and error handling
- Rate limiting and request tracking for API protection
- Enhanced logging with rotation, colors, and performance metrics
- Station management API for dynamic CRUD operations
- Comprehensive documentation and deployment guides

 Technical Stack:
- Python 3.9+ with FastAPI and Pydantic
- Multi-database architecture with adapter pattern
- Docker containerization with multi-stage builds
- Grafana dashboards for visualization
- Gitea Actions for CI/CD automation
- Enterprise monitoring and alerting

 Ready for deployment to B4L infrastructure!
2025-08-12 15:40:24 +07:00