This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CoinVision — a production cryptocurrency exchange (CEX) Flutter app targeting Android and iOS.
# Run
flutter run
# Build
flutter build apk --debug --target-platform android-arm64 # Android debug
flutter build apk --release --target-platform android-arm64 # Android release
flutter build ipa --release --export-method=ad-hoc # iOS ad-hoc
flutter build ipa --release # iOS release
# Code generation (required after model/provider changes)
dart run build_runner build --delete-conflicting-outputs
dart run build_runner watch # watch mode
# Format & analyze
dart format .
flutter analyze
# Test
flutter test
# Reset
flutter clean && flutter pub get
--dart-defineflutter run --dart-define=API_BASE_URL=https://custom.api.com/api/
flutter run --dart-define=WS_URL=wss://custom.ws.com/market
flutter run --dart-define=ENABLE_MOCK=true
Strict 3-layer clean architecture. Never bypass layers.
用户交互 → Notifier → Repository → Service/API
↓
UI (Widget) ←── State (immutable) ←── Notifier ←──
| Layer | Location | Responsibility |
|---|---|---|
| Presentation | lib/presentation/ |
Rendering & user interaction only. No business logic. |
| Provider (ViewModel) | lib/providers/ |
Riverpod Notifiers. Expose immutable State + methods. |
| Data | lib/data/ |
Services (stateless HTTP), Repositories (SSOT, caching), Models (Freezed) |
| Core | lib/core/ |
Dio client, GoRouter, theme, l10n, utils. No business logic. |
@riverpod annotation for code generationcopyWithref.watch() for state, ref.read(…notifier) for actionsref.invalidate(someProvider)lib/core/router/app_router.dart/asset, /user/*, /broker/* require login4000 triggers logout dialogcontext.push() / context.go() — never Navigator.pushlib/core/network/dio_client.dart with interceptors for token injection, error wrapping, and node failoverlib/providers/node_provider.dart — speed tests nodes, circuit-breaks after 3 failures for 60s@freezed with fromJson/toJsonbuild_runner after any model or provider annotation change*.freezed.dart, *.g.dart) are committed| Data | Storage |
|---|---|
| Auth tokens | flutter_secure_storage (platform vault) |
| User preferences | SharedPreferences |
| Local caching | Hive |
web_socket_channel for market data streamslib/providers/ws_provider.dartdata/models/)data/services/)data/repositories/)providers/)presentation/)ConsumerWidget or ConsumerStatefulWidgetAppColors — rise: #0ecb81, fall: #f6465dformatPrice() / formatChange() from core/utils/ — never hardcode decimal placesflutter_screenutil (design base: 375×812)ListView.builder for lists; const constructors for static sub-widgetsshowModalBottomSheet with isScrollControlled: true5 locales: zh, zh_TW, en, ja, ko. ARB files in lib/core/l10n/. Config in l10n.yaml.
lib/core/config/env_debug.dart, Android package com.ibit.app.testlib/core/config/env_release.dart, Android package com.ibit.appandroid/app/keystore, password in android/key.properties (gitignored)pubspec.yaml: major.minor.patch+major*10000+minor*100+patch<type>(<scope>): <subject> (Conventional Commits)
Scopes: auth, market, trading, futures, asset, user, core, widget, l10n
Use /commit skill to generate commit messages. Only commit locally — do not push unless explicitly asked.
dart format . — no errorsflutter analyze — no errors or warningsprint() / debugPrint() left in codebuild_runner output is up to datecopyWithflutter_secure_storage, not SharedPreferences