Skip to main content

shared_framework/data/
base.rs

1//! Entity identity and auditing.
2//!
3//! Provides the [`BaseEntity`] and [`BaseAuditableEntity`] traits plus the
4//! concrete [`BaseEntityFields`] and [`BaseAuditableFields`] holders.
5//! Implement [`BaseEntity`] on every SeaORM model to expose a uniform
6//! `id`/`uid`/timestamp view used by queries, repositories, and seeders.
7//!
8//! ```ignore
9//! use shared_framework::data::BaseEntity;
10//!
11//! struct MyModel { id: i64, uid: uuid::Uuid, created_at: chrono::DateTime<chrono::Utc>, updated_at: chrono::DateTime<chrono::Utc> }
12//! impl BaseEntity for MyModel {
13//!     fn id(&self) -> i64 { self.id }
14//!     fn uid(&self) -> uuid::Uuid { self.uid }
15//!     fn created_at(&self) -> chrono::DateTime<chrono::Utc> { self.created_at }
16//!     fn updated_at(&self) -> chrono::DateTime<chrono::Utc> { self.updated_at }
17//! }
18//! ```
19
20use chrono::{DateTime, Utc};
21use sea_orm::prelude::DateTimeWithTimeZone;
22use serde::{Deserialize, Serialize};
23use uuid::Uuid;
24
25/// Concrete holder for the common entity columns.
26///
27/// Used when a plain struct (rather than a SeaORM model) needs the same
28/// `id`/`uid`/timestamp shape. Defaults to `id` 0 with a fresh UUID and timestamps.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct BaseEntityFields {
31    /// Primary key value.
32    pub id: i64,
33    /// Stable public identifier, generated as a new UUID v4 on [`BaseEntityFields::new`].
34    pub uid: Uuid,
35    /// Creation timestamp, set to now on [`BaseEntityFields::new`].
36    pub created_at: DateTime<Utc>,
37    /// Last-update timestamp, set to now on [`BaseEntityFields::new`].
38    pub updated_at: DateTime<Utc>,
39}
40
41impl BaseEntityFields {
42    /// Creates a holder with `id` 0, a new UUID v4, and both timestamps set to now.
43    pub fn new() -> Self {
44        let now = Utc::now();
45        Self {
46            id: 0,
47            uid: Uuid::new_v4(),
48            created_at: now,
49            updated_at: now,
50        }
51    }
52}
53
54impl Default for BaseEntityFields {
55    fn default() -> Self {
56        Self::new()
57    }
58}
59
60/// Uniform identity view over a model.
61///
62/// Implement for each SeaORM entity model so generic query and repository code
63/// can read `id`, `uid`, and timestamps without knowing the concrete type.
64pub trait BaseEntity: Send + Sync {
65    /// The loader type used to load relations for this entity.
66    type LoaderType;
67
68    /// Returns a loader for this entity type.
69    fn load() -> Self::LoaderType;
70
71    /// Returns the primary key value.
72    fn id(&self) -> i64;
73
74    /// Returns the stable public identifier.
75    fn uid(&self) -> Uuid;
76
77    /// Returns the creation timestamp.
78    fn created_at(&self) -> DateTimeWithTimeZone;
79
80    /// Returns the last-update timestamp.
81    fn updated_at(&self) -> DateTimeWithTimeZone;
82}
83
84/// Auditable extension that adds creator/updater tracking.
85///
86/// The associated `User` type identifies who created or last updated the row.
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct BaseAuditableFields<U> {
89    /// The shared identity and timestamp columns.
90    pub base: BaseEntityFields,
91    /// The user that created the row.
92    pub created_by: U,
93    /// The user that last updated the row.
94    pub updated_by: U,
95}
96
97/// Auditing view over a model that tracks creator and updater.
98///
99/// Requires [`BaseEntity`] and exposes both users as `User` values.
100pub trait BaseAuditableEntity: BaseEntity {
101    /// The user type stored as creator/updater.
102    type User: Send + Sync + Clone;
103    /// Returns the user that created the row.
104    fn created_by(&self) -> &Self::User;
105    /// Returns the user that last updated the row.
106    fn updated_by(&self) -> &Self::User;
107}