import type { AiEvidenceV2_1 } from '../evidence/schema'; import { sortLedger } from './evidencePayloadCollectionsSorters'; import { capRequestedLimit, sliceByOffsetAndLimit, toPaginationPayload, } from './evidencePayloadCollectionsPaging'; import { MAX_LEDGER_LIMIT, normalizeQueryToken, parseNonNegativeIntQuery, } from './evidencePayloadConfig'; export const toLedgerPayload = (evidence: AiEvidenceV2_1) => { const ledger = sortLedger(evidence.ledger); return { version: evidence.version, timestamp: evidence.timestamp, total_count: ledger.length, filters: { lastSeenAfter: null, lastSeenBefore: null, }, pagination: { requested_limit: null, max_limit: MAX_LEDGER_LIMIT, limit: null, offset: 0, }, ledger, }; }; export const toLedgerPayloadWithFilters = (evidence: AiEvidenceV2_1, requestUrl: URL) => { const lastSeenAfter = normalizeQueryToken(requestUrl.searchParams.get('lastSeenAfter')); const lastSeenBefore = normalizeQueryToken(requestUrl.searchParams.get('lastSeenBefore')); const requestedLimit = parseNonNegativeIntQuery(requestUrl.searchParams.get('limit')); const limit = capRequestedLimit(requestedLimit, MAX_LEDGER_LIMIT); const offset = parseNonNegativeIntQuery(requestUrl.searchParams.get('offset')) ?? 0; const filteredLedger = sortLedger(evidence.ledger).filter((entry) => { if (lastSeenAfter && entry.lastSeen.toLowerCase() < lastSeenAfter) { return false; } if (lastSeenBefore && entry.lastSeen.toLowerCase() > lastSeenBefore) { return false; } return true; }); const ledger = sliceByOffsetAndLimit(filteredLedger, offset, limit); return { version: evidence.version, timestamp: evidence.timestamp, total_count: filteredLedger.length, filters: { lastSeenAfter: lastSeenAfter ?? null, lastSeenBefore: lastSeenBefore ?? null, }, pagination: toPaginationPayload({ requestedLimit, maxLimit: MAX_LEDGER_LIMIT, limit, offset, pageSize: ledger.length, totalCount: filteredLedger.length, }), ledger, }; };