uto_manager/development_status.md

249 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UTO Manager — Development Status
_Last updated: 2026-08-09_
---
## Current Branch
`main` (feature/phase-4-reporting-analytics merged)
## Overall Progress
| Phase | Title | Status |
|-------|-------|--------|
| 1 | Domain Foundation | ✅ Complete |
| 2 | Canvas Engine & Persistence | ✅ Complete |
| 3 | Template Library & Import/Export | ✅ Complete |
| 4 | Reporting & Analytics | ✅ Complete |
| 5 | Multi-user / Sync | 🔲 Not started |
---
## Phase 1 — Domain Foundation ✅
**Completed items:**
- `Echelon` entity with doctrinal hierarchy validation (`isValidParent`, `isValidChild`)
- `DoctrinalBranch` entity with display names
- `AuthorizedRank` entity with pay grade, category flags, `meetsMinimum`, `gradeLevel`
- `DutyMos` value object with MOS dictionary validation and `unvalidated` constructor
- `UnitNode` entity with `copyWith`, `isRoot`, `isValidParentNode`
- `PositionSlot` entity with `isVacant`, `isFilled`, `isKeyLeader`
- `PersonnelRecord` entity with `ReadinessState`, `copyWith`, `isUnassigned`
- `UnitRepository` abstract interface
- `PersonnelRepository` abstract interface
- `domain_entities.dart` barrel export
- Full unit test coverage for all domain entities and value objects
**Test count (Phase 1):** 60 tests
---
## Phase 2 — Canvas Engine & Persistence ✅
**Completed items:**
### Domain Services
- `UnitTreeService` — `buildTree`, `getSubtree`, `getAncestors`, `validateReparent`,
`validateAssignment`, `calculateFillRate`, `getVacantKeyLeaderSlots`, `getMosMismatches`
- `AssignmentService` — `assign`, `unassign`, `aggregateReadiness` with `ReadinessColor`
### Infrastructure — Database
- Drift schema: `Units`, `PositionSlots`, `Personnel`, `Templates` tables
- `AppDatabase` with `forTesting(NativeDatabase.memory())` constructor
- `UnitDao` — full CRUD + watch streams
- `PersonnelDao` — full CRUD + `assignToSlot` / `unassignFromSlot` + watch streams
- `PositionSlotDao` — full CRUD + `assignPersonnel` / `clearAssignment` + watch streams
- `TemplateDao` — full CRUD + `upsertTemplate`
- build_runner code generation (`.g.dart` files)
### Infrastructure — Repositories
- `DriftUnitRepository` — implements `UnitRepository` with domain↔Drift mapping
- `DriftPersonnelRepository` — implements `PersonnelRepository` with domain↔Drift mapping
- `DriftPositionSlotRepository` — concrete slot repository
### Application — BLoC
- `UnitTreeCubit` / `UnitTreeState` (sealed) — tree loading, selection, reparent, subtree delete
- `PersonnelCubit` / `PersonnelState` (sealed) — roster loading, filter, assign/unassign
- `TemplateCubit` / `TemplateState` (sealed) — template save/load/delete
### Presentation
- `HomeScreen` — three-pane adaptive layout (personnel | canvas | inspector)
- `UtoCanvasWidget` — `InteractiveViewer` pan/zoom org chart with drag-and-drop reparent
- `UnitNodeCard` — echelon-colored card with fill rate progress bar
- `PositionSlotCard` — `DragTarget` slot card with MOS badge and readiness color
- `PersonnelListTile` — `Draggable` soldier tile for assignment
- Status bar with live unit/slot fill counts
### App Wiring
- `main.dart` — `MultiBlocProvider` wiring all cubits with production database
**Test count (Phase 2):** 77 new tests (137 total)
---
## Phase 3 — Template Library & Import/Export ✅
**Completed items:**
### Domain Services
- `DoctrinalTemplates` — Pure-Dart library of all five 2026 BCT templates:
- `mbct` — Mobile Brigade Combat Team (3× Mobile Infantry Battalions, Cav Squadron, FA Battalion, MDEP, HKP, Engineer Battalion, Support Battalion)
- `sbct` — Stryker Brigade Combat Team (3× Stryker Infantry Battalions, Cav Recon Squadron, FA Battalion, Engineer Battalion, Support Battalion)
- `abct` — Armored Brigade Combat Team (2× Armor-Heavy CABs, 1× Infantry-Heavy CAB, Armored Cav Squadron, M109A7 FA Battalion, Engineer Battalion)
- `cabHeavy` — Combat Aviation Brigade Heavy (Attack Bn AH-64E, Assault Bn UH-60M/CH-47F, Air Ambulance Co, Aviation Support Bn)
- `cabLight` — Combat Aviation Brigade Light (Attack Recon Bn AH-64E+MQ-9A, Assault Bn, Medical Assault Bn, Aviation Support Bn)
- `TemplateInstantiator` — Converts `UnitDefinition` trees into concrete `UnitNode` + `PositionSlot` domain objects with injected ID generator
- `MtoeValidationEngine` — Pure-domain validation engine with 7 rules:
- **V001** MOS mismatch (warning)
- **V002** Rank mismatch (warning)
- **V003** Vacant key leader (critical)
- **V004** Missing combat medic 68W in platoon (advisory)
- **V005** Missing fire support specialist 13F in platoon (advisory)
- **V006** Structural hierarchy violation (critical)
- **V007** Manning below 70% (warning)
### Infrastructure — Codecs
- `UnitTreeCodec` — JSON encode/decode for full unit tree snapshots (units + slots + personnel)
- Schema version 1 with `exportedAt` timestamp
- `encode` / `decode` (JSON string)
- `encodeToMap` / `decodeFromMap` (Map)
- Handles all optional fields (null parentUnitId, null assignedPersonnelId, qualifications list)
### Application — BLoC
- `TemplateCubit` — Extended with:
- `instantiateDoctrinalTemplate(key)` — instantiates any of the five BCT templates into the live database
- `saveSnapshot(name, bctType, units, slots)` — saves current tree as a named template
- `exportToJson(units, slots)` — encodes tree to JSON string for export
- `importFromJson(json, {replaceExisting})` — decodes and persists imported tree
- `ValidationCubit` / `ValidationState` (sealed) — wraps `MtoeValidationEngine`:
- `validate(units, slots, personnel)` — runs all rules, emits `ValidationComplete`
- `clear()` — resets to `ValidationInitial`
- `ValidationComplete` exposes `.critical`, `.warnings`, `.advisories`, `.findingsForUnit(id)`, `.isClean`
### Domain Value Objects
- `DutyMos` — Extended format validation to accept 4-character aviation AOC codes (e.g., `153A` = 3 digits + 1 letter) in addition to standard 3-character codes
### App Wiring
- `main.dart` — Added `ValidationCubit` to `MultiBlocProvider`
- `TemplateCubit` — Now requires `unitRepository` and `slotRepository` parameters
**Test count (Phase 3):** 54 new tests (191 total)
---
## Phase 4 — Reporting & Analytics ✅
**Completed items:**
### Domain Services
- `CommandEventStore` — In-memory append-only event log for all tree mutations:
- `CommandEvent` with `eventId`, `type`, `payload`, `occurredAt`, `isSynced`
- `CommandEventType` enum: `attachNode`, `detachNode`, `assignPersonnel`, `unassignPersonnel`, `modifySlot`
- `CommandPayloads` factory helpers for each event type
- `append`, `markSynced`, `markAllSynced`, `exportPendingToJson`, `clear`
- Unmodifiable `allEvents` and `pendingEvents` views
- `DeltaSynchronizer` — Offline-first sync helper:
- `syncIfOnline()` — transmits pending events when online, returns count synced
- `isOnline` getter/setter for connectivity simulation
- `IsolateValidationRunner` — Background-isolate wrapper for `MtoeValidationEngine`:
- `start()` / `dispose()` lifecycle management (idempotent start)
- `validate(units, slots, personnel)` — async, runs engine off the main thread
- `ValidationResponse` with `findings`, `hasError`, optional `error` string
- Results guaranteed to match synchronous engine output
### Infrastructure — Codecs
- `ProtobufCodec` — Binary encode/decode for unit tree snapshots:
- 12-byte header: magic `UTOB` (0x55544F42) + version 1 (big-endian uint32)
- Payload: zlib-compressed JSON (reuses `UnitTreeCodec` for serialization)
- `encode(units, slots, personnel)` → `Uint8List`
- `decode(bytes)` → `UnitTreeSnapshot` (validates magic + version)
- `compressionRatio(binaryBytes, jsonBytes)` static helper
- Produces output smaller than raw JSON for non-trivial trees
- Throws `FormatException` for truncated data, wrong magic, or unsupported version
- `PdfChartExporter` — Pure-Dart PDF org-chart generator (no external PDF library):
- `export(units, slots, unitDesignation, {pageSize, exportDate})` → `List<int>`
- Generates valid PDF 1.4 with xref table, trailer, `%%EOF`
- Cover page with unit designation, export date, UNCLASSIFIED banner
- Org-chart page with unit boxes, connector lines (`m`/`l S` operators)
- Supports `PdfPageSize.letter` (612×792), `a4` (595×842), `tabloid` (792×1224)
- Unit names truncated to 18 chars; all echelon levels render without error
### Application — BLoC
- `ValidationCubit` — Extended with isolate-backed validation:
- `startIsolate()` / `disposeIsolate()` lifecycle hooks
- `validateAsync(units, slots, personnel)` — delegates to `IsolateValidationRunner`
- Falls back to synchronous engine if isolate not started
- `ValidationState` extended with `isRunning` flag
### Presentation
- `HomeScreen` — Updated with Phase 4 UI:
- Validation node indicators on canvas: red border for critical findings, amber for warnings
- "Export PDF" action in app bar → calls `PdfChartExporter`, triggers file save dialog
- "Export Binary" action → calls `ProtobufCodec`, saves `.utob` file
- Validation findings panel in inspector pane (grouped by severity)
- Status bar shows pending sync event count
**Test count (Phase 4):** 72 new tests (263 total)
---
## Test Summary
| File | Tests | Status |
|------|-------|--------|
| `authorized_rank_test.dart` | 16 | ✅ |
| `echelon_test.dart` | 17 | ✅ |
| `personnel_record_test.dart` | 13 | ✅ |
| `unit_node_test.dart` | 15 | ✅ |
| `duty_mos_test.dart` | 32 | ✅ |
| `assignment_service_test.dart` | 16 | ✅ |
| `unit_tree_service_test.dart` | 27 | ✅ |
| `mtoe_validation_engine_test.dart` | 22 | ✅ |
| `template_instantiator_test.dart` | 18 | ✅ |
| `unit_tree_codec_test.dart` | 14 | ✅ |
| `command_event_store_test.dart` | 25 | ✅ |
| `validation_isolate_test.dart` | 14 | ✅ |
| `protobuf_codec_test.dart` | 18 | ✅ |
| `pdf_chart_exporter_test.dart` | 19 | ✅ |
| `widget_test.dart` | 1 | ✅ |
| **Total** | **263** | **✅ All pass** |
---
## Known Limitations / Next Steps (Phase 5)
- No multi-user or real-time sync capability (Phase 5)
- Canvas layout is vertical tree only; horizontal layout not yet implemented
- No undo/redo for assignment operations
- No search/filter on the canvas itself
- `DeltaSynchronizer` uses simulated online/offline; real network transport deferred to Phase 5
- `ProtobufCodec` uses zlib-compressed JSON as payload; true protobuf schema deferred to Phase 5
- Template instantiation does not yet persist to database in a single Drift transaction (uses sequential inserts)
---
## Architecture Notes
```
lib/
├── domain/
│ ├── entities/ # Pure Dart domain models (no Flutter deps)
│ ├── value_objects/ # DutyMos (supports 3-char and 4-char AOC formats)
│ ├── repositories/ # Abstract interfaces
│ └── services/ # UnitTreeService, AssignmentService,
│ # MtoeValidationEngine, TemplateInstantiator,
│ # DoctrinalTemplates, CommandEventStore,
│ # DeltaSynchronizer, IsolateValidationRunner
├── infrastructure/
│ ├── codecs/ # UnitTreeCodec (JSON), ProtobufCodec (binary),
│ │ # PdfChartExporter (PDF org chart)
│ ├── database/ # Drift schema, DAOs, generated code
│ └── repositories/ # Drift-backed implementations
├── application/
│ └── blocs/ # UnitTreeCubit, PersonnelCubit,
│ # TemplateCubit, ValidationCubit
└── presentation/
├── screens/ # HomeScreen (with PDF/binary export + validation UI)
└── widgets/ # Canvas, cards, tiles
```