Implementierungsplan: Nebenbuch-Features in Busflow
Integration der Nebenbuch-Architektur (GoBD-Compliance, Steuer-Engine, DATEV-Anbindung) in das bestehende Busflow-Monorepo.
IMPORTANT
Entschiedene Vorgaben:
- Alle Schema-Änderungen via Hasura Migrations (
apps/hasura/migrations/), nichtdocker/initdb.d/ change_eventspro Domain-Schema mit polymorphementity_type+entity_idPattern (kein zentralesaudit-Schema) — siehe ADR-019- NestJS
AuditTrailServiceals shared Service für alle Domain-Module (zentraleold_values-Erfassung viaSELECT ... FOR UPDATE) - DATEV-Export: Dual-Format — XML online (Einzelbelege mit BelegLink) + CSV (Buchungsstapel)
- Reconciliation-Upload: CSV (mit flexiblem Parser) + XLSX
- Storno: Gegenläufiger Buchungsbeleg (Stornorechnung), keine Modifikation des Originaldokuments
- Tax Rate: Dynamisch per
TaxRule(Drittland-Ausnahme § 25 Abs. 2 UStG)
Übersicht der Phasen
| Phase | Scope | Deliverables |
|---|---|---|
| 1. Foundation | Schema-Docs (✅ Done), NestJS Service-Docs | Nur Dokumentation |
| 2. GoBD-Compliance | Hasura Migrations, NestJS Modules | Period Locks, Storno (Gegenbuchung), Audit Event Triggers |
| 3. Tax Engine | NestJS Domain Services, Valibot Schemas | § 25 UStG Business Logic (dynamisch) + Unit Tests |
| 4. DATEV Integration | Export Service, Reconciliation | Dual-Format (XML online + CSV), Reconciliation Upload |
Phase 1: Foundation (Dokumentation)
Schema-Docs sind abgeschlossen. Verbleibend: NestJS API Docs.
NestJS API Docs
[DONE] tax-engine.md
- § 25 UStG Logik, Data Flow, Module Structure, Domain Events
[NEW] apps/api/docs/period-lock.md
PeriodLockServiceSpezifikation: Lock-Erstellung, Validierung, automatischer Lock via DATEV-Export- Integration mit Hasura Actions für Pre-Mutation-Validierung
[DONE] apps/api/docs/storno-workflow.md
InvoiceCancellationService: Storno → Stornorechnung (Gegenbuchung) → optionale Neuausstellung- GoBD: Originaldokument bleibt unverändert, Period-Lock-Validierung als Guard
[DONE] apps/api/docs/datev-integration.md
- Dual-Format: XML online (Einzelbelege mit BelegLink) + CSV (Buchungsstapel)
- Reconciliation: CSV (flexibler Parser, SKR03/SKR04) + XLSX Upload, Diff-Berechnung
Phase 2: GoBD-Compliance (Migrations + NestJS Modules)
Hasura Migrations
[NEW] apps/hasura/migrations/<timestamp>_create_change_events/up.sql
- Alle vier
change_events-Tabellen verwenden das polymorphe Pattern per ADR-019:entity_type VARCHAR NOT NULL,entity_id UUID NOT NULL,correlation_id UUID NULLABLE backoffice.change_events— entity_types:operator,costing_sheet,tour_template,tour_departure,vehicle,supplier,allotment,crew_member,passenger_profile,reseller,notification_template,crew_qualification,crew_absence,vehicle_inspection,price_matrix,operator_integrationcommerce.change_events— entity_types:tour_offering,booking,payment,ticket,invoice,financial_ledger,tax_ledger_entry,ledger_period_lockoperations.change_events— entity_types:service_leg,leg_assignment,expense_receipt,onboard_sale,incident,issue_report,crew_duty_log,boarding_event(+client_event_id,device_id,sync_batch_idfür Offline-Sync)communications.change_events— entity_types:channel_account,contact,conversation- Scope enum (alle Schemas):
GOBD,COMPLIANCE,DSGVO,CONFIG,GENERAL - Index:
(tenant_id, entity_type, entity_id)+ partial(correlation_id) WHERE correlation_id IS NOT NULL
[NEW] apps/hasura/migrations/<timestamp>_create_commerce_compliance/up.sql
commerce.ledger_period_lockscommerce.invoice_cancellationscommerce.reconciliation_uploadscommerce.reconciliation_entries
NestJS Modules (Pro Domain — mit shared AuditTrailService per ADR-019)
Jedes Domain-Modul hat eigene Hasura Event Trigger Handler, die den shared
AuditTrailServicefürchange_events-Einträge verwenden.
Commerce Module
- [NEW]
apps/api/src/commerce/commerce.module.ts - [NEW]
apps/api/src/commerce/services/period-lock.service.ts - [NEW]
apps/api/src/commerce/services/invoice-cancellation.service.ts— erzeugt Stornorechnung (Gegenbuchung) - [NEW]
apps/api/src/commerce/handlers/invoice-audit.handler.ts— ET fürcommerce.invoices(scope: GOBD) - [NEW]
apps/api/src/commerce/handlers/ledger-audit.handler.ts— ET fürcommerce.financial_ledgers,commerce.tax_ledger_entries(scope: GOBD) - [NEW]
apps/api/src/commerce/handlers/booking-audit.handler.ts— ET fürcommerce.bookings,commerce.payments(scope: GENERAL) - [NEW]
apps/api/src/commerce/handlers/offering-audit.handler.ts— ET fürcommerce.tour_offerings/ price_matrix Änderungen (scope: GOBD)
Backoffice Module
- [NEW]
apps/api/src/backoffice/backoffice.module.ts - [NEW]
apps/api/src/backoffice/handlers/costing-sheet-audit.handler.ts— ET fürbackoffice.costing_sheets(scope: CONFIG) - [NEW]
apps/api/src/backoffice/handlers/config-audit.handler.ts— ET fürbackoffice.operators,backoffice.vehicles,backoffice.suppliers,backoffice.allotments,backoffice.resellers(scope: CONFIG) - [NEW]
apps/api/src/backoffice/handlers/passenger-audit.handler.ts— ET fürbackoffice.passenger_profiles(scope: DSGVO)
Operations Module
- [NEW]
apps/api/src/operations/operations.module.ts - [NEW]
apps/api/src/operations/handlers/expense-audit.handler.ts— ET füroperations.expense_receipts,operations.onboard_sales(scope: GOBD — steuerrelevant) - [NEW]
apps/api/src/operations/handlers/crew-duty-audit.handler.ts— ET füroperations.crew_duty_logs(scope: COMPLIANCE — EG 561/2006, BALM-prüfungssicher) - [NEW]
apps/api/src/operations/handlers/boarding-audit.handler.ts— ET füroperations.boarding_events(scope: GENERAL — Erstattungsstreitigkeiten)
[MODIFY] app.module.ts
CommerceModule,BackofficeModule,OperationsModuleimportieren
Phase 3: Tax Engine (§ 25 UStG Business Logic)
Shared Types (Valibot Schemas)
- [NEW]
apps/api/src/shared/tax/tax-strategy.enum.ts - [NEW]
apps/api/src/shared/tax/geography.enum.ts—EU | THIRD_COUNTRY - [NEW]
apps/api/src/shared/tax/schemas.ts— Valibot Schemas für CostComponent (incl.geography), TaxRule, MarginResult (incl. split)
[NEW] apps/api/src/shared/tax/margin-calculator.ts
- Reine Funktion:
calculateMarginTax(customerGross, procurementItems[]) → MarginResult - Geography-Split: Aufteilen in
margin_taxable_net(EU-Anteil) undmargin_exempt_net(Drittland-Anteil) gem. § 25 Abs. 2 - Negativmargen: Wenn
total_margin ≤ 0→margin_taxable_net = 0,tax_amount = 0. Kein Verlustvortrag. - Output enthält alle § 25 Abs. 5 Pflichtfelder:
customer_gross_amount,procurement_gross_amount,margin_taxable_net,margin_exempt_net,tax_base_amount,tax_amount,tax_rate
CAUTION
§ 25 Abs. 2 UStG — Drittland-Ausnahme: Steuerfreie Marge bei Vorleistungen im Drittland (Schweiz, UK). Der margin-calculator berechnet den Split anhand des CostComponent.geography-Felds. § 25 Abs. 4 UStG — Vorsteuerabzugsverbot: Kein VSt-Abzug für FREMD-Vorleistungen. Wird in Phase 4 (DATEV-Mapping) durchgesetzt.
[NEW] apps/api/src/shared/tax/vat-calculator.ts
- Reine Funktion:
calculateStandardVat(netSellingPrice, rate) → { taxBase, taxAmount, taxRate } - Default rate:
0.19(konfigurierbar für Sondersätze/Länder)
Backoffice Domain Service
- [NEW]
apps/api/src/backoffice/services/tax-resolver.service.ts— EIGEN/FREMD → TaxStrategy
Commerce Domain Service
- [NEW]
apps/api/src/commerce/services/tax-calculator.service.ts— Actuals → TaxLedgerEntry
Unit Tests
- [NEW]
apps/api/src/shared/tax/margin-calculator.spec.ts - [NEW]
apps/api/src/shared/tax/vat-calculator.spec.ts - [NEW]
apps/api/src/backoffice/services/tax-resolver.spec.ts
Phase 4: DATEV Integration (Dual-Format)
DATEV Export (Dual-Strategie)
- [NEW]
apps/api/src/commerce/services/datev-export.service.ts- Format 1 — DATEV XML online: Einzelbelege (Invoices als PDF, ExpenseReceipts mit
<BelegLink>zu Quittungsfotos) → "Zero-Touch Accounting" - Format 2 — DATEV-Format CSV: Aggregierte Buchungsstapel (Journal Entries) der Periode
- § 25 Abs. 4 Vorsteuerabzugsverbot: FREMD-Vorleistungen werden auf SKR 03: Konto 3220 ("Wareneingang Margenbesteuerung") ohne Vorsteuerabzug gemappt
- Validiert Period-Lock (muss gesperrt sein oder wird automatisch gesperrt)
- Format 1 — DATEV XML online: Einzelbelege (Invoices als PDF, ExpenseReceipts mit
- [NEW]
apps/api/src/commerce/services/datev-export.spec.ts
Reconciliation Upload
- [NEW]
apps/api/src/commerce/services/reconciliation.service.ts- Akzeptiert: CSV (flexibler Parser, konfigurierbare Delimiter, SKR03/SKR04-kompatibel) + XLSX
- Parst BWA/SuSa, erstellt
reconciliation_uploads+reconciliation_entries - Diff-Berechnung:
busflow_amountvs.datev_amount
- [NEW]
apps/api/src/commerce/services/reconciliation.spec.ts
Verification Plan
Unit Tests
bash
cd apps/api && pnpm testHasura Migrations
bash
cd apps/hasura && pnpm run migrate:apply
cd apps/hasura && pnpm run migrate:statusNestJS Build
bash
cd apps/api && pnpm build