dorfteich/apps/web
Claude Fable 5 2bdb0ec2cf
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 6m30s
CI / Auth e2e pack (pull_request) Failing after 5s
CI / Import/export fidelity gate (pull_request) Has been skipped
CI / Build container images (pull_request) Failing after 2s
#224: read-trail storage — partitioning, retention, admin query path
Convert read_events to monthly RANGE partitions on occurred_at, with a
DEFAULT partition as safety net: a lagging maintenance job must never
turn the trail's hard-failure semantics into an outage for classified
reads. The dedup unique pair (#223) moves to per-partition indexes
(PostgreSQL cannot carry it on the parent); a bucket spanning a month
boundary may record one duplicate — over-recording is acceptable, gaps
are not.

New daily job read-trail-maintenance (job-count fence 9 -> 10) creates
months ahead — each with its dedup index — and applies the trail's own
retention readTrail.retentionDays (default 365, deliberately independent
of audit.retentionDays): whole expired months are DROPped without
scanning, remainders deleted by range, every run audited as
read_trail.pruned (catalogue v1.2; the fence regex now admits an
underscore namespace).

Site-Admin query path GET /admin/system/read-events answers "who read
page X" and "what did user Y read" within a period — API-only by
design, documented. Growth measured and documented in data-model.md:
~1 MB per 1000 events including indexes.

Tests: retention pruning + audited deletion + admin queries on the
shared database; the partitioned shape, per-partition P2002 dedup,
months-ahead creation and DROP-based pruning against a fresh database
built by the real migration chain.

Refs #224.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
2026-07-31 12:21:45 +02:00
..
e2e #224: read-trail storage — partitioning, retention, admin query path 2026-07-31 12:21:45 +02:00
public #180: dark mode — Light/Dark/System setting with token-based dark palette 2026-07-28 20:40:47 +02:00
src #213: warn on uploads to classified pages; instance policy can block 2026-07-31 07:33:34 +02:00
Dockerfile #236: pin the Node version 2026-07-31 04:14:55 +02:00
index.html #180: dark mode — Light/Dark/System setting with token-based dark palette 2026-07-28 20:40:47 +02:00
nginx.conf CSP: data:-Fonts erlauben (eingebettete Fonts in Excalidraw-SVGs) 2026-07-19 22:27:17 +02:00
package.json #171: A11y-Tooling — axe-Smoke-Pack in CI 2026-07-21 15:24:56 +02:00
playwright.config.ts Add CD workflow: build-push, deploy Test, smoke suite, promote Int 2026-07-04 19:57:16 +02:00
tsconfig.json Add React SPA shell with routing, layout, and API status 2026-07-04 19:19:12 +02:00
vite.config.ts Add offline editing: local persistence, PWA shell, offline resolution (#38) 2026-07-08 22:08:55 +02:00
vitest.config.ts Keep Playwright specs out of Vitest collection 2026-07-05 00:28:28 +02:00