Accounting classification architecture
Glossary
| Term | Meaning |
|---|---|
| Chart of accounts (COA) | ledger_accounts — master GL codes for the organization |
| Voucher | expense_vouchers — imported purchase document (AP-style) with lines before or at GL posting |
| Journal entry | accounting_journal_entries — official double-entry GL record (draft or posted) |
Vouchers and journals are not the same layer. Vouchers are the import/work queue; journals are the ledger.
Pipeline
Voucher status (computed)
| Status | Rule |
|---|---|
| posted | journal_entry_id is set |
| unmapped | Any line has gl_code without ledger_account_id |
| unbalanced | Sum debits ≠ sum credits (tolerance 0.02) |
| ready | Mapped, balanced, not posted, ≥2 lines with amounts |
Default Inbox excludes posted vouchers. Historical Dynacom GLDet imports must set journal_entry_id at import time.
UI surfaces (no duplication)
| Surface | Scope |
|---|---|
| Accounting → Chart of accounts | COA CRUD only |
| Accounting → Purchases → Inbox | Work queue: unmapped / unbalanced / ready |
| Accounting → Purchases → Suppliers / All expenses | Browse with status visibility |
| Accounting → General ledger | Posted journals + manual drafts |
Do not add COA or duplicate journal lists under Purchases.
API ownership
Canonical REST: kulanz-backend /api/v1/organizations/{slug}/…
Web dashboard and iOS call the backend API directly (Bearer JWT). kulanz-online has no domain BFF for classification, vouchers, or journals — use createOrgApi from src/lib/org-api.ts.
Expense voucher export (CSV/XLSX/PDF) remains a kulanz-online /api/organizations/.../expense-vouchers/export route until migrated.
See ios-v1.md for mobile contracts.
Import order (Dynacom migration)
pnpm ledger:import-coa
pnpm dynacom:import-customers
pnpm dynacom:import-invoices
pnpm dynacom:import-payments
pnpm dynacom:import-purchases
pnpm dynacom:import-gl-posted
pnpm dynacom:verify-gl-import
CSV (expenses:import-2025) remains for ad-hoc files; SQLite + GLDet is canonical for bulk migration.