Buddy (BuddyCinemas) — Enterprise OTT Architecture & Implementation Guide

Purpose: Single source of truth for the AI coding agent. Read this file fully first. Build one module at a time, in order (see §Build Order). Core modules are 1–36; adopt-later hardening modules are 37–42 (designed to plug in without rewrites).


0. Platform Overview

  • Brand: Buddy / BuddyCinemas (buddycinemas.com, Android + iOS apps)
  • Content types: Shorts, Short-series, Series (Season → Episode), Films, Trailers, (Live optional)
  • Entities / billing:
    • Newtact Lab Private Limited (OPC): India users → Razorpay/Cashfree → GST invoices
    • Thaja FZE LLC: Rest-of-world users → Stripe → VAT; also IP/brand/parent
  • Payment statement descriptor: BUDDYCINEMAS on both gateways
  • App store strategy: "Sign-in only" apps (Netflix model). All paid purchases on web to avoid 15–30% IAP cut. Apps authenticate + stream only.
  • Guest-first access: Watch as guest (anonymous), earn Bonus tokens via ads, later register and merge.

Tech Stack (PNPM Monorepo)

LayerChoice
MonorepoPNPM workspaces (apps/* + packages/*), Turborepo (optional)
Backend/APIHono on Cloudflare Workers, Drizzle ORM, Zod
API spec/docsOpenAPI 3.1 + Scalar (interactive docs), versioned v1/v2
AuthBetter Auth
Admin + WebNext.js + Tailwind, HTML5 player, TanStack Query/Table, shadcn/ui, react-hook-form + Zod
MobileExpo + React Native, DRM-capable player
Storage / HLSCloudflare R2 (zero egress)
CDNCloudflare CDN
TranscodingFFmpeg on on-demand cloud GPU (RunPod / AWS g5, NVENC)
DBCloudflare D1 (start) → Neon/Supabase Postgres (scale)
CacheWorkers KV
StatefulDurable Objects (sessions, concurrency, counters)
QueuesCloudflare Queues (→ Upstash QStash)
CronCloudflare Cron Triggers
EmailResend (→ AWS SES)
SearchTypesense/Meilisearch
AnalyticsCloudflare Analytics Engine + GA4/Firebase/GTM/Mixpanel
Docs renderMarkdown/MDX → auto-rendered HTML (Next.js docs route), auto-synced from repo

Golden architecture rules

  1. Modular monolith on Workers — domain modules; Service Bindings + Durable Objects + Queues.
  2. Vendor abstraction everywhere — external services behind /modules/<domain>/providers/; swap = config change.
  3. Idempotency keys on all payment/token/entitlement writes.
  4. Immutable ledgers for tokens + royalties + admin actions.
  5. API versioning (/v1, /v2) with OpenAPI + Scalar; support phased migration (§36).
  6. Every catalog entity has a public Short-ID + slug (§4). Never expose internal DB ids.
  7. Guest = a real anonymous backend account, upgradable/mergeable into a registered account.
  8. Every feature ships with docs (PRD/FAQ/changelog) that auto-render to HTML (§35).
  9. Build extensible from day 1 (adopt-later, never rebuild) — every module exposes (a) a provider interface, (b) domain events on an outbox/event bus, and (c) feature flags. Future modules (37–42) subscribe to existing events and flip a flag on — no rewrites. See §Roadmap.
  10. KV-first — read-heavy/edge data (configs, entitlement-resolution cache, catalog snapshots, token-value config, session lookups, rate-limit counters) lives in Workers KV; Durable Objects for strongly-consistent counters; D1/Postgres = system of record only.
  11. Zero-trust on the client — assume every request is hostile; all value-bearing logic (tokens, entitlements, ad-reward grants) is server-verified and double-checked (§Security / §39).
  12. Mobile-first — design every surface for phones first: watching works in a mobile browser (responsive HLS web player), and admin + producer portal are fully operable from a phone.
  13. Docs + git on every change — each change updates its module docs (§35) and is committed/pushed.

MONOREPO STRUCTURE (PNPM workspaces)

buddycinemas/
├── pnpm-workspace.yaml
├── turbo.json                      # optional, for caching/parallel builds
├── package.json                    # root scripts (dev, build, lint, typecheck)
├── tsconfig.base.json              # shared TS config, path aliases
├── .env.example                    # documented env vars (never commit real .env)
├── .github/workflows/              # CI: lint, test, deploy, docs auto-sync
├── ARCHITECTURE.md                 # ← this guide (root, read-first)
│
├── docs/                           # §35 source-of-truth docs (MD/MDX), version-controlled
│   ├── modules/                    # one folder per module: PRD.md, FAQ.md, CHANGELOG.md
│   ├── api/                        # API guides
│   └── runbooks/                   # DR, deploy, incident
│
├── apps/
│   ├── api/                        # Hono on Cloudflare Workers (the backend)
│   │   ├── wrangler.toml           # Workers config: bindings (KV, R2, D1, DO, Queues)
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts            # Worker entry, mounts gateway
│   │       ├── gateway/            # §1 versioning, routing, rate-limit, geo, CORS
│   │       ├── modules/            # ← all domain modules (see list below)
│   │       └── shared/             # cross-cutting (see below)
│   │
│   ├── web/                        # Next.js public site + web checkout + responsive HLS player (mobile-first)
│   │   ├── next.config.js
│   │   └── src/{app,components,lib,hooks}
│   │
│   ├── admin/                      # §29 Next.js admin — responsive/touch-first (manage everything from phone)
│   │   └── src/{app,components,lib}
│   │
│   ├── mobile/                     # Expo / React Native (sign-in + stream only)
│   │   ├── app.json
│   │   └── src/{screens,components,navigation,lib}
│   │
│   └── docs-site/                  # §35 auto-rendered HTML docs + §36 Scalar API docs
│       └── src/app/docs/[[...slug]]
│
└── packages/                       # shared, importable workspace packages
    ├── db/                         # Drizzle schema + migrations (single source of DB truth)
    │   ├── schema/                 # one file per domain (content.ts, tokens.ts, royalty.ts…)
    │   └── migrations/
    ├── contracts/                  # shared Zod schemas + inferred TS types (api↔web↔mobile)
    ├── openapi/                    # §36 generated OpenAPI 3.1 spec
    ├── sdk/                        # typed API client (used by web, admin, mobile)
    ├── ui/                         # shared React components / design system (mobile-first)
    ├── config/                     # shared eslint, tsconfig, tailwind presets
    └── core/                       # pure domain logic shared across apps (optional)

apps/api/src/modules/ — backend domains (§ refers to module number above)

modules/
├── auth/            # 2   Better Auth, device/concurrency
├── users/           # 4
├── guest/           # 5   identity, provision, limits, merge
├── social/          # 6   likes, favorites, share
├── content/         # 7
├── metadata/        # 8
├── search/          # 9
├── media/           # 10  FFmpeg HLS→R2  (+ providers/)
├── drm/             # 11
├── player/          # 12
├── entitlements/    # 13
├── revenue/         # 14
├── subscriptions/   # 15
├── payments/        # 16  providers/{stripe,razorpay,cashfree,uae}
├── wallet/          # 17
├── tokens/          # 18  balance, ledger, earning, purchase, unlock-rules, value-config
├── partners/        # 19
├── royalty/         # 21
├── ads/             # 22
├── analytics/       # 23
├── reporting/       # 24  + producer portal endpoints
├── notifications/   # 25
├── email/           # 26
├── invoicing/       # 27
├── tax/             # 28
├── admin/           # 29  rbac, audit, panels, impersonation
├── backup/          # 30
├── storage/         # 31  providers/{r2,b2,bunny}
├── i18n/            # 32
├── featureflags/    # 33
├── observability/   # 34
├── docs/            # 35  registry, render, sync, changelog
├── webhooks/        # 36
├── jobs/            # 36  cron handlers
└── api/             # 36  openapi, scalar, versioning, migration

Every module folder uses the SAME internal shape (consistency = easy to navigate)

modules/tokens/
├── index.ts          # public exports + route registration
├── routes.ts         # Hono routes (Zod-validated, versioned)
├── service.ts        # business logic (server-verified, zero-trust)
├── repository.ts     # DB access via Drizzle (the ONLY place touching db)
├── schema.ts         # Zod request/response schemas → feeds OpenAPI
├── events.ts         # domain events emitted to outbox (adopt-later hook, Rule 9)
├── providers/        # external-vendor adapters (swap = config)
├── types.ts
└── README.md         # PRD/FAQ stub → auto-rendered by §35

apps/api/src/shared/ — cross-cutting

shared/
├── db/               # Drizzle client + connection
├── idgen/            # §3 shortid (easy charset, 4→8) + slug
├── cache/            # KV helpers (KV-first, Rule 10/12)
├── queue/            # Cloudflare Queues wrappers
├── durable-objects/  # sessions, concurrency caps, atomic counters
├── events/           # outbox / event-bus (Rule 9 adopt-later backbone)
├── providers/        # base provider interface + registry
├── schemas/          # shared Zod
├── errors/           # typed errors + handler
├── config/           # env + feature-flag access
└── utils/

AGENT INSTRUCTIONS (read before writing any code)

These are operating rules for the AI coding agent building this repo. Follow them on every task. When in doubt, ask before deviating from the structure or these rules.

A1. Mobile-first

  • Users must be able to watch content in a mobile browser (responsive HLS web player), not only in the native app.
  • The admin panel and producer portal must be fully usable on a phone — admins/producers manage everything from mobile.
  • Design and test phone layout first, then scale up. No desktop-only screens; touch-first interactions.

A2. KV use as much as possible

  • Prefer Workers KV for read-heavy/edge data: configs, entitlement-resolution cache, catalog snapshots, token-value config, session lookups, rate-limit counters, producer-portal rollups.
  • Use Durable Objects only for strongly-consistent counters (likes, concurrency caps).
  • D1/Postgres = system of record only. Invalidate KV via domain events, never let it drift silently.

A3. Security control (think every time)

  • For every change, explicitly ask: "With this change, can someone tamper with or misuse our system?"
  • If a request carries value (tokens, entitlements, ad rewards, payments): server-verify and double-check it; never trust the client.
  • Validate all input with Zod; keep WAF/rate-limit/CSP/bot-checks intact; emit the right domain events so §39 fraud can watch.
  • Write down the security consideration in the change's doc/PR (see A4).

A4. Documentation updated on every change (in detail)

  • No change is "done" until its module docs are updated: PRD / FAQ / How-it-works / CHANGELOG under /docs/modules/<module>/.
  • Docs are the source of truth and auto-render to HTML (§35). Code change without a matching doc update = incomplete.
  • Record: what changed, why, any API/schema change, and the security consideration (A3).

A5. Push to git

  • Commit and push after every working change. Small, frequent commits with conventional-commit messages (feat:, fix:, docs:, refactor:…) — the changelog (§35) and CI depend on them.
  • CI must pass (lint, typecheck, test, docs-sync) before merge. Never leave working changes uncommitted locally.

A6. Structure & consistency

  • Build modules in Build-Order; one module at a time.
  • Every module follows the standard folder shape above; only repository.ts touches the DB.
  • Never expose internal DB ids — use Short-ID + slug (§3). Vendor calls go through providers/ (swap = config).
  • Reuse packages/contracts + packages/sdk types across api/web/admin/mobile — no duplicated/ad-hoc types.

A7. Pre-commit Verification

  • Always run pnpm lint and pnpm typecheck locally to guarantee zero errors before committing.

A8. Remote Migrations

  • Any changes to the Drizzle schema must be generated (drizzle-kit generate) and applied remotely to keep the Cloudflare D1 instance in sync (wrangler d1 migrations apply <db> --remote). Local-only DB changes are unacceptable.

DOMAIN MODULES (1–36)

Group A — Core Platform

1. API Gateway / Edge Layer

  • API versioning (/v1, /v2), routing, Zod request/response validation
  • Rate limiting (per-user/IP/plan/guest), CORS, security headers, request signing
  • Geo-detection (cf.country) → payment + entity + DRM-territory routing
  • Partner API key management + sandbox

2. Auth & Identity (Better Auth)

  • Email/OTP, social (Google/Apple), sessions, MFA, account linking
  • Device management & concurrency limits (e.g. max 2 streams)
  • RBAC token issuance (enforced via §29)
  • "Sign-in only" entitlement token for apps; guest auth bridge (§5)
  • Sessions in Durable Objects / KV

3. Short-ID & Slug System (cross-cutting utility used by content/metadata/partners)

  • Public Short-ID: 4–8 alphanumeric, lowercase+digits, "easy" charset (exclude ambiguous 0/o/1/l/i)
  • Progressive length: start 4 chars; when a type's 4-char space fills → 5 → 6 … up to 8
  • Manual or auto: create/edit form has optional Short-ID field; blank → auto-generate; provided → validate format + per-type uniqueness, reject duplicates. Examples: 11aa, t9k2, abcde
  • Immutable once published (changing breaks shared links)
  • Slug: auto from title (kebab, transliterated, deduped: naruto-the-last, naruto-the-last-2), optional override
  • Public URLs: buddycinemas.com/film/t9k2/naruto-the-last (Short-ID = source of truth, slug cosmetic)
/shared/idgen  → /shortid (easy charset, 4→8, per-type namespace, collision retry)  /slug

4. User & Profile

  • Accounts, multiple profiles (kids/adult), watchlist, favorites, continue-watching, history
  • Parental PIN, language/locale prefs
  • accountType: guest | registered, mergedFromGuestIds[]

5. Guest Account & Merge

  • First visit → device fingerprint + signed guest cookie (web) / install-ID (mobile) → anonymous account + guest session
  • Guest can browse, watch AVOD, earn BonusTokens, unlock content, build history
  • Merge on registration: transfer balances, ledger, entitlements, history, watchlist, favorites, likes
  • Conflict policy (config): sum balances, union history, keep latest resume point
  • Audit: mergedFromGuestIds[] (user) / mergedIntoUserId (guest, soft-archived)
  • Anti-abuse: rate-limit guest creation per IP/fingerprint, cap pre-registration bonus tokens, flag mass-merge
/modules/guest → /identity /provision /limits /merge

6. Social / Engagement

  • Like/Unlike (toggle + Durable-Object aggregate counters)
  • Favorite/Save (My List; syncs with §4 watchlist)
  • Share (Short-ID+slug URL, Open Graph meta, deep links web→app, referral tag)
  • Works for guest + registered, survives merge; rate-limited/deduped
/modules/social → /likes /favorites /share

Group B — Content

7. Content / Catalog

  • Types: Shorts, Short-series, Series, Films, Trailers, Live. Hierarchy Title → Season → Episode
  • Short-ID + slug on every entity (§3); states draft/scheduled/published/archived/takedown
  • Per-episode vs single purchase, collections/franchises/bundles
  • Availability/license windows per title per territory; multi-source rendition mapping

8. Metadata

  • Languages, genres, sub-genres, categories, tags, keywords — each with Short-ID + slug (filter URLs)
  • Cast & crew, credits; ratings + CBFC certificates (U/UA/A); per-territory maturity; i18n titles/synopsis
  • Images/posters (multiple aspect ratios), SEO metadata

9. Search & Discovery

  • Full-text (Typesense/Meilisearch adapter), filters/facets/autocomplete
  • Filter by Short-ID-backed genres/tags (stable shareable URLs)
  • Recommendations, admin-configurable homepage rails

Group C — Media & Streaming

10. Video / Media Processing — FFmpeg HLS → R2

  • Resumable upload → master to R2
  • FFmpeg transcoding on on-demand GPU (NVENC, RunPod/AWS g5) via Queue (~₹15–60/title)
  • ABR ladder 1080p/720p/480p (cap 1080p; 4K optional flag)
  • HLS packaging → segments + master.m3u8R2Cloudflare CDN
  • Multi-audio, subtitles (WebVTT/SRT), thumbnail sprites; behind adapter (r2|bunny|b2, transcoder swappable)

11. DRM & Content Security 🔴

  • License server Widevine + FairPlay + PlayReady (EZDRM/Axinom adapter)
  • Signed short-lived playback tokens, token-gated segments, forensic watermarking
  • Geo-blocking/territory + concurrent-stream enforcement, offline licensing, anti-piracy hooks

12. Player Config

  • Per-platform config (web HTML5, Expo/RN), DRM scheme by device, ABR/audio/subtitle defaults, resume
  • Playback heartbeat → watch-time analytics (revenue-share backbone) + QoE source (§37)

Group D — Monetization

13. Entitlements (heart of access control)

  • Single source: "can this user (guest OR registered) watch this title now?" → allow/deny + reason
  • Resolves TVOD windows, EST, SVOD tiers, AVOD free, token unlock; grace/up-downgrades
  • KV-cached resolution with event-driven invalidation

14. Revenue / Monetization

  • TVOD (rent 24/36/72h, buy-watch-once, EST), SVOD (plans/tiers/trials/promos), AVOD (rewarded ads)
  • Ad-break cue points; pricing-rules engine (territory/currency/plan); coupons/gift cards/referrals

15. Subscription & Billing

  • Plans, recurring cycles, renewals, dunning, proration, cancel/refund, pause/resume, lifecycle webhooks

16. Payments (country-routed)

  • Gateway abstraction; India→Razorpay/Cashfree→Newtact(GST) | UAE→Telr/PayTabs→Thaja | ROW→Stripe→Thaja
  • Descriptor BUDDYCINEMAS, webhooks, reconciliation, idempotency, FX, chargebacks
/modules/payments/providers → stripe | razorpay | cashfree | uae-gateway

17. Wallet / Credits (optional fiat top-up; tokens handled in §18)

18. Token / Rewards Economy

  • BonusTokens (ad-earned) + PaidTokens (purchased)
  • Earning: ad batch → server-verified callback → credit (guests too)
  • Purchase: via §16, sold on WEB to avoid IAP (bonus tokens fine in-app)
  • Unlock config: admin-set cost per content type AND per title (short=1, episode=2, film=10), KV-cached
  • Spend policy (bonus-first, expiry, caps); immutable ledger (earn/spend/expire/refund), carried on merge
  • Spend events → §21 royalty attribution
  • Configurable token VALUE (admin, versioned): fiat value of 1 token (and bonus-vs-paid value) is admin-set, stored in KV for fast edge reads, versioned with effective-from dates. Update it monthly (e.g. tied to ad eCPM). Each ledger entry stamps the value-version used, so historical earnings/royalty are never retroactively changed — past unlocks keep their original valuation.
/modules/tokens → /balance /ledger(stamps value-version) /earning(server-verified) /purchase
                  /unlock-rules(KV) /spend-policy /value-config(versioned, KV)

Group E — Partner / Revenue-Share

19. Content Partner / Affiliate

  • Onboarding (KYC, agreements), license terms (territory/exclusivity/share %), rights/ownership mapping

20. (reserved with 19 — partner roles & permissions handled via §29 RBAC partner-scope)

21. Revenue-Share / Royalty Engine

  • Per-title attribution: TVOD (direct), AVOD (watch-time/impression share), SVOD (pool: title-min ÷ total-min × pool × %), Tokens (spend→title)
  • Configurable rules, min guarantees, recoupment; partner statements + payout export; immutable audit
  • Recommended splits: movies 50/50–60/40; platform keeps more on shorts/series

Group F — Advertising

22. Ads

  • Web AdSense/GAM, mobile AdMob, Meta Audience Network, programmatic
  • SSAI/CSAI, VAST/VMAP, ad-break scheduling, rewarded verify → §18 tokens
  • Frequency capping, ad-free for payers, impressions → §21
  • Ad-load: shorts 1, web-series 4, movies 10; target ₹40–120 eCPM

Group G — Data & Analytics

23. Analytics & Telemetry

  • Internal event capture (own pipeline for revenue data), watch-time per user/title/session (guest+registered)
  • GA4/Firebase/GTM/Mixpanel adapters, Analytics Engine, schema/contract mgmt, warehouse export

24. Reporting / BI + Producer Portal

  • Internal dashboards (revenue, retention, churn, MAU/DAU, completion, guest→registered conversion)
  • Producer/Partner self-service portal (RBAC partner-scope, §29) — each producer logs in and sees only their own titles:
    • Revenue & their share — gross by model (TVOD/AVOD/SVOD/token), platform cut vs producer split, period-over-period, payout status, downloadable statements
    • Audience — unique viewers, total + average watch-time, completion rate, plays, likes/favorites/shares, geography, device split — per title and per episode
    • Token activity — how many unlocks, bonus vs paid, value attributed (using the §18 value-version)
  • Near-real-time numbers served from KV-cached rollups (precomputed by §36 cron jobs); heavy history from the warehouse. Scheduled exports (CSV/PDF), and an API for producers who want to pull data.
  • Numbers are derived from the immutable ledgers (§18/§21) — reproducible and dispute-proof.

Group H — Communication

25. Notifications

  • Push (FCM/APNs/Expo), in-app, SMS; triggers: new content, expiry, payment status, recommendations

26. Email

  • Resend (→ SES/SendGrid adapter); templates: welcome, OTP, receipt, rental/token, renewal, failure, reset, partner statements, guest-merge confirmation; MJML/React Email, i18n, BuddyCinemas branding

Group I — Financial / Compliance

27. Invoicing

  • Hybrid: internal PDF + accounting sync (Zoho/India-GST, Xero/QuickBooks)
  • Entity routing Newtact (GST) vs Thaja (VAT), sequential numbering per entity, credit/refund notes, R2 storage

28. Tax & Compliance

  • GST (India OIDAR 18%), UAE VAT, US sales tax; location-based; TDS/withholding on payouts

Group J — Operations / Platform

29. Admin Panel & RBAC

  • Permission = resource:action (e.g. content:publish, payouts:approve, users:impersonate)
  • Role = set of permissions (composable/inheritable); User↔Role(s) scoped (global | partner:<id> | territory:<code>)
  • Enforced at gateway middleware AND UI; every admin action audit-logged (who/what/before-after/IP/time)
RoleScopeCan do
Super Adminglobaleverything incl. roles/permissions, entities
Platform Adminglobalcontent/users/config; no role edits, no payout approval
Content Managerglobalcreate/edit/publish catalog, metadata, Short-IDs
Content Reviewer/QCglobalreview/approve/takedown; no pricing publish
Finance/Billingglobalpayments, invoices, tax, payout approval, refunds
Royalty/Partner Opsglobalpartner onboarding, license terms, statements
Partner Adminpartner:<id>own titles + own analytics/earnings only
Partner Uploaderpartner:<id>upload own masters; no pricing/publish
Ads Managerglobalad config/networks/load rules, eCPM reports
Support/CSglobalview users, reset, grant capped tokens, impersonate (audited)
Marketingglobalpromos/coupons, push/email, homepage rails
Analyst (RO)globaldashboards/reports
Auditor (RO)globalaudit logs, financial/royalty ledgers
/modules/admin → /rbac (/permissions /roles /assignments /policy) /audit /panels /impersonation

30. Backup & Restore / DR — DB snapshots, R2 versioning, DR runbook, PITR, secrets backup. Define RTO/RPO targets.

31. File / Storage — R2 signed URLs, lifecycle, CDN (adapter r2|b2|bunny)

32. Localization / i18n — UI + metadata translation, currency/locale, RTL (Arabic)

33. Feature Flags & Config — remote config, A/B, gradual rollout, kill switches

34. Audit, Logging & Observability — centralized logging, Sentry, tracing, immutable audit, health/alerts

35. Documentation Service ⭐ — version-controlled docs auto-rendered to HTML

  • Doc types per module: PRD, FAQ, Changelog, How-it-works, API guide, runbook
  • Source of truth = repo (/docs MD/MDX) → Next.js docs route renders HTML; CI/webhook auto-sync on merge
  • Versioned per release; changelog auto-built from PRs/conventional commits; searchable; public partner doc space
/docs ; /modules/docs → /registry /render /sync /changelog

36. Webhooks, Jobs & API Lifecycle (OpenAPI/Scalar)

  • Webhooks: inbound (gateways/ad networks), outbound (partners/accounting), retries + dead-letter (Queues)
  • Jobs/Scheduler (Cron): rental-expiry, token-expiry, payout runs, report/rollup gen (producer portal), license-window activation, transcode dispatch, stale guest cleanup
  • API lifecycle: OpenAPI 3.1 (zod→spec) + Scalar docs UI per version; phased migration by cohort (user / feature flag / device / region / partner); deprecation + sunset headers; contract tests
/modules/webhooks  /modules/jobs
/modules/api → /openapi /scalar /versioning(v1,v2) /migration(cohort)

ADOPT-LATER HARDENING MODULES (37–42)

These are NOT built now. But the hooks for them ARE built now (Rule 9): the listed events, provider interfaces, and feature flags must exist from day 1 so each module plugs in later without touching existing code.

37. QoE / Playback Quality Analytics

  • Startup time, rebuffer ratio, bitrate drops, playback errors, exits-before-start — per stream/title/CDN/device
  • Adopt-later hook (build now): §12 player heartbeat already emits playback.* events to the event bus; this module just subscribes. Feature flag qoe.enabled.

38. Multi-CDN & Origin Shield

  • 2+ CDNs with steering/failover, origin-shield to protect R2, per-CDN cost + QoE-based routing
  • Adopt-later hook: §31 storage/CDN already behind an adapter; add a multiCdnRouter provider + flag cdn.multi.enabled. No player or media-pipeline change.

39. Fraud / Anti-Abuse Engine ⭐ (your "double-check everything")

  • Detects: multi-account / shared logins, simultaneous-stream abuse, impossible travel, ad-reward token farming, card/payment fraud, scripted/bot traffic
  • Actions: risk score → challenge (OTP/captcha) → throttle → freeze tokens → block; all decisions audited
  • Adopt-later hook: auth/token/ad/payment modules already emit events (auth.login, token.earn, token.spend, ad.reward, payment.*); engine consumes them. Flag fraud.enforce (start in shadow/log-only mode).

40. Financial Reconciliation

  • Three-way reconcile: gateway payouts ↔ token/royalty ledgers ↔ invoices; dispute & adjustment workflow
  • Adopt-later hook: all sources are already immutable ledgers (§16/§18/§21/§27) with idempotency keys — reconciliation reads them, writes nothing destructive. Flag recon.enabled.

41. Security & Key Management (KMS)

  • DRM content-key custody, secret rotation, signing-key rotation, WAF/DDoS posture, pen-test remediation track
  • Adopt-later hook: §11 DRM and §1 gateway already read keys/secrets from a secrets provider — swap to managed KMS provider via config. No call-site changes.

42. Live + DVR (optional)

  • Low-latency HLS ingest, packager, live ad-stitching, catch-up/DVR
  • Adopt-later hook: §7 already models a Live content type; §11/§12 DRM+player reused. Separate ingest path only. Flag live.enabled.

SECURITY & ANTI-ABUSE (cross-cutting, enforced from day 1)

Principle: the client is untrusted. Every value-bearing action is server-verified AND double-checked.

Multi-login / account sharing

  • Device fingerprint + registered-device list; hard concurrency cap in Durable Objects (e.g. 2 streams)
  • Impossible-travel + simultaneous-geo detection → risk flag (feeds §39)
  • Short-lived, signed, single-use playback tokens bound to device + title + IP range

Token / reward misuse

  • Ad completion verified server-side (signed network callback + nonce; never trust client "I watched it")
  • Idempotent earn/spend writes; per-IP/device/day earn caps; anomaly alerts on spikes
  • Immutable ledger = any manipulation is detectable and reversible via compensating entries

Script injection / tampering

  • Zod validation on every input; output encoding; strict CSP + security headers (§1)
  • No business/value logic on the client; entitlements + token math always recomputed server-side
  • WAF + rate-limiting at the gateway; bot detection (Cloudflare Turnstile) on signup/reward/checkout
  • Parameterized queries via Drizzle (no string-built SQL); signed webhooks (verify gateway/ad signatures)

Guest abuse

  • Rate-limit guest creation per IP/fingerprint; cap pre-registration bonus tokens; flag mass-merge patterns

ROADMAP — Maturity Stages (Launch → Scale → Enterprise-Hardened)

StageGoalModules in scopeWhat you can defer (hooks ready)
1. Launch-readyShip + earn safely1–36 core, §Security baseline, §39 in shadow/log-onlyMulti-CDN, QoE dashboards, full KMS, Live, formal reconciliation
2. Scale-readyHandle growth + partner trustTurn on 37 (QoE), 39 (enforce), 40 (reconciliation)38 multi-CDN, 41 full KMS, 42 Live
3. Enterprise-hardenedAudited, resilient, regulated38 (multi-CDN), 41 (KMS + pen-test + WAF), 30 DR with RTO/RPO, data residency42 Live/DVR when business needs it

Why this avoids rebuilds: every stage-2/3 module only subscribes to events, swaps a provider, or flips a feature flag that already exist after Stage 1. No core module is rewritten to adopt them.


Build Order

Phase 0 — Foundation: [1] Gateway · [3] Short-ID/slug · [36-api] OpenAPI+Scalar · [35] Docs skeleton · shared (db/providers/config/errors) · event bus / outbox + feature-flag service (so 37–42 can attach later)

Phase 1 — Identity & Content: [2] Auth (Better Auth) · [5] Guest · [4] Users · [7] Content · [8] Metadata · [9] Search · [6] Social

Phase 2 — Media (prove with ONE title): [31] Storage · [10] FFmpeg→HLS→R2 · [11] DRM · [12] Player + heartbeat

Phase 3 — Money correctness (highest rigor + tests): [13] Entitlements · [18] Tokens (immutable ledger + versioned value) · [5-merge] Guest merge · [16] Payments · [14] Revenue · [15] Subscriptions · [17] Wallet · §Security baseline + §39 shadow mode

Phase 4 — Partner economics: [19] Partners · [21] Royalty engine · [22] Ads · [24] Producer portal

Phase 5 — Admin & RBAC: [29] RBAC → audit → panels → impersonation → admin UI

Phase 6 — Data & comms: [23] Analytics → [24] Reporting/rollups · [25] Notifications · [26] Email

Phase 7 — Finance & ops: [27] Invoicing · [28] Tax · [32] i18n · [33] Flags · [36] Webhooks+Jobs · [30] Backup/DR · [34] Observability

Phase 8 — Lifecycle & docs: [36] phased migration · [35] finalize auto-rendered versioned docs

Phase 9+ — Adopt-later (when needed): [37] QoE · [39] enforce fraud · [40] reconciliation · [38] multi-CDN · [41] KMS · [42] Live


Non-negotiables / commonly-forgotten

  • Mobile-first everything — users can fully watch (HLS) in a mobile browser, not just the app; admin + producer portal are fully usable on a phone (responsive, touch-first). No desktop-only screens.
  • KV-first — use Workers KV wherever possible (configs, entitlement cache, catalog snapshots, token-value config, rollups, sessions, rate-limits). DB = system of record only; DO for strong-consistency counters.
  • Security control on EVERY change — for any change ask: "with this, can someone tamper with or misuse our system?" If yes, server-verify + double-check before shipping.
  • Docs updated on EVERY change, in detail — no change merges without updating its module PRD/FAQ/changelog (§35). Code change without doc change = incomplete.
  • Push to git — commit + push after every working change (conventional commits; small, frequent commits; CI runs lint/test/deploy/docs-sync).
  • Idempotency keys on payment/token/entitlement writes
  • Immutable audit for tokens + royalty + admin actions
  • Token VALUE versioned (KV) — ledger stamps version used; monthly updates never rewrite history
  • Short-IDs immutable once published
  • Guest anti-abuse: cap pre-registration bonus tokens, rate-limit creation, flag mass-merge
  • Zero-trust: ad rewards + entitlements + token math always server-verified; WAF + bot checks; CSP; Zod on all inputs
  • Outbox/event bus + feature flags from day 1 so 37–42 plug in without rewrites
  • KV-first for configs, entitlement cache, rollups, token-value config
  • Producer portal scoped strictly to own titles (partner RBAC)
  • DRM before scaling content deals; sell paid tokens/subscriptions on WEB (avoid IAP cut)
  • GDPR / India DPDP: data export + delete (incl. guest data); consent for fingerprinting/ad tracking; data residency for §41/30
  • RBAC enforced server-side, not just UI; partner sandbox API; DMCA/takedown workflow
  • DR with RTO/RPO targets, multi-environment (dev/staging/prod) + secrets

PROJECT STATUS

For real-time tracking of what has been implemented so far across all phases, please refer to the PROJECT_STATUS.md tracker at the root of the repository.