Tighten meme moderation quality gate

This commit is contained in:
2026-07-03 12:45:59 -03:00
parent d80d596664
commit 2baa814cbd
7 changed files with 102 additions and 11 deletions
+2 -2
View File
@@ -23,7 +23,7 @@ The server listens on `http://localhost:8080` by default.
- `TRUST_PROXY`: set to `true` when running behind a trusted reverse proxy so upload limits use `X-Forwarded-For`
Uploads accept PNG and JPEG images. The server rejects files over 5 MB, any image edge over `6000px`, and images over 20 million pixels. Accepted uploads are decoded, metadata-stripped, resized so the longest edge is at most `1600px`, and stored as WebP.
Upload caps are 5 per hour per IP, 10 per day per IP, and 100 globally per day. AI-approved uploads publish immediately; ambiguous uploads are queued for the secret admin review page; likely illegal uploads are rejected immediately.
Upload caps are 5 per hour per IP, 10 per day per IP, and 100 globally per day. Strong AI-approved uploads publish immediately; ambiguous or low-quality uploads are queued for the secret admin review page; likely illegal uploads are rejected immediately.
Files are stored under sharded date/hash paths:
@@ -56,7 +56,7 @@ Set `SITE_URL` in production so canonical and API discovery URLs use the public
- `GET /media/<sha256>`: returns the normalized WebP image for one approved meme.
- `POST /api/memes`: submits one PNG/JPEG upload as `multipart/form-data` with a file field named `meme`.
API uploads use the exact same path as the browser form: persistent IP upload quotas, file size checks, image dimension and pixel checks, metadata-stripping WebP normalization, AI moderation, and admin-review queueing. A published upload returns `201`; a queued upload returns `202`; moderation rejection returns `422`.
API uploads use the exact same path as the browser form: persistent IP upload quotas, file size checks, image dimension and pixel checks, metadata-stripping WebP normalization, AI moderation, and admin-review queueing. A published upload returns `201`; a queued upload returns `202` with `moderationReason`; moderation rejection returns `422` with `moderationReason`.
Public API reads are rate-limited per IP and return `429` with `Retry-After` when exceeded. List and metadata responses include `RateLimit-*` headers and a `rateLimit` object.