diff --git a/Nuvolari/AndroidManifest.xml b/Nuvolari/AndroidManifest.xml deleted file mode 100644 index 8e3aa4f..0000000 --- a/Nuvolari/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Nuvolari/CLAUDE.md b/Nuvolari/CLAUDE.md new file mode 100644 index 0000000..00dcd7b --- /dev/null +++ b/Nuvolari/CLAUDE.md @@ -0,0 +1,50 @@ +# CLAUDE.md — Radar Meteo Piemonte + +## Project +Cross-platform weather-radar app for the Piedmont region (Italy). Android first, iOS later, +single Flutter codebase. Free app monetized with AdMob (GDPR consent via UMP). +Region-scoped now (Piemonte) but extensible to other regions via configuration. + +## 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. +- Use ONLY AdMob TEST ad unit IDs in development. +- 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). +- Radar data via RadarSource interface with adapters: + DpcRadarSource (default, public), ArpaRadarSource (stub, awaits authorization), + 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 (MVP): 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. +- Radar (future): ARPA Piemonte (HDF5 ODIM), access via email info.meteo@arpa.piemonte.it. + License CC BY 4.0 — credit "Fonte: Arpa Piemonte - www.arpa.piemonte.it". +- Forecast: MET Norway api.met.no (CC BY 4.0, commercial OK) — MANDATORY identifying + User-Agent (app name + contact). Fallback: ItaliaMeteo ICON-2I via MeteoHub (CC BY 4.0, + credit "ItaliaMeteo-ARPAE"). Do NOT use Open-Meteo free tier (non-commercial only). +- Alerts: ARPA Piemonte XML-CAP bulletin — reproduce alert levels WITHOUT reinterpreting; + link the official channel. +- Base map: OSM data via PMTiles/MapTiler — show OSM/ODbL attribution. +- Lightning: DO NOT use Blitzortung (commercial use prohibited). + +## 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. + +## Store / compliance targets +- Google Play: target API 36 (Android 16) by 2026-08-31; closed testing 12 testers / 14 days; + Data safety section; prominent disclosure for location; signed AAB. +- Consent: Google-certified CMP (UMP), IAB TCF 2.3, non-personalized ads if user declines. +- iOS later: keep platform abstractions clean (ATT + privacy nutrition label to add). + +## Docs to maintain in /docs +architecture.md, data-sources.md, licenses.md, stack-decisions.md, roadmap.md, privacy.md diff --git a/Nuvolari/MainActivity.cs b/Nuvolari/MainActivity.cs deleted file mode 100644 index 11d2270..0000000 --- a/Nuvolari/MainActivity.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Android.App; -using Android.OS; -using Android.Gms.Maps; -using Android.Gms.Maps.Model; -using Android.Widget; -using Android.Locations; -using System.Threading.Tasks; -using System.Linq; - -/* - * IDEE: - * Fare una versione molto base dell'app senza troppe funzionalità, giusto per mostrare una mappa. - * Fare poi una versione con più funzionalità, ma con pubblicità per guadagnare qualcosa da quello. - */ - -namespace Nuvolari -{ - [Activity(Label = "@string/app_name", MainLauncher = true)] - public class MainActivity : Activity, IOnMapReadyCallback - { - private MapFragment? mapFragment; - private GoogleMap? googleMap; - private SearchView? searchView; - - protected override void OnCreate(Bundle? savedInstanceState) - { - base.OnCreate(savedInstanceState); - - // Usa il layout personalizzato con SearchView e MapFragment - SetContentView(Resource.Layout.activity_main); - - // Ottieni riferimenti ai componenti UI - searchView = FindViewById(Resource.Id.searchView); - mapFragment = FragmentManager.FindFragmentById(Resource.Id.map) as MapFragment; - - mapFragment?.GetMapAsync(this); - - // Gestione ricerca - if (searchView != null) - { - searchView.QueryTextSubmit += async (s, e) => - { - var query = e?.Query ?? string.Empty; - await SearchAndMoveToLocationAsync(query); - searchView.ClearFocus(); - }; - } - } - - public void OnMapReady(GoogleMap map) - { - googleMap = map; - // Imposta solo la navigazione base (scroll/zoom) - googleMap.UiSettings.CompassEnabled = false; - googleMap.UiSettings.MapToolbarEnabled = false; - googleMap.UiSettings.MyLocationButtonEnabled = false; - - // Posizione iniziale: Milano - var position = new LatLng(45.4642, 9.19); - googleMap.MoveCamera(CameraUpdateFactory.NewLatLngZoom(position, 10)); - } - - private async Task SearchAndMoveToLocationAsync(string query) - { - if (string.IsNullOrWhiteSpace(query) || googleMap == null) - return; - - var geocoder = new Geocoder(this); -#pragma warning disable CA1422 // Suppress warning for obsolete API on Android 33+ - var addresses = await Task.Run(() => geocoder.GetFromLocationName(query, 1)); -#pragma warning restore CA1422 - var address = addresses?.FirstOrDefault(); - if (address != null) - { - var latLng = new LatLng(address.Latitude, address.Longitude); - RunOnUiThread(() => - { - googleMap?.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(latLng, 10)); - }); - } - else - { - RunOnUiThread(() => - { - Toast.MakeText(this, "Luogo non trovato", ToastLength.Short).Show(); - }); - } - } - } -} diff --git a/Nuvolari/Nuvolari.csproj b/Nuvolari/Nuvolari.csproj deleted file mode 100644 index b0468b9..0000000 --- a/Nuvolari/Nuvolari.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - net9.0-android - 21 - Exe - enable - enable - com.companyname.Nuvolari - 1 - 1.0 - - full - - - - - \ No newline at end of file diff --git a/Nuvolari/Nuvolari.sln b/Nuvolari/Nuvolari.sln deleted file mode 100644 index faf5fd4..0000000 --- a/Nuvolari/Nuvolari.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.13.35931.197 d17.13 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nuvolari", "Nuvolari.csproj", "{B6CEEA40-2867-4F58-96EA-BB986DE9489C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B6CEEA40-2867-4F58-96EA-BB986DE9489C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6CEEA40-2867-4F58-96EA-BB986DE9489C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6CEEA40-2867-4F58-96EA-BB986DE9489C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B6CEEA40-2867-4F58-96EA-BB986DE9489C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {646B2C8A-0EA4-4133-AB5A-3C6DD1D72D94} - EndGlobalSection -EndGlobal diff --git a/Nuvolari/Resources/AboutResources.txt b/Nuvolari/Resources/AboutResources.txt deleted file mode 100644 index 219f425..0000000 --- a/Nuvolari/Resources/AboutResources.txt +++ /dev/null @@ -1,44 +0,0 @@ -Images, layout descriptions, binary blobs and string dictionaries can be included -in your application as resource files. Various Android APIs are designed to -operate on the resource IDs instead of dealing with images, strings or binary blobs -directly. - -For example, a sample Android app that contains a user interface layout (main.xml), -an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) -would keep its resources in the "Resources" directory of the application: - -Resources/ - drawable/ - icon.png - - layout/ - main.xml - - values/ - strings.xml - -In order to get the build system to recognize Android resources, set the build action to -"AndroidResource". The native Android APIs do not operate directly with filenames, but -instead operate on resource IDs. When you compile an Android application that uses resources, -the build system will package the resources for distribution and generate a class called "Resource" -(this is an Android convention) that contains the tokens for each one of the resources -included. For example, for the above Resources layout, this is what the Resource class would expose: - -public class Resource { - public class Drawable { - public const int icon = 0x123; - } - - public class Layout { - public const int main = 0x456; - } - - public class Strings { - public const int first_string = 0xabc; - public const int second_string = 0xbcd; - } -} - -You would then use Resource.Drawable.icon to reference the drawable/icon.png file, or -Resource.Layout.main to reference the layout/main.xml file, or Resource.Strings.first_string -to reference the first string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/Nuvolari/Resources/layout/activity_main.axml b/Nuvolari/Resources/layout/activity_main.axml deleted file mode 100644 index c12dc11..0000000 --- a/Nuvolari/Resources/layout/activity_main.axml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Nuvolari/Resources/layout/activity_main.xml b/Nuvolari/Resources/layout/activity_main.xml deleted file mode 100644 index f949852..0000000 --- a/Nuvolari/Resources/layout/activity_main.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - \ No newline at end of file diff --git a/Nuvolari/Resources/mipmap-anydpi-v26/appicon.xml b/Nuvolari/Resources/mipmap-anydpi-v26/appicon.xml deleted file mode 100644 index 7751f69..0000000 --- a/Nuvolari/Resources/mipmap-anydpi-v26/appicon.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Nuvolari/Resources/mipmap-anydpi-v26/appicon_round.xml b/Nuvolari/Resources/mipmap-anydpi-v26/appicon_round.xml deleted file mode 100644 index 7751f69..0000000 --- a/Nuvolari/Resources/mipmap-anydpi-v26/appicon_round.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Nuvolari/Resources/mipmap-hdpi/appicon.png b/Nuvolari/Resources/mipmap-hdpi/appicon.png deleted file mode 100644 index 0abfc1b..0000000 Binary files a/Nuvolari/Resources/mipmap-hdpi/appicon.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-hdpi/appicon_background.png b/Nuvolari/Resources/mipmap-hdpi/appicon_background.png deleted file mode 100644 index 513e69d..0000000 Binary files a/Nuvolari/Resources/mipmap-hdpi/appicon_background.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-hdpi/appicon_foreground.png b/Nuvolari/Resources/mipmap-hdpi/appicon_foreground.png deleted file mode 100644 index 99d3a29..0000000 Binary files a/Nuvolari/Resources/mipmap-hdpi/appicon_foreground.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-mdpi/appicon.png b/Nuvolari/Resources/mipmap-mdpi/appicon.png deleted file mode 100644 index 7b5a2e2..0000000 Binary files a/Nuvolari/Resources/mipmap-mdpi/appicon.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-mdpi/appicon_background.png b/Nuvolari/Resources/mipmap-mdpi/appicon_background.png deleted file mode 100644 index 9e2d1e4..0000000 Binary files a/Nuvolari/Resources/mipmap-mdpi/appicon_background.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-mdpi/appicon_foreground.png b/Nuvolari/Resources/mipmap-mdpi/appicon_foreground.png deleted file mode 100644 index a28d342..0000000 Binary files a/Nuvolari/Resources/mipmap-mdpi/appicon_foreground.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xhdpi/appicon.png b/Nuvolari/Resources/mipmap-xhdpi/appicon.png deleted file mode 100644 index b28b73c..0000000 Binary files a/Nuvolari/Resources/mipmap-xhdpi/appicon.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xhdpi/appicon_background.png b/Nuvolari/Resources/mipmap-xhdpi/appicon_background.png deleted file mode 100644 index 658be3f..0000000 Binary files a/Nuvolari/Resources/mipmap-xhdpi/appicon_background.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xhdpi/appicon_foreground.png b/Nuvolari/Resources/mipmap-xhdpi/appicon_foreground.png deleted file mode 100644 index 70a542a..0000000 Binary files a/Nuvolari/Resources/mipmap-xhdpi/appicon_foreground.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxhdpi/appicon.png b/Nuvolari/Resources/mipmap-xxhdpi/appicon.png deleted file mode 100644 index f9af117..0000000 Binary files a/Nuvolari/Resources/mipmap-xxhdpi/appicon.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxhdpi/appicon_background.png b/Nuvolari/Resources/mipmap-xxhdpi/appicon_background.png deleted file mode 100644 index 9171c3e..0000000 Binary files a/Nuvolari/Resources/mipmap-xxhdpi/appicon_background.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxhdpi/appicon_foreground.png b/Nuvolari/Resources/mipmap-xxhdpi/appicon_foreground.png deleted file mode 100644 index cb63bfb..0000000 Binary files a/Nuvolari/Resources/mipmap-xxhdpi/appicon_foreground.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxxhdpi/appicon.png b/Nuvolari/Resources/mipmap-xxxhdpi/appicon.png deleted file mode 100644 index 1d948d6..0000000 Binary files a/Nuvolari/Resources/mipmap-xxxhdpi/appicon.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxxhdpi/appicon_background.png b/Nuvolari/Resources/mipmap-xxxhdpi/appicon_background.png deleted file mode 100644 index 1232d8c..0000000 Binary files a/Nuvolari/Resources/mipmap-xxxhdpi/appicon_background.png and /dev/null differ diff --git a/Nuvolari/Resources/mipmap-xxxhdpi/appicon_foreground.png b/Nuvolari/Resources/mipmap-xxxhdpi/appicon_foreground.png deleted file mode 100644 index 9f9c9e6..0000000 Binary files a/Nuvolari/Resources/mipmap-xxxhdpi/appicon_foreground.png and /dev/null differ diff --git a/Nuvolari/Resources/values/ic_launcher_background.xml b/Nuvolari/Resources/values/ic_launcher_background.xml deleted file mode 100644 index 6ec24e6..0000000 --- a/Nuvolari/Resources/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - #2C3E50 - \ No newline at end of file diff --git a/Nuvolari/Resources/values/strings.xml b/Nuvolari/Resources/values/strings.xml deleted file mode 100644 index 3137010..0000000 --- a/Nuvolari/Resources/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - Nuvolari - Hello, Android! -