部署文档.md 5.3 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project

CoinVision — a production cryptocurrency exchange (CEX) Flutter app targeting Android and iOS.

Commands

# 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

Runtime overrides via --dart-define

flutter 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

Architecture

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.

State Management — Riverpod 2

  • Use @riverpod annotation for code generation
  • State objects must be immutable Freezed classes, updated with copyWith
  • In Widgets: ref.watch() for state, ref.read(…notifier) for actions
  • Notifier re-initialization: ref.invalidate(someProvider)

Navigation — GoRouter 14

  • All routes defined in lib/core/router/app_router.dart
  • StatefulShellRoute with 5 bottom-nav branches (preserves tab state)
  • Auth guard: routes under /asset, /user/*, /broker/* require login
  • Session expiry: API error code 4000 triggers logout dialog
  • Always use context.push() / context.go() — never Navigator.push

Networking — Dio

  • Central client in lib/core/network/dio_client.dart with interceptors for token injection, error wrapping, and node failover
  • Multi-node resilience: lib/providers/node_provider.dart — speed tests nodes, circuit-breaks after 3 failures for 60s
  • Timeouts: connect 15s, receive 15s
  • Session error (code 4000) → auto logout; interceptor suppresses duplicate navigation

Data Models — Freezed

  • All domain models use @freezed with fromJson/toJson
  • Run build_runner after any model or provider annotation change
  • Generated files (*.freezed.dart, *.g.dart) are committed

Storage

Data Storage
Auth tokens flutter_secure_storage (platform vault)
User preferences SharedPreferences
Local caching Hive

Real-time Data — WebSocket

  • web_socket_channel for market data streams
  • Lifecycle managed in lib/providers/ws_provider.dart
  • Manual reconnect logic on disconnect

Key Conventions

New feature development order (required)

  1. Define Freezed domain model (data/models/)
  2. Implement Service — stateless HTTP only (data/services/)
  3. Implement Repository — SSOT, caching, data transform (data/repositories/)
  4. Implement Notifier — Freezed State + methods (providers/)
  5. Implement Screen/Widget — ConsumerWidget, 3-state UI (presentation/)

UI rules

  • Widgets use ConsumerWidget or ConsumerStatefulWidget
  • Always handle loading / error / empty three states
  • Use AppColors — rise: #0ecb81, fall: #f6465d
  • Use formatPrice() / formatChange() from core/utils/ — never hardcode decimal places
  • Layout scaled with flutter_screenutil (design base: 375×812)
  • Use ListView.builder for lists; const constructors for static sub-widgets
  • BottomSheets via showModalBottomSheet with isScrollControlled: true

Localization

5 locales: zh, zh_TW, en, ja, ko. ARB files in lib/core/l10n/. Config in l10n.yaml.

Environment / Build

  • Debug config: lib/core/config/env_debug.dart, Android package com.ibit.app.test
  • Release config: lib/core/config/env_release.dart, Android package com.ibit.app
  • Android signing: keystore at android/app/keystore, password in android/key.properties (gitignored)
  • Version format in pubspec.yaml: major.minor.patch+major*10000+minor*100+patch

Git Commit Convention

<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.

Pre-commit Checklist

  • dart format . — no errors
  • flutter analyze — no errors or warnings
  • No print() / debugPrint() left in code
  • build_runner output is up to date
  • State is immutable Freezed; updated via copyWith
  • Tokens stored in flutter_secure_storage, not SharedPreferences