fix(scoping): Skatteverket per företag + nåbara startkort + företags-scopade val (#1610)
* fix(scoping): skatteverket per company + true pristine gates + scoped dismissals Skatteverket connections become per (user, company): the token table carried BOTH UNIQUE(user_id) and UNIQUE(company_id) (two stacked half migrations), so one connection leaked "connected" onto every company the user belongs to, sync ran the token against the wrong orgnr (behorighet 403), and reconnecting from another company silently moved the row and went dark on the first company's crons. Token reads/writes are now scoped by company through the whole chain (token-store, api-client refresh coalescing, skvRequest and its 21 call sites, resolve-auth, crons, MCP), /skattekonto/saldo answers 401 NOT_CONNECTED for companies without their own row (which is what the page's startkort keys on), and the dashboard connect-nudge counts only the active company's row. Bookkeeping's pristine start card now keys on all-years emptiness via a count probe instead of "no active filters": the default fiscal-year selection counted as a filter, which made the card unreachable on brand-new companies (it showed "inga traffar" instead). Two browser-global localStorage keys become company-scoped with legacy fallbacks: the inbox onboarding dismissal (dismissing on one company hid the card everywhere) and the periodisering auto-detect toggle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scoping): dedupe cron work per (user, company) + guard the ledger probe CodeRabbit findings on #1610: the skattekonto sync cron still deduped token rows by user_id alone, which would drop every company but one for multi-company operators (the exact scenario the PR fixes); and the all-years ledger probe could leave a stale false behind on a failed refetch, letting the pristine card render unconfirmed. The probe now resets to unknown in flight and carries the fetch generation guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
Jakob Wennberg
parent
4e14182a00
commit
18c20e68e6
@@ -0,0 +1,29 @@
|
||||
-- Skatteverket connections are per (user, company).
|
||||
--
|
||||
-- The table historically carried two half-finished uniqueness models stacked
|
||||
-- on top of each other:
|
||||
-- * 20260330130000 replaced UNIQUE(user_id) with UNIQUE(company_id)
|
||||
-- * 20260428120000 re-added UNIQUE(user_id) (its guard only looked for a
|
||||
-- (user_id) unique constraint, so it did not see the company one)
|
||||
-- leaving BOTH single-column constraints in place: one row per user AND one
|
||||
-- row per company. A multi-company operator could therefore never hold a
|
||||
-- connection for more than one of their companies, and reconnecting while
|
||||
-- another company was active silently moved the single row (the app's
|
||||
-- DELETE-by-user + INSERT-with-active-company pattern), going dark on the
|
||||
-- original company's nightly sync.
|
||||
--
|
||||
-- The application now reads and writes token rows scoped by
|
||||
-- (user_id, company_id); this migration makes the schema say the same thing.
|
||||
-- Legacy rows with NULL company_id (pre-multi-tenant) are left in place: the
|
||||
-- scoped reads never match them, so those users simply reconnect per company.
|
||||
|
||||
ALTER TABLE public.skatteverket_tokens
|
||||
DROP CONSTRAINT IF EXISTS skatteverket_tokens_user_id_key;
|
||||
|
||||
ALTER TABLE public.skatteverket_tokens
|
||||
DROP CONSTRAINT IF EXISTS skatteverket_tokens_company_id_key;
|
||||
|
||||
ALTER TABLE public.skatteverket_tokens
|
||||
ADD CONSTRAINT skatteverket_tokens_user_id_company_id_key UNIQUE (user_id, company_id);
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
Reference in New Issue
Block a user