# CLAUDE.md — Nuvolari ## Project Cross-platform precipitation-radar app for the Piedmont region (Italy). Android first, iOS later, single Flutter codebase. Region-scoped now (Piemonte) but extensible to other regions via configuration. ## Scope **Radar on a map, plus official alerts and rain notifications. Nothing else.** In scope: - Animated precipitation radar over an OpenStreetMap base map - ARPA Piemonte official alert bulletin (XML-CAP), republished verbatim - "Rain incoming" notifications by geographic cell Explicitly out of scope — do not add these back without being asked: - Weather forecasts of any kind - Lightning - Home-screen widget - Advertising and consent flows The app is currently free with **no advertising**. Ads may return later, so prefer data sources that permit commercial use; do not adopt a non-commercial-only source on the grounds that there are no ads today. ## Golden rules - Code, identifiers and commit messages in English. UI text in Italian via ARB localization. - Never commit secrets. Use .env + --dart-define; keep .gitignore updated. - Never poll ARPA/DPC servers directly from the app: always go through our backend/CDN. - Never store precise user locations server-side: rain notifications use geographic CELLS. - Do not use ARPA/DPC name, logo or the word "ufficiale" in a way implying an official app. ## Architecture - Monorepo: /app (Flutter), /backend (Python worker), /docs (detailed docs), /tool (scripts). - Radar data via RadarSource interface with adapters: DpcRadarSource (live, reads our CDN), ArpaRadarSource (stub, awaits access), MockRadarSource (offline/demo). Active source chosen by region config + runtime flag. - App reads PNG frames + manifest.json from CDN produced by the backend worker (crop to Piemonte bbox, reproject to EPSG:3857). ## Data sources & licenses (attribution is mandatory on the Sources screen) - Radar (active): Radar-DPC — base https://radar-api.protezionecivile.it/ , GET /findLastProductByType?type=VMI , POST /downloadProduct (GeoTIFF via presigned S3). REQUIRE header `origin: https://radar.protezionecivile.it`. License CC BY-SA — credit "Radar-DPC"; derivative data products must stay CC BY-SA. Docs: dpc-radar.readthedocs.io. The rasters are on a **custom projection centred on Italy**, not EPSG:4326 or 3857, and their GeoKeys are internally inconsistent — read the CRS from each file, never hardcode it. - Radar (future): ARPA Piemonte (HDF5 ODIM, 5-minute volumes). The data is free, but the real-time access link **must be requested by email** at info.meteo@arpa.piemonte.it, and ARPA states no licence — only that the data is free of charge. Both the request and the licence question are the project owner's to resolve. Adapter stays a disabled stub. - Alerts: ARPA Piemonte XML-CAP bulletin at https://www.arpa.piemonte.it/export/xmlcap/allerta.xml — reproduce alert levels WITHOUT reinterpreting; link the official channel. Six level values, not four: VERDE, GIALLO, ARANCIONE, ROSSO, plus BIANCO (avalanche scale out of season) and "-" (no data). - Base map: OpenFreeMap (https://openfreemap.org), free OSM vector tiles with no API key and no request limits. Mandatory credits: "© OpenMapTiles" and "© OpenStreetMap contributors" (ODbL). OpenFreeMap's own credit is optional. ## Verification loop (run after each milestone) - `dart format .` ; `flutter analyze` ; `flutter test` ; `flutter build appbundle` - Backend: `python -m pytest` ; lint. Commit frequently with clear messages. - `tool/verify.ps1` runs all of the above and skips stages that do not exist yet. - Verify visually on the `nuvolari` AVD before calling a milestone done. Twice now, running the app has caught defects that passing tests did not. ## Store / compliance targets - Google Play: target API 36 (Android 16); closed testing 12 testers / 14 days; Data safety section; prominent disclosure for location; signed AAB. - No advertising, so no CMP and no IAB TCF obligations while that holds. - iOS later: keep platform abstractions clean (privacy nutrition label to add). ## Docs to maintain in /docs architecture.md, data-sources.md, licenses.md, stack-decisions.md, roadmap.md, privacy.md