Buchhaltung

Client-scoped bookkeeping module with invoice lists, categorized entries, and VAT-oriented reports per month, quarter, and year.

What it does

accounting is the Buchhaltung module: a client-scoped (Mandant) bookkeeping overview for month, quarter, and year periods. It lists invoice-like rows and all bookings, groups them by category and report group, and produces a VAT-oriented report (output VAT, input VAT, payable/refund) per client and period. Amounts are EUR, stored in cents, with German-locale formatting.

Buchhaltung is a bookkeeping overview and preparation surface — it is not tax advice (the module API returns a legal_notice with every bootstrap payload).

How to open / enable it

  • Web: /modules/accounting. The UI title is Buchhaltung (i18n key accounting.title; badge "AI Finance Workspace").
  • Unlike most bundled modules there is no bundled-modules/accounting/ directory in the repo. The module is registered as a locally installed module: resolveLocalModuleBySlug("accounting") (src/lib/module-store/local-modules.ts) resolves it from the workspace modules directory (<workspace>/modules) or the managed modules directory, where its module.json (with renderer: "react") and api/handler.mjs live.
  • The repo ships the first-party parts: when a module entry with slug accounting and the React renderer resolves, src/app/(app)/modules/[slug]/page.tsx renders the built-in React UI src/components/modules/accounting-module.tsx instead of an iframe. The generic module API route (src/app/api/modules/[slug]/api/[...endpointPath]/route.ts) executes the installed module's api/handler.mjs; the module's schema migrations travel with that installed module directory rather than db/migrations/.
  • No special role is required beyond a normal authenticated session (no developer-mode or admin gate).

Key workflows

All tabs share a common header: Mandant selector, period kind (month / quarter / year), year, and month/quarter pickers, plus quick stats (client, period label, entry count), a refresh button, and actions to add income, add expense, and manage categories. All data is scoped to the selected Mandant.

Track invoices and bookings

  1. Invoices tab — table of invoice/credit-note entries: direction badge (income/expense), booking date, invoice number, description + counterparty, category, and net/VAT/gross amounts. Click a row to edit.
  2. Entries tab — all bookings with entry kind (invoice, credit_note, expense, income, adjustment, payment), direction, date, description, counterparty, VAT code (rate + side), net and gross amounts, and per-row edit/delete actions.

Record an entry

  1. Use Add income / Add expense (or edit an existing row) to open the entry dialog.
  2. Fill description, counterparty, direction, entry kind, booking date, invoice number, invoice date, due date, VAT code/side/rate, category, an optional linked document, net/VAT/gross amounts, and notes.
  3. Save; the tables and report refresh for the selected period.

Manage categories

The Categories tab has two panels: a split view showing income/expense/balance net per category grouped by report group (revenue, operating, tax, asset, liability, equity, other), and a manage view for creating/editing categories (name, machine key, direction scope income/expense/both, report group, color, sort order). System categories are editable but marked with a badge.

Review VAT

The Tax Report tab summarizes output VAT, input VAT, and payable VAT/refund, taxable income/expense net amounts, and a per-VAT-code breakdown table (vat_code, vat_side, rate, net, VAT, gross).

How the agent can drive it

Five accounting_* tools are exposed for chat, Live Voice, and the native runtime (definitions: services/clapilot-agent/src/tool-definitions.mjs; handlers: src/lib/agent-runtime/tool-proxy.ts; catalog family "Buchhaltung" in src/lib/agent-tool-catalog.ts):

ToolPurposeParameters
accounting_list_categorieslist categories
accounting_list_entrieslist entries for one client and periodmandant_id, period_kind (month/quarter/year), year (2000-2100), month (1-12), quarter (1-4), direction (income/expense), entry_kind, limit (1-1000)
accounting_generate_reportbookkeeping/VAT report for one client and periodmandant_id, period_kind, year, month, quarter
accounting_create_entrycreate one entryrequired: mandant_id, description, amount_net; optional: direction, entry_kind, booking_date, invoice_date, due_date, invoice_number, counterparty_name, category_id/category_key, document_id, vat_code, vat_side, vat_rate, amount_vat, amount_gross, notes
accounting_update_entryupdate one entryrequired: id; all create fields optional

Integration behavior:

  • The open module publishes page context (module: "accounting", mandant_id, period_kind, year, month/quarter, entry_count, active tab) so agents can act on the visible client and period.
  • A page capability with action rule exists in services/clapilot-agent/src/page-capabilities.mjs: inside the module, the agent must use accounting_generate_report for Monats-/Quartals-/Jahresauswertungen, the list tools for inspecting rows, and the create/update tools for recording or adjusting a booking instead of only describing steps.
  • Successful mutations trigger a module reload in the open UI (triggerReload with refresh topic module).
  • There is no accounting_delete_entry tool: deleting an entry is UI/module-API only (DELETE /entries/:id).
  • A CLI skill clapilot-cli-accounting (workspace-seed/skills/clapilot-cli-accounting/SKILL.md) mirrors the same five actions through the clapilot-cli binary for shell-based agent runs.

Module API reference

Base: /api/modules/accounting/api (executed by the installed module's api/handler.mjs)

RoutePurpose
`GET /bootstrap?mandant_id&period_kind&year&monthquarter`
GET /categorieslist categories
POST /categories, PATCH /categories/:idcreate/update a category
GET /entries?mandant_id&period_kind&year&month&quarter&direction&entry_kind&limitlist entries with period metadata
POST /entriescreate an entry (required: mandant_id, description, amount_net)
PATCH /entries/:idupdate an entry
DELETE /entries/:iddelete an entry
`GET /reports?mandant_id&period_kind&year&monthquarter`

Configuration & limits

  • Mandant scoping is mandatory: entries require a mandant_id, and lists/reports are filtered to the selected client; the UI shows no entries until a Mandant is selected.
  • Currency: EUR only; amounts are stored in cents (amount_net_cents, amount_vat_cents, amount_gross_cents) and formatted with the German locale. Money inputs accept digits, dots, and commas.
  • VAT codes (with default rate and side): de_standard (19%, output), de_reduced (7%, output), tax_free (0%), zero_rated (0%), reverse_charge (19%, both), intra_community (19%, both), small_business (0%). The VAT side auto-updates from the direction when the code changes.
  • Entry kinds: invoice, credit_note, expense, income, adjustment, payment; directions: income, expense; report groups: revenue, operating, tax, asset, liability, equity, other.
  • All user-facing labels are localized (German/English/Italian) under the accounting.* keys in src/lib/i18n.ts.

Troubleshooting

  • Module route 404s or shows no module: the accounting module directory (with module.json and api/handler.mjs) must be present in the workspace/managed modules directory; the repo alone does not register the slug.
  • Empty tables: select a Mandant and a period that contains bookings — everything is filtered by client and period.
  • Agent cannot delete an entry: expected; deletion exists only in the UI/module API, not as an agent tool.