Roku TV App — Feature Backlog

Q2 2026 Roadmap: QR Login & Multi-Profile

Platform: Roku SceneGraph + BrighterScript Backend: Shared with other platforms (api-v2.duriooplus.com) Branch: main (commits pending screens)

Agenda

01

QR Login

Sign in with your phone — no typing on the remote. 10 acceptance criteria, 7 phases, 7 new files + 2 modified.

10 AC 7 new files
02

Multi-Profile

Family profile selection, creation, editing, content filtering per profile. 11 AC, 11 phases, 26 new files + 8 modified.

11 AC 0% done

Problem: Typing on a TV Remote

Current State

  • Email/password login requires typing with D-pad
  • Slow, error-prone, frustrating — 30+ keystrokes for email alone
  • OTP via email adds more steps (switch device, open email, memorize code)
  • High drop-off rate on login screen — measurable funnel loss

Other Platforms Already Have This

  • QR code scan → sign in on phone → TV auto-logs in
  • Socket.io WebSocket for instant push (Roku: polling every 3s)
  • Rapid adoption on other platforms — proven pattern
  • Covers create-account + login in one flow
10 Acceptance Criteria covering QR display, polling, OneLink URL, back nav, error states, device limits, analytics
QR Login flow diagram showing Roku QR screen, mobile authentication, and TV auto-login
Screenshot from other platform: QR/code displayed on TV → user authenticates on phone → TV auto-logs in.

Architecture: Roku Adaptation

Current State (How It Works Today)

TV / App
Other platforms
POST /auth/request-code
← code: 12345678
Backend
Redis keys
Phone Web
POST /auth/verify-code
Socket.io emit
code-verified-X
  • code-device-id:{device_id} maps device → code payload, TTL 5 min
  • code:{code} maps code → device payload, TTL 5 min
  • After verifyCode(), backend emits via Socket.io and deletes both keys
  • Works for WebSocket-capable TV apps; Roku cannot listen to Socket.io

Solution: Add Result Caching + Polling Endpoint

Roku TV
POST /auth/check-code-status
every 3s
Backend
Redis key #3
Phone Web
verify-code → signIn()
code-result:{device_id}
{ user, token }
  • Add code-result:{device_id} with short TTL after phone verification
  • New POST /auth/check-code-status returns pending, expired, or login payload
  • Delete result key after Roku reads it — one-time consumption
  • Roku uses same existing Actions.Login() success path

Roku Client Work

LoginQRCodeScreen RequestCodeTask QRCodePollingTask QrUtils.bs LoginIntroScreen StackNavigator

Implementation Plan & Risks

Phases

  1. API Layer — RequestCodeTask, QRCodePollingTask, QrUtils
  2. QR Screen — Layout + polling + back-navigation
  3. Intro Mods — "Sign in with Phone" button
  4. Navigation — StackNavigator registration
  5. Analytics — Mixpanel events
  6. Assets — QR frame background image
  7. Testing — 8 manual test cases

Backend: 1 New Endpoint

POST /auth/check-code-status — accepts { device_id }, returns { status: "pending" }, { user, token }, or { expired: true }

Test Coverage (8 Cases)

QR scan → login URL entry → login No network → error + retry Code expiry → auto-refresh Back → polling stops Device limit reached Server error → retry Quick back-and-forth

Problem: One-Size-Fits-All Family Experience

Current State

  • Single profile per account — no personalization
  • All content, watch history, favorites apply globally
  • Cannot restrict content by age group per child
  • Families with multiple children share the same recommendations

Impact

  • 4-year-old sees content meant for 12-year-old
  • Watch history mixed across family members
  • Parents can't control what each child watches
  • No differentiation between parent and child experience
11 Acceptance Criteria covering profile selection, CRUD, limits, guest handling, content filtering, analytics
Multi-profile selection screen screenshot from other platform
Screenshots from other platform: profile selection and profile management flows already available outside Roku.

Architecture: From Other platforms to Roku

