Summary
Implement Pushboy storage and fanout support for activity-scoped Live Activity update tokens.
Admin-api and node-server will send activityId with future update-token registrations, but Pushboy still needs to persist token/activity associations and gate update/end fanout by activity before this can fix over-fanout.
Required contract changes
/v1/live-activity/tokens must accept optional activityId.
- Token write and token/activity association write must be transactional.
- Add
live_activity_token_activities(activity_id, token_id, created_at, last_seen_at, source).
- Keep
start fanout as topic broadcast.
- Gate
update and future end fanout behind LIVE_ACTIVITY_SCOPED_UPDATE_FANOUT, default off.
- When
LIVE_ACTIVITY_SCOPED_UPDATE_FANOUT=false, keep current broadcast fanout behavior but emit shadow metrics comparing broadcast candidates vs associated candidates for the job activityId.
- When
LIVE_ACTIVITY_SCOPED_UPDATE_FANOUT=true, update/end fanout should select only tokens associated with the job activityId.
- FCM Live Activity tokens should also be associated to
activityId from successful start dispatch recipients, because Android receives the usable update token after start.
- APNs
ExpiredToken must invalidate Live Activity tokens.
- APNs logs must not print raw token values.
Acceptance criteria
- Registering a token with
{ activityId } creates or refreshes the token/activity row in the same transaction as the token write.
- Re-registering the same token for a later activity updates
last_seen_at and creates/refreshes the later activity association without breaking prior data needed for diagnostics.
start jobs still use topic fanout.
- With scoped fanout off, operators can see broadcast-candidate count and activity-associated-candidate count per update/end job.
- With scoped fanout on, update/end jobs dispatch only to tokens associated with that exact
activityId.
- APNs
ExpiredToken outcomes remove/disable stale LA tokens so they do not keep participating in fanout.
- No raw APNs/FCM token is logged by provider send or outcome paths.
Summary
Implement Pushboy storage and fanout support for activity-scoped Live Activity update tokens.
Admin-api and node-server will send
activityIdwith future update-token registrations, but Pushboy still needs to persist token/activity associations and gate update/end fanout by activity before this can fix over-fanout.Required contract changes
/v1/live-activity/tokensmust accept optionalactivityId.live_activity_token_activities(activity_id, token_id, created_at, last_seen_at, source).startfanout as topic broadcast.updateand futureendfanout behindLIVE_ACTIVITY_SCOPED_UPDATE_FANOUT, default off.LIVE_ACTIVITY_SCOPED_UPDATE_FANOUT=false, keep current broadcast fanout behavior but emit shadow metrics comparing broadcast candidates vs associated candidates for the jobactivityId.LIVE_ACTIVITY_SCOPED_UPDATE_FANOUT=true, update/end fanout should select only tokens associated with the jobactivityId.activityIdfrom successful start dispatch recipients, because Android receives the usable update token after start.ExpiredTokenmust invalidate Live Activity tokens.Acceptance criteria
{ activityId }creates or refreshes the token/activity row in the same transaction as the token write.last_seen_atand creates/refreshes the later activity association without breaking prior data needed for diagnostics.startjobs still use topic fanout.activityId.ExpiredTokenoutcomes remove/disable stale LA tokens so they do not keep participating in fanout.