Skip to main content

backbone_pos/domain/entity/
mod.rs

1//! Domain Entities
2//!
3//! Generated by metaphor-schema. Do not edit manually.
4
5pub mod pos_closing_entry;
6pub mod pos_invoice;
7pub mod pos_invoice_item;
8pub mod pos_payment;
9pub mod pos_profile;
10pub mod pos_opening_entry;
11pub mod pos_cash_movement;
12pub mod pos_discount;
13pub mod pos_manager_pin;
14pub mod pos_floor_plan;
15pub mod pos_table;
16pub mod pos_closing_status;
17pub mod pos_invoice_status;
18pub mod pos_payment_method;
19pub mod pos_cash_rounding_strategy;
20pub mod pos_profile_status;
21pub mod pos_session_status;
22pub mod pos_cash_movement_type;
23
24// Re-exports
25pub use pos_closing_entry::PosClosingEntry;
26pub use pos_closing_entry::PosClosingEntryBuilder;
27pub use pos_closing_entry::PosClosingEntryId;
28pub use pos_invoice::PosInvoice;
29pub use pos_invoice::PosInvoiceBuilder;
30pub use pos_invoice::PosInvoiceId;
31pub use pos_invoice_item::PosInvoiceItem;
32pub use pos_invoice_item::PosInvoiceItemBuilder;
33pub use pos_invoice_item::PosInvoiceItemId;
34pub use pos_payment::PosPayment;
35pub use pos_payment::PosPaymentBuilder;
36pub use pos_payment::PosPaymentId;
37pub use pos_profile::PosProfile;
38pub use pos_profile::PosProfileBuilder;
39pub use pos_profile::PosProfileId;
40pub use pos_opening_entry::PosOpeningEntry;
41pub use pos_opening_entry::PosOpeningEntryBuilder;
42pub use pos_opening_entry::PosOpeningEntryId;
43pub use pos_cash_movement::PosCashMovement;
44pub use pos_cash_movement::PosCashMovementBuilder;
45pub use pos_cash_movement::PosCashMovementId;
46pub use pos_discount::PosDiscount;
47pub use pos_discount::PosDiscountBuilder;
48pub use pos_discount::PosDiscountId;
49pub use pos_manager_pin::PosManagerPin;
50pub use pos_manager_pin::PosManagerPinBuilder;
51pub use pos_manager_pin::PosManagerPinId;
52pub use pos_floor_plan::PosFloorPlan;
53pub use pos_floor_plan::PosFloorPlanBuilder;
54pub use pos_floor_plan::PosFloorPlanId;
55pub use pos_table::PosTable;
56pub use pos_table::PosTableBuilder;
57pub use pos_table::PosTableId;
58pub use pos_closing_status::PosClosingStatus;
59pub use pos_invoice_status::PosInvoiceStatus;
60pub use pos_payment_method::PosPaymentMethod;
61pub use pos_cash_rounding_strategy::PosCashRoundingStrategy;
62pub use pos_profile_status::PosProfileStatus;
63pub use pos_session_status::PosSessionStatus;
64pub use pos_cash_movement_type::PosCashMovementType;
65
66// ==========================================================================
67// Entity Trait
68// ==========================================================================
69
70use std::fmt::Debug;
71
72/// Trait for domain entities
73///
74/// All generated entities implement this trait, providing
75/// a common interface for working with domain objects.
76pub trait Entity: Debug + Clone {
77    /// The type of the entity's unique identifier
78    type Id: Debug + Clone + PartialEq;
79
80    /// Get the entity's unique identifier
81    fn entity_id(&self) -> &Self::Id;
82
83    /// Get the entity type name
84    fn entity_type() -> &'static str;
85}
86
87// ==========================================================================
88// Audit Metadata
89// ==========================================================================
90
91use chrono::{DateTime, Utc};
92use serde::{Deserialize, Serialize};
93use uuid::Uuid;
94#[cfg(feature = "openapi")]
95use utoipa::ToSchema;
96
97/// Audit metadata stored as JSONB in the database
98///
99/// This struct consolidates audit fields (timestamps and actors) into a single
100/// JSONB column for efficient storage and flexible querying.
101#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
102#[cfg_attr(feature = "openapi", derive(ToSchema))]
103pub struct AuditMetadata {
104    /// Timestamp when the record was created
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub created_at: Option<DateTime<Utc>>,
107
108    /// Timestamp when the record was last updated
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub updated_at: Option<DateTime<Utc>>,
111
112    /// Timestamp when the record was soft-deleted
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub deleted_at: Option<DateTime<Utc>>,
115
116    /// User ID who created the record
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub created_by: Option<Uuid>,
119
120    /// User ID who last updated the record
121    #[serde(skip_serializing_if = "Option::is_none")]
122    pub updated_by: Option<Uuid>,
123
124    /// User ID who deleted the record
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub deleted_by: Option<Uuid>,
127}
128
129impl AuditMetadata {
130    /// Create new audit metadata with created_at set to now
131    pub fn new() -> Self {
132        Self {
133            created_at: Some(Utc::now()),
134            ..Default::default()
135        }
136    }
137
138    /// Create with creator ID
139    pub fn with_creator(creator_id: Uuid) -> Self {
140        Self {
141            created_at: Some(Utc::now()),
142            created_by: Some(creator_id),
143            ..Default::default()
144        }
145    }
146
147    /// Touch the record (update updated_at)
148    pub fn touch(&mut self) {
149        self.updated_at = Some(Utc::now());
150    }
151
152    /// Touch with updater ID
153    pub fn touch_by(&mut self, updater_id: Uuid) {
154        self.updated_at = Some(Utc::now());
155        self.updated_by = Some(updater_id);
156    }
157
158    /// Soft delete the record
159    pub fn soft_delete(&mut self) {
160        self.deleted_at = Some(Utc::now());
161    }
162
163    /// Soft delete with deleter ID
164    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
165        self.deleted_at = Some(Utc::now());
166        self.deleted_by = Some(deleter_id);
167    }
168
169    /// Restore a soft-deleted record
170    pub fn restore(&mut self) {
171        self.deleted_at = None;
172        self.deleted_by = None;
173    }
174
175    /// Check if record is deleted
176    pub fn is_deleted(&self) -> bool {
177        self.deleted_at.is_some()
178    }
179
180    /// Check if record is active (not deleted)
181    pub fn is_active(&self) -> bool {
182        self.deleted_at.is_none()
183    }
184}