Changelog
v2.0: Full admin panel (six phases)
Section titled “v2.0: Full admin panel (six phases)”Ships the “approved-for-build” v2 architecture from deliverables/07-admin-architecture.md, superseding the 7-screen MVP admin.
P1: Foundation
Section titled “P1: Foundation”- Commit:
a0f04ec - RBAC v2:
admin_rolestable,permissions.decorator,permissions.guard, seed for the 6 built-in roles - Admin user CRUD (
/admin/admins) - Approvals queue (
/admin/approvals) with two-person rule enforcement - Audit log with JSON diff viewer (
/admin/audit-logs) - Admin frontend scaffold: TanStack Query, TanStack Table, permission-aware sidebar, ⌘K command palette
P2: Media & Publishing
Section titled “P2: Media & Publishing”- Commit:
9b5e233 - Cloudflare Stream integration: direct upload URLs (TUS/resumable), HMAC-verified webhook, playback ID + duration extraction, auto thumbnails
media_assetstable (kind: video / poster / hero / thumb / caption)- Media library + uploads UI, retry & delete
- Episode media linking, per-language captions
- Publish workflow state machine (
draft → in_review → scheduled → published → archived) publish_schedulestable +publish-schedulercron (1 min)- Genre / trope / cast CRUD
P3: Users & Support
Section titled “P3: Users & Support”- Commits:
452b82c..5ff544d - User search (email / phone / device / country / spend tier), User 360 detail
- Ledger-correct wallet adjust: double-entry writes to
source_promo/sink_refund, balance always derived - Support daily cap: 500 coins/user/day, enforced server-side
- Approval gate at 2000 coins → routes through
admin_approvals - Suspend / ban / reactivate with reason and audit
- Devices list + force-logout-all (bumps
token_version) - GDPR anonymize (approval-gated)
- Support notes thread per user
- Comp subscription (grant TwistCue+ for N days)
P4: Money
Section titled “P4: Money”- Commits:
4c2dd07..8c01a89 - Unified transactions view joining Purchase + Subscription across 5 rails
- Refund pipeline: request → (≤$50 auto-execute if
payments:refund; >$50 through approvals) → provider call → automatic ledger reversal viasink_refund→ optional unlock rollback - Refund shortfall clamping: never take a wallet below zero; logs
underpaid_centsfor finance to reconcile - Price overrides table with resolution:
episode → series → market → default (30 coins) - Coin packages CRUD (per-rail SKU list)
- Promos: bonus-multiplier, coin-grant, trial-extension; budget caps
- Reconciliation CSV upload per rail, daily rollup diffs
- Economy monitor: coins minted vs burned, bonus liability
P5: Analytics & Curation
Section titled “P5: Analytics & Curation”- Commits:
946bb5a..6d697d9 - Rollup crons:
rollups-hourly(revenue/series/funnel),free-series-rotation-daily - Overview KPIs, retention cohort grid (D1/D7/D30)
- Revenue dashboard (ARPU/ARPPU/LTV by rail/country/day)
- Per-series drop-off analysis (watch progress histograms)
- Funnel:
preview_view → ep1_start → paywall_hit → unlock → repeat_unlock - Curation: For You rail builder (drag order), collection CRUD (manual + rule-based), preview-reel
editorial_hero_score - Free-today rotation scheduler (
free_series_rotationstable) - Feed composer service (reads rails + collections + free rotation for
/v1/feed)
P6: Engagement & Moderation
Section titled “P6: Engagement & Moderation”- Commit:
7a4ca67 - Segment builder (
segmentstable, JSON query builder) - Push campaigns: compose → estimate audience → schedule → send
- 3/day cap surfaced pre-send: composer shows
targeted / cappedbefore firing push-schedulercron (1 min) picks up scheduled campaigns- Comment moderation queue: keyword flags, hide/delete, per-user strike tracking, auto-suspend commenting at 3 strikes
- Reports queue with cascade actions (hide comment + strike author in one action)
- Streak & rewards config (
reward_configs): daily rewarded-ads cap (≤3), streak curve - Feature flags (
feature_flags): anything prefixedpublic_*is exposed on the public/v1/flagsendpoint
v2.0 polish pass
Section titled “v2.0 polish pass”- Commit:
fa0199c - Terminology sweep, RTL preview in localization panels, empty-state improvements
- Command palette entries for every top-level route
v1 → v2 breaking changes
Section titled “v1 → v2 breaking changes”AdminUser.rolemigrated from string enum torole_id FK admin_roles(string kept as denormalized column during migration; will be removed post-launch)./admin/statsstill exists but has been superseded by/admin/analytics/overview.