backbone-mail 0.2.32

Odoo mail core port — message/notification/followers/activity/alias/sms queue (schema: messaging)
//! Domain Entities
//!
//! Generated by metaphor-schema. Do not edit manually.

pub mod mail_activity;
pub mod mail_activity_type;
pub mod mail_activity_plan;
pub mod mail_activity_plan_template;
pub mod mail_alias_domain;
pub mod mail_alias;
pub mod mail_attachment;
pub mod mail_message_attachment;
pub mod mail_message_star;
pub mod mail_message;
pub mod mail;
pub mod mail_notification;
pub mod mail_message_subtype;
pub mod mail_message_reaction;
pub mod mail_followers;
pub mod mail_presence;
pub mod mail_blacklist;
pub mod mail_tracking_value;
pub mod discuss_channel;
pub mod discuss_channel_member;
pub mod mail_guest;
pub mod mail_server;
pub mod fetchmail_server;
pub mod mail_gateway_allowed;
pub mod phone_blacklist;
pub mod mail_message_schedule;
pub mod mail_scheduled_message;
pub mod sms;
pub mod sms_template;
pub mod sms_tracker;
pub mod mail_activity_state;
pub mod mail_activity_chaining_type;
pub mod mail_activity_category;
pub mod mail_activity_delay_unit;
pub mod mail_activity_delay_from;
pub mod mail_alias_contact;
pub mod mail_message_type;
pub mod mail_state;
pub mod mail_failure_type;
pub mod notification_failure_type;
pub mod mail_notification_type;
pub mod mail_notification_status;
pub mod mail_moderation_status;
pub mod mail_presence_status;
pub mod discuss_channel_type;
pub mod sidebar_fold_state;
pub mod member_custom_notifications;
pub mod smtp_authentication;
pub mod smtp_encryption;
pub mod fetchmail_state;
pub mod sms_state;
pub mod sms_failure_type;

// Re-exports
pub use mail_activity::MailActivity;
pub use mail_activity::MailActivityBuilder;
pub use mail_activity::MailActivityId;
pub use mail_activity_type::MailActivityType;
pub use mail_activity_type::MailActivityTypeBuilder;
pub use mail_activity_type::MailActivityTypeId;
pub use mail_activity_plan::MailActivityPlan;
pub use mail_activity_plan::MailActivityPlanBuilder;
pub use mail_activity_plan::MailActivityPlanId;
pub use mail_activity_plan_template::MailActivityPlanTemplate;
pub use mail_activity_plan_template::MailActivityPlanTemplateBuilder;
pub use mail_activity_plan_template::MailActivityPlanTemplateId;
pub use mail_alias_domain::MailAliasDomain;
pub use mail_alias_domain::MailAliasDomainBuilder;
pub use mail_alias_domain::MailAliasDomainId;
pub use mail_alias::MailAlias;
pub use mail_alias::MailAliasBuilder;
pub use mail_alias::MailAliasId;
pub use mail_attachment::MailAttachment;
pub use mail_attachment::MailAttachmentBuilder;
pub use mail_attachment::MailAttachmentId;
pub use mail_message_attachment::MailMessageAttachment;
pub use mail_message_attachment::MailMessageAttachmentBuilder;
pub use mail_message_attachment::MailMessageAttachmentId;
pub use mail_message_star::MailMessageStar;
pub use mail_message_star::MailMessageStarBuilder;
pub use mail_message_star::MailMessageStarId;
pub use mail_message::MailMessage;
pub use mail_message::MailMessageBuilder;
pub use mail_message::MailMessageId;
pub use mail::Mail;
pub use mail::MailBuilder;
pub use mail::MailId;
pub use mail_notification::MailNotification;
pub use mail_notification::MailNotificationBuilder;
pub use mail_notification::MailNotificationId;
pub use mail_message_subtype::MailMessageSubtype;
pub use mail_message_subtype::MailMessageSubtypeBuilder;
pub use mail_message_subtype::MailMessageSubtypeId;
pub use mail_message_reaction::MailMessageReaction;
pub use mail_message_reaction::MailMessageReactionBuilder;
pub use mail_message_reaction::MailMessageReactionId;
pub use mail_followers::MailFollowers;
pub use mail_followers::MailFollowersBuilder;
pub use mail_followers::MailFollowersId;
pub use mail_presence::MailPresence;
pub use mail_presence::MailPresenceBuilder;
pub use mail_presence::MailPresenceId;
pub use mail_blacklist::MailBlacklist;
pub use mail_blacklist::MailBlacklistBuilder;
pub use mail_blacklist::MailBlacklistId;
pub use mail_tracking_value::MailTrackingValue;
pub use mail_tracking_value::MailTrackingValueBuilder;
pub use mail_tracking_value::MailTrackingValueId;
pub use discuss_channel::DiscussChannel;
pub use discuss_channel::DiscussChannelBuilder;
pub use discuss_channel::DiscussChannelId;
pub use discuss_channel_member::DiscussChannelMember;
pub use discuss_channel_member::DiscussChannelMemberBuilder;
pub use discuss_channel_member::DiscussChannelMemberId;
pub use mail_guest::MailGuest;
pub use mail_guest::MailGuestBuilder;
pub use mail_guest::MailGuestId;
pub use mail_server::MailServer;
pub use mail_server::MailServerBuilder;
pub use mail_server::MailServerId;
pub use fetchmail_server::FetchmailServer;
pub use fetchmail_server::FetchmailServerBuilder;
pub use fetchmail_server::FetchmailServerId;
pub use mail_gateway_allowed::MailGatewayAllowed;
pub use mail_gateway_allowed::MailGatewayAllowedBuilder;
pub use mail_gateway_allowed::MailGatewayAllowedId;
pub use phone_blacklist::PhoneBlacklist;
pub use phone_blacklist::PhoneBlacklistBuilder;
pub use phone_blacklist::PhoneBlacklistId;
pub use mail_message_schedule::MailMessageSchedule;
pub use mail_message_schedule::MailMessageScheduleBuilder;
pub use mail_message_schedule::MailMessageScheduleId;
pub use mail_scheduled_message::MailScheduledMessage;
pub use mail_scheduled_message::MailScheduledMessageBuilder;
pub use mail_scheduled_message::MailScheduledMessageId;
pub use sms::Sms;
pub use sms::SmsBuilder;
pub use sms::SmsId;
pub use sms_template::SmsTemplate;
pub use sms_template::SmsTemplateBuilder;
pub use sms_template::SmsTemplateId;
pub use sms_tracker::SmsTracker;
pub use sms_tracker::SmsTrackerBuilder;
pub use sms_tracker::SmsTrackerId;
pub use mail_activity_state::MailActivityState;
pub use mail_activity_chaining_type::MailActivityChainingType;
pub use mail_activity_category::MailActivityCategory;
pub use mail_activity_delay_unit::MailActivityDelayUnit;
pub use mail_activity_delay_from::MailActivityDelayFrom;
pub use mail_alias_contact::MailAliasContact;
pub use mail_message_type::MailMessageType;
pub use mail_state::MailState;
pub use mail_failure_type::MailFailureType;
pub use notification_failure_type::NotificationFailureType;
pub use mail_notification_type::MailNotificationType;
pub use mail_notification_status::MailNotificationStatus;
pub use mail_moderation_status::MailModerationStatus;
pub use mail_presence_status::MailPresenceStatus;
pub use discuss_channel_type::DiscussChannelType;
pub use sidebar_fold_state::SidebarFoldState;
pub use member_custom_notifications::MemberCustomNotifications;
pub use smtp_authentication::SmtpAuthentication;
pub use smtp_encryption::SmtpEncryption;
pub use fetchmail_state::FetchmailState;
pub use sms_state::SmsState;
pub use sms_failure_type::SmsFailureType;

