1use crate::error::{ContinuityValidationError, ContinuityValidationResult};
2use crate::validation::{require_non_empty, require_non_empty_slice, require_schema_version};
3use crate::vocab::{IncidentSeverityV1, IncidentStatusV1};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
8pub struct IncidentCaseV1 {
9 pub schema_version: String,
10 pub incident_case_id: String,
11 pub service_level_profile_id: String,
12 pub severity: IncidentSeverityV1,
13 pub opened_at: String,
14 pub summary: String,
15 pub commander_ref: String,
16 pub status: IncidentStatusV1,
17}
18
19impl IncidentCaseV1 {
20 pub const SCHEMA_VERSION: &'static str = "IncidentCaseV1";
21
22 pub fn new(
23 incident_case_id: impl Into<String>,
24 service_level_profile_id: impl Into<String>,
25 severity: IncidentSeverityV1,
26 opened_at: impl Into<String>,
27 summary: impl Into<String>,
28 commander_ref: impl Into<String>,
29 status: IncidentStatusV1,
30 ) -> Result<Self, ContinuityValidationError> {
31 let value = Self {
32 schema_version: Self::SCHEMA_VERSION.to_string(),
33 incident_case_id: incident_case_id.into(),
34 service_level_profile_id: service_level_profile_id.into(),
35 severity,
36 opened_at: opened_at.into(),
37 summary: summary.into(),
38 commander_ref: commander_ref.into(),
39 status,
40 };
41 value.validate()?;
42 Ok(value)
43 }
44
45 pub fn validate(&self) -> ContinuityValidationResult {
46 require_schema_version(&self.schema_version, Self::SCHEMA_VERSION)?;
47 require_non_empty(&self.incident_case_id, "incident_case_id")?;
48 require_non_empty(&self.service_level_profile_id, "service_level_profile_id")?;
49 require_non_empty(&self.opened_at, "opened_at")?;
50 require_non_empty(&self.summary, "summary")?;
51 require_non_empty(&self.commander_ref, "commander_ref")?;
52 Ok(())
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
57pub struct ContainmentDecisionV1 {
58 pub schema_version: String,
59 pub containment_decision_id: String,
60 pub incident_case_id: String,
61 pub decision: String,
62 pub justification: String,
63 pub approved_by: Vec<String>,
64 pub generated_at: String,
65}
66
67impl ContainmentDecisionV1 {
68 pub const SCHEMA_VERSION: &'static str = "ContainmentDecisionV1";
69
70 pub fn new(
71 containment_decision_id: impl Into<String>,
72 incident_case_id: impl Into<String>,
73 decision: impl Into<String>,
74 justification: impl Into<String>,
75 approved_by: Vec<String>,
76 generated_at: impl Into<String>,
77 ) -> Result<Self, ContinuityValidationError> {
78 let value = Self {
79 schema_version: Self::SCHEMA_VERSION.to_string(),
80 containment_decision_id: containment_decision_id.into(),
81 incident_case_id: incident_case_id.into(),
82 decision: decision.into(),
83 justification: justification.into(),
84 approved_by,
85 generated_at: generated_at.into(),
86 };
87 value.validate()?;
88 Ok(value)
89 }
90
91 pub fn validate(&self) -> ContinuityValidationResult {
92 require_schema_version(&self.schema_version, Self::SCHEMA_VERSION)?;
93 require_non_empty(&self.containment_decision_id, "containment_decision_id")?;
94 require_non_empty(&self.incident_case_id, "incident_case_id")?;
95 require_non_empty(&self.decision, "decision")?;
96 require_non_empty(&self.justification, "justification")?;
97 require_non_empty_slice(&self.approved_by, "approved_by")?;
98 require_non_empty(&self.generated_at, "generated_at")?;
99 Ok(())
100 }
101}
102
103#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
104pub struct ForensicFreezeV1 {
105 pub schema_version: String,
106 pub forensic_freeze_id: String,
107 pub incident_case_id: String,
108 pub frozen_surfaces: Vec<String>,
109 pub retention_hold_until: String,
110 pub initiated_at: String,
111}
112
113impl ForensicFreezeV1 {
114 pub const SCHEMA_VERSION: &'static str = "ForensicFreezeV1";
115
116 pub fn new(
117 forensic_freeze_id: impl Into<String>,
118 incident_case_id: impl Into<String>,
119 frozen_surfaces: Vec<String>,
120 retention_hold_until: impl Into<String>,
121 initiated_at: impl Into<String>,
122 ) -> Result<Self, ContinuityValidationError> {
123 let value = Self {
124 schema_version: Self::SCHEMA_VERSION.to_string(),
125 forensic_freeze_id: forensic_freeze_id.into(),
126 incident_case_id: incident_case_id.into(),
127 frozen_surfaces,
128 retention_hold_until: retention_hold_until.into(),
129 initiated_at: initiated_at.into(),
130 };
131 value.validate()?;
132 Ok(value)
133 }
134
135 pub fn validate(&self) -> ContinuityValidationResult {
136 require_schema_version(&self.schema_version, Self::SCHEMA_VERSION)?;
137 require_non_empty(&self.forensic_freeze_id, "forensic_freeze_id")?;
138 require_non_empty(&self.incident_case_id, "incident_case_id")?;
139 require_non_empty_slice(&self.frozen_surfaces, "frozen_surfaces")?;
140 require_non_empty(&self.retention_hold_until, "retention_hold_until")?;
141 require_non_empty(&self.initiated_at, "initiated_at")?;
142 Ok(())
143 }
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
147pub struct ContinuityExceptionV1 {
148 pub schema_version: String,
149 pub continuity_exception_id: String,
150 pub incident_case_id: String,
151 pub exception_kind: String,
152 pub reason: String,
153 pub expires_at: String,
154 pub post_hoc_review_required: bool,
155}
156
157impl ContinuityExceptionV1 {
158 pub const SCHEMA_VERSION: &'static str = "ContinuityExceptionV1";
159
160 pub fn new(
161 continuity_exception_id: impl Into<String>,
162 incident_case_id: impl Into<String>,
163 exception_kind: impl Into<String>,
164 reason: impl Into<String>,
165 expires_at: impl Into<String>,
166 post_hoc_review_required: bool,
167 ) -> Result<Self, ContinuityValidationError> {
168 let value = Self {
169 schema_version: Self::SCHEMA_VERSION.to_string(),
170 continuity_exception_id: continuity_exception_id.into(),
171 incident_case_id: incident_case_id.into(),
172 exception_kind: exception_kind.into(),
173 reason: reason.into(),
174 expires_at: expires_at.into(),
175 post_hoc_review_required,
176 };
177 value.validate()?;
178 Ok(value)
179 }
180
181 pub fn validate(&self) -> ContinuityValidationResult {
182 require_schema_version(&self.schema_version, Self::SCHEMA_VERSION)?;
183 require_non_empty(&self.continuity_exception_id, "continuity_exception_id")?;
184 require_non_empty(&self.incident_case_id, "incident_case_id")?;
185 require_non_empty(&self.exception_kind, "exception_kind")?;
186 require_non_empty(&self.reason, "reason")?;
187 require_non_empty(&self.expires_at, "expires_at")?;
188 Ok(())
189 }
190}