# Architecture ## System Overview The application is a state-driven desktop client with an event-processing pipeline: 1. ingest prediction events from MQTT, 2. persist accepted values in SQLite, 3. evaluate risk based on recent history, 4. update UI state and rendering, 5. export animation state for external consumers. ## Module Structure - `vassistent.bootstrap` Application startup/shutdown orchestration (`ApplicationInitializer`, `ApplicationShutdownManager`) - `vassistent.service` Runtime services and integrations (MQTT, persistence, statistics, evaluation, process management) - `vassistent.model` Core state/data objects (`AppState`, `ProblemLevel`, `DatabaseEntry`, `RatioPoint`) - `vassistent.controller` Connects app state/services with Swing views - `vassistent.ui` Window and visual components - `vassistent.util` Configuration loading/validation and logging ## Runtime Flow ### Startup sequence 1. `App.main` initializes look-and-feel. 2. `ApplicationInitializer.initialize()` validates config and wires all services. 3. MQTT subscription is registered on configured topic. 4. Optional external processes are started via `ProcessManagerService`. 5. UI window/controller is created on the Swing event thread. 6. JVM shutdown hook is registered through `ApplicationShutdownManager`. ### Event processing sequence 1. MQTT message arrives (`MqttClientService.messageArrived`). 2. Payload is routed to `BinaryEventService.handlePayload`. 3. Payload validation checks: - `valid == true` - `_id` is present - `prediction` is `0` or `1` - duplicate `_id` vs last processed message is rejected 4. Accepted value is stored by `DataPersistenceService`. 5. `EvaluationService` requests ratio from `StatisticsService.getRatio(20)`. 6. Ratio is mapped to a `ProblemLevel`. 7. `AppState` updates notify registered listeners. 8. `AnimationFileService` writes the corresponding animation JSON file. ## Core Domain Rules `EvaluationService` maps ratios to levels: - `< 0.5` -> `NONE` - `>= 0.5` -> `WARNING` - `>= 0.8` -> `HIGH` - `>= 0.9` -> `DISASTER` Persistence schema (`binary_event`): - `id` (autoincrement primary key) - `value` (`0`/`1`) - `timestamp` (ISO local date-time string) ## Integration Boundaries - **MQTT**: Eclipse Paho client, broker URL and topic from config. - **Database**: local SQLite file (`data/health.db` by default). - **UI streaming tab**: JCEF browser for a configured URL (`streaming.url`). - **External processes**: optional Python simulator and Unreal launcher script. - **Animation output**: JSON file written to `animation.output.path`. ## Shutdown Behavior `ApplicationShutdownManager` performs: 1. MQTT disconnect, 2. managed process shutdown, 3. runtime database file deletion (`data/health.db`), 4. logger shutdown. ## Architectural Tradeoffs - **Pros** - Clear service boundaries and explicit startup wiring. - Good testability for service layer and integration logic. - Configuration validation catches many misconfigurations early. - **Current tradeoffs** - Local database lifecycle is ephemeral by default (deleted on shutdown). - Startup is tightly coupled to external-process configuration when enabled. - UI logic is mostly verified indirectly through state and service tests.