What ships in this project
- Postgres
reactionstable withentry_kind,entry_slug,kindenum (support / concern),user_idandclient_tokencolumns under XOR check, partial unique indexes, and RLS policies. - Anonymous client token stored in an httpOnly cookie
(
oln_anon_id, 1-year max-age) so anonymous reactions remain attributable to a single browser without identifying the user. - Server actions (
reactAction,unreactAction) returning a discriminatedActionResultso the client widget can rollback on rejection and lock the UI for write-once anonymous reactions. - Client widget (
ReactionButtons) with optimistic apply/rollback, retract on second click for registered users, and anaria-pressedselected state. - Mounted on
/journal/[slug]and/register/[slug]for parity.
Why
Entry 015 commits to a reaction primitive in principle. This project implements the thin slice end-to-end so the priority signal exists before the roadmap surface needs it (Entry 016).
Open follow-ups
- G-036 — operational parameters (anonymous-vs-registered weighting, cooldowns, abuse heuristics).
- Aggregation views beyond per-entry counts (e.g., a "most reacted" surface).