Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
86abe08
ML Analytics: validation metrics, feature importance, backtest, tab s…
Apr 24, 2026
c86048d
handover Day 1: alert routes, DB health check, env vars, pan-African …
Apr 24, 2026
c19c8a1
handover Day 2: deterministic reports — remove every random.* from re…
Apr 24, 2026
d839130
handover Day 3: reports sections.* + alerts unified source + real POS…
Apr 24, 2026
ad0734b
handover Day 4: scheduler leader election + gate create_all() on dev env
Apr 24, 2026
86a86c4
handover Day 5-6: alerts ack workflow + severity sort + reports water…
Apr 24, 2026
9b0f27c
handover Week 3: audit_log → DB, filled operator pack, env.prod.example
Apr 24, 2026
e1b44f1
handover: finish deterministic coverage, acceptance tests, readiness CLI
Apr 24, 2026
32b339d
handover: finish post-v1 roadmap — alerts DB, model compare, fairness
Apr 24, 2026
f444381
handover: drop the stale 'skeleton' note at the top of the operator pack
Apr 24, 2026
a04799c
handover: security + ML honesty pass per audit
Apr 25, 2026
151e10d
handover: drop the stale commit hash from the operator pack header
Apr 25, 2026
789b517
env: 12-month MODIS LST animation (Ethiopia → /environmental)
Apr 25, 2026
40ba36a
env: country-border clip + Monthly/Yearly toggle on LST animation
Apr 25, 2026
5d453ed
env: LST animation default 0.25° + Resolution dropdown
Apr 25, 2026
db17c91
env: water-balance dashboard, Manager's Read, reservoir what-if, Hydr…
Apr 27, 2026
c10c1ed
transboundary: Cross-Border Flux tab + Soman et al. 2026 SWOT QC chain
May 11, 2026
bbae178
cache: refresh GEE CHIRPS grid + SWOT Hydrocron v2 snapshots
May 12, 2026
e1d748d
reports: status-doc generator + April 2026 progress and status reports
May 12, 2026
a4a647b
ml: separate ground-truth vs pseudo-label rows in WQ training (roadma…
May 15, 2026
b9456c1
ml: baseline benchmarks + beats_empirical promotion gate (roadmap §7)
May 15, 2026
63c5b64
nisar: staleness gate so cached soil-moisture re-fetches live data
May 15, 2026
1e5b6b3
soil-moisture: data-driven NISAR provenance banner + fix cold-load ti…
May 16, 2026
f4f50b0
nisar: real per-station soil-moisture time series via cloud byte-range
May 16, 2026
ee2ebb0
recent-water: surface Landsat-8/9, Dynamic World, SAR layers in map UI
May 27, 2026
6c3ee90
admin: /admin/ml/baselines panel for roadmap §7 promotion gate
May 28, 2026
2ae2e8c
discharge: replace stale TODOs with cross-references to real SWOT path
May 28, 2026
4a9064b
demo_restart: source .env before launching uvicorn
May 28, 2026
76537b5
ml: split-conformal prediction intervals for WQ models (roadmap §3)
May 28, 2026
175a06e
ml: PSI drift monitor + conformal/drift surfaces in admin (§6, §3 pol…
May 28, 2026
6ec45c2
ml: canonical spatiotemporal feature store + WQ backfill ETL (roadmap…
May 28, 2026
65bfaae
ml: route WQ training through the feature store; admin stats endpoint
May 28, 2026
11c3a6b
backend audit (roadmap §3): tests, prompt caching, RBAC, dead-code cl…
May 29, 2026
48b5362
swot: test the KaRIn wide-swath lake surface-area pipeline (roadmap §9)
May 29, 2026
eee310d
nisar: label Blue Nile pilot 'Real data (200 m)' when live (roadmap §8)
May 29, 2026
7a4d1dd
provenance: DataProvenance + citations on Hydrology/Environmental/ML/…
May 29, 2026
0639c94
hooks: extract useWaterBody + migrate WaterBodyDetail to it (roadmap §7)
May 29, 2026
976495f
export: reusable ExportMenu (CSV/GeoJSON/PDF), wire the stub hubs (ro…
May 29, 2026
fd78319
story: 90-second guided Blue Nile walkthrough at /story (roadmap §11)
May 29, 2026
681eeac
a11y: enforce WCAG 2.1 AA color-contrast app-wide + remediate (roadma…
May 29, 2026
bb18b95
test: guard Historical WSE chart overlay toggles (roadmap §10)
May 29, 2026
1429206
i18n: extend locales beyond nav + parity guard, wire a hub title (roa…
May 29, 2026
b8ae226
docs: flagship-basin UAT demo runbook (roadmap §1)
May 29, 2026
3e43dda
test: fix WQ label-kind tests shadowed by the feature store
May 29, 2026
ac20174
swot: PLD/SWORD crosswalk separating observed vs modeled coverage
May 29, 2026
4e99cb7
alerts: acknowledgement workflow + per-alert deep-links
May 29, 2026
adb912d
frontend: i18n hub copy + chart tooltips, useApiResource adoption 4→2…
May 29, 2026
b836626
deploy: TLS staging overlay + audit_log auto-migration + CORS hardeni…
May 29, 2026
dd71cad
backend + map: SWOT crosswalk integration, GRACE/PO.DAAC freshness, d…
May 29, 2026
dbbb425
handover: tick §9 readiness lines that the May work just made true
May 29, 2026
e8d45d4
ops: health endpoint HTTP status codes + missing sub-routes + ETL ena…
May 29, 2026
0d8742e
cache: refresh seed data across river altimetry, GEE, NISAR, WQ, SWOT
May 29, 2026
5a5523a
handover: annotate §9 health-endpoint line with the safety fixes
May 29, 2026
42564ea
ops: address May 30 readiness audit — safe defaults, gates, backups, …
May 29, 2026
b9cc6b0
ops: close second readiness-audit pass (#1, #2 conftest, #4 — #8)
May 29, 2026
3c24db2
ml: fairness-by-biome reporting (post-handover roadmap item #6)
May 30, 2026
c86ebdf
deps: bump axios + override ws to clear Dependabot alerts
Jun 2, 2026
15f4984
docs: add Water Hub tool-description doc (parallels trade hub)
Jun 11, 2026
c0c7751
add handover readiness and water stress intelligence
Jun 25, 2026
b6ca017
close June handover issues in readiness app
Jun 26, 2026
a079c9f
update June handover report
Jun 26, 2026
fa8df2a
rename June Water Hub report docx
Jun 26, 2026
4fd199e
remove resolved issues from June report
Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
50 changes: 46 additions & 4 deletions .env.prod.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Production secrets for docker-compose.prod.yml. Copy to .env.prod and fill in.
# NEVER commit .env.prod — it's covered by .gitignore (add there if missing).
# NEVER commit .env.prod — it's covered by .gitignore.

# ── Database ──────────────────────────────────────────────────────────
POSTGRES_USER=water_hub
Expand All @@ -12,18 +12,60 @@ SECRET_KEY=
# Comma-separated origins the backend trusts for CORS
CORS_ORIGINS=https://waterhub.example.com

# Optional third-party credentials
# ── LLM providers (optional — leave blank to disable policy briefs) ───
# Primary: Anthropic Claude
ANTHROPIC_API_KEY=
# Alternative: Google Gemini (free tier available)
GEMINI_API_KEY=

# ── Google Earth Engine (optional but required for fresh satellite data)
GEE_SERVICE_ACCOUNT_EMAIL=
GEE_PROJECT_ID=
GEE_CREDENTIALS_JSON= # absolute path inside the backend container
# Either inline the key JSON here (preferred in Docker — single-line string)
# or leave this blank and mount the file + set GEE_PRIVATE_KEY_FILE.
GEE_CREDENTIALS_JSON=

# ── NASA Earthdata (optional — only for ICESat-2 ATL13 altimetry) ─────
# Register at https://urs.earthdata.nasa.gov/
EARTHDATA_USERNAME=
EARTHDATA_PASSWORD=

# ── DAHITI altimetry validator (optional — paid tier only) ───────────
# Register at https://dahiti.dgfi.tum.de/
DAHITI_API_KEY=

# ── Frontend build args (inlined into the static bundle) ──────────────
# Leave empty to use same-origin requests (nginx proxies /api to backend:8000)
VITE_API_URL=
VITE_USE_DEMO_API=false
VITE_SENTRY_DSN=
VITE_APP_VERSION= # e.g. a git sha
VITE_APP_VERSION= # e.g. a git sha or "handover-un-v1"

# ── Container runtime ─────────────────────────────────────────────────
FRONTEND_PORT=80

# ── Scheduled work (APScheduler ETL) ──────────────────────────────────
# True in production so NISAR refresh, alert scans, and feature-store
# backfill actually run. Set to false for read-only demo hosts.
ETL_ENABLED=true

# ── Recent-water surface layers (optional) ────────────────────────────
# GEE asset paths for the post-2022 surface-water overlays. Each layer
# stays hidden in the UI until its asset path is populated. Bake the
# assets first with backend/app/scripts/build_landsat_recent_asset.py
# and the equivalent scripts for Dynamic World / Sentinel-1 SAR water.
WATERHUB_RECENT_WATER_ASSET=
WATERHUB_SAR_WATER_ASSET=
WATERHUB_LANDSAT_RECENT_ASSET=

# ── Self-registration ────────────────────────────────────────────────
# Default false on a UN-facing deployment — operators add users via the
# admin route. Set to true only for workshop / hackathon flows.
ALLOW_SELF_REGISTRATION=false

# ── TLS overlay (docker-compose.tls.yml) ──────────────────────────────
# Only needed when you bring up the stack with -f docker-compose.tls.yml.
# Caddy will obtain a Let's Encrypt cert for $WATERHUB_DOMAIN automatically.
# ACME_EMAIL is used by Let's Encrypt for expiry warnings and rate-limit identity.
WATERHUB_DOMAIN=waterhub.example.com
ACME_EMAIL=ops@example.com
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
node_modules/
backend/venv/

# Test + working artefacts that must not be in the handover
test-results/
todo
.docx-backups/
# Manual save-as backups created by the docx editor while iterating on
# the monthly report. The canonical files (Monthly_progress_report_*.docx)
# stay tracked; only the timestamped or change-keyed backups are noise.
Monthly_progress_report_*_before_*.docx
Monthly_progress_report_*_open_before_*.docx

# Python
__pycache__/
*.pyc
Expand Down Expand Up @@ -107,6 +117,7 @@ glob

# Allow technical documentation and associated figures
!Water_Hub_Technical_Documentation.tex
!docs/un-handover/*.pdf
!docs/figures/*.pdf
!docs/figures/*.png
!docs/generate_*.py
Binary file added Monthly_progress_report_April_2026.docx
Binary file not shown.
Binary file added Monthly_progress_report_April_2026_02.docx
Binary file not shown.
170 changes: 170 additions & 0 deletions Monthly_progress_report_June_2026.md

Large diffs are not rendered by default.

Binary file added Monthly_progress_report_May_2026.docx
Binary file not shown.
142 changes: 142 additions & 0 deletions Monthly_progress_report_May_2026.md

Large diffs are not rendered by default.

Binary file added Monthly_progress_report_May_2026_open.docx
Binary file not shown.
Binary file added Monthly_progress_report_WaterHub_June_2026.docx
Binary file not shown.
376 changes: 376 additions & 0 deletions Progress/generate_water_hub_tool_description.py

Large diffs are not rendered by default.

Binary file added Progress/water_hub_tool_description.docx
Binary file not shown.
77 changes: 77 additions & 0 deletions Progress/water_hub_tool_description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Water Hub for Africa

*Tool Description and Intended Functionality*

## 1. Tool Overview

Water Hub for Africa is an open-data, satellite-backed water intelligence platform designed to help analysts monitor, compare, and interpret evidence about Africa's surface water, water storage, water quality, soil moisture, hydrological balance, and transboundary river systems. The tool takes heterogeneous public Earth-observation and in-situ datasets that are usually difficult to compare directly (different missions, revisit cycles, spatial resolutions, processing levels, and reference frames), converts them into a consistent analytical structure, and exposes the results through an interactive dashboard, a read-only API, a Python client, command-line workflows, and generated reports.

The project addresses a practical problem: water-resource evidence for Africa is fragmented across many satellite missions, agencies, file formats, time periods, and processing conventions. A single question, such as whether a strategic reservoir is losing storage, whether a lake's water quality is deteriorating, or whether an upstream change is altering transboundary flow, may require data from radar and laser altimetry, optical and synthetic-aperture-radar imagery, gravimetry, precipitation and evapotranspiration models, soil-moisture missions, and national water statistics. Water Hub for Africa provides a common workflow for bringing those sources into one governed analytical environment.

In much of Africa, conventional hydrological monitoring cannot answer these questions on its own. Ground-based gauge networks are sparse and have thinned since their 1970s peak, so many basins, lakes, and reservoirs now have little or no continuous in-situ measurement, and national hydrological services often work with limited observational coverage. Water Hub for Africa is built for that reality: it uses openly available satellite observation to provide consistent, continent-wide monitoring where ground stations are absent, discontinued, or unreported, and to set whatever in-situ data does exist in a wider spatial and temporal context. The tool remains a decision-support and screening environment rather than an official real-time warning service or a regulatory decision engine: every panel discloses whether its number is a direct observation, a cached last-good value, a modelled estimate, or a pre-launch demonstration, so that each signal is read together with its provenance and known limitations.

### Design principles

Several design principles shape the tool. First, every result should remain traceable to its source mission, sensor, vintage, retrieval method, and known caveats. Second, data gaps should be visible rather than hidden; where a satellite has no coverage or the cache is stale, the tool should label the result as data-constrained or modelled instead of fabricating a number. Third, analytics should be reproducible from the local curated cache, so that reports, dashboard pages, and API responses tell the same story and a report regenerated later returns identical numbers. Fourth, uncertainty language should be contained: modelled and synthetic values are flagged as such, and descriptive monitoring panels should not be read as operational warnings.

## 2. Intended Users

The tool is intended for water-resource, environmental, and programme teams that work with African water evidence and need a repeatable way to turn open Earth-observation data into operational insight. Its primary users are not casual visitors looking for a marketing site; they are analysts who need to inspect data coverage, compare basins and countries, track water bodies over time, assess water quality, and prepare defensible briefing material.

Water-resource and basin-authority analysts can use the platform to track reservoir and lake storage, surface-water extent, water levels, and renewable-water availability. The storage and altimetry modules are especially relevant for teams asking whether a strategic reservoir is filling or drawing down, how a lake's area has changed against the historical record, and how upstream conditions propagate downstream.

Transboundary, regional-economic-community, and basin-commission teams can use the tool to monitor shared rivers and lakes, cross-border flux, and the water-balance context of co-riparian states. The dashboard is structured so that a user can focus on a water body, a basin, a country, or all Africa, then move across modules while keeping the same geographic context.

Environmental, public-health, and fisheries analysts can use the water-quality and harmful-algal-bloom modules as a screening surface (chlorophyll-a, turbidity, Secchi depth, total suspended solids, and cyanobacteria proxies) to prioritize which water bodies and periods deserve closer in-situ sampling, not to certify that water is safe or unsafe.

Researchers, donor programmes, and project managers can use the tool to generate consistent evidence packs, policy briefs, and reproducible PDF or Word-style documentation. The platform is useful when an institution needs to explain not only what an indicator says, but also which satellite it came from, how recent the observation is, and what caveats should accompany the interpretation.

### User expectations

- The user should be comfortable interpreting satellite-derived and modelled water indicators.
- The user should expect uneven data coverage across regions, sensors, and time periods (cloud cover, revisit gaps, no-coverage swaths).
- The user should treat modelled and screening signals as prompts for review, not as operational forecasts or conclusions.
- The user should use the disclosed source, sensor, vintage, method, and caveat information when citing outputs.
## 3. Core Functionality

The core functionality of Water Hub for Africa begins with ingestion. The project includes source-specific ingesters for satellite altimetry, optical and SAR imagery, gravimetry, precipitation, evapotranspiration, soil moisture, land-surface temperature, surface-water masks, and national water statistics. Some ingesters fetch live data from Google Earth Engine and mission archives (NASA Earthdata, PO.DAAC, ASF DAAC, DAHITI, Hydroweb), while others load curated local files. In both cases, the pipeline writes the retrieved payload to a disk-backed cache with provenance metadata, so the fetch can be audited and reproduced later, and a staleness gate decides when a cached value must be refreshed.

## 4. Analytical Modules

The platform is organized around 9 modules. Each module answers a specific analytical question while sharing the same curated data layer, provenance discipline, and five-state honesty convention (observed, cached, modelled, synthetic, mixed). The modules are designed to be interpretable rather than opaque: indicators and forecasts should be connected to clear input evidence, and dashboard pages should make caveats and data lineage available to the analyst.

### M1: Surface water and storage monitoring

Module 1 tracks how much water is stored in Africa's lakes and reservoirs and how it is changing. It combines a HydroLAKES-backed water-body catalogue, JRC Global Surface Water extent, multi-mission altimetry water-surface elevation (ICESat-2, SWOT, Sentinel-3, Jason, Envisat, DAHITI), and hypsometric area-volume curves to produce storage time-series. A linear-reservoir what-if view offers an optimistic / central / pessimistic 90-day outlook. Each series flags whether a value is observed or modelled.

### M2: Water quality and harmful algal blooms

Module 2 screens the optical water quality of lakes and reservoirs. It derives chlorophyll-a, turbidity, Secchi depth, total suspended solids, coloured dissolved organic matter (CDOM), and a cyanobacteria bloom proxy from Sentinel-2 and Sentinel-3 and, where available, hyperspectral sensors (EMIT, PRISMA, EnMAP, PACE). The output is a screening surface that prioritizes water bodies and periods for in-situ sampling; training labels are tagged ground-truth, empirical, or pseudo-label so that headline metrics exclude weak labels.

### M3: Soil moisture and agricultural water

Module 3 characterizes near-surface and root-zone soil moisture across the continent. It fuses NISAR L3 soil-moisture estimates where live granules exist, SMAP L3, Sentinel-1 SAR backscatter, and ERA5-Land and FLDAS reanalysis. The Blue Nile pilot switches to a high-resolution "real data" legend the moment a live granule covers the region; elsewhere a modelled preview is clearly labelled.

### M4: Hydrological balance and drought

Module 4 answers whether a basin has enough renewable water. It computes a water budget (precipitation minus evapotranspiration) from CHIRPS and MODIS / TerraClimate, drought indicators (SPI / SPEI) from CHIRPS and GLDAS, and a total-water-storage context from GRACE and GRACE-FO mascons. A rule-based "Manager's Read" turns the numerical state into deterministic plain-language interpretation.

### M5: Transboundary basin monitoring

Module 5 monitors how water moves across borders. It estimates cross-border flux from SWOT discharge (Manning's equation on water-surface elevation, width, and slope) against a curated transboundary-crossing table, aggregates shared-basin stations from DAHITI and Hydroweb, and cross-checks renewable-water rollups against FAO AQUASTAT. Each reach is labelled observed, no-coverage, modelled-cache, or not-yet-mapped.

### M6: Flood detection and alerting

Module 6 turns the monitoring layer into attention signals. A scheduled alert engine scans water levels, surface extent, and quality indicators against configurable thresholds and recurrence rules, raising prioritized alerts with an acknowledgement-and-note workflow and an audit trail. The output is a review queue for analysts, not an authoritative flood warning.

### M7: ML analytics and forecasting

Module 7 provides the machine-learning layer. A canonical feature store feeds trained models whose promotion is gated by a beats-empirical-baseline check; conformal prediction intervals quantify uncertainty, a population-stability drift monitor watches for input shift, and fairness-by-biome reporting checks that performance does not collapse for under-represented water-body types. All ML outputs are flagged modelled by definition.

### M8: Policy brief generation

Module 8 generates briefs from validated module outputs. A deterministic path produces the same numbers for the same inputs, while a grounded large-language-model path (Claude, with prompt caching and an anti-drift contract test) turns the disclosed evidence into a concise memo with citations and caveats. Its value is consistency: the dashboard, the API, and the brief tell the same story.

### M9: Dashboards and APIs

Module 9 is the publication and access layer. It includes the React dashboard, the FastAPI service, and the Python client, plus reproducible report and export generation. It allows human users to explore the platform interactively (by water body, basin, or country) and allows scripts or external systems to consume the same read-only analytical outputs.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Water Hub — Pan-African Satellite Water Monitoring Platform

A full-stack platform for monitoring water resources across **55 African countries** using multi-mission satellite remote sensing. Tracks **543 water bodies** (lakes, reservoirs, rivers, wetlands) with data from 17+ satellite missions including SWOT, Sentinel-3, ICESat-2, GRACE/GRACE-FO, and NISAR.
A full-stack platform for monitoring water resources across **55 African countries** using multi-mission satellite remote sensing. Tracks **2,865 curated water bodies** (lakes, reservoirs, rivers, wetlands) with data from 17+ satellite missions including SWOT, Sentinel-3, ICESat-2, GRACE/GRACE-FO, and NISAR.

## Features

- **543 Water Bodies** — Lakes, reservoirs, rivers, wetlands, and crater lakes across 6 African regions with real coordinates and polygons
- **2,865 Curated Water Bodies** — Lakes, reservoirs, rivers, wetlands, and crater lakes across 6 African regions with real coordinates and polygons
- **Recent Water Layers (2022→now)** — Three extension overlays continuing JRC's 1984–2021 archive: Landsat-8/9 30 m (JRC-compatible for trend analysis), Dynamic World 10 m (high-resolution snapshot, catches sub-km² ponds), Sentinel-1 SAR (cloud-immune for Congo Basin / monsoon seasons). Dormant-by-default — activated by setting `WATERHUB_*_ASSET` env vars to baked GEE asset IDs.
- **55 Country Profiles** — Unified country-level water dashboards with lakes, rivers, soil moisture, water quality, storage, and GRACE TWS
- **Multi-Mission Altimetry** — 17 satellite missions (SWOT, Sentinel-3, ICESat-2, Jason, etc.) with combined water surface elevation time series
- **NISAR Soil Moisture** — L-band SAR soil moisture coverage for 54 African countries with heatmap overlays
Expand Down Expand Up @@ -91,7 +92,7 @@ The backend provides **444 endpoints** across 20+ router modules:
| Module | Prefix | Description |
|--------|--------|-------------|
| Country Profiles | `/api/country` | Unified water profiles for 55 African countries |
| Water Bodies | `/api/demo/water-bodies` | 543 water bodies with metadata and time series |
| Water Bodies | `/api/demo/water-bodies` | Curated African water-body registry with metadata and time series |
| Altimetry | `/api/altimetry` | Multi-mission satellite altimetry, DAHITI validation |
| Transboundary | `/api/transboundary` | 8 basins, discharge, water budgets, shared waters |
| SWOT Lakes | `/api/swot` | SWOT satellite lake catalog, WSE, area, storage |
Expand Down
Binary file added Water_Hub_Status_Report.docx
Binary file not shown.
Binary file added Water_Hub_Status_Report_April_2026_01.docx
Binary file not shown.
66 changes: 66 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Python build / cache
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
.pytest_cache/
.ruff_cache/
.coverage
.coverage.*
htmlcov/

# Environment + secrets — never bake into the image
.env
.env.*
!.env.example
*.pem
*.key
credentials/

# Virtualenvs
venv/
.venv/
env/

# IDE / OS
.vscode/
.idea/
.DS_Store
*.swp

# Tests + tooling output
test-results/
.tox/
build/
dist/

# Git history not needed at runtime (multi-GB pack files)
.git/
.gitignore
.gitattributes

# Cached satellite data — these are operator-managed via the
# backend_data named volume in docker-compose.prod.yml. Baking them
# into the image would make every model retrain produce a multi-GB
# image diff. Mount them at runtime instead.
app/data/
data/

# Generated ML models — same reasoning as data/. Operators load
# trained models via the registry path mounted at /app/app/data/ml_models.
app/services/ml/cache/

# Local SQLite databases used in dev only
*.db
*.sqlite

# Logs
*.log
logs/

# Backups + scratch
*.bak
*.tmp
*.orig
Loading
Loading