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