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}