Kanzlei Software Architecture — Orcha × Claude × DATEV
Date: 2026-04-03
Status: Draft spec
1. System Overview
flowchart TB
subgraph Users["Kanzlei Staff"]
STB["👤 Steuerberater"]
SFA["👤 Steuerfachangestellte"]
BH["👤 Buchhalter"]
end
subgraph KanzleiApp["Kanzlei App (new front-end)"]
MATRIX["Matrix View\nMandant × Topic"]
INBOX["AI Inbox\nPending Reviews"]
CHAT["Claude Chat\n(per mandate context)"]
end
subgraph Orcha["Orcha (Data + Orchestration)"]
API["REST API + MCP Server"]
SCHED["Scheduler\n(cron jobs)"]
DB[(PostgreSQL)]
PIPE["Ingestion\nPipeline"]
TRIAGE["Email\nTriage"]
end
subgraph Claude["Claude (Intelligence Layer)"]
CLAUDE_API["Anthropic API\n(called by Orcha)"]
CLAUDE_MCP["Claude Desktop/Web\n(calls Orcha MCP)"]
end
subgraph DATEV["DATEV"]
DUO["Unternehmen Online"]
REWE["Kanzlei-\nRechnungswesen"]
LODAS["LODAS / L&G"]
ELSTER_D["→ ELSTER"]
end
STB & SFA & BH --> KanzleiApp
STB --> CLAUDE_MCP
KanzleiApp --> API
CLAUDE_MCP -->|"MCP read/write\n(pending review)"| API
SCHED -->|"generate briefing,\ndraft replies"| CLAUDE_API
SCHED -->|"DATEV sync,\ndeadline check"| DB
CLAUDE_API -->|"analysis result"| DB
PIPE --> DB
TRIAGE --> PIPE
TRIAGE -->|"client questions"| CLAUDE_API
API -->|"booking proposals\nvia Maesn"| DUO
DUO --> REWE
REWE -->|"journal entries,\nBWA, bank txns"| API
LODAS --> ELSTER_D
REWE --> ELSTER_D
style Orcha fill:#e8f5e9,stroke:#2e7d32
style Claude fill:#e3f2fd,stroke:#1565c0
style DATEV fill:#fff3e0,stroke:#e65100
style KanzleiApp fill:#f3e5f5,stroke:#7b1fa2
2. Two Directions of Claude Integration
flowchart LR
subgraph Direction1["Direction A: Orcha calls Claude"]
O1[Orcha Scheduler] -->|"POST /messages\n(Anthropic API)"| C1[Claude API]
C1 -->|"structured response"| O1
O1 -->|"store result"| DB1[(Orcha DB)]
end
subgraph Direction2["Direction B: Claude calls Orcha"]
H[Human in Claude] -->|"natural language"| C2[Claude]
C2 -->|"MCP tool call\norcha-tasks-create"| O2[Orcha MCP Server]
O2 -->|"→ pending_review queue"| DB2[(Orcha DB)]
end
|
A: Orcha → Claude API |
B: Claude → Orcha MCP |
| Trigger |
Scheduled job or pipeline event |
Human conversation |
| Who initiates |
Orcha backend |
Claude (on behalf of human) |
| Use cases |
Morning briefing, draft replies, Bescheid analysis, BWA commentary |
"Show me Müller's open items", "Create a task for Weber's UStVA" |
| Write behavior |
Direct write (Orcha is the caller, trusts itself) |
Pending review (queued for human confirmation) |
| Auth |
API key (server-to-server) |
OAuth + MCP scopes |
3. Matrix Navigation: Mandant × Topic
The core UI concept — a two-axis matrix where every cell is a (Mandant, Topic) pair.
flowchart TB
subgraph Nav["Navigation"]
ALL["🏠 Dashboard\n(all mandates, all topics)"]
ALL -->|"click Mandant"| MAND["📋 Mandant View\nMüller GmbH"]
ALL -->|"click Topic"| TOPIC["📂 Topic View\nLohn"]
MAND -->|"click Topic"| CELL["🔍 Cell View\nMüller × Lohn"]
TOPIC -->|"click Mandant"| CELL
end
3a. Dashboard (all × all)
┌──────────────────────────────────────────────────────────────────────┐
│ 🏠 Dashboard Frau Schmidt ▼ │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ 🔴 3 urgent 🟡 12 today 🟢 28 this week ✅ 47 AI completed │
│ │
│ ┌─────────────┬────────┬──────┬────────┬──────────┬────────┬──────┐│
│ │ Mandant │ FiBu │ Lohn │ JA │ StErkl │ Berat. │Compl.││
│ ├─────────────┼────────┼──────┼────────┼──────────┼────────┼──────┤│
│ │ Müller GmbH │ 🟡 3 │ ✅ │ 🔴 1 │ 🟢 2 │ — │ ✅ ││
│ │ Weber KG │ ✅ │ 🟡 1 │ — │ 🔴 1 │ 🟡 1 │ ✅ ││
│ │ Fischer e.K.│ 🟡 5 │ ✅ │ — │ — │ — │ — ││
│ │ Schulz GmbH │ ✅ │ ✅ │ 🟢 1 │ 🟢 1 │ — │ ✅ ││
│ │ ... │ │ │ │ │ │ ││
│ └─────────────┴────────┴──────┴────────┴──────────┴────────┴──────┘│
│ │
│ 📬 AI Inbox (5 pending reviews) │
│ ├─ Draft reply to Müller re: Steuerbescheid — [Approve] [Edit] │
│ ├─ UStVA Entwurf Weber KG — [Review in DATEV] [Reject] │
│ └─ 3 more... │
│ │
└──────────────────────────────────────────────────────────────────────┘
3b. Mandant View (one client × all topics)
┌──────────────────────────────────────────────────────────────────────┐
│ 📋 Müller GmbH Frau Schmidt ▼ │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ [FiBu] [Lohn] [Jahresabschluss] [Steuererklärungen] [Beratung] │
│ [Compliance] │
│ │
│ ── FiBu ──────────────────────────────────────────── 🟡 3 open ── │
│ │ 📄 12 neue Belege — Kontierung vorgeschlagen [Review] │ │
│ │ 🔄 UStVA März — Daten vollständig [Prüfen] │ │
│ │ 📊 BWA Feb — Claude-Analyse verfügbar [Lesen] │ │
│ │
│ ── Lohn ──────────────────────────────────────────── ✅ done ──── │
│ │ ✅ Lohnabrechnung März — in DATEV LODAS übermittelt │ ��
│ │
│ ── Jahresabschluss ───────────────────────────────── 🔴 1 open ── │
│ │ ⚠️ Rückstellungen fehlen — Claude-Vorschlag verfügbar [Prüfen]│ │
│ │
│ ── Steuererklärungen ─────────────────────────────── 🟢 2 open ── │
│ │ 📋 KSt 2025 — Datenpaket 80% komplett [Details] │ │
│ │ 📋 GewSt 2025 — Datenpaket 60% komplett [Details] │ │
│ │
│ 💬 Ask Claude about Müller GmbH... [Chat →] │
│ │
└──────────────────────────────────────────────────────────────────────┘
3c. Topic View (all clients × one topic)
┌──────────────────────────────────────────────────────────────────────┐
│ 📂 Lohn — All Mandanten Frau Schmidt ▼ │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ Filter: [Alle ▼] [März 2026 ▼] [Status: Offen ▼] │
│ │
│ ┌─────────────┬────────────┬──────────┬───────────┬───────────────┐│
│ │ Mandant │ Status │ Frist │ Nächster │ Aktion ││
│ │ │ │ │ Schritt │ ││
│ ├─────────────┼────────────┼──────────┼───────────┼───────────────┤│
│ │ Müller GmbH │ ✅ Done │ 01.04. │ — │ — ││
│ │ Weber KG │ 🟡 Data │ 05.04. │ Bewegungs-│ [DATEV →] ││
│ │ │ received │ │ daten │ ││
│ │ Fischer e.K.│ ✅ Done │ 01.04. │ — │ — ││
│ │ Schulz GmbH │ ✅ Done │ 01.04. │ — │ — ││
│ │ Becker OHG │ 🔴 Missing │ 05.04. │ Stundenauf│ [Mahnen →] ││
│ │ │ data │ │ stellung │ ││
│ └─────────────┴────────────┴──────────┴───────────┴───────────────┘│
│ │
│ 📊 Lohn Summary: 18/22 done | 3 pending | 1 overdue │
│ │
└──────────────────────────────────────────────────────────────────────┘
3d. Cell View (one client × one topic)
┌──────────────────────────────────────────────────────────────────────┐
│ 🔍 Müller GmbH → Lohn Frau Schmidt ▼ ��
│ ← Müller GmbH | ← Lohn (alle Mandanten) │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ Status: ✅ Done for März 2026 │
│ │
│ ── Aufgaben ───────────────────────────────────────────────────── │
│ │ ✅ Bewegungsdaten erfasst 02.04.2026 │ │
│ │ ✅ Lohnabrechnung in DATEV LODAS 02.04.2026 │ │
│ │ ✅ SV-Meldungen übermittelt 02.04.2026 │ │
│ │ ✅ Lohnsteueranmeldung via ELSTER 03.04.2026 │ │
│ │
│ ── Dokumente ──────────────────────────────────────────────────── │
│ │ 📄 Stundenaufstellung_März.pdf [Ansehen] │ │
│ │ 📄 Krankmeldung_Meier.pdf [Ansehen] │ │
│ │
│ ── Historie ───────────────────────────────────────────────────── │
│ │ Feb 2026: ✅ | Jan 2026: ✅ | Dez 2025: ✅ │ │
│ │
│ 💬 Ask Claude about Müller × Lohn... [Chat →] │
│ │
└──────────────────────────────────────────────────────────────────────┘
4. Data Model Extension
New entities needed on top of existing Orcha schema:
erDiagram
tenant ||--o{ legal_entity : has
legal_entity ||--o{ mandate_topic : has
mandate_topic ||--o{ task : contains
task ||--o{ ai_action : generates
mandate_topic {
uuid id PK
uuid legal_entity_id FK
text topic_key "fibu|lohn|ja|sterkl|beratung|compliance"
text status "on-track|attention|overdue|done"
jsonb config "topic-specific settings"
}
task {
uuid id PK
uuid mandate_topic_id FK
uuid assignee_id FK "→ identity"
text title
text description
text status "open|in-progress|pending-review|done|rejected"
text priority "urgent|today|this-week|backlog"
text source "system|human|ai"
boolean ai_completable "can Claude do this?"
timestamp due_date
timestamp completed_at
jsonb context "mandate-specific data snapshot"
}
ai_action {
uuid id PK
uuid task_id FK "optional"
uuid legal_entity_id FK
text action_type "draft-reply|briefing|analysis|kontierung|bescheid-check"
text status "pending-review|approved|rejected|expired"
uuid created_by "system or claude-session"
jsonb input "what Claude received"
jsonb output "what Claude produced"
text review_note "human feedback on approve/reject"
timestamp reviewed_at
uuid reviewed_by FK "→ identity"
}
employee_briefing {
uuid id PK
uuid identity_id FK
date briefing_date
jsonb content "structured briefing data"
text narrative "Claude-generated text"
timestamp generated_at
}
inbox_item {
uuid id PK
uuid legal_entity_id FK
text channel "email|datev-duo|portal|finanzamt"
text classification "invoice|steuerbescheid|client-question|finanzamt-letter|unknown"
text status "triaged|processing|needs-human|resolved"
jsonb raw_data "original message/document reference"
uuid routed_to_task FK "→ task (if created)"
uuid routed_to_ai_action FK "→ ai_action (if draft created)"
}
datev_sync {
uuid id PK
uuid legal_entity_id FK
text sync_type "rewe-journal|rewe-bwa|rewe-opos|rewe-bank"
timestamp last_sync_at
jsonb last_result "summary of what was synced"
text status "active|paused|error"
}
datev_sync ||--o{ datev_journal_entry : pulls
datev_sync ||--o{ datev_bwa_row : pulls
datev_sync ||--o{ datev_opos_item : pulls
datev_sync ||--o{ datev_bank_txn : pulls
datev_journal_entry {
uuid id PK
uuid legal_entity_id FK
date booking_date
text account_number "Sachkonto"
text contra_account "Gegenkonto"
decimal amount
text tax_key "USt-Schlüssel"
text cost_center
text booking_text
text document_ref "Belegnummer"
}
datev_bwa_row {
uuid id PK
uuid legal_entity_id FK
text period "2026-03"
text row_key "BWA Zeile (Umsatzerlöse, Materialaufwand, etc.)"
decimal amount
decimal prior_year_amount
}
datev_opos_item {
uuid id PK
uuid legal_entity_id FK
text account_type "debitor|kreditor"
text account_number
text partner_name
text invoice_ref
date invoice_date
date due_date
decimal open_amount
decimal original_amount
}
datev_bank_txn {
uuid id PK
uuid legal_entity_id FK
text bank_account
date value_date
decimal amount
text purpose "Verwendungszweck"
text counterparty
text counterparty_iban
uuid matched_document_id FK "→ document (if reconciled)"
}
5. Scheduled Jobs — Who Runs What
flowchart TB
subgraph OrchaJobs["Orcha Scheduler (cron)"]
direction TB
J1["⏰ 06:00 DATEV REWE Sync\nPull journal entries, BWA, OPOS, bank"]
J2["⏰ 07:00 Deadline Scanner\nCheck all mandates for approaching Fristen"]
J3["⏰ 07:30 Morning Briefing\nQuery DB → call Claude API → store"]
J4["⏰ continuous Email Triage\nMonitor inbox → classify → route"]
J5["⏰ continuous Ingestion Pipeline\nOCR → extract → kontieren → DATEV export"]
J6["⏰ 22:00 Closing Status Update\nRecalculate mandate_topic statuses"]
end
subgraph ClaudeCalls["Claude API Calls (from Orcha)"]
direction TB
C1["📝 Briefing narrative generation"]
C2["✉️ Draft reply composition"]
C3["📊 BWA analysis & commentary"]
C4["📋 Bescheid comparison"]
C5["📑 Rückstellungen suggestions"]
C6["🔍 Inbox classification\n(complex items)"]
end
J3 -->|"sends data, gets narrative"| C1
J4 -->|"client question detected"| C2
J1 -->|"new BWA data available"| C3
J4 -->|"Steuerbescheid detected"| C4
J6 -->|"JA closing incomplete"| C5
J4 -->|"unknown item"| C6
style OrchaJobs fill:#e8f5e9,stroke:#2e7d32
style ClaudeCalls fill:#e3f2fd,stroke:#1565c0
Job Summary
| Job |
Runner |
Schedule |
Calls Claude? |
Writes to |
| DATEV REWE Sync |
Orcha |
Daily 06:00 |
No |
datev_sync, booking data |
| Deadline Scanner |
Orcha |
Daily 07:00 |
No |
task (creates urgent tasks) |
| Morning Briefing |
Orcha → Claude |
Daily 07:30 |
Yes (narrative) |
employee_briefing |
| Email Triage |
Orcha → Claude |
Continuous |
Yes (classification + drafts) |
inbox_item, ai_action |
| Ingestion Pipeline |
Orcha → Claude |
Continuous |
Yes (extraction) |
document, ingestion |
| Closing Status |
Orcha |
Daily 22:00 |
No |
mandate_topic |
| BWA Commentary |
Orcha → Claude |
After REWE sync |
Yes (analysis) |
ai_action |
| Bescheid Check |
Orcha → Claude |
On inbox detection |
Yes (comparison) |
ai_action, task |
Current tools (read-only) plus new write tools:
flowchart LR
subgraph Existing["Existing MCP Tools (read)"]
R1[orcha-docs-get]
R2[orcha-docs-list]
R3[orcha-docs-search]
R4[orcha-docs-line-items]
R5[orcha-data-master-data]
R6[orcha-master-data-legal-entities]
R7[orcha-fpna-data-map]
R8[orcha-fpna-excel]
end
subgraph NewRead["New MCP Tools (read)"]
NR1[orcha-tasks-list\nby mandate/topic/assignee/status]
NR2[orcha-tasks-get\nfull task with context]
NR3[orcha-mandate-status\nmatrix overview for one mandate]
NR4[orcha-topic-status\none topic across all mandates]
NR5[orcha-briefing-get\ntoday's briefing for employee]
NR6[orcha-deadlines-upcoming\nnext N days across mandates]
NR7[orcha-datev-bwa\nBWA data for mandate+period]
NR8[orcha-datev-opos\nopen items from DATEV]
NR9[orcha-inbox-list\nrecent inbox items+status]
end
subgraph NewWrite["New MCP Tools (write → pending review)"]
NW1["orcha-tasks-create\n→ pending review"]
NW2["orcha-tasks-update\n→ pending review"]
NW3["orcha-ai-draft-reply\n→ pending review"]
NW4["orcha-ai-analysis-save\n→ pending review"]
end
style Existing fill:#e8f5e9
style NewRead fill:#e3f2fd
style NewWrite fill:#fff3e0
MCP Scopes
| Scope |
Tools |
Description |
docs:read |
existing doc tools |
Query documents |
master-data:read |
existing master data tools |
GL accounts, cost centers, vendors |
fpna:read / fpna:write |
existing FP&A tools |
Financial planning data |
tasks:read |
tasks-list, tasks-get |
Query tasks |
tasks:write |
tasks-create, tasks-update |
Create/update tasks (→ pending review) |
mandate:read |
mandate-status, topic-status, deadlines |
Matrix overview queries |
datev:read |
datev-bwa, datev-opos |
DATEV synced data |
inbox:read |
inbox-list |
Inbox items |
ai:write |
ai-draft-reply, ai-analysis-save |
Save AI outputs (→ pending review) |
7. DATEV Integration Points
flowchart LR
subgraph Orcha
MAESN[Maesn API Client]
SYNC[DATEV Sync Worker]
DB[(Orcha DB)]
end
subgraph DATEV
DUO[Unternehmen Online]
REWE[Kanzlei-Rechnungswesen]
BANK[Bank online]
end
MAESN -->|"① Push booking proposals\n(Rechnungseingang)"| DUO
DUO -->|"Steuerberater books"| REWE
REWE -->|"② Pull journal entries\n(Buchungsstapel)"| SYNC
REWE -->|"③ Pull BWA\n(Auswertungen)"| SYNC
REWE -->|"④ Pull OPOS\n(offene Posten)"| SYNC
BANK -->|"⑤ Pull bank transactions\n(Kontoauszüge)"| SYNC
SYNC --> DB
style Orcha fill:#e8f5e9
style DATEV fill:#fff3e0
| # |
Direction |
Data |
Frequency |
API |
| ① |
Orcha → DATEV |
Booking proposals (Sachkonto, KST, Betrag, USt) |
Per ingestion |
Maesn Rechnungsdatenservice |
| ② |
DATEV → Orcha |
Journal entries (what was actually booked) |
Daily 06:00 |
Maesn Buchungsstapel API |
| ③ |
DATEV → Orcha |
BWA (monthly management report) |
Daily 06:00 |
Maesn Auswertungen API |
| ④ |
DATEV → Orcha |
Open items (unpaid invoices) |
Daily 06:00 |
Maesn OPOS API |
| ⑤ |
DATEV → Orcha |
Bank transactions |
Daily 06:00 |
Maesn Bankdaten API |
8. Full Data Flow — End to End
sequenceDiagram
participant Email as 📧 Email
participant Triage as Orcha Triage
participant Claude as Claude API
participant DB as Orcha DB
participant UI as Kanzlei App
participant DATEV as DATEV
participant Human as 👤 Employee
Note over Email,Human: === Invoice arrives ===
Email->>Triage: New email
Triage->>Claude: Classify (invoice/question/Bescheid?)
Claude-->>Triage: "invoice"
Triage->>DB: Create inbox_item(classification=invoice)
Triage->>DB: Trigger ingestion pipeline
Note over DB: OCR → Extract → Kontierung → Validate
DB->>DATEV: Push booking proposal via Maesn
DB->>DB: Create task(mandate=Müller, topic=fibu, title="Neue Rechnung prüfen")
UI-->>Human: Task appears in matrix
Note over Email,Human: === Client question arrives ===
Email->>Triage: "Wann ist meine ESt fällig?"
Triage->>Claude: Classify → "client-question"
Triage->>DB: Create inbox_item
Triage->>Claude: Draft reply (with Fristenkalender context)
Claude-->>DB: Save ai_action(type=draft-reply, status=pending-review)
UI-->>Human: Draft appears in AI Inbox
Human->>UI: [Approve] or [Edit & Send]
Note over Email,Human: === Morning briefing ===
DB->>DB: Scheduler triggers at 07:30
DB->>DB: Query tasks, deadlines, new items for Schmidt
DB->>Claude: Generate narrative briefing
Claude-->>DB: Save employee_briefing
UI-->>Human: Briefing on dashboard + email
Note over Email,Human: === DATEV sync ===
DB->>DATEV: Pull journal entries, BWA, OPOS (06:00)
DATEV-->>DB: Store in datev_sync tables
DB->>Claude: Analyze BWA changes
Claude-->>DB: Save ai_action(type=analysis, status=pending-review)
UI-->>Human: "BWA-Analyse für Müller verfügbar" in matrix
9. Technology Decisions
| Component |
Technology |
Rationale |
| Kanzlei App frontend |
Hiccup + HTMX |
Consistent with existing Orcha admin; server-rendered, fast, no JS framework needed |
| Kanzlei App server |
Clojure (same monolith) |
New routes in existing app, shared DB access |
| Claude integration (backend) |
Anthropic API (direct) |
Orcha already has workers/llm.clj for Claude calls |
| Claude integration (interactive) |
MCP over HTTP |
Already implemented in link/mcp/ |
| DATEV sync |
Maesn REST API |
Already integrated for outbound; extend for inbound |
| Scheduler |
Clojure scheduled tasks |
Simple cron-like jobs in the existing system |
| Database |
PostgreSQL (existing) |
Add new tables to existing schema |
| Real-time updates |
HTMX SSE / polling |
Existing notification pattern |