Capability Map
Feature-by-feature status, assessed against the code as it stands on master. Each row links to the technical detail.
Shipped implemented and working · Partial incomplete or unverified · Planned not built
Accounts and identity
| Capability | Status | Notes |
|---|---|---|
| Register and log in | Shipped | JWT, 7-day expiry, bcrypt |
| Onboarding flow | Shipped | 11 screens, fan and creator branches |
| Profiles | Shipped | Avatar, banner, bio, links |
| Following | Shipped | |
| Blocking | Shipped | |
| Session management | Shipped | Active sessions, login history, logout-everywhere |
| Identity verification | Partial | Documents captured; no review workflow |
| Badges | Shipped | PlayPal automatic, others manual |
| Password reset | Planned | Routes exist, service functions are empty — needs an email provider |
| Account deletion | Partial | Endpoint exists; verify what it actually removes |
Content
| Capability | Status | Notes |
|---|---|---|
| Text, photo, and clip posts | Shipped | |
| Home feed | Shipped | Cursor pagination, 60 s cache, refresh-without-losing-position |
| Comments | Shipped | |
| Reactions | Shipped | Six kinds, deduplicated |
| Mentions | Shipped | |
| Impression tracking | Shipped | View and video-watch duration |
| Image processing | Shipped | 3–5 variants, smart cropping, CDN |
| Video processing | Shipped | Mux transcoding and HLS |
| Share to DM | Shipped | |
| Content moderation | Partial | Reports captured, moderationStatus columns exist, no review surface |
Messaging
| Capability | Status | Notes |
|---|---|---|
| Direct messages | Shipped | |
| Realtime delivery | Shipped | Socket.IO |
| Typing indicators | Shipped | |
| Read receipts | Shipped | |
| Edit and delete | Shipped | Soft delete |
| Channels and rooms | Shipped | Four visibility levels |
| Subscriber-gated rooms | Shipped | Verified against an active subscription |
| Presence (online status) | Partial | In-memory per pod — inconsistent across the two replicas |
Live
| Capability | Status | Notes |
|---|---|---|
| Livestreaming | Shipped | RTMP in, HLS out, via Mux |
| Livestream chat | Shipped | Persisted |
| Voice rooms | Shipped | LiveKit, self-hosted |
| Video rooms | Shipped | |
| Coin gifting | Shipped | Feeds creator earnings |
| Mux webhook verification | Missing | Endpoint is unauthenticated — a security gap |
Sessions
| Capability | Status | Notes |
|---|---|---|
| Availability schedule | Shipped | Recurring hours and blocked dates |
| Booking | Shipped | |
| Private session rooms | Shipped | Only the two parties |
| Cancellation | Partial | Status changes; no refund flow |
| Timezone handling | Missing | Times stored without a timezone — will break across regions |
Monetisation
| Capability | Status | Notes |
|---|---|---|
| Play Coin purchase | Shipped | RevenueCat, idempotent |
| Coin gifting and spending | Shipped | Ledger-backed |
| Platform subscriptions | Shipped | |
| Double-entry ledger | Shipped | Idempotency-protected |
| Monthly payouts | Shipped | Two-phase, distributed lock, admin API |
| Store | Partial | Works; catalog is thin |
| Creator subscriptions | Partial | Webhook cannot identify the target creator; depends on a client follow-up call |
| Stripe webhooks | Missing | Empty handler — Connect onboarding completion and transfer failures are invisible |
| Earnings accuracy | Partial | Subscription revenue estimated from current subscriber count, not settled transactions |
Discovery
| Capability | Status | Notes |
|---|---|---|
| Trending clips, creators, coaches, games, searches | Shipped | Redis-cached, 5 min |
| Search | Shipped | Users, clips, games |
| Game catalog | Shipped | IGDB, synced daily |
| Sponsors | Shipped | |
| Discover feed | Partial | Returns every user — no ranking, filtering, or pagination |
Notifications
| Capability | Status | Notes |
|---|---|---|
| In-app inbox | Shipped | Cursor-paginated |
| Push notifications | Shipped | Expo, self-healing token cleanup |
| Realtime badge | Shipped | |
| Per-category preferences | Shipped | Nine push categories |
| Deep links | Shipped | Typed targets |
| Planned | Preferences exist, no delivery mechanism | |
| Push receipts | Partial | Tickets checked, receipts not — some failures invisible |
Platform and operations
| Capability | Status | Notes |
|---|---|---|
| Kubernetes deployment | Shipped | Probes, anti-affinity, non-root |
| Infrastructure as code | Shipped | Terraform |
| Secrets management | Shipped | Sealed Secrets |
| TLS | Shipped | Let's Encrypt, auto-renewing |
| Centralised logging | Shipped | Loki + Grafana |
| Mobile crash reporting | Shipped | Bugsnag |
| Autoscaling | Partial | Media worker and nodes only |
| Staging environment | Planned | Chart plan written, not deployed |
| CI/CD | Missing | Deploys run from a laptop |
| Alerting | Missing | |
| Metrics | Missing | |
| API test coverage | Partial | Configured, no tests written |
Recommended priorities
Security first — small, contained, and each closes a real hole:
- Verify the Mux webhook signature (detail)
- Fail closed when
REVENUECAT_WEBHOOK_SECRETis unset (detail) - Confirm
JWT_SECRETandADMIN_SECRETare set everywhere — the defaults are insecure
Correctness — each is a bug users or creators can feel:
- Fix the
ogun/adminprefix so media-ready events fire (detail) - Fix the error middleware so
HttpErrorreturns its intended status (detail) - Resolve the VIP subscription target in the webhook, removing the client dependency
- Derive subscription earnings from ledger entries rather than a live count
Operational resilience — the compounding investments:
- Staging environment
- CI on pull requests
- Alerting on existing logs
- Versioned image tags and automated deploys
