Closes#1673. Token rows are per (user, company), but the read resolver
short-circuited to the caller's own row whenever a userId was passed, so a
member who never pressed "Anslut" resolved to "no token" for a company that
was connected. The company-wide fallback used .maybeSingle(), which errors
as soon as two members have both connected and turned that into "nobody
connected" for everyone.
- resolve-auth: findCompanyTokenUser() reads all of the company's rows
ordered by created_at desc and picks the caller's own active row first,
then any other member's active row, then needs_reconsent rows; the userId
branch no longer short-circuits. The auth carries the token OWNER's userId
so refresh writes back to the owner's row.
- /skattekonto/saldo and /skattekonto/sync resolve the company token instead
of getTokens(caller); /declaration/submitted and /decided answer a
SESSION_EXPIRED reconnect prompt for needs_reconsent instead of
NOT_CONNECTED. Connect/disconnect//status stay on the caller's own row.
- The connection.expired event names the token owner, not the caller who
triggered the sync; the notification lookup filters by company too.
- The two kvittens crons flag needs_reconsent through the same shared pick
instead of .maybeSingle().
Tests: two members, one connects, both read; both connect, both read; no
row -> NOT_CONNECTED; dead-only rows -> reconnect prompt; sync auth carries
the owner; event recipient is the owner.
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>