# Audit log and document integrity (GeBüV compliance)

> From the Zendrea manual for AI assistants, generated 2026-10-31 from the knowledge of Zendrea's built-in assistant. All topics: https://www.zendrea.ch/llms.txt; all of them in one file: https://www.zendrea.ch/llms-full.txt. Screen names are quoted in English, account numbers are those of the standard Swiss chart, and nothing here is tax or legal advice.

The app implements GeBüV-defensible traceability in two independent layers, both shipping in the current build.

**Change log on journal entries:** every create, update (rebook), and delete on a journal entry is recorded in an audit table inside the same transaction as the mutation, so the audit row can never diverge from the data it describes. Each row captures timestamp, user id (resolved automatically from the active session), action, and before/after snapshots as JSON — the snapshot includes the entry header, all lines, and the attached receipt if any. Attaching or replacing a receipt on an already-booked entry is logged the same way (the Details column shows the filename and the first digits of its SHA-256, old → new). Fiscal-period close and reopen toggles are logged as dedicated actions, so reopen→edit→reclose cycles are fully reconstructable from the log.

**Receipt content hash:** every uploaded receipt has its SHA-256 and byte size computed at upload time and stored on the receipts row. The SAF-T export is a ZIP holding the audit file (XML) and a receipts list (CSV): one row per receipt with its booking's TransactionID and Belegnummer, the file name, where it is stored, its SHA-256 and size — an auditor with the SAF-T export plus the receipt files can verify every file's integrity independently of the database.

**Where it surfaces:** the audit log exports as Excel-friendly CSV (UTF-8 with BOM, semicolon-delimited) via Settings → Export Data → Audit log (4th radio). Receipt hashes appear in the receipts list inside the SAF-T export of the same panel.

**Not yet logged** (be honest if asked): receipt-metadata edits (OCR re-runs, manual creditor/IBAN corrections), chart-of-accounts edits, VAT-code changes, company-settings changes. Today's scope matches what Bexio, CashCtrl, and Banana Plus cover.

**Common questions:**
- "Is this app GeBüV-konform?" → Yes — full audit trail on journal entries, SHA-256 hash on every uploaded receipt, period toggles logged. Hand the auditor the audit-log CSV plus the SAF-T export.
- "Where is the change log?" → Settings → Export Data → Audit log CSV.
- "How do I prove a receipt wasn't swapped?" → Each receipt carries a SHA-256 stored at upload time and listed in the receipts list of the SAF-T export. Re-hash the file and compare.
- "Can I correct a booking that is already paid?" → Yes, but only its descriptive half. The pencil on a settled row opens a restricted correction: everything the settlement is sized against (amount, accounts, VAT, entry date, paid-from) is locked, while the descriptive fields stay editable — for expenses and asset purchases that is description, Belegnummer, due date and receipt; for manual entries and credit notes description, Belegnummer and receipt; for salaries the description only (the SAL- number is a system link token). The correction is logged as a normal update with before/after, and it never re-books the entry — the payment, the credit-note allocations, the amortization schedule and the FX snapshot are untouched; on an asset purchase the register description follows automatically, so the amortization labels stay in step. To change an amount or an account you still have to undo the payment first. Customer INVOICES work differently but reach the same guarantee: editing a booked invoice always re-books it, and if it is paid, an edit that leaves the money side unchanged (description, revenue account, invoice number, due date) keeps the recorded payment, while an amount/client/currency/date change asks for explicit confirmation before the payment is removed — never silently.
- "Can I delete a posted booking?" → Yes, but the deletion is logged with the full before-state in the audit log. Use a reversal entry in closed periods if you prefer not to mutate history directly.
- "I deleted a bill but its payment is still there" → That can no longer happen. A booking that something else depends on — the cash that settled it, or the disposal that wrote an asset off — cannot be deleted on its own. The delete confirmation lists every dependent entry with its document number, date, period and amount, and removes them together once confirmed. Entries booked BEFORE this guard shipped may still have a stranded payment: look for a lone debit on the payable (a liability account carrying a debit balance is the tell) and delete that payment from its own period's Ledger.
- "Why can't I delete this entry?" → A dependent entry sits in a **closed** fiscal period. Deleting across a closed year has to be deliberate: reopen the period in Settings → Manage fiscal periods, delete, then close it again. Both toggles are recorded in the audit log, so the reopen→delete→reclose cycle stays reconstructable.
