* feat(arcim): import Bokio underlag and link to verifikat Adds an optional, re-runnable step that pages the Bokio /uploads, resolves each receipt's target verifikat via the SIE-preserved voucher number, and archives it through the document service linked to the journal entry. Closes the gap where neither the SIE GL import nor the entity import carries the receipts/underlag attached to each verifikat. - lib/providers/bokio: getBytes() binary download + an attachments resource module (uploads list, GUID->voucher index, per-upload download); pageSize capped at 100, file type taken from the upload's contentType since the download is octet-stream - importProviderDocuments: bulk in-memory resolution keyed on (fiscal period, series, number) — scoped per fiscal year because Bokio restarts numbering at V1 each year; idempotent on (company_id, sha256) so re-runs don't duplicate the undeletable BFL-linked rows - POST /import-documents route, kept off the migration critical path because the Bokio document API is rate-limited (200 req/60s) - journal_entry_id link only for v1; reuses the document-service link path (same module as #804) rather than forking it Closes #786 Signed-off-by: Jonas Hagberg <jonas@lindan.se> * fix(arcim): stable pagination order + account for unresolvable receipts Addresses two findings from a Codex review pass on the import step: - Add .order('id') to the paged journal_entries / document_attachments / fiscal_periods reads. fetchAllRows pages with .range(), and PostgREST paging without a deterministic order can skip/repeat rows once a table exceeds one page (journal_entries crosses 1000 across several migrated years), which would defeat both voucher resolution and the sha256 dedup. - Keep every upload carrying a journalEntryId in scope instead of pre-filtering on a resolvable voucher ref, so a receipt whose Bokio entry number didn't parse (or resolves to no verifikat) is counted as unmatched rather than silently dropped from the best-effort report. Tests: add unresolvable-ref and zero-uploads cases; mock now supports .order(). Signed-off-by: Jonas Hagberg <jonas@lindan.se> --------- Signed-off-by: Jonas Hagberg <jonas@lindan.se>
Accounted
Open-source Swedish accounting software for sole traders (enskild firma) and limited companies (aktiebolag).
What is Accounted?
Accounted implements double-entry bookkeeping compliant with Swedish accounting law (Bokforingslagen). It supports the BAS 2026 chart of accounts, handles VAT declarations (momsdeklaration), SIE import/export, and enforces 7-year document retention. Built for sole traders and limited companies operating in Sweden.
Features
- Double-entry bookkeeping -- BAS 2026 chart of accounts, draft/commit workflow, sequential voucher numbering
- Invoicing -- Create, send, and track invoices with mixed VAT rates and PDF generation
- Bank reconciliation -- PSD2 bank connection via Enable Banking, 4-pass automatic matching
- VAT declaration -- SKV 4700 form mapping, per-rate breakdown, EU/export handling
- Tax reports -- NE-bilaga, INK2, SRU export for Skatteverket
- Supplier invoices -- Registration, payment tracking, input VAT deduction
- Document archive -- SHA-256 integrity, 7-year retention enforcement, full archive ZIP export
- SIE import/export -- Standard Swedish accounting interchange format
- Extension system -- Opt-in plugins for AI categorization, receipt OCR, email, calendar, and more
Self-Hosting
git clone https://github.com/erp-mafia/gnubok.git
cd Accounted
./setup.sh # Prompts for Supabase credentials, generates .env
docker compose up -d
You need a Supabase project and must apply the database migrations before first use. See SELF-HOSTING.md for the full step-by-step guide, including Supabase setup, auth configuration, optional features (AI, email, push notifications), and troubleshooting.
Development Setup
Prerequisites: Node.js 20+, a Supabase project.
npm install
npm run dev # Start dev server (auto-generates extension registry)
npm test # Run tests
npm run build # Production build
npm run lint # ESLint
Tech Stack
- Framework: Next.js 16 (App Router), React 19, TypeScript (strict)
- Database: Supabase (PostgreSQL + Row Level Security + email/password auth + TOTP MFA)
- Styling: Tailwind CSS 4 + shadcn/ui
- Integrations: Enable Banking (PSD2), Anthropic SDK, LangChain, OpenAI, Resend, JSZip
Documentation
- SELF-HOSTING.md -- Full self-hosting guide (Docker, Supabase setup, migrations, optional features)
- CLAUDE.md -- Architecture, bookkeeping engine, database conventions, extension system
- CONTRIBUTING.md -- Development workflow, code style, pull request process
- SECURITY.md -- Vulnerability reporting policy
Contributing
Contributions are welcome. See CONTRIBUTING.md for the full guide.
All commits require a DCO sign-off (git commit -s).
License
AGPL-3.0-or-later with an extension exception: third-party extensions that interact solely through the documented Extension API may be licensed under any terms, including proprietary. See LICENSE for details and NOTICE for third-party attributions.