77 lines
3.5 KiB
C#
77 lines
3.5 KiB
C#
namespace ROLAC.API.Entities.Logging;
|
|
|
|
/// <summary>
|
|
/// An append-only audit row recording a meaningful action: a data change (Create/Update/
|
|
/// Delete with before→after values), a security event (login, role/permission change), or a
|
|
/// key business action (check issued, expense approved, ...). Does NOT inherit AuditableEntity.
|
|
/// </summary>
|
|
public class AuditLog
|
|
{
|
|
public long Id { get; set; }
|
|
public DateTimeOffset Timestamp { get; set; }
|
|
public LogLevelEnum Level { get; set; } = LogLevelEnum.Information;
|
|
|
|
/// <summary>One of <see cref="AuditActions"/>.</summary>
|
|
public string Action { get; set; } = null!;
|
|
|
|
/// <summary>One of <see cref="AuditCategories"/> — drives the UI grouping.</summary>
|
|
public string Category { get; set; } = null!;
|
|
|
|
public string? EntityName { get; set; }
|
|
|
|
/// <summary>String to cover int, Guid and string primary keys uniformly.</summary>
|
|
public string? EntityId { get; set; }
|
|
|
|
/// <summary>JSON <c>{ "before": {...}, "after": {...} }</c> (jsonb column); sensitive fields masked.</summary>
|
|
public string? Changes { get; set; }
|
|
|
|
/// <summary>Human-readable one-liner, e.g. "Check #1042 issued to Acme — $1,200.00".</summary>
|
|
public string? Summary { get; set; }
|
|
|
|
public string? UserId { get; set; }
|
|
/// <summary>Denormalized actor email — survives user deletion and avoids a join in the grid.</summary>
|
|
public string? UserEmail { get; set; }
|
|
public string? IpAddress { get; set; }
|
|
public string? CorrelationId { get; set; }
|
|
}
|
|
|
|
/// <summary>Canonical audit action names (stored verbatim in <see cref="AuditLog.Action"/>).</summary>
|
|
public static class AuditActions
|
|
{
|
|
public const string Create = "Create";
|
|
public const string Update = "Update";
|
|
public const string Delete = "Delete";
|
|
public const string Login = "Login";
|
|
public const string Logout = "Logout";
|
|
public const string LoginFailed = "LoginFailed";
|
|
public const string RoleChanged = "RoleChanged";
|
|
public const string PasswordChanged = "PasswordChanged";
|
|
public const string UserDeactivated = "UserDeactivated";
|
|
public const string PermissionChanged = "PermissionChanged";
|
|
public const string InvitationCreated = "InvitationCreated";
|
|
public const string InvitationAccepted = "InvitationAccepted";
|
|
public const string CheckIssued = "CheckIssued";
|
|
public const string CheckVoided = "CheckVoided";
|
|
public const string ExpenseApproved = "ExpenseApproved";
|
|
public const string ExpenseRejected = "ExpenseRejected";
|
|
public const string StatementFinalized = "StatementFinalized";
|
|
|
|
public static readonly IReadOnlyList<string> All =
|
|
[
|
|
Create, Update, Delete, Login, Logout, LoginFailed, RoleChanged,
|
|
PasswordChanged, UserDeactivated, PermissionChanged,
|
|
InvitationCreated, InvitationAccepted, CheckIssued,
|
|
CheckVoided, ExpenseApproved, ExpenseRejected, StatementFinalized,
|
|
];
|
|
}
|
|
|
|
/// <summary>Top-level audit grouping (stored verbatim in <see cref="AuditLog.Category"/>).</summary>
|
|
public static class AuditCategories
|
|
{
|
|
public const string DataChange = "DataChange";
|
|
public const string Security = "Security";
|
|
public const string Business = "Business";
|
|
|
|
public static readonly IReadOnlyList<string> All = [DataChange, Security, Business];
|
|
}
|