Skip to main content

backbone_banking/domain/entity/
mod.rs

1//! Domain Entities
2//!
3//! Generated by metaphor-schema. Do not edit manually.
4
5pub mod bank;
6pub mod bank_account;
7pub mod bank_clearance;
8pub mod bank_reconciliation;
9pub mod bank_statement_import;
10pub mod bank_transaction;
11pub mod fx_gain_loss;
12pub mod reconcile_preset;
13pub mod bank_status;
14pub mod bank_account_status;
15pub mod bank_account_type;
16pub mod matched_source_type;
17pub mod match_method;
18pub mod recon_status;
19pub mod source_format;
20pub mod import_status;
21pub mod txn_status;
22pub mod fx_direction;
23pub mod match_on;
24pub mod preset_status;
25
26// Re-exports
27pub use bank::Bank;
28pub use bank::BankBuilder;
29pub use bank::BankId;
30pub use bank_account::BankAccount;
31pub use bank_account::BankAccountBuilder;
32pub use bank_account::BankAccountId;
33pub use bank_clearance::BankClearance;
34pub use bank_clearance::BankClearanceBuilder;
35pub use bank_clearance::BankClearanceId;
36pub use bank_reconciliation::BankReconciliation;
37pub use bank_reconciliation::BankReconciliationBuilder;
38pub use bank_reconciliation::BankReconciliationId;
39pub use bank_statement_import::BankStatementImport;
40pub use bank_statement_import::BankStatementImportBuilder;
41pub use bank_statement_import::BankStatementImportId;
42pub use bank_transaction::BankTransaction;
43pub use bank_transaction::BankTransactionBuilder;
44pub use bank_transaction::BankTransactionId;
45pub use fx_gain_loss::FxGainLoss;
46pub use fx_gain_loss::FxGainLossBuilder;
47pub use fx_gain_loss::FxGainLossId;
48pub use reconcile_preset::ReconcilePreset;
49pub use reconcile_preset::ReconcilePresetBuilder;
50pub use reconcile_preset::ReconcilePresetId;
51pub use bank_status::BankStatus;
52pub use bank_account_status::BankAccountStatus;
53pub use bank_account_type::BankAccountType;
54pub use matched_source_type::MatchedSourceType;
55pub use match_method::MatchMethod;
56pub use recon_status::ReconStatus;
57pub use source_format::SourceFormat;
58pub use import_status::ImportStatus;
59pub use txn_status::TxnStatus;
60pub use fx_direction::FxDirection;
61pub use match_on::MatchOn;
62pub use preset_status::PresetStatus;
63
64// ==========================================================================
65// Entity Trait
66// ==========================================================================
67
68use std::fmt::Debug;
69
70/// Trait for domain entities
71///
72/// All generated entities implement this trait, providing
73/// a common interface for working with domain objects.
74pub trait Entity: Debug + Clone {
75    /// The type of the entity's unique identifier
76    type Id: Debug + Clone + PartialEq;
77
78    /// Get the entity's unique identifier
79    fn entity_id(&self) -> &Self::Id;
80
81    /// Get the entity type name
82    fn entity_type() -> &'static str;
83}
84
85// ==========================================================================
86// Audit Metadata
87// ==========================================================================
88
89use chrono::{DateTime, Utc};
90use serde::{Deserialize, Serialize};
91use uuid::Uuid;
92#[cfg(feature = "openapi")]
93use utoipa::ToSchema;
94
95/// Audit metadata stored as JSONB in the database
96///
97/// This struct consolidates audit fields (timestamps and actors) into a single
98/// JSONB column for efficient storage and flexible querying.
99#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
100#[cfg_attr(feature = "openapi", derive(ToSchema))]
101pub struct AuditMetadata {
102    /// Timestamp when the record was created
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub created_at: Option<DateTime<Utc>>,
105
106    /// Timestamp when the record was last updated
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub updated_at: Option<DateTime<Utc>>,
109
110    /// Timestamp when the record was soft-deleted
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub deleted_at: Option<DateTime<Utc>>,
113
114    /// User ID who created the record
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub created_by: Option<Uuid>,
117
118    /// User ID who last updated the record
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub updated_by: Option<Uuid>,
121
122    /// User ID who deleted the record
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub deleted_by: Option<Uuid>,
125}
126
127impl AuditMetadata {
128    /// Create new audit metadata with created_at set to now
129    pub fn new() -> Self {
130        Self {
131            created_at: Some(Utc::now()),
132            ..Default::default()
133        }
134    }
135
136    /// Create with creator ID
137    pub fn with_creator(creator_id: Uuid) -> Self {
138        Self {
139            created_at: Some(Utc::now()),
140            created_by: Some(creator_id),
141            ..Default::default()
142        }
143    }
144
145    /// Touch the record (update updated_at)
146    pub fn touch(&mut self) {
147        self.updated_at = Some(Utc::now());
148    }
149
150    /// Touch with updater ID
151    pub fn touch_by(&mut self, updater_id: Uuid) {
152        self.updated_at = Some(Utc::now());
153        self.updated_by = Some(updater_id);
154    }
155
156    /// Soft delete the record
157    pub fn soft_delete(&mut self) {
158        self.deleted_at = Some(Utc::now());
159    }
160
161    /// Soft delete with deleter ID
162    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
163        self.deleted_at = Some(Utc::now());
164        self.deleted_by = Some(deleter_id);
165    }
166
167    /// Restore a soft-deleted record
168    pub fn restore(&mut self) {
169        self.deleted_at = None;
170        self.deleted_by = None;
171    }
172
173    /// Check if record is deleted
174    pub fn is_deleted(&self) -> bool {
175        self.deleted_at.is_some()
176    }
177
178    /// Check if record is active (not deleted)
179    pub fn is_active(&self) -> bool {
180        self.deleted_at.is_none()
181    }
182}