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.
Frontend ↔ Backend Integration
Transport contract
- Base URL: browser callers use
NEXT_PUBLIC_API_URL, usually defaulting tohttp://localhost:3001. - Versioning: none; routes are mounted directly below
/api. - Client: native browser
fetch;app/lib/adminFetch.tsis a narrow wrapper for admin throttling. - Authentication: backend-issued HTTP-only
auth_tokenJWT cookie; calls usecredentials: "include". - CSRF: no CSRF token. Backend relies on same-site cookies, strict CORS/Origin checks for state-changing requests, and JSON-only request bodies. This must not be confused with frontend UI checks.
- Schemas/types: manually maintained interfaces and JSON access in each repo. No shared package, OpenAPI document, or generated client.
- Errors: backend usually returns
{error: string}plus an HTTP status. Pages interpret special statuses locally; submission verification depends on412. - Retry: normal calls do not retry.
adminFetchhandles a single rate-limit retry fromRetry-After. - Pagination: conventions vary (
page/limit, offset-derived lists, page-size admin tables). - Live transport: support and live-event endpoints use SSE with database polling/heartbeats. No WebSocket implementation was found.
Endpoint ownership map
| Product area | Frontend caller | Backend route/owner |
|---|---|---|
| Session | dashboard layout/login/profile | src/api/routes/auth.ts: /api/auth/me, OAuth initiation/callbacks, logout, providers, email |
| Onboarding/referral attribution | /onboarding | onboarding.ts, referral cookie middleware and attribution services |
| Operational campaigns | dashboard campaigns/submit/admin | campaigns.ts and admin campaign routes |
| Submission/create/history | submit modal/history/admin submissions | submissions.ts, verifications.ts, admin submission handlers |
| Stats/leaderboard | dashboard/admin overview | stats.ts, admin stats/chart handlers |
| Payout request | payout page | payouts.ts, payout processing utilities |
| Payout review/send | admin payouts | adminPayoutReview.ts, TOTP, rail dispatcher |
| Payment methods | payout method UI | methods.ts, stripe.ts, paypal.ts, usdt.ts |
| Tax forms | tax onboarding/admin tax/year-end | taxForms.ts, adminTaxForms.ts, adminFtinConfig.ts, adminYearEnd.ts |
| Profile/social ownership | profile/verification modal | users.ts, verifications.ts |
| Notifications | dashboard shell/admin announcements | notifications.ts, admin announcement routes |
| Support | shared /dashboard/support Whop ChatElement screen | supportChat.ts and whopSupportChat.ts; Whop Support Channels |
| Affiliates | dashboard stats/admin affiliates | referrals.ts, /r/:code, admin referral routes |
| Featured games/services | public/admin pages | games.ts, services.ts, admin mutations |
| PV tracker | admin PV page | adminPvTracker.ts → file-backed pvTracker.ts |
Major workflow traces
Submit a video
text
SubmitVideoModal
→ POST /api/submissions {campaignId, videoLink}
→ submissions router + SubmitVideoSchema
→ campaign/platform/video scrape
→ linked-account ownership lookup
→ Submission + initial ViewSnapshot
→ JSON result shown in modal/historyIf ownership is missing:
text
412 response with platform/account metadata
→ AccountVerificationModal
→ POST /api/verifications/start
→ creator adds code to social bio
→ POST /api/verifications/check
→ LinkedSocialAccount created
→ original submission retriedRequest and approve payout
text
Payout page
→ GET balance/method/tax state
→ POST /api/payouts/request
→ Payout REQUESTED + async rescrape
→ PayoutItems / READY_FOR_REVIEW
→ admin payout detail and item decisions
→ approve → AWAITING_SEND
→ TOTP-protected send → payment rail
→ COMPLETED/FAILED returned on subsequent readsReferral link
next.config.ts rewrites frontend-origin /r/:code to the backend route. The backend resolves aliases/canonical codes and sets referral/device cookies while the browser still sees the frontend origin. Onboarding completion consumes attribution data and writes Referral/WebUser.referredById.
Fragile cross-repository dependencies
- Status strings are duplicated: submission, payout, tax, support, announcement, rail, and campaign booleans have no shared definition.
canSubmitis computed by the backend and used by the campaign UI, but submission creation has its own enforcement set. The current router does not clearly enforce every UI gate (acceptingSubmissions,paused, and all campaign toggles), so the UI must not be considered authoritative.- Frontend dashboard access assumes administrator status for all nested routes; backend creator APIs only require authentication.
- Special
412response structure is a hidden contract for account verification/retry. - Both Discord-era IDs and
webUserIdare serialized/queried; callers must know which key an endpoint expects. - Monetary fields mix string rates/budgets and numeric computed values. Frontend formatting assumes backend parsing/output semantics.
- Payout status and
amountmeaning differ between legacy and current rows. - The frontend manually knows endpoint paths and payload property names. Backend changes are not compiler-checked across repositories.
Parallel/duplicate server paths
| Capability | Active frontend path | Parallel backend path | Finding |
|---|---|---|---|
| Contact | Next /api/contact | Express /api/contact | Active public form calls Next; backend path has its own abuse persistence/limits |
| Booking | Calendly embed | Express /api/bookings + admin UI | BookCallScheduler can call backend but appears unused |
| Whop count | Next /api/live/clipper-count | Express same path | Public statistic calls Next implementation |
| Roblox game/thumbnail | Next proxy for public case studies | Express proxy | Dashboard campaign cards can use backend; public case studies use Next |
These duplicates have different caching, persistence, or failure behavior and should not be consolidated during an audit.
Webhooks and server-to-server flows
Stripe, PayPal, and NowPayments send webhooks directly to backend webhook routes. They do not pass through Next.js. The frontend contact route independently calls Turnstile and Resend server-to-server. OAuth providers call backend callbacks, which set the cookie and redirect to the frontend.