| name | siae-flutter |
| description | Use when developing Flutter mobile apps with MVVM + Riverpod, ObjectBox persistence, Amplify/Cognito auth, Firebase, Dio networking, or code generation. Guida lo sviluppo di app Flutter SIAE. Trigger: Flutter, Dart, Riverpod, ObjectBox, Get_it, Amplify, Cognito, app mobile, widget, build_runner, Dio, Crashlytics, deep link, geolocation.
|
| paths | **/*.dart |
SIAE Flutter — DevForge
╔══════════════════════════════════════════════════════════════════╗
║ ███████╗██╗ █████╗ ███████╗ ██████╗ ███████╗██╗ ██╗ ║
║ ██╔════╝██║██╔══██╗██╔════╝ ██╔══██╗██╔════╝██║ ██║ ║
║ ███████╗██║███████║█████╗ ██║ ██║█████╗ ██║ ██║ ║
║ ╚════██║██║██╔══██║██╔══╝ ██║ ██║██╔══╝ ╚██╗ ██╔╝ ║
║ ███████║██║██║ ██║███████╗ ██████╔╝███████╗ ╚████╔╝ ║
║ ╚══════╝╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚══════╝ ╚═══╝ ║
║ 🔨 DevForge · SIAE Flutter Patterns ║
║ "Il codice si forgia. Il developer cresce." ║
╚══════════════════════════════════════════════════════════════════╝
Tipo: Flexible | Fase SDLC: 4. Implementation
📊 Dai repo itsiae: Le app mobile senza pattern MVVM rigoroso accumulano 2.5x piu' bug di stato rispetto a quelle con separazione netta ViewModel/View.
Fonte: analisi su repository mobile itsiae.
Panoramica
Pattern Flutter SIAE per sviluppo app mobile. Definisce lo stack standard, l'architettura
MVVM con Riverpod, la gestione della persistenza, autenticazione, networking e integrazioni native.
Questa skill si applica a tutti i progetti Flutter SIAE. Lo stack descritto e' lo
standard adottato a partire dal progetto TuneX e replicabile su nuove app.
1. Stack Tecnologico
| Tecnologia | Ruolo | Versione |
|---|
| Flutter | Framework UI cross-platform | 3.32.x stable |
| Dart | Linguaggio | 3.x |
| Riverpod | State management (MVVM) | 2.x |
| Get_it | Service Locator / DI | 8.x |
| ObjectBox | Database NoSQL locale | 4.x |
| Flutter Secure Storage | Cifratura dati sensibili | 9.x |
| AWS Amplify (Cognito) | Autenticazione | 2.x |
| Firebase Crashlytics | Crash reporting | 4.x |
| Firebase Messaging | Push notifications | 15.x |
| Firebase Remote Config | Configurazione remota | 5.x |
| Dio | HTTP client | 5.x |
| build_runner | Code generation (DTO, entity) | 2.x |
| Barlow | Font family | — |
| flutter_svg | Grafica vettoriale SVG | 2.x |
Per dettagli su ogni componente vedi reference/stack-details.md.
2. Architettura — MVVM con Riverpod
┌─────────────────────────────────────────────────┐
│ View (Widget) │
│ - Solo UI, zero logica business │
│ - Osserva il ViewModel via ref.watch() │
└──────────────────────┬──────────────────────────┘
│ ref.watch / ref.read
┌──────────────────────▼──────────────────────────┐
│ ViewModel (Notifier) │
│ - Logica di presentazione │
│ - Espone stato immutabile (state) │
│ - Chiama Repository/Service via ref │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ Repository / Service │
│ - Accesso dati (API, DB locale) │
│ - Registrato in Get_it │
│ - Iniettato nel ViewModel via Provider │
└─────────────────────────────────────────────────┘
Regole MVVM:
- View: solo widget,
ref.watch() per leggere stato, ref.read() per azioni
- ViewModel:
Notifier o AsyncNotifier di Riverpod, stato immutabile con copyWith
- Repository: interfaccia + implementazione, registrato in Get_it, testabile con mock
- Model/Entity: classi Dart pure, generate con
build_runner dove possibile
Struttura directory:
lib/
├── core/ # Configurazione, costanti, theme, routing
│ ├── config/ # Environment, API URLs
│ ├── constants/ # Stringhe, dimensioni, durate
│ ├── router/ # GoRouter o Navigator 2.0
│ └── theme/ # ThemeData, colori, tipografia (Barlow)
├── data/ # Layer dati
│ ├── datasources/ # Remote (API Dio) e Local (ObjectBox)
│ ├── models/ # DTO generati (build_runner)
│ └── repositories/ # Implementazioni repository
├── domain/ # Layer dominio (puro Dart)
│ ├── entities/ # Entita' business
│ ├── repositories/ # Interfacce repository (abstract)
│ └── usecases/ # Casi d'uso (opzionale)
├── presentation/ # Layer UI
│ ├── common/ # Widget condivisi
│ ├── providers/ # Riverpod providers e ViewModels
│ └── screens/ # Schermate (una directory per feature)
│ └── feature_x/
│ ├── feature_x_screen.dart
│ ├── feature_x_viewmodel.dart
│ └── widgets/ # Widget locali della feature
├── services/ # Servizi cross-cutting
│ ├── auth_service.dart # AWS Amplify/Cognito
│ ├── analytics_service.dart
│ ├── push_service.dart # Firebase Messaging
│ └── connectivity_service.dart
└── di/ # Dependency Injection setup
└── injection.dart # Get_it registration
Per pattern Riverpod dettagliati vedi reference/riverpod-patterns.md.
3. Persistenza e Sicurezza Dati
ObjectBox — Database NoSQL locale
- Usare per dati strutturati con query frequenti (cache, entita' offline)
- Annotare entita' con
@Entity(), relazioni con @Backlink()
- Generare binding con
build_runner
Flutter Secure Storage — Dati sensibili
- SEMPRE per token, credenziali, dati PII
- MAI salvare token in ObjectBox, SharedPreferences o file plain text
- Wrappare in un
SecureStorageService registrato in Get_it
abstract class SecureStorageService {
Future<void> write(String key, String value);
Future<String?> read(String key);
Future<void> delete(String key);
Future<void> deleteAll();
}
4. Autenticazione — AWS Amplify (Cognito)
- Configurare Amplify in
main.dart prima di runApp()
- Gestire il ciclo auth via
AuthService (sign in, sign up, sign out, token refresh)
- Token JWT in Flutter Secure Storage, MAI in memoria persistente non cifrata
- Usare
Amplify.Auth.fetchAuthSession() per ottenere token validi prima di ogni API call
5. Networking — Dio
- Client Dio centralizzato con interceptor per:
- Auth: inject token Cognito nell'header
Authorization
- Retry: retry automatico su 5xx e timeout (max 2 retry)
- Logging: log request/response in debug mode
- Connectivity: check connettivita' prima di ogni request
- Base URL da environment config, MAI hardcoded
- Timeout: connect 10s, receive 30s
6. Firebase
| Servizio | Uso | Configurazione |
|---|
| Crashlytics | Crash reporting automatico | FlutterError.onError + PlatformDispatcher.onError |
| Messaging | Push notifications | FCM token registrato su backend |
| Remote Config | Feature flags, config runtime | Fetch con cache 12h, fallback a defaults |
- Inizializzare Firebase in
main.dart prima di Amplify
- Config da
google-services.json (Android) e GoogleService-Info.plist (iOS)
- MAI committare file Firebase config con chiavi di produzione — usare flavor/scheme
7. Integrazioni Native
| Modulo | Package | Note |
|---|
| Geolocalizzazione | geolocator + geocoding | Permessi runtime, fallback graceful |
| Mappe | google_maps_flutter | API key da env, MAI hardcoded |
| Fotocamera | camera o image_picker | Permessi runtime, compressione immagini |
| Deep Links | App Links (Android) + Universal Links (iOS) | Configurazione in AndroidManifest.xml e Info.plist |
8. Code Generation (build_runner)
- Usare
build_runner per: DTO (json_serializable), entita' ObjectBox, router (go_router_builder), Riverpod (riverpod_generator)
- Comando:
dart run build_runner build --delete-conflicting-outputs
- File generati:
*.g.dart, *.freezed.dart — committarli nel repo (no generation in CI)
- Pattern naming:
model.dart → model.g.dart
9. Brand e Design
- Font: Barlow (Google Fonts), caricato da assets locali per performance offline
- SVG:
flutter_svg per tutte le icone e illustrazioni — no PNG/JPG per icone
- Theme:
ThemeData centralizzato in core/theme/, estendere con ThemeExtension per colori custom
- Responsive:
MediaQuery e LayoutBuilder, breakpoint per tablet/phone
Classificazione Rischio Operazioni
| Operazione | Livello | Card |
|---|
| Lettura/analisi codice Flutter | 🟢 Sicuro | No |
| Creazione/modifica widget e viewmodel | 🟡 Medio | Si |
| Modifica config Amplify/Firebase | 🔴 Alto | Si |
| Modifica dependency injection (Get_it) | 🟡 Medio | Si |
Modifica pubspec.yaml (dipendenze) | 🟡 Medio | Si |
Esecuzione build_runner | 🟡 Medio | Si |
Modifica AndroidManifest.xml / Info.plist | 🔴 Alto | Si |
| Build e deploy su store | 🚨 Critico | Si |
Vincoli
- NON usare
setState() per logica oltre l'UI locale di un singolo widget
- NON salvare token o credenziali fuori da Flutter Secure Storage
- NON hardcodare URL, API key o config Firebase nel codice sorgente
- NON usare
dynamic o disabilitare type safety — Dart strong typing sempre
- SEMPRE seguire il pattern MVVM: View → ViewModel (Notifier) → Repository
- SEMPRE registrare i servizi in Get_it e iniettarli via Provider, mai istanziare direttamente
- SEMPRE gestire permessi nativi (camera, location) con fallback graceful
- PRE-FLIGHT OBBLIGATORIA per operazioni con rischio >= 🟡
Tabella Anti-Razionalizzazione
| Pensiero | Realta' |
|---|
| "Per questa schermata basta setState" | setState scala male. Riverpod mantiene lo stato coerente tra schermate. |
| "Il token lo metto in SharedPreferences, tanto e' locale" | SharedPreferences e' plain text. I token vanno in Secure Storage, sempre. |
| "ObjectBox e' overkill, uso un file JSON" | ObjectBox ha query tipizzate e relazioni. Un file JSON diventa ingestibile. |
| "La API key di Google Maps la metto nel codice, tanto e' pubblica" | Le API key vanno in env config. Hardcoded = impossibile ruotare senza release. |
| "Il build_runner lo eseguo solo io, non serve committare i .g.dart" | Senza file generati committati, il CI non builda. Committa sempre i generati. |
| "Amplify lo configuro dopo, prima faccio funzionare l'app" | L'auth e' il primo gate. Senza auth, ogni API call e' un placeholder. |
| "Deep link li aggiungo alla fine" | I deep link richiedono config nativa. Aggiungerli dopo rompe il routing. |
| "Per ora testo manualmente, i test li scrivo dopo" | I widget test in Flutter sono veloci. Scriverli dopo significa non scriverli mai. |
Limiti Operativi
| Vincolo | Limite | Se superato |
|---|
| Tentativi fix per errore | 2 | Fermati. Diagnosi diversa necessaria. |
| File modificati per singolo step | 5 | Se devi toccare piu' file, decomponi in sub-task. |
| Output max per raccomandazione | 200 righe | Prioritizza. Top 5 issue, non lista esaustiva. |
REQUIRED SUB-SKILL: siae-tdd
Implementa ogni widget e viewmodel seguendo siae-tdd (test fallente prima del codice).
Risorse Aggiuntive
Pre-flight card (formato standard, vedi lib/checkpoint-schema.md)
| 🟡 MEDIO (reversibile) — 🔨 DevForge · siae-flutter |
|---|
| 1. Azione: |
| 💡 Perché: · 🚫 Se NO: |