# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Build & Development Commands ```bash flutter pub get # Install dependencies flutter analyze # Run static analysis (run after every task) dart format # Format code flutter test # Run tests flutter run -d # Run app on device dart run build_runner build # Generate ObjectBox code after entity changes ``` **Important:** Run `flutter analyze` after every task and fix any reported issues before committing. ## Architecture Overview This is a Flutter app for job/task management with MQTT-based backend communication. The app is written in German for end users. ### Core Components **AppState** (`lib/app_state.dart`) - Singleton managing global state: `appUserId`, in-memory jobs list - Handles persistence via DatabaseService with coalesced writes - Emits `jobsUpdated` events via both StreamController and DartMQ **DartMQ** (`lib/services/dart_mq.dart`) - Lightweight in-app pub/sub message bus for decoupled communication - Key topics defined in `MQTopics`: `connectionStatus`, `authResponse`, `jobsResponse`, `taskEvents`, `jobsUpdated`, `chatIncoming`, `chatOutgoing` - UI and services subscribe/publish without direct dependencies **MqttService** (`lib/services/mqtt_service.dart`, aliased as `StompService`) - MQTT client connecting to Mosquitto broker at `mqtt-2.assecutor.de:42099` - Handles authentication, job loading, chat messages, task completion - Message envelope pattern with ACK/retry system for reliable delivery - Offline message queuing via DatabaseService - Publishes all server events through DartMQ topics **DatabaseService** (`lib/services/database_service.dart`) - ObjectBox-based local persistence - Stores jobs, task status, user data, chat messages, queued MQTT messages - Entities in `lib/entities/` require `dart run build_runner build` after changes ### Data Flow 1. `LoginView` initiates MQTT connection, sends credentials to `/server/login` 2. Server responds on `/client/{appId}/auth` → MqttService publishes `MQTopics.authResponse` 3. On success, `AppState` stores `appUserId`, `JobsView` requests jobs via `/server/{userId}/jobs/assigned` 4. Jobs arrive on `/client/{userId}/jobs` → published to `MQTopics.jobsResponse` → persisted → UI refresh via `MQTopics.jobsUpdated` 5. Task updates flow through `/client/{userId}/notifications` → `MQTopics.taskEvents` ### Models - **Job** (`lib/models/job.dart`): Contains pickup/delivery addresses, cargo items, and tasks - **Task** (`lib/models/task.dart`): Abstract base with subtypes: `ConfirmationTask`, `PhotoTask`, `TodoListTask`, `SignatureTask`, `BarcodeTask`, `CommentTask`, `GenericTask` - **ChatMessage** (`lib/models/chat_message.dart`): Chat with direction, content type, job linking ### Views - `LoginView` → `JobsView` → `CargoItemsView` → Task screens - `ChatsView` → `ChatDetailsView` - Task capture screens in `lib/tasks/`: photo, signature, barcode ## Key Patterns - All services are singletons (factory constructors returning `_instance`) - MQTT messages wrapped in `MessageEnvelope` for reliable delivery with ACK - UI subscribes to DartMQ topics rather than holding service references - Jobs are normalized before persistence to ensure consistent data