shared-framework 0.0.17

Reusable building blocks for HTTP services — Hyper routing, SeaORM data layer, validation, OpenAPI docs, jobs, queues, cache.
Documentation
//! Entity identity and auditing.
//!
//! Provides the [`BaseEntity`] and [`BaseAuditableEntity`] traits plus the
//! concrete [`BaseEntityFields`] and [`BaseAuditableFields`] holders.
//! Implement [`BaseEntity`] on every SeaORM model to expose a uniform
//! `id`/`uid`/timestamp view used by queries, repositories, and seeders.
//!
//! ```ignore
//! use shared_framework::data::BaseEntity;
//!
//! struct MyModel { id: i64, uid: uuid::Uuid, created_at: chrono::DateTime<chrono::Utc>, updated_at: chrono::DateTime<chrono::Utc> }
//! impl BaseEntity for MyModel {
//!     fn id(&self) -> i64 { self.id }
//!     fn uid(&self) -> uuid::Uuid { self.uid }
//!     fn created_at(&self) -> chrono::DateTime<chrono::Utc> { self.created_at }
//!     fn updated_at(&self) -> chrono::DateTime<chrono::Utc> { self.updated_at }
//! }
//! ```

use chrono::{DateTime, Utc};
use sea_orm::prelude::DateTimeWithTimeZone;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// Concrete holder for the common entity columns.
///
/// Used when a plain struct (rather than a SeaORM model) needs the same
/// `id`/`uid`/timestamp shape. Defaults to `id` 0 with a fresh UUID and timestamps.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaseEntityFields {
    /// Primary key value.
    pub id: i64,
    /// Stable public identifier, generated as a new UUID v4 on [`BaseEntityFields::new`].
    pub uid: Uuid,
    /// Creation timestamp, set to now on [`BaseEntityFields::new`].
    pub created_at: DateTime<Utc>,
    /// Last-update timestamp, set to now on [`BaseEntityFields::new`].
    pub updated_at: DateTime<Utc>,
}

impl BaseEntityFields {
    /// Creates a holder with `id` 0, a new UUID v4, and both timestamps set to now.
    pub fn new() -> Self {
        let now = Utc::now();
        Self {
            id: 0,
            uid: Uuid::new_v4(),
            created_at: now,
            updated_at: now,
        }
    }
}

impl Default for BaseEntityFields {
    fn default() -> Self {
        Self::new()
    }
}

/// Uniform identity view over a model.
///
/// Implement for each SeaORM entity model so generic query and repository code
/// can read `id`, `uid`, and timestamps without knowing the concrete type.
pub trait BaseEntity: Send + Sync {
    /// The loader type used to load relations for this entity.
    type LoaderType;

    /// Returns a loader for this entity type.
    fn load() -> Self::LoaderType;

    /// Returns the primary key value.
    fn id(&self) -> i64;

    /// Returns the stable public identifier.
    fn uid(&self) -> Uuid;

    /// Returns the creation timestamp.
    fn created_at(&self) -> DateTimeWithTimeZone;

    /// Returns the last-update timestamp.
    fn updated_at(&self) -> DateTimeWithTimeZone;
}

/// Auditable extension that adds creator/updater tracking.
///
/// The associated `User` type identifies who created or last updated the row.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaseAuditableFields<U> {
    /// The shared identity and timestamp columns.
    pub base: BaseEntityFields,
    /// The user that created the row.
    pub created_by: U,
    /// The user that last updated the row.
    pub updated_by: U,
}

/// Auditing view over a model that tracks creator and updater.
///
/// Requires [`BaseEntity`] and exposes both users as `User` values.
pub trait BaseAuditableEntity: BaseEntity {
    /// The user type stored as creator/updater.
    type User: Send + Sync + Clone;
    /// Returns the user that created the row.
    fn created_by(&self) -> &Self::User;
    /// Returns the user that last updated the row.
    fn updated_by(&self) -> &Self::User;
}