Aller au contenu principal

Changelog

Alle Updates, neue Funktionen und Verbesserungen.

In Entwicklung

Sicherheit

  • No duplicate scheduled invoices: scheduled invoices are now claimed atomically before sending, so an overlapping run of the every-5-minute send job can never email the same invoice to a client twice. A send that fails is automatically retried on the next run, and every scheduled send is now recorded in the compliance ledger with its PDF — exactly like a manual send.

Hinzugefügt

  • Swiss QR invoice guides: three new German guides explain the QR invoice (/ratgeber/qr-rechnung-schweiz), the difference between IBAN and QR-IBAN (/ratgeber/qr-iban-vs-iban-schweiz), and how free QR invoice generator options compare (/ratgeber/bester-qr-rechnung-generator-schweiz). The free QR generator page links to all three.
  • Expanded QR generator FAQ: the free QR invoice generator now answers 11 frequently asked questions (up from 3) in all four languages — including whether data is stored, account requirements, QR-IBAN support, and how the QR invoice replaced the old payment slips.
  • AI search visibility: robots.txt now explicitly welcomes AI search and citation crawlers (ChatGPT, Claude, Perplexity) on public pages while keeping private app areas blocked and opting out of model training (Content-Signal: search=yes, ai-input=yes, ai-train=no). A new llms.txt gives AI systems a concise, canonical description of Slonge Billing and the free QR invoice generator.

Behoben

  • French and Italian QR generator pages no longer repeat "| Slonge Billing" twice in the browser-tab title.
  • The QR generator page no longer emits duplicate WebApplication structured data; it now ships one localized WebApplication entry plus new breadcrumb and how-to structured data for search engines.

Hinzugefügt

  • French and Italian documentation for the Calendar feature.

Geändert

  • Localized landing-page URLs: the free Swiss QR-invoice generator now has French (/fr/creer-facture-qr-suisse) and Italian (/it/creare-fattura-qr-svizzera) URLs instead of reusing the German address. Old links redirect automatically, and the language switcher, sitemap, and hreflang tags all point to the right per-locale URL.

Sicherheit

  • Encrypted calendar tokens at rest: Google Calendar OAuth access and refresh tokens are now encrypted in the database (AES-256-GCM) instead of stored in plaintext, so a database compromise can no longer expose live calendar credentials. Tokens are only ever decrypted in memory at the moment they're used.

Geändert

  • Clearer "calendar not set up" message: If Google Calendar integration isn't configured, clicking Connect now returns a clear "Google Calendar isn't configured yet" message instead of bouncing you to a confusing Google error page.

Behoben

  • AI account suggestion when marking an invoice as paid: Clicking ✨ AI-Vorschlag in the "mark invoice as paid" dialog now reliably recommends a revenue account instead of often returning "Keine passende Kontoempfehlung gefunden". The request was sending an invalid booking type, which nudged the AI toward a bank-to-receivable entry that has no revenue line for the dialog to use. When a suggestion still can't be applied (for example, the AI proposes a revenue account your chart doesn't contain), the dialog now logs the reason and falls back to the standard accounts so you're never blocked.

Hinzugefügt

  • CRM activity timeline: Companies and contacts now have an activity timeline — log notes, calls, tasks, and meetings (with start/end time, location, and participants) against a record. Contacts get a dedicated detail page, reachable from the contacts list and the new Kontakte entry in the navigation. Activities use a flexible association model, so a single entry can be linked to clients, contacts, leads, opportunities, projects, invoices, quotes, or vendor bills.
  • Sales opportunities: Qualified deals are now tracked as opportunities (stage, value, probability, expected close) alongside leads, including won → project conversion.
  • Calendar import: Import meetings from Google Calendar (live sync) and .ics files (Outlook/Apple export). Eligible meetings land on the CRM timeline, are matched to the right company or contact, and billable ones convert to an unbilled time entry in one click — hours taken from the actual meeting duration. Recurring series are expanded DST-correctly; declined, internal-only, and solo meetings are imported non-billable. Optional AI suggests billability and the likely client for ambiguous meetings. Available in the dashboard (Settings → Calendar, Calendar → Review) and via the CLI/MCP (slonge calendar import|sync|review). Attendee data is kept privacy-aware: unmatched attendees stay raw and are never auto-promoted to contacts, and disconnecting a calendar purges its imported participant data.
  • In the Review queue, meetings with no automatic match now offer a Suggest with AI action that proposes the likely client, whether it's billable, and a confidence score; once a meeting has been turned into a time entry it's marked Recorded as time entry and can't be converted twice.

Geändert

  • Features page previews: The sections on the public Features page now show real product screenshots — invoicing, AI receipt capture, cash-flow forecast, chart of accounts, client management, and the dashboard — instead of placeholder graphics.
  • Clearer sidebar icons: Accounting, customer, project, and CRM menu entries (e.g. *Journal*, *Chart of accounts*, *Balance sheet*, *Income statement*, *VAT returns*, *Year-end closing*, *Companies*, *Contacts*, *Leads*, *Pipeline*, *Week view*, *Quotes*) now each have a distinct icon instead of sharing a handful of generic ones.

