# ADR 0002 — Moderated comments with server-forced author Date: 2026-10-03 ## Status Accepted ## Context Comments are user-generated content on a public site. Risks: identity spoofing (a request forging `author`), spam (no gate), and orphaned identity data (nested user lookups through restrictive read access). QA-D04 required a real backend for comments. ## Decision - Comments default to `status: 'pending'`; only `approved` are publicly visible. The read access rule returns `{ status: { equals: 'approved' } }` for non-admins. - The author is forced server-side on create, twice: a `beforeChange` hook on the collection and the custom route — REST-created comments can never spoof identity. - `authorName` is denormalized at submit time (snapshot of `fullName`, else «عضو») to avoid nested user-read access issues when rendering; the email is never exposed. - Approval/rejection is admin-only, done in the Payload admin panel. Authors cannot edit or delete their comments (moderated model). - Authors see their own pending comments rendered on the post page tagged «قيد المراجعة» (via `overrideAccess` query filtered to their own author id), so a submitted comment does not "vanish". ## Tests for a real ADR - **Hard to reverse**: the display-name snapshot and status lifecycle are visible in every rendered comment and in the DB. - **Surprising**: forcing author in two places (hook + route) and `overrideAccess` for the pending query are non-obvious. - **Real trade-off**: moderation latency for users vs. spam safety; denormalization vs. live join through restricted user reads.