Context
Follow-up from PR #4743. The PR walks back PR #3393's auto-approval for community logo uploads — community uploads now queue as `review_status='pending'` for moderator review when the brand has no verified owner. This closes the abuse vector Harvin demonstrated (anyone can swap any brand's logo instantly).
But the security and PM reviews both flagged: the moderation queue has no documented owner, no SLA, and no abuse signals. If it doesn't move, every unverified brand becomes un-updatable in practice, and the walk-back regresses UX without the safety upside.
What we need
-
Queue ownership. Who reviews pending logo uploads? The `brand-registry-moderators` working group exists (`server/src/services/brand-logo-auth.ts:MODERATOR_GROUP_SLUG`), but membership and rotation aren't documented.
-
SLA. Publish a target review time (e.g., 48hr). Surface it in the upload response: "Typically reviewed within 48 hours." Today the response says "queued for moderator review" with no time hint.
-
Queue UI. Moderators need a list view of pending uploads — by domain, by upload time, with the proposed image rendered inline. The review endpoint exists (`POST /api/brands/:domain/logos/:id/review` in `server/src/routes/brand-logos.ts`); a moderator-facing list page does not.
-
Slack notification on new pending. `notifyRegistryEdit` already fires for brand edits — should also fire for new pending logo uploads, posting to the moderators' Slack channel with an inline preview + review link.
-
Per-user pending-queue depth alert. From the security review: a member can submit logo uploads to every unowned domain they enumerate to either probe ownership state or saturate the queue. Alert when a single user has >N pending across distinct domains in a rolling window. Soft-rate-limit (auto-pause new pending from that user after threshold).
-
Per-brand pending logo cap. The `MAX_LOGOS_PER_BRAND=10` cap counts pending+approved (`server/src/db/brand-logo-db.ts:188`). A community uploader can saturate the cap with 10 pending uploads before any legitimate owner verifies. Either raise the cap for verified-owner uploads OR reserve N slots for verified-owner uploads OR auto-evict oldest pending when an owner verifies and uploads.
Out of scope
Related
Definition of done
- Working group has documented owner + rotation.
- Slack notification wired (small PR).
- Per-user queue-depth signal in PostHog + threshold-based soft-pause (medium PR).
- Per-brand cap logic adjusted to reserve owner slots (small PR).
- Queue UI for moderators (medium PR, can be a new admin page or extend an existing one).
Context
Follow-up from PR #4743. The PR walks back PR #3393's auto-approval for community logo uploads — community uploads now queue as `review_status='pending'` for moderator review when the brand has no verified owner. This closes the abuse vector Harvin demonstrated (anyone can swap any brand's logo instantly).
But the security and PM reviews both flagged: the moderation queue has no documented owner, no SLA, and no abuse signals. If it doesn't move, every unverified brand becomes un-updatable in practice, and the walk-back regresses UX without the safety upside.
What we need
Queue ownership. Who reviews pending logo uploads? The `brand-registry-moderators` working group exists (`server/src/services/brand-logo-auth.ts:MODERATOR_GROUP_SLUG`), but membership and rotation aren't documented.
SLA. Publish a target review time (e.g., 48hr). Surface it in the upload response: "Typically reviewed within 48 hours." Today the response says "queued for moderator review" with no time hint.
Queue UI. Moderators need a list view of pending uploads — by domain, by upload time, with the proposed image rendered inline. The review endpoint exists (`POST /api/brands/:domain/logos/:id/review` in `server/src/routes/brand-logos.ts`); a moderator-facing list page does not.
Slack notification on new pending. `notifyRegistryEdit` already fires for brand edits — should also fire for new pending logo uploads, posting to the moderators' Slack channel with an inline preview + review link.
Per-user pending-queue depth alert. From the security review: a member can submit logo uploads to every unowned domain they enumerate to either probe ownership state or saturate the queue. Alert when a single user has >N pending across distinct domains in a rolling window. Soft-rate-limit (auto-pause new pending from that user after threshold).
Per-brand pending logo cap. The `MAX_LOGOS_PER_BRAND=10` cap counts pending+approved (`server/src/db/brand-logo-db.ts:188`). A community uploader can saturate the cap with 10 pending uploads before any legitimate owner verifies. Either raise the cap for verified-owner uploads OR reserve N slots for verified-owner uploads OR auto-evict oldest pending when an owner verifies and uploads.
Out of scope
Related
Definition of done