Last Modified: 2025-12-29
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Check for staleness: If this file is older than 2 months, ask the user to confirm the instructions are still valid before proceeding.
Make responses concise and only reply with necessary information. Avoid verbose explanations unless specifically requested.
Check worktree status before any work: Refuse to process any prompts if the git worktree is not clean. Ask the user to commit or stash changes first.
Automatically commit any edits done by AI with AI co-authorship:
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
DPIP (Disaster Prevention Information Platform) is a Flutter-based mobile application developed by a Taiwan-based team. It integrates earthquake early warning (EEW) data from TREM-Net (Taiwan Real-time Earthquake Monitoring Network) and Central Weather Bureau data to provide users with disaster prevention information.
Target Platforms: Android and iOS
IMPORTANT: AI usage is prohibited in this repository except for documentation purposes only. All documentation must follow Effective Dart style guidelines.
- Do NOT use AI to generate or modify code
- Documentation is the ONLY acceptable use case for AI
- All documentation must adhere to Effective Dart conventions
Flutter 3.35.1 • channel stable
Framework • revision 20f8274939 • 2025-08-14 10:53:09 -0700
Engine • hash 6cd51c08a88e7bbe848a762c20ad3ecb8b063c0e
Tools • Dart 3.9.0 • DevTools 2.48.0Required minimum:
- Flutter SDK >=3.38.0
- Dart SDK >=3.10.0 <4.0.0
flutter pub get --no-exampledart run build_runner buildFor conflicting outputs:
dart run build_runner build --delete-conflicting-outputsAndroid APK:
flutter build apk --releaseAndroid for specific platforms:
flutter build apk --release --target-platform android-arm64,android-x64iOS:
flutter build ios --releaseThe project uses package:lint/strict.yaml with additional custom rules defined in analysis_options.yaml:
flutter_style_todos: errorprefer_single_quotes: warningavoid_annotating_with_dynamic: errorpublic_member_api_docs: warning
Generated files (**.freezed.dart, **.g.dart) are excluded from analysis.
Format settings (page_width: 80, trailing_commas: preserve):
dart format lib/The app follows a Provider-based state management architecture with the following key components:
Five primary providers managed through GlobalProviders:
DpipDataModel- Real-time earthquake and weather dataSettingsLocationModel- User location preferencesSettingsMapModel- Map display settingsSettingsNotificationModel- Notification preferencesSettingsUserInterfaceModel- UI settings and localization
These are initialized early in main.dart and provided app-wide via MultiProvider.
Uses go_router with type-safe routing via code generation (router.g.dart):
- TypedGoRoute for standard routes
- TypedShellRoute for nested navigation (e.g., settings)
- Route observation via
TalkerRouteObserverfor debugging
The app performs optimized cold start initialization:
Global.init()- Loads essential data (package info, preferences, GeoJSON, location database, time tables)Preference.init()- Initializes SharedPreferencesGlobalProviders.init()- Sets up state management- Parallel loading of localizations (AppLocalizations, LocationNameLocalizations)
- Conditional initialization based on first launch:
- First launch: FCM and notifications initialized before runApp
- Subsequent launches: Background initialization after runApp for faster startup
CompassServiceandLocationServiceManagerinitialized asynchronously
lib/
├── api/ # API client and data models
│ ├── exptech.dart # Main API client with gzip/zstd compression
│ ├── route.dart # API endpoint definitions
│ └── model/ # JSON-serializable data models (freezed/json_annotation)
├── app/ # Feature modules organized by screen
│ ├── home/ # Home page with timeline and weather
│ ├── map/ # MapLibre-based map with earthquake/weather layers
│ ├── settings/ # Settings screens (nested routing)
│ ├── welcome/ # Onboarding flow
│ ├── changelog/ # Changelog display
│ └── layout.dart # Main app layout wrapper
├── core/ # Core services and initialization
│ ├── compass.dart # Compass sensor service
│ ├── device_info.dart # Device information
│ ├── eew.dart # Earthquake Early Warning logic
│ ├── fcm.dart # Firebase Cloud Messaging
│ ├── gps_location.dart # GPS location services
│ ├── i18n.dart # Internationalization loaders
│ ├── notify.dart # Local notification management (awesome_notifications)
│ ├── preference.dart # SharedPreferences wrapper
│ ├── providers.dart # Global state providers
│ ├── rts.dart # Real-time seismic data
│ ├── service.dart # Background services (LocationServiceManager)
│ └── update.dart # App update checking
├── models/ # State management models
│ ├── data.dart # DpipDataModel (ChangeNotifier)
│ ├── settings/ # Settings models
│ └── map/ # Map-specific models
├── utils/ # Utility functions and extensions
│ ├── constants.dart # App-wide constants
│ ├── extensions/ # Extension methods (BuildContext, Response, etc.)
│ ├── functions.dart # Helper functions
│ └── intensity_color.dart, radar_color.dart # Color mapping utilities
├── widgets/ # Reusable UI components
├── app.dart # DpipApp widget (MaterialApp wrapper)
├── global.dart # Global singleton (packageInfo, location data, GeoJSON)
├── main.dart # App entry point
└── router.dart # Type-safe routing configuration
- Compressed Assets: Location data and time tables are gzip-compressed (
assets/*.json.gz) and decompressed on load for reduced APK size - Network Compression: API client supports gzip, deflate, and zstd compression via custom
_GzipClient - GeoJSON Data: Box and town boundaries loaded from
assets/box.jsonandassets/map/town.json.gz
- Load Balancing: Multiple API endpoints with random selection (
api-1.exptech.dev,api-2.exptech.dev,lb-1.exptech.devthroughlb-4.exptech.dev) - Model Generation: Uses
json_annotationandfreezedfor immutable data models - Type-Safe Routes: All API endpoints centralized in
api/route.dartwith parameter validation
Multi-channel notification system with granular control:
- EEW (Earthquake Early Warning)
- Earthquake reports (intensity, monitor, report)
- Weather alerts (thunderstorm, advisory, evacuation)
- Tsunami information
- Announcements
Notifications use awesome_notifications for local notifications and FCM for push notifications. Settings stored via SettingsNotificationModel and synced to backend.
MapLibre GL-based map (lib/app/map/) with multiple layer managers:
managers/lightning.dart- Lightning strike visualizationmanagers/precipitation.dart- Precipitation datamanagers/radar.dart- Weather radar tilesmanagers/temperature.dart- Temperature overlaysmanagers/tsunami.dart- Tsunami warning zonesmanagers/wind.dart- Wind data
Supports query parameters for initial state (e.g., /map?layers=radar,lightning&report=12345).
Uses i18n_extension package with translations in assets/translations/. Supported locales:
- English (en)
- Japanese (ja)
- Korean (ko)
- Russian (ru)
- Vietnamese (vi)
- Chinese Simplified (zh-Hans)
- Chinese Traditional (zh-Hant)
Crowdin integration for community translations.
This project uses code generation for:
- Routing:
go_router_buildergenerates type-safe routes inrouter.g.dart - JSON Serialization:
json_serializablegenerates.g.dartfiles for models - Freezed Models:
freezedgenerates immutable data classes with.freezed.dartfiles
Always run dart run build_runner build after modifying:
- Route definitions in
router.dart - Models with
@JsonSerializable()or@freezedannotations
Several packages use forked versions from ExpTechTW:
android_alarm_manager_plus(from plus_plugins)disable_battery_optimizationflutter_icmp_ping
maplibre_gl- Map renderingawesome_notifications+awesome_notifications_fcm- Notificationsfirebase_core+firebase_messaging- Push notifications (min iOS 15 support)provider- State managementgo_router- Navigationfreezed_annotation+json_annotation- Code generationgeolocator- GPS locationi18n_extension- Internationalizationzstandard- Compression support
The app uses Firebase for:
- Cloud Messaging (FCM) for push notifications
- Crashlytics (Android only) for crash reporting
Ensure Firebase configuration files exist:
- Android:
android/app/google-services.json - iOS:
ios/Runner/GoogleService-Info.plist
Based on .github/pull_request_template.md:
- Keep PRs small when possible
- Use descriptive commit messages
- Update relevant documentation and include screenshots
- Avoid force-pushing after review
- Use draft PRs for work in progress
PR Types:
- Refactoring (重構)
- New Feature (新功能)
- Bug Fix (錯誤修復)
- Optimization (最佳化)
- Documentation Update (技術文件更新)
UI Changes Checklist:
- Semantic variable naming
- AA color contrast compliance
The app includes comprehensive logging via talker_flutter:
- Route:
/debug/logs(AppDebugLogsPage) - All providers and core services log through
TalkerManager.instance - Cold start performance metrics logged in
main.dart
- Lazy Initialization: Non-critical services (DeviceInfo on Android, Compass, Location) initialize asynchronously after runApp
- First Launch Detection: Distinguishes first launch to prioritize critical initialization (FCM/notifications)
- Parallel Loading: Localizations and global data load concurrently
- Asset Compression: Reduces initial load time and APK size
- No existing test suite (no
test/directory) - Settings are organized with numbered prefixes in paths:
(1.eew),(2.earthquake),(3.weather),(4.tsunami),(5.basic) - Some legacy code exists in
app_old/androute/directories - HTTP proxy support available via settings (
lib/app/settings/proxy/)