Skip to main content

profile_runtime/
exception.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use stack_ids::{ApplicabilityContextId, ProfileExceptionBundleId};
4
5pub const PROFILE_EXCEPTION_BUNDLE_V1_SCHEMA: &str = "profile_exception_bundle_v1";
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
8pub struct ProfileExceptionBundleV1 {
9    pub schema_version: String,
10    pub profile_exception_bundle_id: ProfileExceptionBundleId,
11    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12    pub affected_context_refs: Vec<ApplicabilityContextId>,
13    #[serde(default, skip_serializing_if = "Vec::is_empty")]
14    pub affected_profile_refs: Vec<String>,
15    pub exception_class: String,
16    pub reason: String,
17    pub scope: String,
18    pub starts_at: String,
19    pub expires_at: String,
20    #[serde(default, skip_serializing_if = "Vec::is_empty")]
21    pub approval_refs: Vec<String>,
22    #[serde(default, skip_serializing_if = "Vec::is_empty")]
23    pub residual_obligations: Vec<String>,
24    #[serde(default, skip_serializing_if = "Vec::is_empty")]
25    pub added_monitoring_obligations: Vec<String>,
26    #[serde(default, skip_serializing_if = "Vec::is_empty")]
27    pub added_post_hoc_review_obligations: Vec<String>,
28    #[serde(default, skip_serializing_if = "Vec::is_empty")]
29    pub replay_expectations: Vec<String>,
30    #[serde(default, skip_serializing_if = "Vec::is_empty")]
31    pub cleanup_obligations: Vec<String>,
32    #[serde(default, skip_serializing_if = "Vec::is_empty")]
33    pub compensation_obligations: Vec<String>,
34    pub recorded_at: String,
35}
36
37impl ProfileExceptionBundleV1 {
38    /// Returns true when the exception bundle is active for the requested validity timestamp.
39    pub fn is_active_as_of(&self, valid_as_of: &str) -> bool {
40        self.starts_at.as_str() <= valid_as_of && valid_as_of <= self.expires_at.as_str()
41    }
42}