## Context Every write endpoint needs rate limits to prevent abuse. Use Upstash Ratelimit or a simple in-memory + Redis fallback. ## Acceptance criteria - [ ] `lib/ratelimit.ts` exports a `limit(key, config)` helper - [ ] Applied to: magic link requests, sign-up, recovery requests, contact form, job posting, report submission, avatar upload - [ ] Returns `429` with `Retry-After` header on breach - [ ] Logged to `AuditLog` when a user consistently hits limits Depends on #1.
Context
Every write endpoint needs rate limits to prevent abuse. Use Upstash Ratelimit or a simple in-memory + Redis fallback.
Acceptance criteria
lib/ratelimit.tsexports alimit(key, config)helper429withRetry-Afterheader on breachAuditLogwhen a user consistently hits limitsDepends on #1.