namespace ROLAC.API.Entities.Logging;
///
/// 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.
///
public class AuditLog
{
public long Id { get; set; }
public DateTimeOffset Timestamp { get; set; }
public LogLevelEnum Level { get; set; } = LogLevelEnum.Information;
/// One of .
public string Action { get; set; } = null!;
/// One of — drives the UI grouping.
public string Category { get; set; } = null!;
public string? EntityName { get; set; }
/// String to cover int, Guid and string primary keys uniformly.
public string? EntityId { get; set; }
/// JSON { "before": {...}, "after": {...} } (jsonb column); sensitive fields masked.
public string? Changes { get; set; }
/// Human-readable one-liner, e.g. "Check #1042 issued to Acme — $1,200.00".
public string? Summary { get; set; }
public string? UserId { get; set; }
/// Denormalized actor email — survives user deletion and avoids a join in the grid.
public string? UserEmail { get; set; }
public string? IpAddress { get; set; }
public string? CorrelationId { get; set; }
}
/// Canonical audit action names (stored verbatim in ).
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 UserDeactivated = "UserDeactivated";
public const string PermissionChanged = "PermissionChanged";
public const string CheckIssued = "CheckIssued";
public const string CheckVoided = "CheckVoided";
public const string ExpenseApproved = "ExpenseApproved";
public const string StatementFinalized = "StatementFinalized";
public static readonly IReadOnlyList All =
[
Create, Update, Delete, Login, Logout, LoginFailed, RoleChanged,
UserDeactivated, PermissionChanged, CheckIssued, CheckVoided,
ExpenseApproved, StatementFinalized,
];
}
/// Top-level audit grouping (stored verbatim in ).
public static class AuditCategories
{
public const string DataChange = "DataChange";
public const string Security = "Security";
public const string Business = "Business";
public static readonly IReadOnlyList All = [DataChange, Security, Business];
}