Skip to main content

backbone_payroll/domain/entity/
mod.rs

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