Appearance
Historical snapshot archived 2026-09-25. This records an earlier review or plan, not current implementation or live ticket state. For current work, follow root AGENTS.md, the relevant BloxClips skill, and owning repository source/tests. Preserve approved decisions as evidence; verify their present authority before acting.
Known Issues & Architectural Risks
Problems discovered during audit. Not a refactoring proposal — documentation only.
Issue 1: DELETE Endpoint Exists But May Have Gaps
Evidence
- Frontend:
features/admin/user-detail/api/adminUserDetail.ts:36-37callsDELETE /api/admin/submissions/:id - Backend: Route exists at
admin.ts:3039-3073
Current Behavior
DELETE endpoint implemented with requireAdmin + auditLog. Deletes submission and calls checkAndCloseCampaign if was ACCEPTED.
Risk
- No ownership check — any admin can delete any submission
- No check for
paidOutorpaidViewsTotal— deleting a paid submission loses audit trail ViewSnapshotandPayoutItemcascade delete (Prisma cascade) — may lose history
Confidence
Confirmed — route exists but has gaps
Issue 2: Banned Users Can Still Submit
Evidence
src/api/routes/submissions.ts— no ban check onPOST /api/submissionssrc/api/routes/admin.ts:1179— ban createsIdentityBlacklistentriessrc/utils/moderation.ts—phoneBlacklistValue,upsertBlacklistEntry
Current Behavior
Banned user (via Discord ID, email, phone, IP) can still submit videos.
Risk
Banned fraudsters continue submitting; moderation ineffective.
Confidence
Confirmed — no check in submission create
Issue 3: Email Gate Disabled in Two Places
Evidence
submissions.ts:270-284— commented outSubmitVideoModal.tsx:285-290— commented outEmailGatewrapper
Current Behavior
Users can submit without verified email.
Risk
No email for payout notifications, tax form reminders, support.
Confidence
Confirmed — explicitly commented
Issue 4: Rejection Reason Not Stored on Submission
Evidence
admin.ts:1483—reasonfrom request bodyadmin.ts:1607— reason only inAdminAuditLog.details.reasonSubmissionmodel has norejectionReasonfield
Current Behavior
Deny/Flag reason only in audit log (hard to query/display).
Risk
Clipper never sees why denied; admin can't filter by reason.
Confidence
Confirmed — schema lacks field
Issue 5: Duplicate Status Logic (Frontend + Backend)
Evidence
- Frontend:
features/submissions/lib/status.ts—getSubmissionStatusTone - Frontend:
SubmissionReviewRow.tsx:139-168—getStatusBadge(duplicate mapping) - Backend:
prisma/schema.prisma:331— status string enum - Backend:
validation/schemas.ts:90—UpdateSubmissionStatusSchemaenum
Current Behavior
Status strings duplicated in 4+ places; no single source of truth.
Risk
Adding status requires changes in multiple files; drift likely.
Confidence
Confirmed — grep shows 4+ locations
Issue 6: Legacy Discord Approval Code Still Present
Evidence
submissions.ts:37-124— entirepostToDiscordLogChannelfunction commented outbuttonHandler.ts:155-158— returns "use dashboard" for submission buttons
Current Behavior
Dead code in repo; confusion for new developers.
Risk
Accidental re-enable; maintenance burden.
Confidence
Confirmed — explicitly commented
Issue 7: Two Coexisting Payout Flows (Legacy + Delta)
Evidence
Submission.paidOut+paidAmount+payoutId(legacy)Submission.paidViewsTotal+paidAmountTotal+PayoutItem(delta)Payout.statushas both legacy and new values
Current Behavior
Both flows work; legacy excluded from delta via paidOut=false filter.
Risk
Complexity; double-payment bugs; confusing admin UI.
Confidence
Confirmed — schema + code
Issue 8: No Rate Limit on Submission Creation
Evidence
submissions.ts— no rate limiter onPOST /api/submissions- Only 10-min cross-campaign cooldown per user
Current Behavior
User can spam submissions (limited only by campaign duplicate check).
Risk
API abuse, Apify cost burn, moderation queue flood.
Confidence
Confirmed — no userLimiter on route
Issue 9: Campaign Budget Pre-Check Race Condition
Evidence
admin.ts:1498-1515— budget check BEFORE status updateadmin.ts:1537-1572— budget clamp AFTER status update- No transaction spanning both
Current Behavior
Two admins accept simultaneously → both pass pre-check → both clamp → budget exceeded.
Risk
Budget overspend; inconsistent frozenViewCount.
Confidence
Strong evidence — non-atomic check-then-act
Issue 10: Payout Item Badges Only at Payout Time
Evidence
processRequest.ts:150-156— badges computed during rescraperunTrackingTick.ts— no badge computation
Current Behavior
Fraud signals (low like ratio, view spike) only detected when user requests payout.
Risk
Fraudulent submissions tracked for 30 days before detection.
Confidence
Confirmed — code inspection
Issue 11: Manual View Count Priority Inconsistency
Evidence
campaignBudget.ts:46—manualViewCount ?? frozenViewCount ?? currentViewscalculateSubmissionEarnings.ts:106— same priorityrescrape.ts:142—manualViewCount ?? frozenViewCount ?? outcome.viewsAtPayoutadmin.ts:444— stats:manualViewCount ?? frozenViewCount ?? currentViews
Current Behavior
Consistent priority: manual > frozen > current. But not documented as invariant.
Risk
Future change could break priority silently.
Confidence
Confirmed — consistent but implicit
Issue 12: Tracking Stop Conditions Scattered
Evidence
runTrackingTick.ts:150-152— query excludestrackingStoppedAt,frozenViewCount,campaign.viewsFrozenrunTrackingTick.ts:178-187— expiry check setstrackingStoppedAtrunTrackingTick.ts:131— 3 failures setsFLAGGED+trackingStoppedAtadminPayoutReview.ts:489-496— payout reject/flag setstrackingStoppedAt
Current Behavior
Multiple code paths stop tracking; no single "stopTracking" function.
Risk
Inconsistent state; missed cleanup (e.g., nextPollAt not nulled in all paths).
Confidence
Strong evidence — multiple mutation sites
Issue 13: Cross-Campaign Duplicate Cooldown Only 10 Min
Evidence
submissions.ts:325-338—RECENT_DUPLICATE_WINDOW_MS = 10 * 60 * 1000
Current Behavior
User can re-submit same video to different campaign after 10 minutes.
Risk
Low barrier to spam across campaigns.
Confidence
Confirmed — constant value
Issue 14: No Self-Review Prevention for Admins
Evidence
admin.ts:1495—adminId = req.user!.discordId- No check if admin owns the submission
Current Behavior
Admin can accept/deny their own submission.
Risk
Conflict of interest; no audit trail of self-action.
Confidence
Suspected — no code preventing it
Issue 15: Submission.addedByAdmin Field Unused
Evidence
prisma/schema.prisma:339—addedByAdmin Boolean @default(false)- No API to create admin-added submission
- No frontend UI
Current Behavior
Field always false; dead code.
Risk
Schema drift; confusion.
Confidence
Confirmed — no write path
Issue 16: Submission.messageId Legacy Field
Evidence
prisma/schema.prisma:334—messageId String?submissions.ts:111-114— commented Discord message ID update- No current use
Current Behavior
Always null.
Confidence
Confirmed — dead code
Issue 17: ViewSnapshot Created on Submission Create (Before Review)
Evidence
submissions.ts:515-527— ViewSnapshot created at PENDING
Current Behavior
Snapshots exist for denied/flagged submissions (never accepted).
Risk
Chart noise; wasted storage; misleading admin charts.
Confidence
Confirmed — code path
Issue 18: campaign.viewsFrozen Not Checked on Submission Create
Evidence
submissions.ts:291— checkscampaign.active,acceptingSubmissions,isDeleted- Does NOT check
viewsFrozen
Current Behavior
Can submit to frozen campaign (if acceptingSubmissions not yet false).
Risk
Submissions to frozen campaigns enter PENDING but never tracked.
Confidence
Strong evidence — missing check
Issue 19: Affiliate Sweep on Payout Approve (Not Send)
Evidence
adminPayoutReview.ts:545-557—sweepCommissionsIntoPayoutat approveadminPayoutReview.ts:855— reverse on terminal send failure only
Current Behavior
Referral commissions moved to payout at approve, not send. If send fails transiently, sweep stays.
Risk
Referrer "paid" for payout that hasn't sent; accounting mismatch.
Confidence
Confirmed — code inspection
Issue 20: Tax Form Snapshot Taken at Approve, Not Send
Evidence
adminPayoutReview.ts:514-521—taxFormSnapshotIdcaptured at approve- If form changes between approve and send, snapshot stale
Current Behavior
Year-end 1099 uses form at approve time.
Risk
Tax form mismatch if user updates between approve/send (days/weeks apart).
Confidence
Suspected — design choice, not bug
Issue 21: No Integration Test Coverage for Critical Flows
Evidence
- No test files for
runTrackingTick,processPayoutRequest,computeScrapeBudgetClamp - Unit tests only for pure functions (
pollScheduler.test.ts,clipperGroups/domain.test.ts)
Current Behavior
Critical money/budget logic untested end-to-end.
Risk
Regressions in budget clamp, payout math, tracking.
Confidence
Confirmed — test directory scan
Issue 22: Apify Cost Tracking Not Enforced
Evidence
costTracker.tsrecords usage per user- No limit/alert/block on high spend
Current Behavior
Malicious user could burn Apify budget via payout rescrapes.
Risk
Uncontrolled API costs.
Confidence
Confirmed — tracker exists, no enforcement
Issue 23: YouTube Quota Not Monitored
Evidence
youtube.ts— batch calls, no quota tracking- No circuit breaker
Current Behavior
Quota exhaustion → all YouTube scrapes fail → submissions flagged after 3 failures.
Risk
Silent tracking degradation.
Confidence
Suspected — no quota handling code
Issue 24: Submission.duration Not Used for Earnings
Evidence
prisma/schema.prisma:336—duration Int @default(0)calculateSubmissionEarnings.ts— only usesvideoType(short/long)
Current Behavior
Duration stored but not used; videoType from scrape determines rate.
Confidence
Confirmed — field exists, not used in earnings