Commit History
-
refactor: rename "indicators" to "EO products" throughout
KSvend +2: Claude, HappyFull rename across codebase: - app/indicators/ → app/eo_products/ - IndicatorResult → ProductResult, IndicatorMeta → ProductMeta - IndicatorRegistry → ProductRegistry, BaseIndicator → BaseProduct - NdviIndicator → NdviProduct (and Water, SAR, Buildup) - indicator_id → product_id in models, APIs, and frontend - /api/indicators → /api/eo-products - All user-facing text updated - Frontend page/element IDs updated - 27 tests passing Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>df6bf75 -
fix: address code review — memory, dedup, confidence, zoom, overview
KSvend +2: Claude, HappyCritical fixes: - Memory: compute_seasonal_stats_pixel uses Welford's online algorithm instead of stacking all bands in RAM (prevents OOM at native res) - Memory: worker releases z-score rasters from indicators after compound signal detection via release_rasters() Important fixes: - Extract _compute_spatial_completeness, _classify_zscore, _compute_trend_zscore to BaseIndicator (was copy-pasted 4x) - Remove fake mean_obs_per_composite=5.0 — confidence model is now 3-factor (temporal, baseline depth, spatial completeness) - overview.py factors anomaly_months into composite score penalty - Worker zoom: order=1 (bilinear) and upsample to finest resolution instead of downsampling to coarsest - Water chart: compute baseline from water fractions directly instead of misleadingly scaling raw MNDWI values - Buildup _compute_stats docstring consistency Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthrop…7daf007 -
feat: add output pipeline for seasonal analysis and compound signals
KSvend +2: Claude, Happy- Charts: anomaly markers (red rings) on months exceeding z-score threshold; default y-axis labels per indicator - Maps: new render_hotspot_map() for z-score change visualization over true-color base layer - Narrative: generate_compound_signals_text() for cross-indicator compound signal descriptions - Report: anomaly column in summary table, compound signals section, hotspot maps in indicator blocks, confidence breakdown table in technical annex - Worker: generates hotspot maps, detects compound signals via spatial z-score overlap, passes both to PDF report Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>1e8f4b0 -
feat: add cross-indicator compound signal detection
KSvend +1: Claude Opus 4.6 (1M context)Implements compound signal module with 4 detection patterns: - land_conversion: NDVI decline + settlement growth - flood_event: SAR backscatter decrease + water increase - drought_stress: NDVI decline + water decline + SAR increase - displacement_pressure: settlement growth adjacent to vegetation loss Includes overlap calculation, confidence tagging, and comprehensive tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>ae4c60c -
feat: add four-factor confidence scoring model
KSvendcbe084f -
feat: add seasonal baseline computation module
KSvend +1: Claude Opus 4.6 (1M context)Implements core seasonal baseline functionality for EO anomaly detection: - group_bands_by_calendar_month: Maps multi-year band indices to calendar months - compute_seasonal_stats_aoi: Computes per-month AOI-level stats from baseline raster - compute_seasonal_stats_pixel: Computes per-pixel statistics across bands - compute_zscore: Computes z-scores with std-floor to avoid division-by-zero All 6 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>03db879 -
feat: add anomaly, hotspot, confidence fields to IndicatorResult; add CompoundSignal model
KSvend87be95e -
feat: add test fixtures for EO product overhaul
KSvend46ca87a -
refactor: strip to 4 real EO indicators, remove all tests and mock fallbacks
KSvend +2: Claude, HappyKeep only NDVI, Water (MNDWI), SAR, and Built-up — the four indicators with full openEO batch pipelines. Remove 8 unused indicators, all test files, and every placeholder/fallback path. Failures now propagate as errors instead of silently returning synthetic data. - Delete: cropland, fires, food_security, lst, nightlights, no2, rainfall, vegetation - Delete: entire tests/ directory - Remove _fallback() from all indicators — process() raises on failure - Remove harvest() fallback-to-placeholder on current data failure - Worker no longer falls back to process() when batch submit fails - Remove placeholder caveat from narrative engine and PDF report - Re-weight overview scores for 4 indicators (ndvi 0.30, sar 0.25, water 0.25, buildup 0.20) - Remove build_lst_graph from openeo_client Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>c42be1f
-
test: update report tests for new narrative structure
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>5304f8c -
feat: add cross-indicator narrative engine with interpretation templates
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>31dea57
-
test: extract shared helpers to conftest, strengthen harvest assertions
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>99383a9 -
feat: add batch support to water indicator
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>14b5fe5 -
feat: add batch support to buildup indicator
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>762f7b2 -
feat: add batch support to SAR indicator
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>311d610 -
fix: NDVI harvest baseline_path never assigned after download
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>cb89291 -
test: add batch flow E2E test for NDVI pipeline
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>6844e35 -
feat: three-phase batch job worker (submit → poll → harvest)
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>f491e48 -
feat: implement NdviIndicator.harvest() with graceful degradation
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>bf99ddb -
feat: implement NdviIndicator.submit_batch() for openEO batch jobs
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>b7f7fb5 -
feat: add batch job interface to BaseIndicator (uses_batch, submit_batch, harvest)
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>e9494fc -
feat: add submit_as_batch() helper for openEO batch jobs
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>09bef8e
-
feat: add composite score computation and overview map renderer
KSvend +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1159329 -
feat: add built-up settlement extent indicator via NDBI
KSvend +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b222a93 -
feat: add SAR backscatter indicator with change detection and flood mapping
KSvend +1: Claude Sonnet 4.6Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9908d66 -
feat: add SAR and built-up graph builders to openEO client
KSvendae1086e -
feat: rewrite nightlights indicator with VIIRS EOG direct download
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>e0a0ce4 -
feat: rewrite rainfall indicator with CHIRPS direct download
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>e5905cb -
feat: rewrite LST indicator with Sentinel-3 SLSTR via openEO
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>6c9ecc3 -
feat: rewrite water indicator with pixel-level MNDWI via openEO
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>8154eee -
feat: add MNDWI and LST graph builders to openEO client
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>5408eb3 -
test: add end-to-end smoke test for NDVI openEO pipeline
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>7403c8c -
feat: add pixel-level NDVI indicator via CDSE openEO
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>2dc7d77 -
feat: add raster-on-true-color map renderer (render_raster_map)
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>a0aee0c -
test: add synthetic GeoTIFF fixtures for raster map tests
KSvend +2: Claude, HappyGenerated 12-band NDVI monthly (float32, -0.2 to 0.9) and 3-band true-color RGB (uint16, 800-1500 range) fixtures covering the same 22x17 pixel AOI at ~100m resolution. Fixtures simulate seasonal NDVI patterns and semi-arid landscape for comprehensive raster testing. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>f4b45d7 -
feat: add openEO client with NDVI and true-color graph builders
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>866c331 -
feat: add centralized config module with resolution and openEO settings
KSvend +1: Claude Haiku 4.5- RESOLUTION_M: spatial resolution in meters (default 100m for free-tier HF Space) - MAX_AOI_KM2: maximum AOI size in km² (default 500) - OPENEO_BACKEND: openEO backend URL (default CDSE) - OPENEO_CLIENT_ID/SECRET: OAuth2 credentials from environment All environment variables are configurable via APERTURE_* prefixed env vars. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>364b8f4 -
feat: refactor NO2 to aggregate hourly→monthly chart data
KSvend +1: Claude Sonnet 4.6When season_months is provided, NO2 now outputs per-month chart data with baseline band (mean/min/max) instead of a single annual mean. Adds _build_monthly_chart_data static method and tracks _current_monthly_means and _baseline_per_year_monthly in _api_query. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0833984 -
feat: refactor LST to aggregate daily→monthly chart data
KSvend +1: Claude Sonnet 4.6Adds per-month current and baseline means to LSTIndicator so that season-filtered views show a monthly temperature chart instead of a single annual mean. Includes _build_monthly_chart_data static method and wires it into process() when season_months is provided. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d6f1ed7 -
feat: filter fires chart data by season_months
KSvend +1: Claude Sonnet 4.6Pass season_months through to _build_chart_data so only detections in the selected season are included in the monthly chart output. Adds two unit tests covering filtered and unfiltered behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5d58ffc -
feat: refactor cropland to use season_months, add rainfall season filter
KSvend +1: Claude Sonnet 4.6Task 5: Remove GROWING_SEASON constant from cropland; _stac_comparison now accepts season_months (defaults to all months 1-12), stores per-month medians, and exposes _build_monthly_chart_data for richer chart output. _fetch_tile_footprints also respects season_months. Task 7: _build_chart_data in rainfall now accepts season_months and filters the output date keys so only season-relevant months appear in charts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4ba0929 -
feat: add per-month chart data to vegetation and water indicators (Tasks 4 & 6)
KSvend +1: Claude Sonnet 4.6Both indicators now track baseline_per_year_monthly and current_monthly_medians during _stac_comparison, and expose a _build_monthly_chart_data static method that returns per-month dates/values/baseline_mean/min/max arrays when season_months is provided. process() falls back to the existing 2-point chart when season_months is absent or STAC data is unavailable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5f44056 -
feat: wire season_months through worker to all indicators
KSvend +1: Claude Sonnet 4.6Add season_months: list[int] | None = None to the abstract process() signature in BaseIndicator, pass it from the worker via job.request.season_months(), and update all 9 indicator implementations plus the worker test mock to accept the parameter (ignored for now). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>55881c1 -
feat: add season_start/season_end to JobRequest with wrap support
KSvend +2: Claude, HappyGenerated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>1b15a5f -
feat: add baseline range to NO2 and Nightlights chart data
KSvend +1: Claude Sonnet 4.6Store per-year baseline values during API queries and expose baseline_range_mean/min/max in chart_data for both indicators when >=2 baseline years are available. Tests cover range inclusion, the single-year guard, and the None/fallback paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a392efe -
feat: add baseline range (min/mean/max) to vegetation and cropland chart data
KSvend +1: Claude Sonnet 4.6Track per-year means during the baseline STAC loop and expose them as baseline_range_min/mean/max scalars in _build_chart_data when 2+ years are available. Adds test_indicator_vegetation.py and extends test_indicator_cropland.py with range assertions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1e77056 -
feat: add baseline range to water and LST indicators (Tasks 7 & 8)
KSvend +1: Claude Sonnet 4.6Track per-year baseline means during STAC/API queries and expose baseline_range_mean/min/max in chart_data when 2+ years are available. Water uses 2 dp, LST uses 1 dp, matching each indicator's existing precision. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a2116ac -
feat: add baseline range (min/mean/max) to rainfall chart data
KSvend +1: Claude Sonnet 4.6Store per-year monthly values from the baseline loop as `_baseline_per_year`, then compute and attach `baseline_mean`, `baseline_min`, and `baseline_max` arrays in `_build_chart_data` when that data is available. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e5b5196 -
feat: add monthly and summary baseline overlay to chart renderer
KSvend +1: Claude Sonnet 4.6Adds two baseline overlay modes to render_timeseries_chart: monthly mode renders a per-date shaded band and dashed mean line behind the current data line; summary mode renders horizontal axhspan/axhline equivalents. Detection is automatic from chart_data keys — no-baseline path is fully backward compatible. Adds three tests covering both modes and the no-op case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>770ffd4
-
feat: cartopy map renderers for points, choropleth, grid, and status overlays
KSvend +2: Claude, HappyRewrites app/outputs/maps.py to handle four map types (grid heatmap, points, choropleth, status) dispatched via SpatialData.map_type, with MERLx palette, cartopy basemap, and graceful fallback when cartopy is absent. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>1e692d7