Note (2026-04-24): After this document was written,
legal_entitywas renamed totenantand the oldtenantwas renamed toorganization. Read references to these terms with the pre-rename meaning.
Reorganize the codebase so that Accounts Payable (AP) logic is explicitly isolated into its own packages, preparing the architecture for Accounts Receivable (AR) to be introduced as a parallel vertical with its own pipeline, data sources, UI, and integrations.
Status: Implemented. The reorganization described here has been completed. See the ap-refactor branch for the implementation.
The codebase is currently organized by technical layer (workers/, app/, schema/, db/) rather than by business domain. AP logic is spread across these layers:
workers/ingestion/post_process/workers/acquisition/workers/matching/app/http/documents/accounts_payable.cljintegrations/Shared infrastructure (transcription, classification, extraction, auth, notifications) is already generic.
workers/, app/, schema/) remains the primary axis, with ap/ and ar/ as subdivisions within each.ap and ar, not accounts_payable and accounts_receivable.schema/) stay unsplit — no schema/ap/ or schema/ar/ until needed.workers/
ap/
ingestion/ ← current workers/ingestion/
orchestrator.clj
transcription.clj
classification.clj
extraction.clj
validation.clj
fraud.clj
post_process/
accounts.clj
cost_center.clj
supplier.clj
accruals.clj
tax_compliance.clj
financial_validation.clj
...
acquisition/ ← current workers/acquisition/
matching/ ← current workers/matching/
ar/
... ← future
AP list becomes a top-level route. Generic document management stays under /documents/.
app/http/
ap.clj ← current app/http/documents/accounts_payable.clj
ar.clj ← future
documents/
documents.clj ← route assembly (stays)
shared.clj ← shared helpers (stays)
upload.clj ← generic upload (stays)
management.clj ← contracts, POs, GRNs list (stays)
view.clj ← unified detail handler (stays)
view/
shared.clj ← layout, SSE (stays)
invoice.clj ← type-specific renderer (stays — it renders invoice detail, not AP logic)
contract.clj ← stays
purchase_order.clj ← stays
goods_received_note.clj ← stays
notice.clj ← stays
integrations/
ap/
datev.clj ← current DATEV/MAESN integration
ar/
... ← future (easybill.de, etc.)
db/, http/, oauth/, email/, logging/, util/, schema/ — shared infrastructureadmin/, link/ — orthogonal servicesapp/http/documents/view/invoice.clj — view renderer, not AP business logic/documents/accounts-payable/... → /ap/...
/documents/upload → /documents/upload (stays)
/documents/management/... → /documents/management/... (stays)
/documents/view/:id/... → /documents/view/:id/... (stays)
/ar/... → AR list, bulk ops, AR-specific actions
AP and AR become top-level nav items alongside Documents, Settings, etc.
ap_ prefix)| Current | Target |
|---|---|
doc_source |
ap_doc_source |
doc_source_email |
ap_doc_source_email |
doc_source_email_pending_sync |
ap_doc_source_email_pending_sync |
doc_source_email_processed_messages |
ap_doc_source_email_processed_messages |
doc_source_webhook |
ap_doc_source_webhook |
doc_source_ses |
ap_doc_source_ses |
doc_source_ses_processed |
ap_doc_source_ses_processed |
ingestion |
ap_ingestion |
ingestion_post_process_stat |
ap_ingestion_post_process_stat |
document_cluster |
ap_document_cluster |
document_match |
ap_document_match |
datev_export_audit |
ap_datev_export_audit |
supplier_verification |
ap_supplier_verification |
supplier_verification_document |
ap_supplier_verification_document |
acquisition_llm_stat |
ap_acquisition_llm_stat |
qa_dataset_item |
ap_qa_dataset_item |
| Table | Reason |
|---|---|
tenant, legal_entity, legal_entity_* |
Org structure |
identity, tenant_membership |
Auth |
document |
Shared — gets domain column ('ap' / 'ar') |
gl_accounts_dataset |
Chart of accounts, used by both AP and AR |
cost_center_dataset |
Shared master data |
business_partner_dataset |
Has both Kreditoren (AP) and Debitoren (AR) |
booking_history_upload |
Shared — gets domain column when AR arrives |
booking_history_item |
Shared — inherits domain from upload |
notification_* |
Shared notification system |
api_key, api_request_log |
Shared API infrastructure |
oauth_*, http_session |
Auth infrastructure |
fpna_data_map |
Shared FP&A |
document Table ChangeAdd a domain column:
text NOT NULL DEFAULT 'ap''ap', 'ar'Worker orchestrators get namespaced under domain:
;; Current
:com.getorcha.workers.ingestion/orchestrator
:com.getorcha.workers.acquisition/orchestrator
:com.getorcha.workers.matching.worker/orchestrator
;; Target
:com.getorcha.workers.ap.ingestion/orchestrator
:com.getorcha.workers.ap.acquisition/orchestrator
:com.getorcha.workers.ap.matching/orchestrator
;; Future
:com.getorcha.workers.ar.ingestion/orchestrator
schema/ap/, schema/ar/) — only when AR schemas diverge enough