Skip to main content

backbone_activity/domain/entity/
mod.rs

1//! Domain Entities
2//!
3//! Generated by metaphor-schema. Do not edit manually.
4
5pub mod activity;
6pub mod activity_type;
7pub mod activity_status;
8pub mod activity_direction;
9
10// Re-exports
11pub use activity::Activity;
12pub use activity::ActivityBuilder;
13pub use activity::ActivityId;
14pub use activity_type::ActivityType;
15pub use activity_status::ActivityStatus;
16pub use activity_direction::ActivityDirection;
17
18// ==========================================================================
19// Entity Trait
20// ==========================================================================
21
22use std::fmt::Debug;
23
24/// Trait for domain entities
25///
26/// All generated entities implement this trait, providing
27/// a common interface for working with domain objects.
28pub trait Entity: Debug + Clone {
29    /// The type of the entity's unique identifier
30    type Id: Debug + Clone + PartialEq;
31
32    /// Get the entity's unique identifier
33    fn entity_id(&self) -> &Self::Id;
34
35    /// Get the entity type name
36    fn entity_type() -> &'static str;
37}
38
39// ==========================================================================
40// Audit Metadata
41// ==========================================================================
42
43use chrono::{DateTime, Utc};
44use serde::{Deserialize, Serialize};
45use uuid::Uuid;
46#[cfg(feature = "openapi")]
47use utoipa::ToSchema;
48
49/// Audit metadata stored as JSONB in the database
50///
51/// This struct consolidates audit fields (timestamps and actors) into a single
52/// JSONB column for efficient storage and flexible querying.
53#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
54#[cfg_attr(feature = "openapi", derive(ToSchema))]
55pub struct AuditMetadata {
56    /// Timestamp when the record was created
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub created_at: Option<DateTime<Utc>>,
59
60    /// Timestamp when the record was last updated
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub updated_at: Option<DateTime<Utc>>,
63
64    /// Timestamp when the record was soft-deleted
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub deleted_at: Option<DateTime<Utc>>,
67
68    /// User ID who created the record
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub created_by: Option<Uuid>,
71
72    /// User ID who last updated the record
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub updated_by: Option<Uuid>,
75
76    /// User ID who deleted the record
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub deleted_by: Option<Uuid>,
79}
80
81impl AuditMetadata {
82    /// Create new audit metadata with created_at set to now
83    pub fn new() -> Self {
84        Self {
85            created_at: Some(Utc::now()),
86            ..Default::default()
87        }
88    }
89
90    /// Create with creator ID
91    pub fn with_creator(creator_id: Uuid) -> Self {
92        Self {
93            created_at: Some(Utc::now()),
94            created_by: Some(creator_id),
95            ..Default::default()
96        }
97    }
98
99    /// Touch the record (update updated_at)
100    pub fn touch(&mut self) {
101        self.updated_at = Some(Utc::now());
102    }
103
104    /// Touch with updater ID
105    pub fn touch_by(&mut self, updater_id: Uuid) {
106        self.updated_at = Some(Utc::now());
107        self.updated_by = Some(updater_id);
108    }
109
110    /// Soft delete the record
111    pub fn soft_delete(&mut self) {
112        self.deleted_at = Some(Utc::now());
113    }
114
115    /// Soft delete with deleter ID
116    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
117        self.deleted_at = Some(Utc::now());
118        self.deleted_by = Some(deleter_id);
119    }
120
121    /// Restore a soft-deleted record
122    pub fn restore(&mut self) {
123        self.deleted_at = None;
124        self.deleted_by = None;
125    }
126
127    /// Check if record is deleted
128    pub fn is_deleted(&self) -> bool {
129        self.deleted_at.is_some()
130    }
131
132    /// Check if record is active (not deleted)
133    pub fn is_active(&self) -> bool {
134        self.deleted_at.is_none()
135    }
136}