fix(company): migration reset no longer blocks on existing vouchers, sequences, or invoices (#1977)

* fix(company): migration reset no longer blocks on existing vouchers, sequences, or invoices

The 2026-08-18 eligibility rule stopped the archive-and-replace reset before
the first journal entry, voucher sequence, or invoice. The reset deletes
nothing: the source stays a write-closed, downloadable retention container,
and the unchecked Radera foretag path already produced the same outcome
without any of those guards, so the blockers only led owners into a dead
end (Carrierstories, 2026-08-26). External-state blockers are unchanged.

Closes #1916

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(decisions): move the migration-reset entry to the end of the log

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:
Jakob Wennberg
2026-08-27 14:35:19 +02:00
committed by GitHub
co-authored by Claude Fable 5 Jakob Wennberg
parent dfed55cb6c
commit c0ecb34a2b
8 changed files with 231 additions and 131 deletions
+1
View File
@@ -1284,6 +1284,7 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-08-26] Webhook event catalogue lives in lib/webhooks/public-events.ts (grouped, with docs prose) and the fan-out handler set, the v1 create enum (so the OpenAPI spec and skills/accounted-api), and the docs page all derive from it: the enum and the docs had drifted to 24 of the 28 events the handler delivered, so the four reconciliation.* events were rejected at subscribe time. No API_V1_VERSION bump: the changelog already lists them as additive.
[2026-08-26] Removed the phantom V1_ENDPOINT_SCOPES entries GET /api/v1/openapi.yaml, GET /api/v1/companies/:companyId and GET /api/v1/companies/:companyId/events instead of building the routes: no route file, registry entry, docs, skill or test referenced them, and the new scope-registry-parity test needs the map to describe only what exists. A company-detail GET can be added later with its entry in the same PR.
[2026-08-26] gnubok_connect_bank / gnubok_connect_skatteverket moved from catalogVisibility 'search' to the default catalog: Claude.ai can only invoke tools present in tools/list, so search-only tools are discover-only there and the onboarding skill's steps 3-4 dead-ended on client-side tool-not-found (verified via event_log: the server never received the calls). Search-only visibility remains fine for tools an agent reads about before asking the user, but anything a skill instructs the agent to CALL must be in the default catalog.
[2026-08-26] Migration reset eligibility no longer blocks on existing journal entries, voucher sequences, or invoices (20260826150000, reverses the 2026-08-18 first-record rule): the reset never deletes, the retained source stays write-closed and downloadable from the replacement, and the unchecked "Radera företag" path already produced the same archived-source-plus-fresh-company outcome with no protection at all, so the blockers only routed owners into a dead end (Carrierstories, 2026-08-26, two fiscal years imported in the wrong order). External-state blockers (locked or closed periods, filings and staging state, live bank sync, running imports, integrations, workers, 30-day window, sandbox) are unchanged.
[2026-08-26] Dashboard layout diet (responsiveness plan B4): the four nav-visibility probes (WooCommerce/Shopify connections, webshop orders, mileage trips) became one SECURITY INVOKER RPC get_dashboard_nav_flags (20260826120000) rather than a client-side badge hook, because the flags gate whole nav rows and loading them after mount pops rows into the sidebar; RLS still applies inside the function. The layout's getDashboardAuthContext now verifies the JWT locally (lib/auth/claims.ts, shared with requireAuth) with getUser() as the fallback: the proxy already did the per-request revocation check, so the layout's own getUser() was a second Supabase Auth round trip on every hard load. The user-keyed reads (profile, preferences, memberships) moved into the company-resolution wave and the memberships join now supplies the active company row and role, so the layout went from ~20 network calls in 4 waves to ~12 in 2. The memberships-with-embedded-settings single query was NOT attempted: the PostgREST embed shape was unverified and the settings-names query is parallel anyway.
[2026-08-26] OAuth consent pre-checks ALL scopes (one-click, list collapsed in details): founder call after the read-only default dead-ended agent flows; defensible because every write is staged for approval, rows stay untickable, grant revocable.
[2026-08-26] accounting_method optional with form default (AB=accrual, EF=cash) in CompanySetupSchema/planCompanySetup: founder call to cut agent onboarding input to orgnr + moms period; the default is flagged (accounting_method_defaulted) and must be read back in the preview, never silent.