- Add POST /providers/accounts/custom-rtmp endpoint for saved RTMP servers
- Encrypt rtmpUrl/streamKey in accessTokenEnc/refreshTokenEnc fields
- Decrypt and return rtmpUrl/streamKey in GET /providers/accounts for CUSTOM_RTMP
- Skip token revocation on DELETE for CUSTOM_RTMP accounts
- Decrypt CUSTOM_RTMP credentials into CUSTOM destinations on plan create/update
- Handle CUSTOM destinations in prepare lifecycle (already READY, skip provider auth)
- Add debug logging for plan operations and user upsert
- Add executionMode and gameId columns to StreamPlan schema
- Add migration for new columns
- Support executionMode/gameId in plan create and update endpoints
- Add version field to health check response from package.json
- Change LinkedAccount unique constraint to (userId, serviceId, accountId)
- Add linkedAccountId to StreamDestination for per-account targeting
- OAuth callbacks upsert by accountId so different accounts create new rows
- Delete endpoint changed to /providers/accounts/:id
- getDecryptedToken resolves tokens by linkedAccountId instead of serviceId
- /start transition wrapped in try-catch (enableAutoStart compatibility)
- /end always attempts YouTube complete transition regardless of plan status
- autoDetectEndedPlans loads tokens per-destination
When the Data Use Checkup hasn't granted numeric ID access, the SDK
returns oculusId (string username) instead. This makes nonce optional,
skips nonce verification for non-numeric userIds, and uses oculusId as
the metaId when numeric ID is unavailable.