Files
Europa/Nuvolari
Alby96andClaude Opus 5 85b2c99949 Scaffold the Flutter app with Italian l10n and region configuration
Creates the app skeleton and the seam everything else in the project hangs
off: region-specific data lives in an asset file, not in code, so adding a
region later is a new JSON file rather than a refactor.

Notable choices:

- applicationId and namespace are it.nuvolari.app rather than the doubled
  it.nuvolari.nuvolari that `flutter create` produces, with the Kotlin package
  and the iOS bundle identifiers moved to match.
- SDK levels are pinned instead of inherited from `flutter.*`. Google Play
  requires API 36, and that is a release blocker rather than something to let a
  Flutter upgrade change silently. minSdk 24 is the highest floor the planned
  dependencies impose.
- Riverpod and Dio-free for now, no code generation: see docs/stack-decisions.md.
- Italian is the l10n source language, so app_it.arb is the template rather
  than a translation of an English original.

The region parser rejects rather than repairs. An inverted bounding box, a map
centre outside its own bounds, an unknown adapter name, a duplicate zone code
or an empty attribution list all throw with the offending field named. Each of
those would otherwise fail silently and visibly wrong: a swapped latitude and
longitude renders the radar in the wrong place, an unknown adapter falling back
to mock would show demo frames where live data was expected, and a missing
attribution is a licence violation rather than a cosmetic gap.

Tests run against the asset that actually ships and against a captured copy of
the live ARPA CAP feed, so the eleven zone codes in the config are checked
against the eleven the feed really emits rather than against a list retyped
from documentation.

Verified: dart format clean, flutter analyze 0 issues, 50 tests passing,
flutter build appbundle --debug produces an AAB with applicationId
it.nuvolari.app, minSdk 24, targetSdk 36.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 11:24:26 +02:00
..

Nuvolari

Precipitation radar for Piedmont, Italy. Android first, iOS later, one Flutter codebase.

Radar imagery comes from the public Radar-DPC platform, forecasts from MET Norway, weather alerts from the ARPA Piemonte XML-CAP bulletin. The app is free and ad-supported, with GDPR consent through Google's UMP.

Nuvolari is an independent app. It is not affiliated with, endorsed by, or operated by ARPA Piemonte or the Dipartimento della Protezione Civile. For civil-protection purposes the official channels always prevail.

Layout

app/       Flutter application (Dart package "nuvolari")
backend/   Python worker: fetches DPC rasters, crops, reprojects, renders PNG frames
docs/      architecture, data sources, licenses, stack decisions, roadmap, privacy
tool/      verification scripts

Start with docs/architecture.md, then docs/roadmap.md for what is built and what is next.

Toolchain

Tool Version
Flutter 3.47.3 stable (Dart 3.13.3)
Android SDK platform 36, build-tools 36.0.0, platform-tools
JDK 21
Python 3.12+ (3.14 works; rasterio ships wheels for it)

Configuration

Secrets never enter the repository. Copy the template and fill it in:

cp env.example.json env.json     # env.json is git-ignored
Key Purpose
MAP_STYLE_URL MapLibre style URL. Empty falls back to a local offline style.
RADAR_MANIFEST_URL Base URL of the published manifest.json.
RADAR_SOURCE mock (offline demo), dpc (live), arpa (disabled stub).
METNO_USER_AGENT_CONTACT Contact address for the MET Norway User-Agent — mandatory for forecasts.
ADMOB_APP_ID, ADMOB_BANNER_UNIT_ID Empty means Google's test ad units are used.

Running

cd app
flutter run --dart-define-from-file=../env.json

With no env.json the app starts in demo mode: mock radar frames from assets, offline base map style, test ad units. No network and no credentials required.

Verifying

.\tool\verify.ps1              # format, analyze, test, build, lint, pytest
.\tool\verify.ps1 -SkipBuild   # fast inner loop

Stages whose target does not exist yet are skipped, so this runs from day one.

Attribution

Radar-DPC (CC BY-SA) · MET Norway (CC BY 4.0) · Arpa Piemonte · © OpenStreetMap contributors (ODbL). See docs/licenses.md for the obligations these carry — in particular, the rendered radar frames are a derived product of CC BY-SA data and inherit share-alike.