There is no anonymous session to start and nothing to mint: the app comes up on
Home with no account, and the first QR scan performs the unauthenticated
joinAlert, which returns a deviceToken the client stores with the alert. That
token — not a user, not a session — is what the subscriber calls carry as
X-Device-Token, and what the socket puts in ?deviceToken=.
- apiClient takes an optional device token per request; when present it is sent
instead of the access token, because it is the narrower credential
- alarmApi.joinAlert returns it; getAlert/alarmStatus/ackAlarm/
removeSubscription/qrImage and the socket URL accept it
- the alert record keeps the token beside its subscribe token, so a queued ack
for an alert that is gone still resolves the right device
- login is now a destination, never a wall: without a session the app is the
subscriber view, and the login screen's 'continue without an account' button
is gone because there is nothing to continue from
tsc clean, 129 tests (8 new ones pin the header transport and the
no-access-token join).