* fix(skatteverket): stop hot-retrying APIGW subscription rejections in the AGI kvittenser cron The kvittenser reconciliation cron runs every 2 hours. When Skatteverkets API gateway rejects our client on the AGI hantera API (401 Invalid client id or secret, mapped to SkatteverketAuthError ACCESS_DENIED), the failure is a portal configuration gap: the APIGW client behind SKATTEVERKET_APIGW_CLIENT_ID has no Utvecklarportalen subscription for the service. Retrying cannot heal it and the user reconnecting via BankID does not help, yet the catch block fell through to console.error on every run, producing roughly 12 error-level log entries per day for one pending declaration. Add a dedicated catch branch for ACCESS_DENIED that logs at warn level with the actionable hint (which env var, which portal subscription) plus declarationId, companyId, and period, and records a distinct apigw_config result status. The status is counted in the run summary log line and the JSON response so the config gap stays visible. Every other error path is unchanged and still logs at error level. Adds route tests: cron auth 401, signed happy path, ACCESS_DENIED warn plus apigw_config without error-level logging, reconsent and TOKEN_REVOKED paths unchanged, other auth codes and generic errors still error-level. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(skatteverket): warn once per run on APIGW access denial (CodeRabbit) Gate the ACCESS_DENIED console.warn behind a run-level flag so a run with many affected declarations logs the identical configuration hint once, while every declaration still records its apigw_config outcome. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.