allsource_core/domain/value_objects/
system_stream.rs1use crate::domain::value_objects::{EntityId, EventType, TenantId};
2
3pub const SYSTEM_EVENT_TYPE_PREFIX: &str = "_system.";
24
25pub const SYSTEM_TENANT_ID: &str = "_system";
27
28pub const SYSTEM_ENTITY_ID_PREFIX: &str = "_system:";
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum SystemDomain {
34 Tenant,
36 Audit,
38 Config,
40 Schema,
42 Policy,
44}
45
46impl SystemDomain {
47 pub fn as_str(&self) -> &'static str {
49 match self {
50 Self::Tenant => "tenant",
51 Self::Audit => "audit",
52 Self::Config => "config",
53 Self::Schema => "schema",
54 Self::Policy => "policy",
55 }
56 }
57
58 pub fn all() -> &'static [SystemDomain] {
60 &[
61 Self::Tenant,
62 Self::Audit,
63 Self::Config,
64 Self::Schema,
65 Self::Policy,
66 ]
67 }
68}
69
70pub mod tenant_events {
72 pub const CREATED: &str = "_system.tenant.created";
73 pub const UPDATED: &str = "_system.tenant.updated";
74 pub const SUSPENDED: &str = "_system.tenant.suspended";
75 pub const REACTIVATED: &str = "_system.tenant.reactivated";
76 pub const DELETED: &str = "_system.tenant.deleted";
77 pub const QUOTA_UPDATED: &str = "_system.tenant.quota_updated";
78 pub const USAGE_UPDATED: &str = "_system.tenant.usage_updated";
79}
80
81pub mod audit_events {
83 pub const RECORDED: &str = "_system.audit.recorded";
84}
85
86pub mod config_events {
88 pub const SET: &str = "_system.config.set";
89 pub const DELETED: &str = "_system.config.deleted";
90}
91
92pub mod schema_events {
94 pub const REGISTERED: &str = "_system.schema.registered";
95 pub const UPDATED: &str = "_system.schema.updated";
96 pub const DELETED: &str = "_system.schema.deleted";
97}
98
99pub mod policy_events {
101 pub const CREATED: &str = "_system.policy.created";
102 pub const UPDATED: &str = "_system.policy.updated";
103 pub const DELETED: &str = "_system.policy.deleted";
104}
105
106pub fn is_system_event_type(event_type: &str) -> bool {
108 event_type.starts_with(SYSTEM_EVENT_TYPE_PREFIX)
109}
110
111pub fn is_system_entity_id(entity_id: &str) -> bool {
113 entity_id.starts_with(SYSTEM_ENTITY_ID_PREFIX)
114}
115
116pub fn is_system_tenant_id(tenant_id: &str) -> bool {
118 tenant_id == SYSTEM_TENANT_ID
119}
120
121pub fn system_entity_id(domain: SystemDomain, resource_id: &str) -> String {
125 format!(
126 "{}{}:{}",
127 SYSTEM_ENTITY_ID_PREFIX,
128 domain.as_str(),
129 resource_id
130 )
131}
132
133pub fn system_tenant_id() -> TenantId {
135 TenantId::new_unchecked(SYSTEM_TENANT_ID.to_string())
136}
137
138pub fn system_event_type(event_type_str: &str) -> EventType {
142 debug_assert!(
143 event_type_str.starts_with(SYSTEM_EVENT_TYPE_PREFIX),
144 "System event type must start with '{}'",
145 SYSTEM_EVENT_TYPE_PREFIX
146 );
147 EventType::new_unchecked(event_type_str.to_string())
148}
149
150pub fn system_entity_id_value(domain: SystemDomain, resource_id: &str) -> EntityId {
152 EntityId::new_unchecked(system_entity_id(domain, resource_id))
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn test_system_event_type_prefix() {
161 assert!(is_system_event_type("_system.tenant.created"));
162 assert!(is_system_event_type("_system.config.set"));
163 assert!(!is_system_event_type("order.placed"));
164 assert!(!is_system_event_type("system.tenant.created"));
165 }
166
167 #[test]
168 fn test_system_entity_id_prefix() {
169 assert!(is_system_entity_id("_system:tenant:acme"));
170 assert!(is_system_entity_id("_system:config:max_conn"));
171 assert!(!is_system_entity_id("user-123"));
172 assert!(!is_system_entity_id("system:tenant:acme"));
173 }
174
175 #[test]
176 fn test_system_tenant_id() {
177 assert!(is_system_tenant_id("_system"));
178 assert!(!is_system_tenant_id("default"));
179 assert!(!is_system_tenant_id("acme-corp"));
180 }
181
182 #[test]
183 fn test_system_entity_id_construction() {
184 let id = system_entity_id(SystemDomain::Tenant, "acme-corp");
185 assert_eq!(id, "_system:tenant:acme-corp");
186
187 let id = system_entity_id(SystemDomain::Config, "max_connections");
188 assert_eq!(id, "_system:config:max_connections");
189
190 let id = system_entity_id(SystemDomain::Audit, "tenant-1");
191 assert_eq!(id, "_system:audit:tenant-1");
192 }
193
194 #[test]
195 fn test_system_domain_all() {
196 let domains = SystemDomain::all();
197 assert_eq!(domains.len(), 5);
198 }
199
200 #[test]
201 fn test_system_event_type_constants_are_valid() {
202 let constants = [
204 tenant_events::CREATED,
205 tenant_events::UPDATED,
206 tenant_events::SUSPENDED,
207 tenant_events::REACTIVATED,
208 tenant_events::DELETED,
209 tenant_events::QUOTA_UPDATED,
210 tenant_events::USAGE_UPDATED,
211 audit_events::RECORDED,
212 config_events::SET,
213 config_events::DELETED,
214 schema_events::REGISTERED,
215 schema_events::UPDATED,
216 schema_events::DELETED,
217 policy_events::CREATED,
218 policy_events::UPDATED,
219 policy_events::DELETED,
220 ];
221
222 for constant in constants {
223 let result = EventType::new(constant.to_string());
224 assert!(
225 result.is_ok(),
226 "System event type '{}' failed validation: {:?}",
227 constant,
228 result.err()
229 );
230 }
231 }
232
233 #[test]
234 fn test_system_tenant_id_is_valid() {
235 let result = TenantId::new(SYSTEM_TENANT_ID.to_string());
236 assert!(result.is_ok(), "System tenant ID should be valid");
237 }
238
239 #[test]
240 fn test_system_entity_ids_are_valid() {
241 for domain in SystemDomain::all() {
242 let id_str = system_entity_id(*domain, "test-resource");
243 let result = EntityId::new(id_str.clone());
244 assert!(
245 result.is_ok(),
246 "System entity ID '{}' failed validation: {:?}",
247 id_str,
248 result.err()
249 );
250 }
251 }
252
253 #[test]
254 fn test_system_event_type_helper() {
255 let et = system_event_type(tenant_events::CREATED);
256 assert_eq!(et.as_str(), "_system.tenant.created");
257 }
258
259 #[test]
260 fn test_system_entity_id_value_helper() {
261 let eid = system_entity_id_value(SystemDomain::Tenant, "acme");
262 assert_eq!(eid.as_str(), "_system:tenant:acme");
263 }
264}