| | | 1 | | using ArturRios.Heimdall.Shared.Messages; |
| | | 2 | | using ArturRios.Heimdall.Shared.Time; |
| | | 3 | | using FluentValidation; |
| | | 4 | | |
| | | 5 | | namespace ArturRios.Heimdall.Query.Input.Validation; |
| | | 6 | | |
| | | 7 | | /// <summary>Input validation for <see cref="ListAuditLogQuery" /> (UC-48 AF-48a, NFR-10).</summary> |
| | | 8 | | public class ListAuditLogQueryValidator : PaginatedQueryValidator<ListAuditLogQuery> |
| | | 9 | | { |
| | | 10 | | /// <summary>Matches <c>AuditLog.Action</c>'s <c>[MaxLength]</c>: a longer filter could never match a row.</summary> |
| | | 11 | | private const int MaxActionLength = 200; |
| | | 12 | | |
| | 38 | 13 | | public ListAuditLogQueryValidator() |
| | | 14 | | { |
| | | 15 | | // Compared as UTC on both sides, so an offset-less bound and a "Z" bound compare as the |
| | | 16 | | // handler will filter with them. |
| | 38 | 17 | | RuleFor(query => query.To) |
| | 38 | 18 | | .Must((query, to) => |
| | 38 | 19 | | to is null || query.From is null || UtcInstant.Of(to.Value) >= UtcInstant.Of(query.From.Value)) |
| | 38 | 20 | | .WithMessage(AuditMessages.InvalidDateRange); |
| | | 21 | | |
| | 38 | 22 | | RuleFor(query => query.Action) |
| | 38 | 23 | | .MaximumLength(MaxActionLength) |
| | 38 | 24 | | .WithMessage(PaginationMessages.FilterTooLong); |
| | 38 | 25 | | } |
| | | 26 | | } |