// ==========================================================================
// Entity Trait
// ==========================================================================

use std::fmt::Debug;

/// Trait for domain entities
///
/// All generated entities implement this trait, providing
/// a common interface for working with domain objects.
pub trait Entity: Debug + Clone {
    /// The type of the entity's unique identifier
    type Id: Debug + Clone + PartialEq;

    /// Get the entity's unique identifier
    fn entity_id(&self) -> &Self::Id;

    /// Get the entity type name
    fn entity_type() -> &'static str;
}

// ==========================================================================
// Audit Metadata
// ==========================================================================

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[cfg(feature = "openapi")]
use utoipa::ToSchema;

/// Audit metadata stored as JSONB in the database
///
/// This struct consolidates audit fields (timestamps and actors) into a single
/// JSONB column for efficient storage and flexible querying.
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
pub struct AuditMetadata {
    /// Timestamp when the record was created
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_at: Option<DateTime<Utc>>,

    /// Timestamp when the record was last updated
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_at: Option<DateTime<Utc>>,

    /// Timestamp when the record was soft-deleted
    #[serde(skip_serializing_if = "Option::is_none")]
    pub deleted_at: Option<DateTime<Utc>>,

    /// User ID who created the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_by: Option<Uuid>,

    /// User ID who last updated the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_by: Option<Uuid>,

    /// User ID who deleted the record
    #[serde(skip_serializing_if = "Option::is_none")]
    pub deleted_by: Option<Uuid>,
}

impl AuditMetadata {
    /// Create new audit metadata with created_at set to now
    pub fn new() -> Self {
        Self {
            created_at: Some(Utc::now()),
            ..Default::default()
        }
    }

    /// Create with creator ID
    pub fn with_creator(creator_id: Uuid) -> Self {
        Self {
            created_at: Some(Utc::now()),
            created_by: Some(creator_id),
            ..Default::default()
        }
    }

    /// Touch the record (update updated_at)
    pub fn touch(&mut self) {
        self.updated_at = Some(Utc::now());
    }

    /// Touch with updater ID
    pub fn touch_by(&mut self, updater_id: Uuid) {
        self.updated_at = Some(Utc::now());
        self.updated_by = Some(updater_id);
    }

    /// Soft delete the record
    pub fn soft_delete(&mut self) {
        self.deleted_at = Some(Utc::now());
    }

    /// Soft delete with deleter ID
    pub fn soft_delete_by(&mut self, deleter_id: Uuid) {
        self.deleted_at = Some(Utc::now());
        self.deleted_by = Some(deleter_id);
    }

    /// Restore a soft-deleted record
    pub fn restore(&mut self) {
        self.deleted_at = None;
        self.deleted_by = None;
    }

    /// Check if record is deleted
    pub fn is_deleted(&self) -> bool {
        self.deleted_at.is_some()
    }

    /// Check if record is active (not deleted)
    pub fn is_active(&self) -> bool {
        self.deleted_at.is_none()
    }
}