1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Domain layer configuration limits
//!
//! Defines validation constraints for domain-level pagination and query operations.
//! These limits enforce business rules and are independent of infrastructure.
//!
//! # Production Tuning
//!
//! These values are suitable for most deployments. Adjust based on:
//!
//! - **MAX_PAGINATION_LIMIT**: Increase if clients need larger batch fetches.
//! Monitor memory usage per request (limit * avg_item_size).
//!
//! - **MAX_PAGINATION_OFFSET**: Lower if cursor-based pagination is preferred.
//! Deep offsets are expensive; consider cursor pagination for offsets > 10,000.
//!
//! - **ALLOWED_SORT_FIELDS**: Extend with indexed fields only. Adding non-indexed
//! fields degrades query performance significantly on large datasets.
//!
//! # Monitoring Recommendations
//!
//! Track these metrics to tune limits:
//! - `pagination.offset_p99`: If consistently high, clients may need cursor pagination
//! - `pagination.limit_avg`: Optimize batch sizes based on actual usage
//! - `query.scan_limit_reached_rate`: High rate indicates filter criteria too broad
/// Maximum allowed pagination limit per request.
///
/// Prevents single requests from retrieving excessive data.
/// Aligns with industry standards (GitHub API, Stripe use 100-1000).
pub const MAX_PAGINATION_LIMIT: usize = 1_000;
/// Maximum allowed pagination offset.
///
/// Prevents requests that would scan deep into result sets.
/// Beyond this, cursor-based pagination is recommended.
pub const MAX_PAGINATION_OFFSET: usize = 1_000_000;
/// Allowed sort field names for pagination validation.
///
/// Whitelist of fields that can be used in sort_by parameter.
/// Only add fields that have corresponding indexes in storage.
pub const ALLOWED_SORT_FIELDS: & = &;