import assert from 'node:assert/strict' import { test } from 'node:test' import fc from 'fast-check' import { cutoffIso, groupByMonth, monthOf, type RetentionRow, rowsToArchive, type SegmentSidecar, segmentsOverlapping, } from './retention.ts' test('cutoff subtracts hot days', () => { assert.equal(cutoffIso(new Date('2026-09-12T00:00:00Z'), 90), '2026-06-14T00:00:00.000Z') }) test('only rows strictly older than the cutoff archive', () => { const rows: RetentionRow[] = [ { id: 'a', ts: '2026-06-13T23:59:59Z' }, { id: 'b', ts: '2026-06-14T00:00:00.000Z' }, { id: 'c', ts: '2026-09-01T00:00:00Z' }, ] assert.deepEqual( rowsToArchive(rows, '2026-06-14T00:00:00.000Z').map((r) => r.id), ['a'], ) }) test('rows group by month', () => { const groups = groupByMonth([ { id: 'a', ts: '2026-01-15T00:00:00Z' }, { id: 'b', ts: '2026-01-02T00:00:00Z' }, { id: 'c', ts: '2026-02-01T00:00:00Z' }, ]) assert.deepEqual([...groups.keys()], ['2026-01', '2026-02']) assert.equal(groups.get('2026-01')?.length, 2) }) test('sidecar overlap selection skips non-overlapping segments', () => { const sc = (month: string, firstTs: string, lastTs: string): SegmentSidecar => ({ version: 1, kind: 'audit', month, segment: 's', count: 1, firstId: 'x', lastId: 'x', firstTs, lastTs, sha256: '0'.repeat(64), bytes: 1, }) const sidecars = [ sc('2026-01', '2026-01-01T00:00:00Z', '2026-01-31T00:00:00Z'), sc('2026-03', '2026-03-01T00:00:00Z', '2026-03-31T00:00:00Z'), ] assert.equal(segmentsOverlapping(sidecars, { since: '2026-02-01T00:00:00Z' }).length, 1) assert.equal(segmentsOverlapping(sidecars, { since: '2026-04-01T00:00:00Z' }).length, 0) assert.equal(segmentsOverlapping(sidecars, {}).length, 2) }) test('property: every row lands in exactly one month group', () => { let counter = 0 const arbRow = fc.record({ id: fc.integer({ min: 0, max: 1_000_000 }).map((n) => `id-${counter++}-${n}`), ts: fc .integer({ min: Date.UTC(2000, 0, 1), max: Date.UTC(2030, 0, 1) }) .map((ms) => new Date(ms).toISOString()), }) fc.assert( fc.property(fc.array(arbRow, { maxLength: 60 }), (rows) => { const groups = groupByMonth(rows) let total = 0 for (const [month, bucket] of groups) { for (const r of bucket) assert.equal(monthOf(r.ts), month) total += bucket.length } assert.equal(total, rows.length) }), ) })