Skip to main content

ringkernel_procint/fabric/
sector.rs

1//! Industry sector templates for process generation.
2//!
3//! Defines process structures for different domains.
4
5use crate::models::{Activity, ActivityCategory, ActivityId, ActivityRegistry};
6
7/// Industry sector template for process generation.
8#[derive(Debug, Clone)]
9pub enum SectorTemplate {
10    /// Healthcare: Patient journey through hospital.
11    Healthcare(HealthcareConfig),
12    /// Manufacturing: Production workflow.
13    Manufacturing(ManufacturingConfig),
14    /// Finance: Loan approval process.
15    Finance(FinanceConfig),
16    /// IT: Incident management (ITIL).
17    IncidentManagement(IncidentConfig),
18}
19
20impl PartialEq for SectorTemplate {
21    fn eq(&self, other: &Self) -> bool {
22        std::mem::discriminant(self) == std::mem::discriminant(other)
23    }
24}
25
26impl Eq for SectorTemplate {}
27
28impl Default for SectorTemplate {
29    fn default() -> Self {
30        Self::Healthcare(HealthcareConfig::default())
31    }
32}
33
34impl SectorTemplate {
35    /// Get display name.
36    pub fn name(&self) -> &'static str {
37        match self {
38            SectorTemplate::Healthcare(_) => "Healthcare",
39            SectorTemplate::Manufacturing(_) => "Manufacturing",
40            SectorTemplate::Finance(_) => "Finance",
41            SectorTemplate::IncidentManagement(_) => "IT Incident Management",
42        }
43    }
44
45    /// Get short code.
46    pub fn code(&self) -> &'static str {
47        match self {
48            SectorTemplate::Healthcare(_) => "HC",
49            SectorTemplate::Manufacturing(_) => "MF",
50            SectorTemplate::Finance(_) => "FN",
51            SectorTemplate::IncidentManagement(_) => "IT",
52        }
53    }
54
55    /// Get activity definitions for this sector.
56    pub fn activities(&self) -> Vec<ActivityDef> {
57        match self {
58            SectorTemplate::Healthcare(cfg) => cfg.activities(),
59            SectorTemplate::Manufacturing(cfg) => cfg.activities(),
60            SectorTemplate::Finance(cfg) => cfg.activities(),
61            SectorTemplate::IncidentManagement(cfg) => cfg.activities(),
62        }
63    }
64
65    /// Get valid transitions for this sector (source_name, target_name, probability).
66    pub fn transitions(&self) -> Vec<TransitionDef> {
67        match self {
68            SectorTemplate::Healthcare(cfg) => cfg.transitions(),
69            SectorTemplate::Manufacturing(cfg) => cfg.transitions(),
70            SectorTemplate::Finance(cfg) => cfg.transitions(),
71            SectorTemplate::IncidentManagement(cfg) => cfg.transitions(),
72        }
73    }
74
75    /// Get parallel activity definitions (fork/join patterns).
76    pub fn parallel_activities(&self) -> Vec<ParallelActivityDef> {
77        match self {
78            SectorTemplate::Healthcare(cfg) => cfg.parallel_activities(),
79            SectorTemplate::Manufacturing(_) => vec![], // Sequential process
80            SectorTemplate::Finance(cfg) => cfg.parallel_activities(),
81            SectorTemplate::IncidentManagement(_) => vec![], // Sequential process
82        }
83    }
84
85    /// Get start activity names.
86    pub fn start_activities(&self) -> Vec<&'static str> {
87        match self {
88            SectorTemplate::Healthcare(_) => vec!["Registration"],
89            SectorTemplate::Manufacturing(_) => vec!["Order Received"],
90            SectorTemplate::Finance(_) => vec!["Application Submitted"],
91            SectorTemplate::IncidentManagement(_) => vec!["Incident Reported"],
92        }
93    }
94
95    /// Get end activity names.
96    pub fn end_activities(&self) -> Vec<&'static str> {
97        match self {
98            SectorTemplate::Healthcare(_) => vec!["Discharge", "Transfer"],
99            SectorTemplate::Manufacturing(_) => vec!["Shipped"],
100            SectorTemplate::Finance(_) => vec!["Loan Disbursed", "Application Rejected"],
101            SectorTemplate::IncidentManagement(_) => vec!["Incident Closed"],
102        }
103    }
104
105    /// Build activity registry for this sector.
106    pub fn build_registry(&self) -> ActivityRegistry {
107        let mut registry = ActivityRegistry::new();
108        for def in self.activities() {
109            let mut activity = Activity::new(def.id, def.name);
110            activity.category = def.category;
111            activity.expected_duration_ms = def.avg_duration_ms;
112            registry.register(activity);
113        }
114        registry
115    }
116}
117
118/// Activity definition.
119#[derive(Debug, Clone)]
120pub struct ActivityDef {
121    /// Activity ID.
122    pub id: ActivityId,
123    /// Activity name.
124    pub name: &'static str,
125    /// Category.
126    pub category: ActivityCategory,
127    /// Average duration in ms.
128    pub avg_duration_ms: u32,
129    /// Duration variance (0.0 - 1.0).
130    pub duration_variance: f32,
131}
132
133/// Transition definition.
134#[derive(Debug, Clone)]
135pub struct TransitionDef {
136    /// Source activity name.
137    pub source: &'static str,
138    /// Target activity name.
139    pub target: &'static str,
140    /// Transition probability (0.0 - 1.0).
141    pub probability: f32,
142    /// Average transition time in ms.
143    pub avg_transition_ms: u32,
144}
145
146/// Parallel activities that can run concurrently (fork/join pattern).
147#[derive(Debug, Clone)]
148pub struct ParallelActivityDef {
149    /// Source activity that triggers the fork.
150    pub fork_from: &'static str,
151    /// Activities that run in parallel.
152    pub parallel_activities: Vec<&'static str>,
153    /// Activity to join to after all parallel activities complete.
154    pub join_to: &'static str,
155    /// Probability of parallel execution (vs sequential).
156    pub probability: f32,
157}
158
159// ============================================================================
160// Healthcare Configuration
161// ============================================================================
162
163/// Healthcare sector configuration.
164#[derive(Debug, Clone)]
165pub struct HealthcareConfig {
166    /// Departments.
167    pub departments: Vec<String>,
168    /// Average patient stay in hours.
169    pub avg_stay_hours: f32,
170    /// Emergency bypass ratio.
171    pub emergency_ratio: f32,
172    /// Readmission rate.
173    pub readmission_rate: f32,
174}
175
176impl Default for HealthcareConfig {
177    fn default() -> Self {
178        Self {
179            departments: vec![
180                "Emergency".into(),
181                "Cardiology".into(),
182                "Orthopedics".into(),
183                "General".into(),
184            ],
185            avg_stay_hours: 48.0,
186            emergency_ratio: 0.15,
187            readmission_rate: 0.08,
188        }
189    }
190}
191
192impl HealthcareConfig {
193    fn activities(&self) -> Vec<ActivityDef> {
194        vec![
195            ActivityDef {
196                id: 1,
197                name: "Registration",
198                category: ActivityCategory::Start,
199                avg_duration_ms: 300_000,
200                duration_variance: 0.3,
201            },
202            ActivityDef {
203                id: 2,
204                name: "Triage",
205                category: ActivityCategory::Task,
206                avg_duration_ms: 600_000,
207                duration_variance: 0.4,
208            },
209            ActivityDef {
210                id: 3,
211                name: "Examination",
212                category: ActivityCategory::Task,
213                avg_duration_ms: 1_800_000,
214                duration_variance: 0.5,
215            },
216            ActivityDef {
217                id: 4,
218                name: "Lab Tests",
219                category: ActivityCategory::Task,
220                avg_duration_ms: 3_600_000,
221                duration_variance: 0.6,
222            },
223            ActivityDef {
224                id: 5,
225                name: "Imaging",
226                category: ActivityCategory::Task,
227                avg_duration_ms: 2_400_000,
228                duration_variance: 0.4,
229            },
230            ActivityDef {
231                id: 6,
232                name: "Diagnosis",
233                category: ActivityCategory::Gateway,
234                avg_duration_ms: 1_200_000,
235                duration_variance: 0.3,
236            },
237            ActivityDef {
238                id: 7,
239                name: "Treatment",
240                category: ActivityCategory::Task,
241                avg_duration_ms: 7_200_000,
242                duration_variance: 0.7,
243            },
244            ActivityDef {
245                id: 8,
246                name: "Surgery",
247                category: ActivityCategory::Task,
248                avg_duration_ms: 14_400_000,
249                duration_variance: 0.5,
250            },
251            ActivityDef {
252                id: 9,
253                name: "Recovery",
254                category: ActivityCategory::Task,
255                avg_duration_ms: 86_400_000,
256                duration_variance: 0.8,
257            },
258            ActivityDef {
259                id: 10,
260                name: "Discharge",
261                category: ActivityCategory::End,
262                avg_duration_ms: 600_000,
263                duration_variance: 0.3,
264            },
265            ActivityDef {
266                id: 11,
267                name: "Transfer",
268                category: ActivityCategory::End,
269                avg_duration_ms: 1_200_000,
270                duration_variance: 0.4,
271            },
272        ]
273    }
274
275    /// Get parallel activity definitions for healthcare.
276    /// Lab Tests and Imaging can run concurrently after Examination.
277    fn parallel_activities(&self) -> Vec<ParallelActivityDef> {
278        vec![ParallelActivityDef {
279            fork_from: "Examination",
280            parallel_activities: vec!["Lab Tests", "Imaging"],
281            join_to: "Diagnosis",
282            probability: 0.4, // 40% of cases do both tests in parallel
283        }]
284    }
285
286    fn transitions(&self) -> Vec<TransitionDef> {
287        vec![
288            TransitionDef {
289                source: "Registration",
290                target: "Triage",
291                probability: 0.85,
292                avg_transition_ms: 60_000,
293            },
294            TransitionDef {
295                source: "Registration",
296                target: "Examination",
297                probability: 0.15,
298                avg_transition_ms: 30_000,
299            }, // Emergency bypass
300            TransitionDef {
301                source: "Triage",
302                target: "Examination",
303                probability: 1.0,
304                avg_transition_ms: 120_000,
305            },
306            TransitionDef {
307                source: "Examination",
308                target: "Lab Tests",
309                probability: 0.6,
310                avg_transition_ms: 60_000,
311            },
312            TransitionDef {
313                source: "Examination",
314                target: "Imaging",
315                probability: 0.3,
316                avg_transition_ms: 60_000,
317            },
318            TransitionDef {
319                source: "Examination",
320                target: "Diagnosis",
321                probability: 0.1,
322                avg_transition_ms: 30_000,
323            },
324            TransitionDef {
325                source: "Lab Tests",
326                target: "Diagnosis",
327                probability: 0.7,
328                avg_transition_ms: 120_000,
329            },
330            TransitionDef {
331                source: "Lab Tests",
332                target: "Imaging",
333                probability: 0.3,
334                avg_transition_ms: 60_000,
335            },
336            TransitionDef {
337                source: "Imaging",
338                target: "Diagnosis",
339                probability: 1.0,
340                avg_transition_ms: 120_000,
341            },
342            TransitionDef {
343                source: "Diagnosis",
344                target: "Treatment",
345                probability: 0.7,
346                avg_transition_ms: 60_000,
347            },
348            TransitionDef {
349                source: "Diagnosis",
350                target: "Surgery",
351                probability: 0.2,
352                avg_transition_ms: 120_000,
353            },
354            TransitionDef {
355                source: "Diagnosis",
356                target: "Discharge",
357                probability: 0.1,
358                avg_transition_ms: 300_000,
359            },
360            TransitionDef {
361                source: "Treatment",
362                target: "Recovery",
363                probability: 0.3,
364                avg_transition_ms: 60_000,
365            },
366            TransitionDef {
367                source: "Treatment",
368                target: "Discharge",
369                probability: 0.6,
370                avg_transition_ms: 300_000,
371            },
372            TransitionDef {
373                source: "Treatment",
374                target: "Treatment",
375                probability: 0.1,
376                avg_transition_ms: 3_600_000,
377            }, // Rework
378            TransitionDef {
379                source: "Surgery",
380                target: "Recovery",
381                probability: 1.0,
382                avg_transition_ms: 60_000,
383            },
384            TransitionDef {
385                source: "Recovery",
386                target: "Discharge",
387                probability: 0.85,
388                avg_transition_ms: 600_000,
389            },
390            TransitionDef {
391                source: "Recovery",
392                target: "Transfer",
393                probability: 0.1,
394                avg_transition_ms: 600_000,
395            },
396            TransitionDef {
397                source: "Recovery",
398                target: "Surgery",
399                probability: 0.05,
400                avg_transition_ms: 1_800_000,
401            }, // Complication
402        ]
403    }
404}
405
406// ============================================================================
407// Manufacturing Configuration
408// ============================================================================
409
410/// Manufacturing sector configuration.
411#[derive(Debug, Clone)]
412pub struct ManufacturingConfig {
413    /// Number of production lines.
414    pub production_lines: u32,
415    /// Average batch size.
416    pub batch_size: u32,
417    /// Defect rate (0.0 - 1.0).
418    pub defect_rate: f32,
419    /// Rework rate.
420    pub rework_rate: f32,
421}
422
423impl Default for ManufacturingConfig {
424    fn default() -> Self {
425        Self {
426            production_lines: 4,
427            batch_size: 100,
428            defect_rate: 0.03,
429            rework_rate: 0.08,
430        }
431    }
432}
433
434impl ManufacturingConfig {
435    fn activities(&self) -> Vec<ActivityDef> {
436        vec![
437            ActivityDef {
438                id: 1,
439                name: "Order Received",
440                category: ActivityCategory::Start,
441                avg_duration_ms: 60_000,
442                duration_variance: 0.2,
443            },
444            ActivityDef {
445                id: 2,
446                name: "Planning",
447                category: ActivityCategory::Task,
448                avg_duration_ms: 1_800_000,
449                duration_variance: 0.4,
450            },
451            ActivityDef {
452                id: 3,
453                name: "Material Prep",
454                category: ActivityCategory::Task,
455                avg_duration_ms: 3_600_000,
456                duration_variance: 0.3,
457            },
458            ActivityDef {
459                id: 4,
460                name: "Production",
461                category: ActivityCategory::Task,
462                avg_duration_ms: 14_400_000,
463                duration_variance: 0.5,
464            },
465            ActivityDef {
466                id: 5,
467                name: "Quality Check",
468                category: ActivityCategory::Gateway,
469                avg_duration_ms: 1_800_000,
470                duration_variance: 0.4,
471            },
472            ActivityDef {
473                id: 6,
474                name: "Rework",
475                category: ActivityCategory::Task,
476                avg_duration_ms: 7_200_000,
477                duration_variance: 0.6,
478            },
479            ActivityDef {
480                id: 7,
481                name: "Packaging",
482                category: ActivityCategory::Task,
483                avg_duration_ms: 1_200_000,
484                duration_variance: 0.3,
485            },
486            ActivityDef {
487                id: 8,
488                name: "Shipped",
489                category: ActivityCategory::End,
490                avg_duration_ms: 600_000,
491                duration_variance: 0.2,
492            },
493        ]
494    }
495
496    fn transitions(&self) -> Vec<TransitionDef> {
497        vec![
498            TransitionDef {
499                source: "Order Received",
500                target: "Planning",
501                probability: 1.0,
502                avg_transition_ms: 30_000,
503            },
504            TransitionDef {
505                source: "Planning",
506                target: "Material Prep",
507                probability: 1.0,
508                avg_transition_ms: 60_000,
509            },
510            TransitionDef {
511                source: "Material Prep",
512                target: "Production",
513                probability: 1.0,
514                avg_transition_ms: 120_000,
515            },
516            TransitionDef {
517                source: "Production",
518                target: "Quality Check",
519                probability: 1.0,
520                avg_transition_ms: 60_000,
521            },
522            TransitionDef {
523                source: "Quality Check",
524                target: "Packaging",
525                probability: 0.92,
526                avg_transition_ms: 30_000,
527            },
528            TransitionDef {
529                source: "Quality Check",
530                target: "Rework",
531                probability: 0.08,
532                avg_transition_ms: 60_000,
533            },
534            TransitionDef {
535                source: "Rework",
536                target: "Quality Check",
537                probability: 1.0,
538                avg_transition_ms: 60_000,
539            },
540            TransitionDef {
541                source: "Packaging",
542                target: "Shipped",
543                probability: 1.0,
544                avg_transition_ms: 120_000,
545            },
546        ]
547    }
548}
549
550// ============================================================================
551// Finance Configuration
552// ============================================================================
553
554/// Finance sector configuration.
555#[derive(Debug, Clone)]
556pub struct FinanceConfig {
557    /// Loan types.
558    pub loan_types: Vec<String>,
559    /// Average approval days.
560    pub avg_approval_days: f32,
561    /// Rejection rate.
562    pub rejection_rate: f32,
563    /// Additional review rate.
564    pub additional_review_rate: f32,
565}
566
567impl Default for FinanceConfig {
568    fn default() -> Self {
569        Self {
570            loan_types: vec![
571                "Personal".into(),
572                "Mortgage".into(),
573                "Auto".into(),
574                "Business".into(),
575            ],
576            avg_approval_days: 5.0,
577            rejection_rate: 0.15,
578            additional_review_rate: 0.20,
579        }
580    }
581}
582
583impl FinanceConfig {
584    fn activities(&self) -> Vec<ActivityDef> {
585        vec![
586            ActivityDef {
587                id: 1,
588                name: "Application Submitted",
589                category: ActivityCategory::Start,
590                avg_duration_ms: 300_000,
591                duration_variance: 0.2,
592            },
593            ActivityDef {
594                id: 2,
595                name: "Document Verification",
596                category: ActivityCategory::Task,
597                avg_duration_ms: 7_200_000,
598                duration_variance: 0.5,
599            },
600            ActivityDef {
601                id: 3,
602                name: "Credit Check",
603                category: ActivityCategory::Task,
604                avg_duration_ms: 3_600_000,
605                duration_variance: 0.3,
606            },
607            ActivityDef {
608                id: 4,
609                name: "Income Verification",
610                category: ActivityCategory::Task,
611                avg_duration_ms: 14_400_000,
612                duration_variance: 0.6,
613            },
614            ActivityDef {
615                id: 5,
616                name: "Risk Assessment",
617                category: ActivityCategory::Gateway,
618                avg_duration_ms: 7_200_000,
619                duration_variance: 0.4,
620            },
621            ActivityDef {
622                id: 6,
623                name: "Additional Review",
624                category: ActivityCategory::Task,
625                avg_duration_ms: 86_400_000,
626                duration_variance: 0.7,
627            },
628            ActivityDef {
629                id: 7,
630                name: "Final Approval",
631                category: ActivityCategory::Gateway,
632                avg_duration_ms: 3_600_000,
633                duration_variance: 0.3,
634            },
635            ActivityDef {
636                id: 8,
637                name: "Loan Disbursed",
638                category: ActivityCategory::End,
639                avg_duration_ms: 1_800_000,
640                duration_variance: 0.2,
641            },
642            ActivityDef {
643                id: 9,
644                name: "Application Rejected",
645                category: ActivityCategory::End,
646                avg_duration_ms: 600_000,
647                duration_variance: 0.2,
648            },
649        ]
650    }
651
652    /// Get parallel activity definitions for finance.
653    /// Credit Check and Income Verification can run concurrently.
654    fn parallel_activities(&self) -> Vec<ParallelActivityDef> {
655        vec![ParallelActivityDef {
656            fork_from: "Document Verification",
657            parallel_activities: vec!["Credit Check", "Income Verification"],
658            join_to: "Risk Assessment",
659            probability: 0.5, // 50% of cases run checks in parallel
660        }]
661    }
662
663    fn transitions(&self) -> Vec<TransitionDef> {
664        vec![
665            TransitionDef {
666                source: "Application Submitted",
667                target: "Document Verification",
668                probability: 1.0,
669                avg_transition_ms: 60_000,
670            },
671            TransitionDef {
672                source: "Document Verification",
673                target: "Credit Check",
674                probability: 0.9,
675                avg_transition_ms: 30_000,
676            },
677            TransitionDef {
678                source: "Document Verification",
679                target: "Document Verification",
680                probability: 0.1,
681                avg_transition_ms: 86_400_000,
682            }, // Missing docs
683            TransitionDef {
684                source: "Credit Check",
685                target: "Income Verification",
686                probability: 0.85,
687                avg_transition_ms: 60_000,
688            },
689            TransitionDef {
690                source: "Credit Check",
691                target: "Application Rejected",
692                probability: 0.15,
693                avg_transition_ms: 60_000,
694            },
695            TransitionDef {
696                source: "Income Verification",
697                target: "Risk Assessment",
698                probability: 1.0,
699                avg_transition_ms: 60_000,
700            },
701            TransitionDef {
702                source: "Risk Assessment",
703                target: "Final Approval",
704                probability: 0.75,
705                avg_transition_ms: 60_000,
706            },
707            TransitionDef {
708                source: "Risk Assessment",
709                target: "Additional Review",
710                probability: 0.20,
711                avg_transition_ms: 60_000,
712            },
713            TransitionDef {
714                source: "Risk Assessment",
715                target: "Application Rejected",
716                probability: 0.05,
717                avg_transition_ms: 60_000,
718            },
719            TransitionDef {
720                source: "Additional Review",
721                target: "Final Approval",
722                probability: 0.7,
723                avg_transition_ms: 60_000,
724            },
725            TransitionDef {
726                source: "Additional Review",
727                target: "Application Rejected",
728                probability: 0.3,
729                avg_transition_ms: 60_000,
730            },
731            TransitionDef {
732                source: "Final Approval",
733                target: "Loan Disbursed",
734                probability: 1.0,
735                avg_transition_ms: 120_000,
736            },
737        ]
738    }
739}
740
741// ============================================================================
742// IT Incident Management Configuration
743// ============================================================================
744
745/// IT Incident Management configuration.
746#[derive(Debug, Clone)]
747pub struct IncidentConfig {
748    /// Priority levels.
749    pub priority_levels: u32,
750    /// Average resolution hours.
751    pub avg_resolution_hours: f32,
752    /// Escalation rate.
753    pub escalation_rate: f32,
754    /// Reopen rate.
755    pub reopen_rate: f32,
756}
757
758impl Default for IncidentConfig {
759    fn default() -> Self {
760        Self {
761            priority_levels: 4,
762            avg_resolution_hours: 8.0,
763            escalation_rate: 0.12,
764            reopen_rate: 0.05,
765        }
766    }
767}
768
769impl IncidentConfig {
770    fn activities(&self) -> Vec<ActivityDef> {
771        vec![
772            ActivityDef {
773                id: 1,
774                name: "Incident Reported",
775                category: ActivityCategory::Start,
776                avg_duration_ms: 300_000,
777                duration_variance: 0.3,
778            },
779            ActivityDef {
780                id: 2,
781                name: "Classification",
782                category: ActivityCategory::Task,
783                avg_duration_ms: 600_000,
784                duration_variance: 0.4,
785            },
786            ActivityDef {
787                id: 3,
788                name: "Assignment",
789                category: ActivityCategory::Task,
790                avg_duration_ms: 300_000,
791                duration_variance: 0.3,
792            },
793            ActivityDef {
794                id: 4,
795                name: "Investigation",
796                category: ActivityCategory::Task,
797                avg_duration_ms: 7_200_000,
798                duration_variance: 0.6,
799            },
800            ActivityDef {
801                id: 5,
802                name: "Escalation",
803                category: ActivityCategory::Task,
804                avg_duration_ms: 1_800_000,
805                duration_variance: 0.4,
806            },
807            ActivityDef {
808                id: 6,
809                name: "Resolution",
810                category: ActivityCategory::Task,
811                avg_duration_ms: 3_600_000,
812                duration_variance: 0.5,
813            },
814            ActivityDef {
815                id: 7,
816                name: "Verification",
817                category: ActivityCategory::Gateway,
818                avg_duration_ms: 1_200_000,
819                duration_variance: 0.3,
820            },
821            ActivityDef {
822                id: 8,
823                name: "Incident Closed",
824                category: ActivityCategory::End,
825                avg_duration_ms: 300_000,
826                duration_variance: 0.2,
827            },
828        ]
829    }
830
831    fn transitions(&self) -> Vec<TransitionDef> {
832        vec![
833            TransitionDef {
834                source: "Incident Reported",
835                target: "Classification",
836                probability: 1.0,
837                avg_transition_ms: 30_000,
838            },
839            TransitionDef {
840                source: "Classification",
841                target: "Assignment",
842                probability: 1.0,
843                avg_transition_ms: 60_000,
844            },
845            TransitionDef {
846                source: "Assignment",
847                target: "Investigation",
848                probability: 1.0,
849                avg_transition_ms: 120_000,
850            },
851            TransitionDef {
852                source: "Investigation",
853                target: "Resolution",
854                probability: 0.85,
855                avg_transition_ms: 60_000,
856            },
857            TransitionDef {
858                source: "Investigation",
859                target: "Escalation",
860                probability: 0.12,
861                avg_transition_ms: 60_000,
862            },
863            TransitionDef {
864                source: "Investigation",
865                target: "Investigation",
866                probability: 0.03,
867                avg_transition_ms: 3_600_000,
868            }, // Additional investigation
869            TransitionDef {
870                source: "Escalation",
871                target: "Investigation",
872                probability: 0.7,
873                avg_transition_ms: 1_800_000,
874            },
875            TransitionDef {
876                source: "Escalation",
877                target: "Resolution",
878                probability: 0.3,
879                avg_transition_ms: 600_000,
880            },
881            TransitionDef {
882                source: "Resolution",
883                target: "Verification",
884                probability: 1.0,
885                avg_transition_ms: 60_000,
886            },
887            TransitionDef {
888                source: "Verification",
889                target: "Incident Closed",
890                probability: 0.95,
891                avg_transition_ms: 60_000,
892            },
893            TransitionDef {
894                source: "Verification",
895                target: "Investigation",
896                probability: 0.05,
897                avg_transition_ms: 300_000,
898            }, // Reopen
899        ]
900    }
901}
902
903#[cfg(test)]
904mod tests {
905    use super::*;
906
907    #[test]
908    fn test_healthcare_template() {
909        let template = SectorTemplate::Healthcare(HealthcareConfig::default());
910        assert_eq!(template.name(), "Healthcare");
911        assert!(!template.activities().is_empty());
912        assert!(!template.transitions().is_empty());
913    }
914
915    #[test]
916    fn test_all_templates() {
917        let templates = vec![
918            SectorTemplate::Healthcare(HealthcareConfig::default()),
919            SectorTemplate::Manufacturing(ManufacturingConfig::default()),
920            SectorTemplate::Finance(FinanceConfig::default()),
921            SectorTemplate::IncidentManagement(IncidentConfig::default()),
922        ];
923
924        for template in templates {
925            let registry = template.build_registry();
926            assert!(
927                !registry.is_empty(),
928                "Registry for {} should not be empty",
929                template.name()
930            );
931        }
932    }
933}