| | | 1 | | using ArturRios.Heimdall.Shared.Messages; |
| | | 2 | | using ArturRios.Mediator.Query; |
| | | 3 | | using FluentValidation; |
| | | 4 | | |
| | | 5 | | namespace ArturRios.Heimdall.Query.Input.Validation; |
| | | 6 | | |
| | | 7 | | /// <summary> |
| | | 8 | | /// Shared pagination rules for every paginated list query (NFR-10): <c>PageNumber</c> must be at |
| | | 9 | | /// least 1, and <c>PageSize</c> must fall within <see cref="MaxPageSize" />. Concrete query |
| | | 10 | | /// validators derive from this and add their own filter-length rules on top — FluentValidation |
| | | 11 | | /// accumulates rules added by both the base and derived constructors into the same rule set. |
| | | 12 | | /// </summary> |
| | | 13 | | public abstract class PaginatedQueryValidator<TQuery> : AbstractValidator<TQuery> where TQuery : BaseQuery |
| | | 14 | | { |
| | | 15 | | /// <summary> |
| | | 16 | | /// The upper bound on <c>PageSize</c>. Matches <see cref="BaseQuery" />'s own default of 100, |
| | | 17 | | /// so a caller who never sets <c>PageSize</c> is always within bounds. |
| | | 18 | | /// </summary> |
| | | 19 | | protected const int MaxPageSize = 100; |
| | | 20 | | |
| | | 21 | | /// <summary> |
| | | 22 | | /// The last page number whose offset, <c>(PageNumber - 1) * PageSize</c>, still fits in an |
| | | 23 | | /// <see cref="int" /> at the largest page size. The pagination helper computes that offset in |
| | | 24 | | /// unchecked arithmetic, so a larger number wrapped to a negative OFFSET, which PostgreSQL |
| | | 25 | | /// rejects — a 500 from nothing more than an absurd query string. |
| | | 26 | | /// </summary> |
| | | 27 | | public const int MaxPageNumber = int.MaxValue / MaxPageSize; |
| | | 28 | | |
| | 241 | 29 | | protected PaginatedQueryValidator() |
| | | 30 | | { |
| | 241 | 31 | | RuleFor(query => query.PageNumber) |
| | 241 | 32 | | .InclusiveBetween(1, MaxPageNumber) |
| | 241 | 33 | | .WithMessage(PaginationMessages.InvalidPageNumber); |
| | | 34 | | |
| | 241 | 35 | | RuleFor(query => query.PageSize) |
| | 241 | 36 | | .InclusiveBetween(1, MaxPageSize) |
| | 241 | 37 | | .WithMessage(PaginationMessages.InvalidPageSize); |
| | 241 | 38 | | } |
| | | 39 | | } |