ConcernOther platformsRoku
Profile GridFlexbox / native gridMarkupGrid + ProfileCard
StateRedux Persist / local storageRegistryUtils (registryWriteJson)
HeaderHTTP interceptorRequestUtils.addGlobalHeaders()
Form InputNative inputsroKeyboardScreen dialog
Avatar loadingNative image cachePoster node + fallback placeholder

7 API Endpoints (Already Exist)

GET /me/my-profiles POST /me/create-profile PATCH /me/update-profile/:id PATCH /me/delete-profile/:id POST /me/set-active-profile/:id GET /profile-avatars GET /content-category-ages

Profile Limits

Free Max 3 profiles 1 parent, 2 children
VIP Max 5 profiles 2 parents, 3 children

Scope: 26 New Files, 8 Modified

ProfileSelectScreen ProfileFormScreen AddProfileTypeScreen ProfileCard ProfileAvatarItem ProfileAgeItem GetProfilesTask CreateProfileTask UpdateProfileTask DeleteProfileTask GetProfileAvatarsTask GetContentAgeCategoriesTask

Modified (8)

main.bs ActionTypes Actions Reducers RequestUtils StackNavigator SplashScreen SettingScreen
Feature flag: m.global.multiProfileEnabled (boolean, toggled via registry/env mode) — guests skip profile selection entirely

Implementation Plan & Status

11 Phases

  1. State & Headers — Redoku profile state + HTTP header injection
  2. API Tasks — 7 task nodes (CRUD + avatars + ages)
  3. ProfileSelectScreen — Grid layout, selection, limits
  4. ProfileFormScreen — Create/edit form, keyboard, avatars
  5. Splash Integration — Route to profile select after login
  6. Settings — "Switch Profile" menu item
  7. Navigation — StackNavigator screen registration
  8. Content Filtering — Profile-aware recommender integration
  9. Assets — Avatars, badges, VIP icon
  10. Analytics — Mixpanel events
  11. Testing — 12 manual test cases

Status

0/11
Not Started

All phases pending — state, headers, API tasks, screens, navigation, testing

Redoku profile state with registry persistence
Profile header on all API requests
7 API task nodes (CRUD + avatars + ages)
SplashScreen routing for profile flow
Settings "Switch Profile" integration
StackNavigator screen registration
ProfileSelectScreen — grid layout + selection
ProfileFormScreen + AddProfileTypeScreen
Content filtering end-to-end test
On-device manual testing

Remaining

  • Screens: ProfileSelectScreen (grid), ProfileFormScreen (create/edit), AddProfileTypeScreen (parent/child)
  • Assets: Profile avatar fallback placeholders, parent badge icon, VIP button icon
  • Testing: 12 manual test cases — selection, CRUD, limits, guest, content filtering, persistence, nav, errors

Build Results

Build: 0 errors
Lint: 0 errors
Format: Passing

Combined Timeline

Planned
Multi-Profile — Foundation
State, headers, 7 API tasks, nav wiring
Planned
Multi-Profile — Screens + Testing
ProfileSelectScreen, ProfileFormScreen, AddProfileTypeScreen, end-to-end testing (12 cases), assets, analytics
Blocked
QR Login
7 new files, 2 modified, 7 phases, 10 AC, 8 test cases | ⚠ Blocked by: POST /auth/check-code-status endpoint
Total Scope 2 features: QR Login + Multi-Profile
Completed Nothing yet
Blocked By Backend: POST /auth/check-code-status endpoint

Questions & Discussion

Key Decisions Needed

  1. Feature ordering: Multi-Profile first (all pending), then QR Login?
  2. Backend timeline: When can /auth/check-code-status be available for QR login?
  3. QA bandwidth: On-device testing across Roku models (Ultra, Express, Stick, Streaming Stick 4K)?
  4. Release strategy: Staged rollout with feature flags per platform, or all-at-once?
  5. Design review: Approve UI layouts — profile selection grid, profile form, and QR screen layout
  6. Profile limits: Confirm Free (3: 1 parent + 2 children) and VIP (5: 2 parents + 3 children) across all platforms?