Sway team docs

Gaming data integration analysis. Internal working document.

This password is a deterrent, not protection. GitHub Pages has no server-side authentication. This page is publicly reachable and its full text reached your browser before this prompt appeared.

Integration plan

What it would take to build, in what order, and what has to be true first.

This is not "add two providers to the existing pipeline"

Two pieces of foundational work must land first, and neither is gaming-specific: an OAuth token store with encryption and refresh (Sway has none), and a session data model (Sway's domain is post-shaped end to end and cannot represent a play session).

TwitchRoblox
ApproachOAuth 2.0 API integration, narrow scope No API integration. On-device OS signals + guided setup
Blocked onWritten answer from Twitch on §VI.C Apple Family Controls entitlement
Unit of dataContacts, follows, safety eventsPlaytime only
Why not more24-hour cache cap; no watch history exists Prohibited by policy; data absent from Open Cloud

Four blockers in the existing code

① Eligibility SQL requires a cookie

All three CTEs in schedule.repository.ts require cookie IS NOT NULL AND btrim(cookie) <> ''. An OAuth account with a null cookie is invisible to the scheduler. Change the predicate — do not stuff a token into the cookie column.

② getConnectedAccount is cookie-typed

Returns { cookie: string } | null. Every consumer destructures .cookie. The type must widen.

③ The post workflow rejects contentless records

if (!hasContent) return { error: 'Post has no content' }. A play session has no text, images or audio. Gaming data must not route through SocialPostWorkflowV2.

④ The platform switch is exhaustive

No default case — so TypeScript errors the moment you add an enum member. That is a feature: a compiler-enforced checklist. Duplicated in v1/ and v2/.

What generalises cleanly

SocialPlatform is a table, not a DB enum — adding twitch needs no migration. Author is already platform-scoped (youtube:UC…twitch:<id>). Alerts are platform-agnostic. The orchestrator fans out over a plain string[].

Twitch ingestion — three modes, two of which ship

ModeTransportFits Workers?Status
A — polling
follows, labels, blocked users
Existing cron orchestrator, 12h cycleYes Reuses the pipeline wholesale
B — whispers
the highest-value capability
EventSub webhooks, HMAC-verifiedYes Stateless HTTP — a perfect fit. Costs 0
C — chat Persistent WebSocket or IRC per childNo Deferred. Needs a Durable Object or container

Who consents when the user is a minor

Both, and neither alone is sufficient.

  • Parent — holder of parental responsibility; provides COPPA verifiable consent via the card-transaction method, bound to the existing subscription event
  • Child — must complete the OAuth flow themselves and be told, in age-appropriate terms, what is collected and that monitoring is active. Not courtesy: ICO Standard 11's operative requirement
  • Twitch's own ToS §2 already requires guardian supervision for minors, which helps
Use the system browser, not a WebView

Rendering Twitch's login inside a WebView Sway controls reproduces the credential-interception pattern that creates the Apple 5.1.1(vi) exposure. Use expo-web-browser. The whole point of OAuth is that Sway never sees the password.

New tables

TableWhy it is new
user_platform_credentials Encrypted OAuth tokens. UserSocialAccount.cookie has no expiry, refresh or scope
play_sessions Carries source and confidence — so an Android exact reading and an iOS threshold band never render identically
platform_contacts Deliberately not Author. Mandatory expiresAt
activity_signals Classifier output. contextRef holds an ID — never message text
Do not reuse Author for chat partners

Author was built for public creators — public figures with bio, followers, region. Pointing it at private children silently converts a public-figure table into a table of minors, inheriting a retention posture designed for public data. And Post.caption is a @db.Text field holding full content: do not add a gaming equivalent.

Where a new abstraction is genuinely required

Sway's Trust Score cannot absorb gaming data. It counts each Social Post once at its worst Trust Level and omits the score when there are no classified posts. Gaming contributes zero classified posts, so a Games platform would render as noDataAnalyzed.

(a) Synthesise post-shaped records(b) Parallel model, separate surface
EffortLowerHigher
Requires fake url and postIdYesNo
Trust Score covers gamingYes, misleadinglyNo
HonestNoYes

Recommend (b). Option (a) means inventing synthetic URLs for events that have none and feeding a trust classifier text it was never designed for. It would produce a number that looks like the existing Trust Score and means something different — the worst outcome for a product whose value is parental trust.

Phased delivery

PhaseEst.Notes
0 — Unblock
Twitch question, Apple entitlement, DPIA, counsel
2–3w
+ wait
Do this regardless. The DPIA is mandatory under Art 35(3)(b)
1 — Foundations
token store, encryption, eligibility fix, hourly validate, retention sweep, child indicator
3–4w Fixes a live App Store exposure. Pays for itself independently of gaming
2 — Twitch read-only
OAuth, follows, labels, diff-and-signal
3–4w
3 — Whispers
EventSub, in-memory classification, alerts
2–3w The highest-value capability on the platform
4 — Roblox on-device
Expo prebuild migration, Android + iOS, checklist
4–6wGated on Phase 0
5 — Games dashboard3–4w See the prototype

Total 17–24 engineer-weeks, of which 5–7 are foundations that pay for themselves independently.

Not planned

Twitch chat monitoring (Mode C), spend tracking, any Roblox API integration, voice chat (does not exist on Twitch).

Start here this week

A spike an engineer can begin immediately, before any of the above is approved:

  1. Register a Twitch application as a Confidential client. Confirm authorization-code + PKCE end to end. ~1 day
  2. Answer the two Unverified questions — own-message echo, and channel.chat.message cost. ~1 day
  3. Test whether an under-13 Roblox account can complete OAuth consent. ~½ day
  4. Submit the Apple Family Controls entitlement request. It has a lead time and blocks dev builds. A form

Items 1–3 are ~3 days and de-risk the two largest unknowns. Item 4 costs nothing to be waiting on.