Behoben

  • Paid invoices now reliably appear in the balance sheet and income statement: When marking an invoice as paid, the payment booking could end up with the same account on both sides (e.g. *Bank* against *Bank*). Such an entry is balanced but nets to zero, so the turnover never reached the income statement and the cash never reached the balance sheet. The payment dialog now refuses a booking where the revenue and payment account are identical, and the revenue side must be an actual revenue-type account — so the sale is always recorded where you expect it.
  • Create invoice no longer "softlocks" after selecting a customer: On the new-invoice page, clicking Create before choosing a customer showed a warning — but after selecting the customer the warning could persist and block submission. Validation now runs in one place with a single clear message that scrolls into view, instead of relying on the browser's generic field prompts.

Geändert

  • Marketing homepage: The hero section now shows a real screenshot of the product dashboard (business overview, cash-flow chart, and open invoices) in place of the previous placeholder.
  • Sitemap: The published sitemap (/sitemap.xml) now lists every public page across all four languages — marketing pages, the Swiss QR-invoice landing pages, the full documentation, the changelog, and the legal pages — so search engines can discover and index the whole site.

Behoben

  • Localized documentation: Opening the documentation home in English, French, or Italian (/docs-en, /docs-fr, /docs-it) no longer shows a "page not found" — it now opens the first article, with the full localized section navigation in the sidebar.

