# Build Tickets M3 This file converts the implementation epics into concrete Codex-ready tickets. ## Ticket format Each ticket must be implemented with: - backend changes if applicable - frontend changes if applicable - tests where applicable - documentation updates - changelog entry ## T-001 Backend package scaffold Create FastAPI package structure: ```text backend/app/main.py backend/app/api/router.py backend/app/core/config.py backend/app/core/database.py backend/app/models/ backend/app/schemas/ backend/app/services/ backend/app/workers/ backend/tests/ ``` Acceptance: - `GET /health` returns status ok. - backend imports cleanly. - tests can run without external geospatial data. ## T-002 Database and Alembic scaffold Add SQLAlchemy and Alembic setup for PostgreSQL/PostGIS. Acceptance: - database URL comes from environment. - migrations directory exists. - first migration creates PostGIS extension if available. - migration plan documented. ## T-003 Project model and API Implement project entity. Acceptance: - create project - list projects - read project - update project - soft delete or archive project - response envelope followed ## T-004 Area model and geometry API Implement areas linked to projects. Acceptance: - create polygon area as GeoJSON - validate geometry - store geometry in PostGIS - calculate area in square meters using projected CRS - return bounds and centroid ## T-005 Frontend foundation Create React + TypeScript app structure. Acceptance: - app boots - route layout exists - API client exists - error/loading components exist - navigation includes Workspace, Map, Datasets, Raster, Vector, Detection, QA/QC, Exports ## T-006 Map workbench foundation Implement map page and area drawing contract. Acceptance: - map displays Kempen default viewport - user can draw or load an example polygon - polygon can be submitted to backend as area - active area can be selected ## T-007 Dataset upload API Implement dataset registration and upload. Acceptance: - accepts GeoTIFF, GeoJSON, ZIP shapefile, GPKG placeholder handling - stores original file under storage/originals - creates dataset row - status starts as uploaded - returns metadata extraction job status ## T-008 Raster metadata service Implement Rasterio metadata extraction. Acceptance: - CRS - bounds - width/height - band count - resolution - nodata - dtype - transform - summary stats for small rasters or sampled stats for large rasters ## T-009 Vector metadata service Implement GeoPandas metadata extraction. Acceptance: - CRS - bounds - feature count - geometry types - columns - invalid geometry count - area summary where applicable ## T-010 GRB reference fetcher skeleton Implement service contract for GRB WFS fetch. Acceptance: - service accepts area geometry - builds BBOX or polygon filter request - stores retrieved features as dataset/layer - if live WFS unavailable, returns a clear source_unavailable status without crashing ## T-011 Detection pipeline interface Implement detection run model and interface. Acceptance: - request creates analysis_run - job lifecycle status exists - deterministic fixture inference can populate detections for demo fixtures - output geometries are stored and exported as GeoJSON ## T-012 QA/QC engine v1 Implement reference-vs-prediction matching. Acceptance: - IoU threshold configurable, default 0.5 - precision, recall, F1 calculated - false positives and false negatives classified - QA result stored - fixture test passes with known expected metrics ## T-013 Export API Implement export registry and GeoJSON export. Acceptance: - export detection results as FeatureCollection - export QA false positives/negatives as FeatureCollection - export analysis summary JSON - exports have stable file paths under storage/exports ## T-014 Frontend dataset and analysis panels Implement visible pages for dataset, detection and QA workflows. Acceptance: - dataset list shows status and metadata - detection page starts run and shows result state - QA page shows metrics and error classes - map overlays are connected to available GeoJSON outputs ## T-015 Stabilization pass Acceptance: - no broken navigation - no unhandled promise rejections - backend health green - core tests green - README quickstart updated - CHANGELOG updated