1use crate::models::{Activity, ActivityCategory, ActivityId, ActivityRegistry};
6
7#[derive(Debug, Clone)]
9pub enum SectorTemplate {
10 Healthcare(HealthcareConfig),
12 Manufacturing(ManufacturingConfig),
14 Finance(FinanceConfig),
16 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 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 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 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 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 pub fn parallel_activities(&self) -> Vec<ParallelActivityDef> {
77 match self {
78 SectorTemplate::Healthcare(cfg) => cfg.parallel_activities(),
79 SectorTemplate::Manufacturing(_) => vec![], SectorTemplate::Finance(cfg) => cfg.parallel_activities(),
81 SectorTemplate::IncidentManagement(_) => vec![], }
83 }
84
85 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 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 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#[derive(Debug, Clone)]
120pub struct ActivityDef {
121 pub id: ActivityId,
123 pub name: &'static str,
125 pub category: ActivityCategory,
127 pub avg_duration_ms: u32,
129 pub duration_variance: f32,
131}
132
133#[derive(Debug, Clone)]
135pub struct TransitionDef {
136 pub source: &'static str,
138 pub target: &'static str,
140 pub probability: f32,
142 pub avg_transition_ms: u32,
144}
145
146#[derive(Debug, Clone)]
148pub struct ParallelActivityDef {
149 pub fork_from: &'static str,
151 pub parallel_activities: Vec<&'static str>,
153 pub join_to: &'static str,
155 pub probability: f32,
157}
158
159#[derive(Debug, Clone)]
165pub struct HealthcareConfig {
166 pub departments: Vec<String>,
168 pub avg_stay_hours: f32,
170 pub emergency_ratio: f32,
172 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 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, }]
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 }, 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 }, 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 }, ]
403 }
404}
405
406#[derive(Debug, Clone)]
412pub struct ManufacturingConfig {
413 pub production_lines: u32,
415 pub batch_size: u32,
417 pub defect_rate: f32,
419 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#[derive(Debug, Clone)]
556pub struct FinanceConfig {
557 pub loan_types: Vec<String>,
559 pub avg_approval_days: f32,
561 pub rejection_rate: f32,
563 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 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, }]
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 }, 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#[derive(Debug, Clone)]
747pub struct IncidentConfig {
748 pub priority_levels: u32,
750 pub avg_resolution_hours: f32,
752 pub escalation_rate: f32,
754 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 }, 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 }, ]
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}