- retention: ежедневный cron (03:17) + запуск на старте удаляет сырые
agent_stats_samples старше STATS_RETENTION_DAYS (по умолчанию 30);
lifetime-итоги на агенте и агрегаты сохраняются
- N+1 на поллинг-пути агента: evaluateAgentPolicy теперь делает по одному
батч-запросу на записи списков / резолвы hostname / имена списков вместо
запроса на каждое правило; mapPolicyRules и port-rules GET — аналогично
- пагинация: GET /agents, /lists, /rules, /install-links принимают
limit/offset и возвращают total; без параметров — прежнее поведение
- openapi.yaml: approve-bulk, PUT /policy-sets/{id}/agents, параметры
пагинации (redocly lint OK); тесты (47 passed)
23 lines
846 B
TypeScript
23 lines
846 B
TypeScript
/**
|
|
* Backwards-compatible list pagination: without limit/offset the response is
|
|
* the full list (total === items.length); with them, a page plus the total.
|
|
*/
|
|
export function applyPagination<T>(
|
|
items: T[],
|
|
query: { limit?: string; offset?: string },
|
|
): { items: T[]; total: number } {
|
|
const total = items.length
|
|
const limitRaw = query.limit !== undefined ? Number(query.limit) : NaN
|
|
const offsetRaw = query.offset !== undefined ? Number(query.offset) : NaN
|
|
if (!Number.isFinite(limitRaw) && !Number.isFinite(offsetRaw)) {
|
|
return { items, total }
|
|
}
|
|
const limit = Number.isFinite(limitRaw)
|
|
? Math.max(1, Math.min(1000, Math.floor(limitRaw)))
|
|
: items.length
|
|
const offset = Number.isFinite(offsetRaw)
|
|
? Math.max(0, Math.floor(offsetRaw))
|
|
: 0
|
|
return { items: items.slice(offset, offset + limit), total }
|
|
}
|