* feat: implement fiscal period date fields component and validation logic
* feat: update fiscal period validation and naming logic
* feat: implement RPC for computing prior opening balances
- Added `compute_prior_opening_balances` RPC to aggregate opening balances for balance-sheet accounts when no opening balance entry is set.
- Updated tests across various reports to utilize the new RPC for fetching prior balances.
- Refactored `getOpeningBalances` to call the RPC when necessary, improving performance and reliability.
- Introduced a script to repair fiscal period chains for companies with broken periods, ensuring proper linking and continuity.
- Enhanced error handling and validation in the repair script to ensure data integrity during the process.
* feat: implement duplicate opening-balance repair for multi-year SIE imports
* feat: enhance SIE entry listing and deduplication logic for opening balances
* fix: refine companyHasPriorActivity logic to exclude storno entries and improve balance counting
* feat: dynamic voucher series dropdown in SIE import
Populate the voucher series picker on the import review step from the
company's own data instead of a hardcoded A/B/C/I list. Shows all A–Z
series with inline labels for the company default ("standard") and any
series that already have a running sequence ("används redan"), and
preselects the company default (falling back to B, then the first
existing series, then A).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address voucher series dropdown review feedback
- Log non-PGRST116 Supabase errors from company_settings and
voucher_sequences fetches instead of silently swallowing them.
- Disable the series Select until the async load completes so users
don't briefly see the 'B' fallback before it snaps to the real
company default.
- Replace the seriesInitializedRef guard with a seriesLoaded state that
resets on company.id change, so switching companies re-runs the
preselection instead of sticking with the prior company's choice.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Implement company and account deletion features
- Add event types for company and account deletion to CoreEvent.
- Enhance Supabase middleware to handle company context resolution and cookie management for archived companies.
- Create API routes for deleting accounts and companies, including necessary validations and event emissions.
- Implement tests for account and company deletion endpoints to ensure proper functionality and error handling.
- Add retention notice component to inform users about bookkeeping data retention during destructive actions.
- Create database migrations to support soft deletion of companies and anonymization of user accounts, ensuring compliance with retention laws.
* feat: enhance account deletion process and update user notifications
* Add service client for onboarding completion check and update escape hatch visibility
* Enhance invite flow and email handling for company members
* Refactor company context and RLS policies for active company isolation
- Update `switchCompany` to remove unnecessary revalidation as client handles navigation.
- Revise `getActiveCompanyId` to prioritize `user_preferences` and validate against non-archived memberships.
- Modify `setActiveCompany` to ensure `user_preferences` is the authoritative source while maintaining cookie compatibility.
- Enhance middleware to resolve active company using `user_preferences` and fallback to first non-archived membership.
- Introduce new API route `/api/company/current` to fetch the active company ID for cross-tab synchronization.
- Implement `CompanyTabSync` component for real-time active company enforcement across tabs.
- Create migration for RLS policies to enforce single-active-company isolation using `current_active_company_id()`.
* feat: implement viewer role enforcement for write permissions
- Added `useCanWrite` hook to determine if the current user has write permissions based on their role in the active company.
- Updated various components (JournalEntryForm, CustomerForm, DeadlineForm, etc.) to disable write actions and show a lock icon with a tooltip for users without write permissions.
- Introduced `requireWritePermission` function to enforce write permissions at the API level, returning a 403 response for viewers.
- Created tests to verify the behavior of the viewer role and write permissions.
- Added database migration to enforce read-only access for viewers at the database level.
* feat: event log, pending operations, and MCP staging
- Event log system: persist bus events to event_log table for external
automation platforms. Batch insert for transaction.synced. Daily
cleanup cron at 02:00 UTC.
- Pending operations: MCP write tools (categorize, create customer,
create invoice) now stage to pending_operations instead of executing
directly. Users review and commit/reject from /pending in the web UI.
- Granskning page: card-based review UI with expandable previews,
commit/reject dialogs. Only shown in nav when pending ops exist.
- Commit route re-executes using core lib functions (no extension
imports). Guards against stale state (double-commit, deleted entities).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: stage new MCP write tools after main merge
Add staging for 4 new write tools from #133:
- mark_invoice_paid, send_invoice, mark_invoice_sent,
match_transaction_invoice
- Expand pending_operations CHECK constraint
- Add commit executors with full execution logic
- Add UI labels and generic preview component
- Remove confirm parameter from categorize (single-call staging)
- Fix UUID in pending op title (fetch transaction description)
- Hide Granskning nav when no pending ops
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review feedback
- Fix TS build error: use `select('*, customer:customers(*)')` for
match_transaction_invoice to avoid array type inference
- Add status guard to commitSendInvoice (prevents duplicate sends)
- Replace auth.admin.getUserById with user email from session auth
- Restore optimistic lock check in commitMatchTransactionInvoice
- Fix tool description typo: expense_software → expense_office
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add support contact links and improve SIE import UX
Add a SupportLink component with a contact dialog throughout the app
(nav, help page, settings, MFA, error pages, empty states). Improve
SIE import flow with phased loading states, structured skip breakdowns,
and an elapsed-time counter. Fix MFA enroll stale factor cleanup and
URL encoding for settings return path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review — open redirect, XSS, test cleanup, fallback email
- Validate returnTo is a relative path in MFA enroll (prevents open redirect)
- Add afterEach import to event-log-handler tests (fixes handler leak)
- HTML-escape user-supplied subject and message in support email body
- Replace hardcoded personal email with support@gnubok.se fallback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SIE parser: Windows-1252 and CP437 encoding detection and decoding
- Bank file parser: add Nordea Business (Företag) CSV format
- Bank file parser: improve format detection for SEB, Länsförsäkringar, generic CSV
- INK2 engine: calculate årets resultat (7222) from income statement for open fiscal years
- Dashboard: parallel Supabase queries, simplified dashboard page
- Fix Swedish characters (å, ä, ö) in BAS data descriptions, validation messages, AI consent disclosures
- Import wizard UI improvements across all steps
- Migration: add 'bas_range' match type to sie_account_mappings constraint
- Extensive new tests for SIE parser encoding and bank file parser
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>