Files
SIG-CM2.0/src/api/SIGCM2.Application/Audit/AuditEventDto.cs
dmolinari 68f96b90c7 feat(application): audit abstractions (UDT-010 B2)
Introduces the contract layer for audit logging per design #D-8:

SIGCM2.Application/Audit/:
- IAuditContext — request-scoped accessor for ActorUserId/ActorRoleId/
  Ip/UserAgent/CorrelationId. Populated by CorrelationIdMiddleware +
  AuditActorMiddleware (B4).
- IAuditLogger.LogAsync(action, targetType, targetId, metadata?, ct) —
  domain-level audit emitter. Enlists in ambient TransactionScope
  (fail-closed per #REQ-AUD-4).
- ISecurityEventLogger.LogAsync(action, result, actorUserId?, attemptedUsername?,
  sessionId?, failureReason?, metadata?, ct) — security-events emitter
  separate from IAuditLogger (different retention, no transaction scope,
  captures login/logout/refresh/permission.denied).
- AuditOptions — bindable POCO with SanitizedKeys[] defaults (used by
  JsonSanitizer in B3).
- AuditEventDto — read projection for GET /api/v1/audit/events (B10).
- AuditEventFilter — query filter record with default Limit=50.

SIGCM2.Domain/Exceptions/:
- AuditContextMissingException : DomainException — fail-closed sentinel
  thrown when IAuditLogger is called without ActorUserId in a user-scoped
  command (#REQ-AUD-4).

Tests (Strict TDD — shape contract, RED → GREEN):
- tests/SIGCM2.Application.Tests/Audit/AuditAbstractionsTests.cs: 11 tests
  covering nullability, signatures, default options, record equality.

Suite: 336/336 Application.Tests (prev 325 + 11 new). 130/130 Api.Tests.

Refs: sdd/udt-010-auditoria-trazabilidad/{spec#REQ-AUD-3/4/5, design#D-8, tasks#B2}
2026-04-16 13:23:11 -03:00

16 lines
461 B
C#

namespace SIGCM2.Application.Audit;
/// Read projection of dbo.AuditEvent for GET /api/v1/audit/events.
/// ActorUsername is resolved by join against dbo.Usuario at query time (denormalized in the DTO).
public sealed record AuditEventDto(
long Id,
DateTime OccurredAt,
int? ActorUserId,
string? ActorUsername,
string Action,
string TargetType,
string TargetId,
Guid? CorrelationId,
string? IpAddress,
string? Metadata);