* feat: add sandbox infrastructure — migration, types, and middleware
Add database migration for sandbox support:
- Add `is_sandbox` boolean column to company_settings
- Update 4 enforcement trigger functions (journal entry immutability,
journal entry line immutability, retention enforcement, document
deletion blocking) to bypass checks for sandbox users
- Add `cleanup_sandbox_user()` SECURITY DEFINER function that handles
FK-safe deletion order (document_attachments → journal_entry_lines →
journal_entries → supplier_invoices → auth.users cascade)
- Add `cleanup_expired_sandbox_users()` function that loops over
sandbox users older than N hours with per-user error handling
Update TypeScript types:
- Add `is_sandbox: boolean` to CompanySettings interface
- Add `is_sandbox: false` to makeCompanySettings() test factory
Update middleware:
- Add `/sandbox` to public routes so the landing page is accessible
without authentication
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add sandbox landing page, seed API, cleanup cron, and banner
Sandbox landing page (app/sandbox/page.tsx):
- Client component matching the existing auth page aesthetic
- Auth check: if logged in as real user, shows message to use incognito
- Otherwise shows feature overview (invoices, transactions, bookkeeping,
reports) with "Starta sandbox" button
- On click: signInAnonymously() → POST /api/sandbox/seed → redirect
- Uses window.location.href for full page load (ensures middleware
picks up new session cookies)
Seed API (app/api/sandbox/seed/route.ts):
- POST handler gated to anonymous users only (403 for real users)
- Idempotent: returns { seeded: false } if company_settings exists
- Seeds ~40 rows: profile, company_settings (is_sandbox: true,
onboarding_complete: true), chart of accounts (via RPC),
fiscal period, 3 customers (Swedish business, EU business,
individual), 4 invoices (paid/sent/overdue/draft), 4 invoice
items, 2 posted journal entries with 5 lines, 8 transactions
(3 categorized, 2 income, 3 uncategorized), 2 deadlines
- Journal entries inserted directly (not via engine) to avoid
event emission, using next_voucher_number() RPC
Cleanup cron (app/api/sandbox/cleanup/cron/route.ts):
- GET handler with CRON_SECRET Bearer token auth
- Creates service role Supabase client
- Calls cleanup_expired_sandbox_users RPC (24h default)
Sandbox banner (components/dashboard/SandboxBanner.tsx):
- Amber bar with dismiss button (client state, reappears on reload)
- Text: "Sandlådemiljö — dina data raderas automatiskt efter 24 timmar"
- "Skapa konto" link to /register
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: integrate sandbox into dashboard — banner, nav, settings safeguards
Dashboard layout (app/(dashboard)/layout.tsx):
- Fetch is_sandbox from company_settings
- Render SandboxBanner at top of page for sandbox users
- Pass isSandbox prop to DashboardNav
- Hide RecaptIdentify analytics for sandbox users
Root page (app/page.tsx):
- Same sandbox banner and isSandbox prop treatment as dashboard layout
(root page has its own layout, not wrapped by (dashboard)/layout)
DashboardNav (components/dashboard/DashboardNav.tsx):
- Add optional isSandbox prop
- Change logout button text to "Avsluta sandbox" when isSandbox
- Redirect to /sandbox instead of /login on logout for sandbox users
- Applied to both desktop sidebar and mobile drawer logout buttons
Settings page (app/(dashboard)/settings/page.tsx):
- Hide "Bank (PSD2)" tab entirely for sandbox users — prevents
connecting real bank accounts from a temporary anonymous session
- Hide "Radera konto" card for sandbox users — account auto-deletes
via cron, and the delete flow requires email confirmation
Vercel config (vercel.json):
- Add sandbox cleanup cron at 04:00 UTC daily
(/api/sandbox/cleanup/cron)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove audit trigger for non-existent tax_codes table
Migration 018 referenced public.tax_codes which was never created
(migration 012 is a placeholder). This caused failures when running
migrations from scratch on a fresh database.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove ALTER FUNCTION for 3 non-existent functions
Removed search_path pinning for create_invoice_with_items,
seed_asset_categories, and update_reconciliation_session_counts —
none of these functions were ever created in any migration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove ALTER for generate_invoice_number (created in later migration)
The function is created in migration 20260306 with search_path already
set, but migration 20260304 tried to ALTER it before it existed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fixed redirect issue
* Update app/api/sandbox/seed/route.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Update app/api/sandbox/seed/route.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Update app/sandbox/page.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Fixed catch block issue
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Add LICENSE (AGPL-3.0-or-later), CONTRIBUTING.md, SECURITY.md, DCO, and NOTICE files.
Rewrite README for open-source audience with self-hosting instructions.
Redesign color palette to grayscale chrome theme across all components.
Add transaction uncategorize API route with tests.
Fix VAT account name mismatches in migration 052.
Improve import page with SIE file support and loading skeleton.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update BAS account catalog with comprehensive SRU codes and K2 flags
- Add currency revaluation service with tests and API route
- Add expenses page and account deletion API
- Enhance booking templates with new patterns and improved tests
- Improve transaction categorization with template picker and description matching
- Polish dashboard, onboarding, import, and transaction UIs
- Refactor year-end service for multi-step closing
- Move SRU generator to ne-bilaga, remove standalone SRU export
- Remove unused dev docs, mock data, and extension hooks
- Add invoice delivery note sequences migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- #43: Improve AI categorization to use account 2350 for loan repayments
instead of incorrectly suggesting 2440 (supplier payables). Add explicit
prompt guidance distinguishing loans from supplier debts.
- #45: Change unclear invoice unit "mån" to "månad"
- #46: Enable email extension in extensions.config.json so it appears in
the marketplace and can be activated by users
- #47: Change "Makulera" to "Ta bort utkast" for draft invoices — reserve
"Makulera" terminology for proforma invoices only
- #48: Show field-level validation errors when supplier creation fails
instead of generic "Validation failed" message
- #49: Temporarily hide Leverantörer and Leverantörsfakturor from sidebar
pending module rework
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reorganize reports page from flat 11-tab bar into 4-column categorized
grid (Bokslut, Skatt & moms, Huvudböcker, Avstämning)
- Move Import from Övrigt to Finans nav group for better discoverability
- Merge standalone Marketplace link into Tillägg section as "Utforska fler..."
- Rename abbreviated "Lev.fakturor" to full "Leverantörsfakturor"
- Add uncategorized transaction count badge to nav (desktop pill + mobile dot)
- Strengthen credit note confirmation with destructive styling and
type-to-confirm pattern requiring exact invoice number
- Clarify invoice send vs mark-sent with "Skickad manuellt" label,
visual hierarchy, and explanatory helper text
- Show Banking and Notifications settings tabs always, with placeholder
message and link to extensions when not enabled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Uncomment Enable Banking extension in loader (now registered at runtime)
- Add subscriptionNotice field to ExtensionDefinition type
- Show confirmation dialog when enabling extensions with subscription requirements
- Fix Settings banking tab: toggle-aware visibility, URL-addressable tabs,
BankSelector widget, correct API paths (/api/extensions/ext/enable-banking/*)
- Replace inline bank connection cards with BankConnectionStatus component
- Add actionable link to Settings from EnableBankingWorkspace
- Update CLAUDE.md with latest architecture docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shared components (ConfirmDeleteDialog, EditEntryDialog, validation utils),
enhance all 12 extension workspaces with edit/delete dialogs, input validation,
period comparisons, and new analytics features. Fix critical bugs in
ProjectBilling margin calculation and EarningsPerLiter revenue allocation.
Add pure calculation modules with 183 new tests across all extensions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move Reports to Finans nav group and auto-expand Övrigt on its pages
- Make report tabs horizontally scrollable with gradient fade on mobile
- Surface deadlines and alerts above the fold on dashboard
- Add dismissible categorization hint card on transactions page
- Split settings company form into 4 separate Cards for scannability
- Add monthly breakdown report, document upload zone, journal entry attachments
- Add batch category selector, receipt document linking, invoice form improvements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove influencer-specific features (campaigns, TikTok, gifts, shadow ledger,
contracts, briefings) and consolidate into a clean ERP foundation with core
bookkeeping, invoicing, receipts, tax reporting, and calendar functionality.
Reorganize database migrations into a clean numbered sequence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>