c84f951a5c2f51279277a506754b2bd94de28249
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ec27228a8e |
style: remove em/en dashes repo-wide, add CLAUDE.md rule against them (#890)
Em dashes (—) and en dashes (–) had spread across comments, docs, tests, and a few UI strings, reading as AI-generated boilerplate rather than house style. Replaced each with punctuation matching its context: colon for explanatory clauses, comma for asides, plain hyphen for numeric/legal ranges (e.g. "21-23§"), "to"/"till" for date ranges, parentheses for paired-dash asides. messages/en.json and messages/sv.json were fixed by hand together to keep sv/en in sync. Left untouched where the dash is the functional subject rather than decorative punctuation: date-range-parser.ts's separator regex, charset-repair.ts's CP1252 byte-mapping table (and its test), the SIE encoding mojibake docs, generic-csv.ts's minus-sign normalizer, the agent system-prompt files that already instruct against em dashes, and a golden iXBRL test fixture compared byte-for-byte. Also fixes two bugs surfaced along the way: an off-by-one in ApiKeysPanel's scope-label split (a leftover from an earlier partial pass), and a charset-repair test that had lost the literal en-dash it exists to verify. Regenerated the agent atom seed migration (skills:generate) since 27 SKILL.md files changed. Added a CLAUDE.md rule against em/en dashes, with an explicit carve-out for the functional-dash cases above. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
db8983ba9e |
Add/bokslut (#718)
* feat(arcim-migration): Briox provider with SIE-over-API import - Briox auth via account ID + application token (no app-level credentials); both tokens rotate on refresh and are persisted - New sie-fetcher pulls the general ledger as SIE through the provider API for Fortnox, Briox and Bjorn Lunden - Wizard stops on a failed SIE import and surfaces the real errors instead of proceeding to the misleading migrate-guard message - PROVIDER_SIE_ONLY_FORTNOX renamed to PROVIDER_SIE_NOT_SUPPORTED; new PROVIDER_TOKEN_INVALID for rejected provider credentials Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(bookkeeping): per-line accruals (periodisering) on invoices and supplier invoices Defer revenue/costs per invoice line to 29xx/17xx interim accounts with automatic monthly dissolution (nightly cron + catch-up at registration), schedule cancellation on credit, year-end auto-detect exclusion for already-scheduled invoices, invoice-inbox service-period extraction for prefill, and an MCP tool to list schedules. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(bokslut): iXBRL arsredovisning generation and Bolagsverket digital filing Generate the annual report as iXBRL from a generated taxonomy registry (K2 element lists, taxonomy:generate/check scripts + CI guard), expose it via the fiscal-period API, and add the bolagsverket extension for digital submission to eget utrymme with webhook-driven status tracking (submissions table + pg tests, lifecycle events, year-end wizard UI). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(mcp): raise origin-guard test timeout to 20s The dynamic import pulls in the full server module; the parse alone flirts with the 5s default under full-suite parallel load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add new scripts and documentation for K2 AB taxonomy generation and validation - Introduced `generate-taxonomy-registry.ts` to automate the generation of the iXBRL taxonomy concept registry from official element lists and tuple models. - Added `validate-ixbrl.mjs` for validating generated iXBRL reports against the official taxonomy package using Arelle. - Included new documentation files: - `k2-ab-arsredovisning-elementlista-2024-09-12_rev20250312_sv.xlsx` - `tuple-innehallsmodell-arsredovisning-k2-2024-09-12.xlsx` - `taxonomi-paket-2024-09-12_rev20250312.zip` * Add tests for bookkeeping accruals dissolution and supplier invoices - Implement tests for the POST /api/bookkeeping/accruals/[id]/dissolve route, covering success and error scenarios. - Add tests for the DELETE /api/supplier-invoices/[id] route, including authentication checks and validation of invoice deletion conditions. - Introduce tests for the Arcim migration provider client, ensuring token handling and error classification. - Create tests for the Bolagsverket extension, validating submission role enforcement and environment settings. - Add Zod schemas for Bolagsverket response payloads to ensure proper validation. - Implement tests for MCP server's list accrual schedules, confirming registration and scope mapping. - Add consistency tests for IXBRL document generation, ensuring duplicate facts and XML escaping are handled correctly. - Introduce typed domain errors for accrual schedules to improve error handling in the service. - Add tests for resolving consent with Briox token refresh concurrency, ensuring proper token management and error handling. * fix(tests): update payload size guard comments to reflect recent changes in tool descriptions and ceiling adjustments * fix(gitattributes): mark generated JSON files in bokslut taxonomy as linguist-generated * feat(migrations): add backfill for invoices.journal_entry_id and fallback for next_voucher_number user_id * feat(bokslut): enhance compliance and financial processing features with new submission details and security measures --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
02f94ef631 |
Fix/critical issues (#351)
* fix: add 15s timeout to accounting provider HTTP clients Node's built-in fetch has no default timeout, so a stalled provider could hold a serverless worker open for many minutes — worse with withRetry (6x on Fortnox, 3x on others) and getPaginated stacking across pages. Wrap each fetch() in the Fortnox, Visma, Bokio, Briox, and Björn Lundén clients with signal: AbortSignal.timeout(15_000), and treat TimeoutError/AbortError as retryable so a single stalled attempt retries cleanly instead of hanging the request. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: add timeouts to OAuth token endpoints Wrap every OAuth2 token exchange, refresh, and revoke POST in an AbortController via a new fetchWithTimeout helper. Without this, a hung provider endpoint holds the request thread indefinitely — worst case being Skatteverket, where refreshAccessToken sits on the hot path of every bookkeeping action and exchangeCodeForTokens races the 5-minute BankID auth-code TTL. On timeout, the Skatteverket OAuth callback now redirects to /reports?tab=vat-declaration with a Swedish retry message instead of leaving the user stranded on the callback URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: close RLS escalation on membership and settings tables Any authenticated user who was a member (including viewer) could issue a direct PostgREST PATCH against company_members and promote themselves to owner, bypassing the app-layer requireWritePermission guard entirely. Reproduced on prod, then verified the fix on staging. Tighten INSERT/UPDATE/DELETE policies on company_members, team_members, api_keys, company_invitations, team_invitations, companies, teams, and company_settings to require the caller to hold role IN ('owner','admin') in the target company/team. Role check is wrapped in SECURITY DEFINER helpers (user_is_company_admin, user_is_team_admin, user_role_in_company) to avoid RLS recursion when a policy on company_members references company_members in its subquery. Add a BEFORE UPDATE trigger on company_members that rejects any role change unless the caller already holds role='owner', so admins cannot mint further owners even though they can otherwise write. Legitimate write paths are unaffected: company creation goes through the create_company_with_owner SECURITY DEFINER RPC, invite acceptance uses the service role, and team->company membership syncs via SECURITY DEFINER triggers. All bypass RLS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(migrations): resolve duplicate schema_migrations version 20260421160000 Two migration files shared timestamp 20260421160000 on main (booking_template_usage.sql and opening_balances_rpc.sql), causing supabase_migrations.schema_migrations PK collisions on any fresh CI run: duplicate key value violates unique constraint "schema_migrations_pkey" Key (version)=(20260421160000) already exists. Bump opening_balances_rpc.sql to 20260421160500. booking_template_usage keeps 20260421160000 because its table already exists on prod; the renamed file has an idempotent CREATE OR REPLACE FUNCTION body and has not yet been deployed to prod, so moving its version is free. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(migrations): make booking_template_usage migration idempotent The table already exists on prod (applied out-of-band) but prod's schema_migrations does not track version 20260421160000, so the next PR-driven deploy would re-run this migration and fail on `CREATE TABLE public.booking_template_usage` with a duplicate-relation error. Add IF NOT EXISTS to CREATE TABLE and CREATE INDEX, and DROP POLICY IF EXISTS before each CREATE POLICY. No functional change on fresh databases; prod just silently no-ops the table/index creates and re-declares policies without dropping-then-missing them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: implement isTimeoutError utility and enforce role restrictions on company_members insert * fix: implement fallback for user_id in commit_journal_entry function when auth.uid() is NULL --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
e42da5c32b |
Staging (#181)
* refactor: remove unnecessary secondary action from EmptyInvoices component * feat: add direct provider layer and provider_consents migration Replace Arcim Sync gateway dependency with direct provider clients for Fortnox, Visma, Briox, Bokio, and Björn Lundén. Adds OAuth config, rate limiting, retry logic, data fetching, and consent storage via new provider_consents/tokens/otc tables. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: migrate arcim extension to direct provider APIs Replace Arcim Sync gateway calls with direct provider API access. Use FortnoxClient.getText() for SIE endpoints that return plain text instead of JSON. OAuth callback now returns HTML with postMessage to communicate with the opener window instead of redirecting. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use OAuth popup window instead of new tab Open provider login in a centered popup that auto-closes on completion via postMessage, keeping the user on a single tab. Falls back to redirect flow if popup is blocked. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add connection status, consent reuse, and SIE duplicate detection - Add listConsents() to query active consents by company - Add GET /status route returning consents, SIE import history, and entity counts - /connect reuses existing accepted consent instead of creating duplicates, and cleans up abandoned (status 0) consents - /status only returns accepted (status 1) consents - /sie-data checks each file's SHA-256 hash against sie_imports to report per-file import status (alreadyImported, importedAt) - /sie-data blocks on SIE validation failure (mirrors manual upload) - /import-sie validates unmapped accounts and auto-activates missing BAS accounts in chart_of_accounts (mirrors manual upload) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: show active connections, SIE file status, and smart re-sync UI - ProviderStep shows active connections with last import date, entity counts, "Synka igen" button, and disconnect option - Already-connected providers greyed out in selection grid - OptionsStep shows per-fiscal-year import status (imported vs new) - SIE toggle disabled with explanation when all files already imported - handleStartMigration skips already-imported SIE files - Auto-skip mapping step and disable SIE on re-sync when up to date - Result step hides empty "0 importerade" rows and shows "Allt är uppdaterat" when nothing new was fetched - OptionRow supports disabled state Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: adjust COMING_SOON_PROVIDERS based on NODE_ENV for development and production * Removed duplicate * Removed duplicate * refactor: redesign reports page navigation from grid boxes to bordered card layout Replace the 4-column grid of uneven TabsList boxes with a CSS grid card using auto-sized columns separated by 1px border dividers. All sections now share equal height via items-stretch, with clear visual separation between groups. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: trigger Vercel deployment * Update supabase/migrations/20260402010000_provider_consents.sql Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update lib/providers/rate-limiter.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * chore: re-trigger checks after migration sync --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |