using System.ComponentModel.DataAnnotations; using Prefab.Data; namespace Prefab.Domain.Common; /// /// Represents an audited entity that also tracks status transitions such as deactivate and delete. /// /// The identifier type. public interface IEntityWithAuditAndStatus : IEntityWithAudit, IStatus { /// /// Gets or sets the identifier of the user that deactivated the entity. /// Guid? InactivatedBy { get; set; } /// /// Gets or sets when the entity was deactivated. /// DateTimeOffset? InactivatedOn { get; set; } /// /// Gets or sets the identifier of the user that soft-deleted the entity. /// Guid? DeletedBy { get; set; } /// /// Gets or sets when the entity was soft-deleted. /// DateTimeOffset? DeletedOn { get; set; } /// /// Gets or sets the concurrency token used for optimistic locking. /// byte[] RowVersion { get; set; } } /// /// Base type for audited entities that support activation, deactivation, and soft-delete flows. /// /// The identifier type. public abstract class EntityWithAuditAndStatus : EntityWithAudit, IEntityWithAuditAndStatus { /// public AuditStatus AuditStatus => DeletedOn.HasValue ? AuditStatus.Deleted : InactivatedOn.HasValue ? AuditStatus.Inactive : AuditStatus.Active; /// public Guid? InactivatedBy { get; set; } /// public DateTimeOffset? InactivatedOn { get; set; } /// public Guid? DeletedBy { get; set; } /// public DateTimeOffset? DeletedOn { get; set; } /// [Timestamp] public byte[] RowVersion { get; set; } = []; /// /// Marks the entity as active by clearing any inactive markers. /// /// Identifier of the user performing the change. public virtual void Activate(Guid? userId = null) { if (InactivatedOn.HasValue) { InactivatedOn = null; InactivatedBy = null; } } /// /// Marks the entity as inactive if it is not already inactive. /// /// Identifier of the user performing the change. public virtual void Deactivate(Guid? userId = null) { if (!InactivatedOn.HasValue) { InactivatedOn = DateTimeOffset.UtcNow; InactivatedBy = userId; } } /// /// Soft deletes the entity when it has not already been deleted. /// /// Identifier of the user performing the change. public virtual void Delete(Guid? userId = null) { if (!DeletedOn.HasValue) { DeletedOn = DateTimeOffset.UtcNow; DeletedBy = userId; } } /// /// Restores a previously soft-deleted entity to an inactive state. /// /// Identifier of the user performing the change. public virtual void Restore(Guid? userId = null) { if (DeletedOn.HasValue) { DeletedOn = null; DeletedBy = null; } } }