import 'package:uto_manager/domain/entities/authorized_rank.dart'; import 'package:uto_manager/domain/entities/doctrinal_branch.dart'; import 'package:uto_manager/domain/entities/echelon.dart'; import 'package:uto_manager/domain/entities/position_slot.dart'; import 'package:uto_manager/domain/entities/unit_node.dart'; import 'package:uto_manager/domain/value_objects/duty_mos.dart'; // --------------------------------------------------------------------------- // Template definition model // --------------------------------------------------------------------------- /// Defines a position slot within a template unit definition. class SlotDefinition { const SlotDefinition({ required this.positionTitle, required this.dutyMos, required this.authorizedRank, this.isKeyLeader = false, }); final String positionTitle; final String dutyMos; final String authorizedRank; final bool isKeyLeader; } /// Defines a unit node within a template, including its slots and children. class UnitDefinition { const UnitDefinition({ required this.name, required this.echelon, required this.branch, this.isKeyLeader = false, this.slots = const [], this.children = const [], }); final String name; final String echelon; final String branch; final bool isKeyLeader; final List slots; final List children; } // --------------------------------------------------------------------------- // Instantiation result // --------------------------------------------------------------------------- /// The result of instantiating a doctrinal template. class InstantiationResult { const InstantiationResult({ required this.units, required this.slots, }); /// All [UnitNode]s in the instantiated tree (flat list, ordered parent-first). final List units; /// All [PositionSlot]s in the instantiated tree. final List slots; } // --------------------------------------------------------------------------- // Service // --------------------------------------------------------------------------- /// Converts a [UnitDefinition] tree into concrete [UnitNode] and /// [PositionSlot] domain objects with generated UUIDs. /// /// This service is pure domain logic with no infrastructure dependencies. /// The caller is responsible for persisting the result to the database. class TemplateInstantiator { const TemplateInstantiator({required this.idGenerator}); /// Function that generates a unique ID string (e.g., UUID v4). final String Function() idGenerator; /// Instantiates [definition] as a root unit (no parent). InstantiationResult instantiate(UnitDefinition definition) { final units = []; final slots = []; _walk(definition, null, units, slots); return InstantiationResult(units: units, slots: slots); } void _walk( UnitDefinition def, String? parentUnitId, List units, List slots, ) { final unitId = idGenerator(); final unit = UnitNode( unitId: unitId, echelon: Echelon.values.firstWhere((e) => e.name == def.echelon), branch: DoctrinalBranch.values.firstWhere((b) => b.name == def.branch), parentUnitId: parentUnitId, name: def.name, isKeyLeader: def.isKeyLeader, ); units.add(unit); for (final slotDef in def.slots) { final slot = PositionSlot( slotId: idGenerator(), unitId: unitId, positionTitle: slotDef.positionTitle, dutyMos: DutyMos.unvalidated(slotDef.dutyMos), authorizedRank: AuthorizedRank.values.firstWhere((r) => r.name == slotDef.authorizedRank), isKeyLeader: slotDef.isKeyLeader, ); slots.add(slot); } for (final child in def.children) { _walk(child, unitId, units, slots); } } }