122 lines
3.8 KiB
Dart
122 lines
3.8 KiB
Dart
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<SlotDefinition> slots;
|
|
final List<UnitDefinition> 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<UnitNode> units;
|
|
|
|
/// All [PositionSlot]s in the instantiated tree.
|
|
final List<PositionSlot> 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 = <UnitNode>[];
|
|
final slots = <PositionSlot>[];
|
|
_walk(definition, null, units, slots);
|
|
return InstantiationResult(units: units, slots: slots);
|
|
}
|
|
|
|
void _walk(
|
|
UnitDefinition def,
|
|
String? parentUnitId,
|
|
List<UnitNode> units,
|
|
List<PositionSlot> 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);
|
|
}
|
|
}
|
|
}
|