Hinzugefügt

  • Multi-language (DE / EN / FR / IT): The entire platform is now available in four languages — German, English, French (Switzerland), and Italian (Switzerland). The language is chosen via the language selector and stored per user (cookie/localStorage), including automatic browser-language detection. Translated are the entire app (all dashboard pages, forms, tables, status, success, and error messages), transactional emails (including dunning reminders), PDF/document templates, the public website (with hreflang alternates and localized SEO/JSON-LD metadata), as well as the knowledge base and the help chatbot. Numbers, amounts, and dates are formatted per language according to Swiss conventions (e.g. CHF 1'234.50).
  • _Note:_ Regulated and legal texts (Swiss QR-Bill, debt-collection/SchKG dunning levels, VAT/tax terms, legal pages) were translated using official multilingual terminology and are ready for legal sign-off before going live.

Behoben

  • Receipt scan: restaurant receipts were incorrectly assigned the reduced VAT rate (2.6 %): The receipt OCR prompt applied the reduced rate across the board for "Food/restaurants". Swiss VAT, however, distinguishes: 8.1 % for restaurant and café consumption on-site, 2.6 % only for groceries to go (supermarket). The prompt now uses the real VAT codes (CH_NORM_8_1, CH_REDUCED_2_6, CH_SPECIAL_3_8) instead of the made-up VM77/VM81/VM26 and primarily reads the VAT rate printed on the receipt.

Hinzugefügt

  • Booked status on the invoice timeline: The status timeline at the top of an invoice now shows the new Booked step after Paid, which turns green as soon as journal entries exist for the invoice. This makes it possible to see at a glance whether a paid invoice has been recorded in the accounting.
  • Prepaid timeline: Already-paid invoices (e.g. PayPal/TWINT) now also get a two-step timeline (Paid → Booked) instead of none at all.

Geändert

  • Paid invoices appear again in "All" and "Paid": The separate "Paid invoices" tab is gone. Prepaid invoices are listed like regular invoices in the main list and carry the paid/booked badge.
  • Paid → Booked badge for all paid invoices: The "Booked" badge, previously only visible for prepaid invoices, is now shown for every paid invoice with journal entries — including standard invoices that were later marked as paid.

Behoben

  • Postal-mail PDF/preview showed no invoice number: For the "Postal mail" delivery method, the template header (including invoice number and dates) was hidden to make room for the Swiss letter-envelope layout — but never shown again anywhere. The postal-mail wrapper now renders its own header block with place/date, subject ("Invoice No. RE-2026-XXX"), and due date.

Hinzugefügt

  • Paid invoices: Invoices for already-paid orders (e.g. via PayPal) can be recorded directly as paid — without a QR payment slip and without dunning. They appear in their own "Paid invoices" tab and can be created via Record paid invoice as well as via the CLI (invoice create --paid) and MCP.

Geändert

  • Project time entries grouped by month: Within a task, time entries are now grouped by month and can be expanded and collapsed per month. The month header shows total hours and total amount; the current month is expanded when the task is opened.

Hinzugefügt

  • Year-end closing: Pre-close checklist with 10 checks, automatic closing entries (account 2990), period lock with reopening (max. 5×/year), trustee bundle (PDF folder always; AbaConnect XML, CSV, receipts ZIP optional). CLI: slonge jahresabschluss {list,check,close,download,reopen}. MCP tools with a 24h cooldown on closing/reopening.
  • VAT quarter recording: New page under Accounting → VAT statements to log submitted ESTV statements.
  • Background job system (internal): DB-based job queue with cron drain.

Geändert

  • Booking lock for closed periods: Journal, invoice, expense, vendor-bill, and credit-note entries dated into a closed period are rejected with HTTP 409.
  • Stripe webhook: Payments that fall into a closed period are quarantined with a notification to tenant admins (no booking, no retry loop).

Behoben

  • Registration & several Settings-touching endpoints stopped working on prod because the prod DB was missing schema added by migrations between 2026-02-27 and 2026-05-16 (_prisma_migrations was stuck behind old failed rows, so prisma migrate deploy refused to apply newer ones; the docker-entrypoint.sh fallback only covered some). Specifically: ComplianceEvent/DocumentArtifact tables, Settings.attachUblXmlOnSend, AuditLog.tokenId, Client.buyerReference. Hotfix applied directly via ops/hotfix/2026-05-18-apply-missing-prod-schema.sql; docker-entrypoint.sh extended with idempotent fallbacks so future container starts re-establish them. Migration-table cleanup deferred to a separate session.
  • Registration error surface: failed signups no longer show a generic "Ein Fehler ist aufgetreten" with nothing for the user or operator to act on. The API now returns a short error code, maps known Prisma failures (P2002 → "Konto existiert bereits", P2022 → "Schema nicht aktuell") to specific messages, and writes a structured pino log entry with the full stack — so the next time something breaks, it surfaces immediately instead of needing prod log archaeology.
  • Registration email-send failure no longer silent: if the verification email fails to deliver, the API returns { success: true, emailSent: false } and the success screen shows an amber state with a one-click "Bestätigungs-E-Mail erneut senden" button instead of telling the user to check an inbox that will never get the email.

Geändert

  • Verification email now uses the platform's BaseTemplate (consistent logo, header, footer, branding) instead of the legacy inline React.createElement component, which rendered as a washed-out full-width orange-button mess in dark-mode email clients. Same German/English/French/Italian copy, properly framed.

Hinzugefügt

  • Runtime Peppol critical-check validation for UBL exports: every generated UBL XML (dashboard download, CLI/MCP, auto-attach on send) is now checked against ~40 SLONGE-CHECK-* rules covering EN 16931, Peppol BIS Billing 3.0, and Swiss specifics — IBAN mod-97, QR-IBAN consistency, the closed Swiss VAT rate set, Swiss UID format, ISO 3166 country codes, line and per-VAT-bucket totals math. The invoice detail page shows a green „Kritische Peppol-Prüfungen bestanden" badge when clean, a red expandable issue list when not. Failed validation now disables the primary download — overrides are a deliberate secondary action, role-gated to Buchhaltung / Administrator:in, with a confirmation dialog. Each override is recorded in the hash-chained compliance ledger as a distinct invoice.ubl_validation_overridden event (separate from the existing invoice.ubl_generated), and the auto-attach pipeline records invoice.ubl_validation_failed when it falls back to PDF-only. CLI gains slonge invoice ubl-validate for CI-gated pre-checks and a --force flag for explicit overrides; new MCP tool invoice_ubl_validate lets agents audit before they send (force-download is deliberately NOT an MCP tool — agents shouldn't bypass validation autonomously).
  • Client.buyerReference (BT-10) — optional buyer-reference field on Client (often a PO number or contract ID). Some Swiss cantonal procurement portals require it on inbound Peppol invoices; the builder emits cbc:BuyerReference when set, and SLONGE-CHECK-META-05 surfaces a warning when it's missing.

Geändert

  • buildInvoiceUbl() validates by default: every call site now gets SLONGE-CHECK validation upfront and throws UblValidationError on critical rule failures. Opt out with { validate: false } when a caller wants the bytes regardless. The currency check (CHF-only) moves from the builder's UblBuildError into the validator (SLONGE-CHECK-CURRENCY-01) — single source of truth.
  • DRY refactor: extracted the per-VAT-category bucket and totals math (computeInvoiceTotals) from the UBL builder into src/lib/e-invoice/totals.ts. Builder consumes the helper, validator uses it to verify round-trip consistency. Slice 1 fixtures stay byte-identical.
  • @slonge/agent-sdk owns the ValidationIssue Zod schema (packages/agent-sdk/src/schemas/peppol-validation.ts). The lib-side validator imports the TS type — single public contract, no drift between the API surface and lib internals. Rule-ID regex ^SLONGE-CHECK-[A-Z]+-\d{2}$ enforced at the schema layer prevents emitting official Peppol BR-* IDs.
  • The validator covers ~40 critical input-level rules, not the full Peppol BIS 3.0 Schematron set (~150 rules), and does not do UBL 2.1 XSD structural validation. The UI says "kritische Peppol-Prüfungen bestanden" — never "Peppol-valid". Full Schematron parity (Slice 4b) is gated on a Peppol Access Point partner being contracted; until then, customers reporting a recipient-side rejection can escalate and we'll add the specific rule manually.

Hinzugefügt

  • Auto-attach Peppol UBL XML to invoice emails (opt-in): a new Settings → Rechnungseinstellungen checkbox (attachUblXmlOnSend, default off) causes every outbound CHF invoice email to include the Peppol BIS Billing 3.0 UBL XML as a second attachment alongside the PDF. Recipients on B2G procurement platforms (federal administration, cantons) or with e-invoice-aware accounting software (Bexio, Abacus, SAP, etc.) can ingest the structured XML directly — no manual download + forward step. Non-CHF invoices and UBL build failures fall back silently to PDF-only (a successful send takes precedence over a perfect attachment). Each auto-attached export records a DocumentArtifact (kind: invoice_xml_ubl_sent) and an invoice.ubl_generated compliance event, tagged generatedFrom: "lib/invoice-send" to distinguish from dashboard / CLI downloads. The toggle is also available via the CLI/MCP settings_update tool, and the slonge invoice send response envelope surfaces ublSha256 + ublByteSize when UBL was attached so agentic callers can verify what shipped.

Geändert

  • DRY refactor: extracted the shared Prisma → UBL mapping (mapInvoiceToUblInput + resolveSupplierIban) from the dashboard + CLI download routes into src/lib/e-invoice/ubl-mapper.ts. Slice 2 reuses it; the existing route behavior is byte-identical.

Hinzugefügt

  • Peppol BIS Billing 3.0 UBL XML export: every CHF invoice can now be exported as a Peppol-conformant UBL 2.1 XML file from the invoice detail page ("E-Rechnung exportieren" card → GET /api/invoices/[id]/ubl), the CLI (slonge invoice ubl -o ), and the MCP server (invoice_ubl tool). The XML carries the Swiss QR reference and payment IBAN in cac:PaymentMeans, ready to hand to a Peppol Access Point or pass into accounting software (cantonal eInvoicing platforms, EN 16931, etc.). Each download is registered as a DocumentArtifact with a SHA-256 digest and records an invoice.ubl_generated compliance event in the per-tenant hash-chained ledger. CHF only in this slice; runtime Peppol Schematron validation and Peppol Access Point delivery land in follow-up slices.

Behoben

  • Compliance ledger now covers secondary expense and vendor-bill mutation surfaces: cross-cutting review of Phase 1.5b found that the expense approve/reject endpoints (POST and DELETE /api/expenses/[id]/approve), the Kreditorenprozess status workflow (PUT /api/expenses/[id]/status), and the vendor-bill approve endpoint (POST /api/vendor-bills/[id]/approve) were mutating financially-relevant status without writing to the ComplianceEvent ledger. They now fire recordExpenseUpdatedEvent / recordVendorBillUpdatedEvent so an auditor can trace approve → freigegeben → bezahlt and PENDING → APPROVED / SCHEDULED transitions through the hash-chained ledger like every other mutation.
  • quote.sent ledger entries no longer carry internalNotes: recordQuoteSentEvent now strips the internal-only internalNotes field from the outbound-communication event payload, matching the metadata hygiene of the other entity helpers.
  • Distinct quote.accepted compliance event: when a quote status transitions to ACCEPTED (via dashboard PATCH or CLI PATCH), the ledger now records both the generic quote.updated event and a dedicated quote.accepted event. Previously the recordQuoteAcceptedEvent helper existed but had no production call sites, so auditors couldn't distinguish acceptance from any other update.

Hinzugefügt

  • Compliance ledger covers journal entries, credit notes, vendor bills, expenses, and quotes: the hash-chained ComplianceEvent table now records lifecycle events for every financially-relevant entity, not just invoices. Each entity has dedicated per-action helpers in src/lib/compliance/{entity}-events.ts (e.g., recordJournalEntryCreatedEvent, recordCreditNoteCreatedFromInvoiceEvent, recordQuoteConvertedEvent). Compliance dossier exports automatically include the new event types — auditors can verify the full chain of financial state changes from a single ZIP. A new test (src/lib/compliance/archive.test.ts) locks in the all-6-entity-types completeness.

Sicherheit

  • Unified audit trail for CLI & MCP: Every write made via the slonge CLI, @slonge/mcp-server, or the streamable HTTP /api/mcp transport now produces an AuditLog row alongside the existing ApiTokenUsage request-envelope record. Covers create/update/delete on clients, projects, invoices, quotes, time entries, expenses, settings, and API tokens — plus the higher-level actions invoice/quote send, quote→invoice convert, and dunning runs. A new AuditLog.tokenId column attributes each change to the specific API token that initiated it (dashboard mutations leave the column null). PATCH endpoints skip writing an audit row when no tracked fields actually changed.

Behoben

  • API token "Revoke" action now visible as a button: On Settings → API Tokens the revoke action per token row was rendered merely as red text without a button frame. The action was clickable but not recognizable as a button — so administrators effectively could not revoke tokens. Switched to the project-wide

Hinzugefügt

  • Compliance dossier: Administrators can export audit-supporting records with event hashes, document checksums, and a manifest. Every invoice create/update/delete/schedule and every sent PDF is now recorded in a per-tenant hash-chained ComplianceEvent ledger (via src/lib/compliance/invoice-events.ts). Sent invoice PDFs are also registered as tamper-evident DocumentArtifact rows with SHA-256 digests (src/lib/compliance/artifacts.ts). Recording happens on both the dashboard and the CLI/MCP surface so agent-driven changes are auditable too. The full ledger + artifacts are now included in tenant backup ZIPs (compliance/events.json, compliance/document-artifacts.json).
  • CLI/MCP — Wave 6: settings_update (CLI: slonge settings update), quote_pdf (slonge quote pdf ), quote_send (slonge quote send ) — completes the v1 tool surface.
  • Streamable HTTP MCP transport at /api/mcp — connect claude.ai / ChatGPT / any remote MCP client without installing the stdio binary. Same bearer-token auth as /api/cli/*.
  • npm packages: @slonge/cli, @slonge/agent-sdk, @slonge/mcp-server to be published publicly at 0.2.0. Install with npm install -g @slonge/cli once released.
  • CLI/MCP Wave 5 — dunning + report + settings_get. Closes out the v1 CLI/MCP surface per the spec. 6 new MCP tools (dunning_list_pending, dunning_get, dunning_run, report_list, report_export, settings_get). 6 new API routes. CLI gains slonge dunning list|status|run, slonge report list|export -o , and slonge settings show. Binary exports (Abacus AbaConnect XML, Abacus ASCII .asr) ride the JSON envelope as contentBase64 and the CLI base64-decodes them when -o is given.
  • CLI/MCP Wave 4 — quote + quote-convert. Full CRUD for quotes via the CLI and the MCP server, plus the quote_convert tool that turns an accepted quote into a draft invoice. Convert pipeline extracted to src/lib/quote-convert.ts and shared with the dashboard route (behavior byte-identical for the dashboard caller). CLI quote create accepts line items as a --items-json array; quote-level VAT falls back to settings.defaultVatRate. 6 new MCP tools (quote_list, quote_get, quote_create, quote_update, quote_delete, quote_convert), 4 new API routes.
  • CLI/MCP Wave 3 — time-entry + expense + receipt OCR. Full CRUD for time entries and expenses via the CLI and the MCP server (11 new MCP tools, 7 new API routes). Time-entry create accepts --project-id (auto-creates the project's "Default" story) or --story-id. Quick alias slonge time-entry log --project-id --hours defaults the date to today.
  • expense upload / expense_upload — first AI-quota-gated CLI/MCP tool. Submit a receipt image or PDF (base64, max 6 MB), get back parsed amount/vendor/date/description plus Swiss accounting suggestions (account number + VAT code). Counts toward the tenant's monthly aiCallsPerMonth quota; returns 403 FORBIDDEN when the plan doesn't include AI, 429 QUOTA_EXCEEDED when the cap is reached. v1 returns OCR data only — receipt persistence to disk/S3 is deferred to a follow-up PR.
  • POST /api/cli/invoice/[id]/send — CLI slonge invoice send and the invoice_send MCP tool can now actually send invoices via the API (previously returned 404). Shares the dashboard's full pipeline — PDF generation, Swiss QR-bill, React Email template, eligibility checks, Resend delivery, automatic draft → sent status flip — via the new src/lib/invoice-send.ts module.
  • Project.budget column — CLI/MCP --budget values now persist instead of being silently dropped. Database migration 20260514120000_add_project_budget adds the nullable column; entrypoint script auto-heals existing deployments on container start.
  • API & MCP documentation page (DE + EN) at /docs/api-mcp with quick start, tool overview, error codes, and security best practices. New "API & MCP" section in the docs navigation; the chatbot now also understands CLI/MCP questions.
  • API tokens for slonge-billing CLI and MCP server. Manage tokens at Settings → API Tokens (admin only). Tokens use Bearer auth (Authorization: Bearer slk_*) and work against staging and production. Each request is rate-limited (60/min) and audit-logged.
  • @slonge/agent-sdk workspace package — Zod schemas + HTTP client, single source of truth for CLI, MCP server, and Next.js route validation.
  • @slonge/mcp-server workspace package — stdio MCP server exposing ~22 tools (client/project/invoice CRUD, invoice send/mark-paid, API token CRUD) for Claude Desktop, Cursor, Claude Code.
  • CLI invoice send + mark-paid subcommands; global --json, --verbose, --dry-run flags; real test:all / test:full commands wired to workspace scripts.

Geändert

  • Quote PDF generation extracted to src/lib/quote-pdf.ts; dashboard route now delegates and returns application/pdf (previously returned a JSON envelope with rendered HTML).
  • Quote send pipeline extracted to src/lib/quote-send.ts (mirrors src/lib/invoice-send.ts). Dashboard send route now attaches the quote PDF to the outgoing email.
  • src/app/api/ai/receipt/route.ts internals refactored — the OCR pipeline (plan gate, monthly quota check, OpenAI call, account/category resolution, UsageRecord write) lives in the new src/lib/receipt-ocr.ts. The dashboard route's response shape is unchanged.
  • src/app/api/quotes/[id]/convert-to-invoice/route.ts internals refactored — the convert pipeline (find-or-create project, atomic invoice + material costs creation, quote status flip, settings increment) lives in the new src/lib/quote-convert.ts. The dashboard route's response shape is unchanged.
  • Dunning processor refactorsrc/app/api/dunning/process/route.ts (the cron entry point) now delegates each tenant's run to src/lib/dunning-run.ts. Behavior byte-identical for the cron caller; the CLI/MCP /api/cli/dunning/run route calls the same lib with a single tenant id.
  • Report exporters split into shared libssrc/lib/reports/{balance-sheet,income-statement,vat-summary,abacus-xml,asr-ascii}.ts. Dashboard routes refactored to thin shims; response shapes preserved byte-identical.
  • Dunning email now matches the invoice email: Dunning reminders are sent in the same layout as invoices — header, line-item list, Swiss QR-Bill in the email body, and a PDF attachment. The previous "View invoice" button linking to a login-protected page was removed; the PDF attachment is the canonical version the customer keeps. The dunning salutation with level, days overdue, and deadline is shown as accompanying text above the invoice.
  • CLI authentication: ~/.slonge/config.json now uses apiToken field (Bearer). Legacy secret field still works on staging with ENABLE_CLI_API=true but prints a deprecation notice; will be removed 2026-11-11.
  • slonge invoice create --description is now required (matches server validation). Previous CLI made it optional and always 400'd.
  • Existing /api/cli/* routes now validate request bodies against shared Zod schemas from @slonge/agent-sdk.
  • /api/cli/invoice list and single-invoice routes now scope tenant by client (always required) instead of project (nullable), so invoices created without a linked project are visible to CLI/MCP callers.
  • Quantity input: steps depend on the unit: The up/down arrow keys in the quantity field of an invoice or quote line item now increment by 1 for piece, day, and flat rate, by 0.1 for hour (the typical billing granularity for hourly work), and by 0.01 for meter and kilogram. Applies on the New invoice, Edit invoice, New quote, and Edit quote pages.

Behoben

  • Dunning fees and default interest in preview, print, and QR-Bill: As soon as an invoice has been dunned, the print view, the attached PDF, and the on-screen preview now show three additional lines — Invoice amount, Dunning fees, and Default interest — and the Total amount as well as the QR-code amount match the current outstanding debt. Previously all three showed only the original invoice amount.
  • "Schedule sending" now actually sends invoices: The cron endpoint /api/invoices/process-scheduled (and the daily dunning endpoint /api/dunning/process) were not being called by any scheduler — the old Kubernetes CronJob manifests under ops/k8s/jobs/ were never deployed (production runs on a single Docker VM, not on Kubernetes). Set up as a host cron on 85.217.161.119 via the new [ops/host-cron/](ops/host-cron/) setup script. Scheduled invoices are now processed every 5 minutes, the daily dunning run at 07:00 UTC. _Prerequisite: the setup script was run once on the VM — see ops/host-cron/README.md._
  • Postal-mail layout: QR code on a second page for long invoices: With too many line items, the middle section of the postal-mail invoice grew into the lower A4 third and overlapped the QR payment part. The layout now switches to natural flow with break-inside: avoid on the QR area — for short invoices the QR still sits on the lower half of the page, for long ones it breaks onto a second page.
  • Swiss cross missing in the postal-mail QR: The dunning and invoice PDFs of the postal-mail variant no longer displayed the mandatory black square with the white Swiss cross at the center of the QR code — causing the QR code to be rejected by many Swiss banking apps. The overlay is now drawn with pure HTML/CSS (instead of an SVG data URI) and renders identically in browser preview, PDF, and print.
  • QR code blurry in the postal-mail preview: QR resolution increased from 400 px to 1024 px and image-rendering: crisp-edges set — the QR now stays sharp at any scaling ratio.

Sicherheit

  • API tokens stored as SHA-256 hash, not plaintext.
  • Token creation requires the TENANT_ADMIN role.
  • Full token revealed exactly once at creation.

Hinzugefügt

  • Documentation overhauled: The public /docs is back in sync with the app — new Dunning section, chart-of-accounts hierarchy (4-level Swiss SME structure), quick actions (configurable dashboard quick actions), foreign-currency receipts in Smart Inbox + expenses (Frankfurter API auto-fetch), template preview with thumbnails, notifications section, and Sign in with Google in the first steps. Both DE and EN updated; chatbot capabilities extended with dunning, smart-inbox, and ai-features.
  • Help chatbot moved to the documentation: The floating help assistant now lives on /docs (and /docs-en) instead of on every authenticated app page. Same RAG-based functionality, less visual noise in day-to-day work. Sign-in still required.
  • Automatic CHANGELOG rotation (planned): A new GitHub Actions step is intended to move ## [Unreleased] into a dated entry (## [YYYY-MM-DD] (sha)) after a successful production deploy and commit it back to main. _Note: Currently temporarily disabled due to a missing OPENAI_API_KEY repo secret; will be re-enabled once the secret is set._
  • Doc-update reminder hook: A PostToolUse hook in .claude/settings.json reminds contributors to update docs/de/, docs/en/, and CHANGELOG.md when source files in src/, packages/, or Prisma migrations are changed.
  • Products as invoice line items: When creating or editing an invoice, you can use the Choose from products button to add products and services from your catalog as line items with one click — including search, multi-select, and automatic adoption of label, unit, and unit price.
  • Send test dunning: Under Settings > Billing there is now a "Send test dunning" card. Admins can use it to send a test dunning reminder of level M1, M2, or M3 to their own or a specified email address — without an overdue invoice, without waiting for the daily cron. Helps validate the template and the Resend configuration before a real dunning run.
  • Book foreign currency directly: Expenses in foreign currency (EUR, USD, etc.) can now be booked directly from the Smart Inbox. The CHF rate is fetched automatically from the Frankfurter API if it is not yet stored. The inbox shows the CHF amount (e.g. ≈ CHF 48.50), or a note that the rate will be fetched at booking time.
  • Automatic dunning (cron): New Kubernetes CronJob dunning-cronjob.yaml calls the dunning process daily at 07:00 UTC. Dunning reminders are now sent automatically (auto mode) or shown for approval (semi_auto mode).

Geändert

  • Line-items API: The status=billed filter no longer includes paid entries; use status=paid for paid entries.
  • PDF attachment now matches the print view: The PDF attached to customer emails is now generated by rendering the same HTML template shown on "Print" in the app — including logo, colors, Swiss QR-Bill, and the full line-item list. Technically: headless Chromium (Playwright) renders the invoice template to PDF instead of the old programmatic PDFKit layout.
  • "View invoice online" button removed: The link in invoice emails led to a page that requires a login — not accessible for external recipients. The PDF attachment fully replaces this view.

Behoben

  • Create client from the invoice/quote editor: The inline "New" dialog next to the client field could not create a client (error "Error creating client") — the form sent the address field, but the data model expects addressLine1. Inline creation now works in both the invoice and the quote editor.
  • Postal-mail address in the right window: The recipient address for physical delivery now sits on the right of the sheet (left 125 mm, width 80 mm), matching the window of Swiss C5/B5 postal-mail envelopes. Previously it was on the left — which avoided slipping when folding or printing in the wrong position.
  • PDF generation in production: The container now installs the Chromium matching playwright-core (instead of Debian's system Chromium), so PDF sending works reliably in Kubernetes.
  • PDF attachment when sending invoices: Emails to customers again contain the invoice as a PDF attachment. Cause: pdfkit was not registered as an external server package, which made PDF generation fail at runtime and the error was silently swallowed. If PDF generation now fails, the email is no longer sent and an error message appears.
  • Invoice print across two pages: Normal invoices (email delivery) are no longer split across two pages. The card border and double inner padding were removed for print, A4 margins of 15 mm set, and line breaks in the middle of table rows prevented.
  • Project status after payment: The invoice status on the project page now updates automatically when switching from the invoice to the project window — even if the project window was already open.
  • Chart-of-accounts account types: Three revenue accounts (financial income, extraordinary income) were incorrectly classified as expense. Both templates corrected.
  • Email-to-Action Automation: Forward emails to your personal inbox address and let AI automatically process them into expenses, vendor bills, leads, or documents.
  • Personal Inbox Address: Each tenant gets a unique address: inbox-{company}@inbox.slonge-billing.ch
  • AI Classification: Incoming emails are analyzed and classified by intent (expense, vendor bill, lead, document).
  • Auto-Create Entries: Receipts become expenses, invoices become vendor bills, inquiries become leads.
  • Settings UI: Configure which email types to process, auto-approval thresholds, and notification preferences under Settings → Smart Inbox.
  • 100% Swiss Hosting: Self-hosted SMTP server on Swiss infrastructure. No third-party email services.
  • Haraka SMTP Server: Lightweight Node.js mail server running on ports 25/587 with TLS.
  • Webhook Integration: Emails processed via secure webhook with master secret authentication.
  • S3 Attachment Storage: Email attachments stored in Swiss Exoscale S3 bucket.
  • Visual Template Selector: When creating invoices or quotes, templates now display as a grid with visual thumbnails. Hover to load preview, click for full A4 preview in modal.
  • User Template Preferences: Selected template is saved per user. Next time you create an invoice/quote, your preferred template is pre-selected.
  • Tenant Default Templates: Admins can set default invoice/quote templates in Settings → Templates.
  • Configurable Quick Actions: Dashboard now shows customizable quick action buttons. Click the settings icon to personalize.
  • 10 Available Actions: New Expense, Scan Bill, New Invoice, New Quote, New Project, New Client, New Product, New Lead, Time Entry, Journal Entry.
  • User Preferences: Select up to 8 actions. First 4 show on mobile. Reorder by dragging up/down.
  • Persistent: Your selection is saved to your profile.
  • Swiss KMU Kontenplan: Full support for hierarchical account structure (1/10/100/1000 levels for Klasse/Hauptgruppe/Gruppe/Konto).
  • Visual Hierarchy: Account list shows indentation and group styling. Groups are not bookable.
  • Template Descriptions: All Kontenplan templates now mention their hierarchical structure.
  • Consolidated AI Invoice: Removed duplicate "AI Rechnung" button. QuickInvoice (Schnellrechnung) remains as the single AI-powered invoice generator.
  • AI Invoice Generator: Create invoices using natural language prompts like "Rechnung für Acme GmbH mit allen unbezahlten Stunden". Opens via button on invoices page. Auto-fetches unbilled time entries and material costs, matches clients/projects with fuzzy search, calculates VAT from settings.
  • AI Cash Flow Forecast: 90-day liquidity prediction with confidence bands. Analyzes per-client payment patterns, detects recurring expenses, shows alerts for shortfalls. Dashboard widget with chart. (GET /api/analytics/cash-flow-forecast)
  • AI Anomaly Detection: Statistical analysis to detect unusual patterns - expense anomalies (>2.5σ), vendor price increases (>20%), new vendor detection, client payment behavior changes. Dashboard widget with severity indicators.
  • AI Project Estimation: Estimate new project costs based on historical data. Input description + complexity → get hours/cost/duration ranges with breakdown by category. Uses AI-enhanced matching when OpenAI configured.
  • AI Smart Reminders: Proactive business reminders on dashboard - overdue invoices, due-soon invoices, unbilled time entries, stale drafts, dormant clients, pending vendor bills, cash flow warnings. Priority levels with direct action links.
  • AI Email Drafting: Generate professional invoice emails with "AI E-Mail-Entwurf" button. Adapts tone for client relationship (new vs long-term), handles initial/reminder/followup/thank_you types, Swiss German business tone.
  • AI Smart Search: Natural language search across all data - "Alle offenen Rechnungen diesen Monat", "Kunde Müller", etc. Understands German/English, parses dates, filters by status. Command palette style UI.
  • AI Duplicate Detection: Find potential duplicate invoices, expenses, vendor bills. Uses Levenshtein similarity for text matching, flags 60%+ as potential and 90%+ as likely duplicates.
  • AI Features Documentation: Comprehensive API reference at docs/AI-FEATURES.md with endpoints, request/response examples, configuration guide.
  • E2E Tests: Playwright tests for AI features covering UI components, API responses, and error handling (e2e/ai-features.spec.ts).
  • Database Migrations: Added missing VendorBill columns (documentUrl, journalEntryId, paymentReference, etc.) that were causing API errors
  • Credit Notes Schema: Added CreditNote and CreditNoteItem tables with proper foreign keys
  • Document Templates: Added DocumentTemplate table for customizable invoice/quote templates
  • Settings Schema: Added creditNotePrefix, creditNoteNextNumber, and quoteValidityDays columns
  • Rate Limit Config: Fixed cashflow API using incorrect rate limit configuration
  • Staging Environment: Set up Exoscale SKS staging environment with DBaaS PostgreSQL

Hinzugefügt

  • Quotes (Angebote): Create and manage quotes with line items, auto-numbering (AN-2026-001), validity dates, and status workflow (Entwurf → Gesendet → Akzeptiert/Abgelehnt). Convert accepted quotes to invoices with one click.
  • Vendor Bills (Lieferantenrechnungen): Track incoming bills from suppliers with line items, approval workflow, payment recording, and PDF attachments. Tabs: Ausstehend, Genehmigt, Überfällig, Bezahlt.
  • AI Vendor Bill Scanner: Upload JPG/PNG of invoices (including Swiss QR-bills) to auto-extract vendor, amount, dates. Shows confidence scores and suggests matching existing vendors.
  • AI Client Insights: View client analytics including revenue stats, payment behavior rating (früh/pünktlich/verspätet), activity level (aktiv/abkühlend/inaktiv/neu), 12-month revenue chart, and AI-generated insights in German.
  • AI Cashflow Forecast: Predict cash flow 30-180 days ahead with confidence bands. Warns of potential liquidity issues. Dashboard widget shows 30-day preview. Export as CSV.
  • AI Booking Suggestions: Receipt scanning now suggests expense accounts, VAT codes, and payment accounts for direct booking.
  • Dashboard Widgets: Cashflow chart (12-month income vs expenses), pending invoices donut, pending bills, quick actions, recent activity timeline, and getting started checklist (dismissible).
  • Top Customers Widget: Shows top 5 clients by revenue with health indicator dots (🟢🟡🔴🔵). Click to navigate to client detail.
  • Customizable Dashboard: Toggle widgets on/off via Settings → Dashboard.
  • Enhanced Client List: Health indicators per row, quick filters (Top-Kunden, Aktive, Inaktive), sorting by revenue, revenue display in list view.
  • Data Import/Export: Export clients, invoices, and other data as CSV with Swiss formatting (DD.MM.YYYY dates, 1'234.56 numbers). Full backup downloads ZIP with all CSVs + receipts. Import wizard supports Bexio CSV format.
  • Document Templates: 4 system templates (Modern, Classic, Minimal, Bold) with customizable colors, bank detail visibility, header/footer text. Preview with sample data. Set defaults per document type.
  • List Page Tabs & Bulk Actions: All list pages (invoices, expenses, projects) now have tabs with counts, multi-select with bulk actions dropdown, unified search, and helpful empty states with CTAs.
  • Reusable List Components: Consistent ListTabs (horizontal scroll on mobile, count badges), BulkActions dropdown, and ListHeader with search/filters across all pages.
  • Swiss Export Formatting: All CSV exports use Swiss date format (DD.MM.YYYY), Swiss number format (1'234.56), and UTF-8 BOM for Excel compatibility.
  • Google OAuth Login: Sign in or register with Google for faster account setup. Existing users can link their Google account for one-click login.
  • Impressum Page: Legal notice page at /legal/imprint with multilingual support (DE/FR/IT/EN).
  • Project Document Import: Upload PDF/DOCX project proposals and let AI extract project details, tasks, and timelines automatically at /projects/import.
  • Automatic Client Matching: When importing projects, the system uses fuzzy matching to find and suggest existing clients.
  • Public Documentation: Browse all help docs at /docs with sidebar navigation.
  • Changelog Page: View all updates at /changelog with timeline layout.
  • English Documentation: Full English docs available at /docs/en/.
  • Auto-embed Updates: Documentation embeddings regenerate automatically on deploy.

Geändert

  • Direct Booking Default: "Direkt verbuchen" checkbox now defaults to checked when creating expenses.
  • Privacy Protection: Sensitive data (emails, phone numbers, IBANs) are sanitized before sending to AI.
  • CI workflow now regenerates RAG embeddings when docs change.
  • CI workflow now purges Cloudflare cache after successful deployment.

Behoben

  • Expense Totals: Foreign currency expenses without CHF conversion now fall back to original amount instead of being excluded from totals.
v1.0.0

Hinzugefügt

  • Invoicing: Swiss QR-Rechnung with PDF export
  • Time Tracking: Project-based time entries with stories/tasks
  • Expense Management: AI-powered receipt scanning and categorization
  • Client Management: Contact database with project history
  • Project Management: Budget tracking, material costs, and billing workflows
  • Accounting: Double-entry bookkeeping according to Swiss SME standards (KMU Kontenrahmen)
  • Reports: Balance sheet, income statement, and tax exports
  • Multi-tenancy: Isolated workspaces with team invitations
  • Role-based Access: Employee, Accountant, and Administrator roles
  • Billing Plans: Starter, Professional, and Enterprise tiers with Stripe integration
  • Branding: Custom logo and primary color per tenant
  • Notifications: In-app notification system with real-time updates
  • In-app Help: AI chatbot powered by RAG documentation search
  • Mobile UX: Responsive design optimized for 360px+ screens
  • Localization: German and English documentation

Sicherheit

  • Email verification for new accounts
  • Two-factor authentication (TOTP)
  • Session management with sign-out-all capability
  • Rate limiting on sensitive endpoints

Das ist der Anfang. Mehr Updates folgen bald!