deckhearth/.convoys/add-rate-limiting
Randall Stillwell 60b842ee41 architect: add-rate-limiting (queued → in-progress; 1 brief, D1 routes back for operator gate-1)
Six decisions ratified — five architect-self-ratifiable, one
(D1, scope expansion to gate the three import routes with auth +
admin-role + import rate-limit, plus the matching Bearer-token fix in
pages/admin/card-import.js) routed back for operator approval before
implementer dispatch.

Architecture: single brief, ~180 LOC across 10 files. Lib refactor
preserves Brief 4's checkAuthRateLimit(req) contract; adds four named
exports (search/upload/generate/import) with a Map<className, Ratelimit>
cache and distinct Redis prefix per class. Per-class limits tuned
against real client behavior — search bumped from 30 to 60/min after
finding ShareModal handleSearch has no debounce; generate bumped from 3
to 5/hour after confirming the generator uses DiceBear (free) not a
paid AI service.

Brief includes verbatim new lib/rate-limit.js shape so the implementer
has zero design discretion, plus per-route verbatim post-edit shapes
for all seven gated handlers and the admin-UI fetch fix.

Decision 1 investigation finding: pages/admin/card-import.js currently
fetches without an Authorization header. Without the matching fix in
this brief, adding getUserFromRequest to the import APIs immediately
breaks the admin UI on first run — the brief is internally consistent
only with both edits shipping together.

Decision 6 correction: the convoy file's claim that vitest transitively
loads lib/rate-limit.js is stale (rg verified no test imports it). The
lib refactor is strictly safer than the convoy file implied.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 22:30:09 -05:00
..
brief-1-extend-rate-limit-and-wire-routes.md architect: add-rate-limiting (queued → in-progress; 1 brief, D1 routes back for operator gate-1) 2026-05-24 22:30:09 -05:00