AP/AR Domain Isolation Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Isolate AP-specific code into ap/ sub-packages and rename AP database tables with ap_ prefix, preparing the codebase for AR introduction.

Architecture: Two-phase refactoring: (A) database table renames with code reference updates, (B) namespace reorganization moving AP worker, HTTP, and integration files under ap/ sub-packages. Each phase is an independent branch/PR.

Tech Stack: Clojure, PostgreSQL, HoneySQL, Malli, Integrant

Design doc: docs/plans/2026-03-13-ap-ar-isolation-design.md


Important: Rename Mechanics

Table renames affect code in two forms:

  1. HoneySQL keywords:doc-source in :from, :join, :insert-into (HoneySQL auto-converts kebab→snake)
  2. Qualified result keys:doc-source/id, {:doc-source/keys [...]} (produced by as-kebab-maps row builder from table name)

Both forms derive from the table name, so renaming doc_sourceap_doc_source means:

Malli schemas in schema/ that use table-derived key namespaces (e.g., :ingestion/id in schema/ingestion.clj) must also be updated to match the new table names.

Migration files (init.sql, squashed migrations) are historical — never edit them. Only create new migrations.

Documentation files (.md) should be updated where they reference table names, but only if the reference is prescriptive (e.g., code examples, query patterns). Descriptive historical references can stay.


Phase A: Database Table Renames

Task 1: Write the database migration

Files:

Step 1: Write the up migration

-- Rename AP-specific tables with ap_ prefix
ALTER TABLE doc_source RENAME TO ap_doc_source;
ALTER TABLE doc_source_email RENAME TO ap_doc_source_email;
ALTER TABLE doc_source_email_pending_sync RENAME TO ap_doc_source_email_pending_sync;
ALTER TABLE doc_source_email_processed_messages RENAME TO ap_doc_source_email_processed_messages;
ALTER TABLE doc_source_webhook RENAME TO ap_doc_source_webhook;
ALTER TABLE doc_source_ses RENAME TO ap_doc_source_ses;
ALTER TABLE doc_source_ses_processed RENAME TO ap_doc_source_ses_processed;
ALTER TABLE ingestion RENAME TO ap_ingestion;
ALTER TABLE ingestion_post_process_stat RENAME TO ap_ingestion_post_process_stat;
ALTER TABLE document_cluster RENAME TO ap_document_cluster;
ALTER TABLE document_match RENAME TO ap_document_match;
ALTER TABLE datev_export_audit RENAME TO ap_datev_export_audit;
ALTER TABLE supplier_verification RENAME TO ap_supplier_verification;
ALTER TABLE supplier_verification_document RENAME TO ap_supplier_verification_document;
ALTER TABLE acquisition_llm_stat RENAME TO ap_acquisition_llm_stat;
ALTER TABLE qa_dataset_item RENAME TO ap_qa_dataset_item;

-- Add domain column to document table
ALTER TABLE document ADD COLUMN domain TEXT NOT NULL DEFAULT 'ap';

-- Rename enum types
ALTER TYPE document_match_status RENAME TO ap_document_match_status;

Note: PostgreSQL automatically updates FK constraints, indexes, and triggers when renaming tables. Sequence and constraint names keep their old names — this is cosmetic and harmless.

Step 2: Write the down migration

ALTER TABLE document DROP COLUMN domain;

ALTER TYPE ap_document_match_status RENAME TO document_match_status;

ALTER TABLE ap_doc_source RENAME TO doc_source;
ALTER TABLE ap_doc_source_email RENAME TO doc_source_email;
ALTER TABLE ap_doc_source_email_pending_sync RENAME TO doc_source_email_pending_sync;
ALTER TABLE ap_doc_source_email_processed_messages RENAME TO doc_source_email_processed_messages;
ALTER TABLE ap_doc_source_webhook RENAME TO doc_source_webhook;
ALTER TABLE ap_doc_source_ses RENAME TO doc_source_ses;
ALTER TABLE ap_doc_source_ses_processed RENAME TO doc_source_ses_processed;
ALTER TABLE ap_ingestion RENAME TO ingestion;
ALTER TABLE ap_ingestion_post_process_stat RENAME TO ingestion_post_process_stat;
ALTER TABLE ap_document_cluster RENAME TO document_cluster;
ALTER TABLE ap_document_match RENAME TO document_match;
ALTER TABLE ap_datev_export_audit RENAME TO datev_export_audit;
ALTER TABLE ap_supplier_verification RENAME TO supplier_verification;
ALTER TABLE ap_supplier_verification_document RENAME TO supplier_verification_document;
ALTER TABLE ap_acquisition_llm_stat RENAME TO acquisition_llm_stat;
ALTER TABLE ap_qa_dataset_item RENAME TO qa_dataset_item;

Step 3: Verify the migration compiles

psql -h localhost -U postgres -d orcha -c "\dt" | head -30

Step 4: Commit the migration files only (code updates come next)


Task 2: Update doc_source family table references

The doc_source family has 7 tables and is the most widely referenced (~1,400 occurrences across ~50 files). Use find-and-replace, processing longest names first to avoid partial replacements.

Replacement order (critical — longest first):

# Old (kebab) New (kebab)
1 doc-source-email-processed-messages ap-doc-source-email-processed-messages
2 doc-source-email-pending-sync ap-doc-source-email-pending-sync
3 doc-source-email ap-doc-source-email
4 doc-source-webhook ap-doc-source-webhook
5 doc-source-ses-processed ap-doc-source-ses-processed
6 doc-source-ses ap-doc-source-ses
7 doc-source ap-doc-source

And the same order for snake_case forms (doc_source_email_processed_messagesap_doc_source_email_processed_messages, etc.) in raw SQL strings.

Scope: All .clj files under src/ and test/, plus repl/ and scripts/.

Exclusions: Do NOT modify files under resources/migrations/ (historical). Do NOT modify CHANGELOG.md.

Step 1: Apply all 7 kebab-case replacements (longest first) across .clj files

For each replacement, use global find-and-replace across the codebase. The kebab form appears in:

Step 2: Apply snake_case replacements in .clj files

The snake_case form appears in raw SQL strings (e.g., "INSERT INTO doc_source ..."). Same longest-first order.

Step 3: Update Malli schemas in src/com/getorcha/schema/doc_source/

Step 4: Run linter and fix any issues

clj-kondo --lint src test dev

Key files with highest reference counts (verify these manually):


Task 3: Update ingestion family table references

Two tables: ingestion and ingestion_post_process_stat.

Critical distinction: The word "ingestion" appears in:

Only change table references in this task.

Replacement patterns:

Old New Context
:ingestion-post-process-stat :ap-ingestion-post-process-stat HoneySQL + qualified keys
ingestion_post_process_stat ap_ingestion_post_process_stat Raw SQL strings
:ingestion/ :ap-ingestion/ Qualified result keys (:ingestion/id, :ingestion/status, etc.)
{:ingestion/keys {:ap-ingestion/keys Destructuring
:ingestion (bare, in HoneySQL position) :ap-ingestion Table ref in :from, :join, :insert-into, :update
"ingestion" or ingestion. in SQL strings "ap_ingestion" / ap_ingestion. Raw SQL

Do NOT replace:

Step 1: Replace ingestion_post_process_stat references first (longest match)

Affects ~5 files:

Step 2: Replace :ingestion/ qualified keys

This is the most impactful change. Affects 30+ files including:

Step 3: Replace bare :ingestion in HoneySQL positions

Search for :ingestion as a table keyword in HoneySQL maps. Common patterns:

Carefully distinguish from :ingestion as a config/queue key (which should NOT change).

Step 4: Run linter

clj-kondo --lint src test dev

Task 4: Update remaining table references

Five table groups with moderate impact.

4a: document_cluster and document_match

Old New
:document-cluster :ap-document-cluster
:document-cluster/ :ap-document-cluster/
document_cluster ap_document_cluster
:document-match :ap-document-match
:document-match/ :ap-document-match/
document_match ap_document_match

Key files:

Also update document_match_status references if this enum type is referenced in code (it was renamed to ap_document_match_status in the migration).

4b: datev_export_audit

Old New
:datev-export-audit :ap-datev-export-audit
:datev-export-audit/ :ap-datev-export-audit/
datev_export_audit ap_datev_export_audit

Key files:

4c: supplier_verification and supplier_verification_document

Old New
:supplier-verification-document :ap-supplier-verification-document
:supplier-verification-document/ :ap-supplier-verification-document/
:supplier-verification :ap-supplier-verification
:supplier-verification/ :ap-supplier-verification/
supplier_verification_document ap_supplier_verification_document
supplier_verification ap_supplier_verification

Replace supplier-verification-document BEFORE supplier-verification (longest first).

Key files:

4d: acquisition_llm_stat

Old New
:acquisition-llm-stat :ap-acquisition-llm-stat
acquisition_llm_stat ap_acquisition_llm_stat

Key files:

4e: qa_dataset_item

Old New
:qa-dataset-item :ap-qa-dataset-item
:qa-dataset-item/ :ap-qa-dataset-item/
qa_dataset_item ap_qa_dataset_item

Key files:

Step (final): Run linter

clj-kondo --lint src test dev

Task 5: Run migration and full test suite

Step 1: Run the migration against local database

psql -h localhost -U postgres -d orcha -c "\i resources/migrations/YYYYMMDDHHMMSS-rename-ap-tables.up.sql"

Or if using migratus from REPL:

(reset) ;; will run pending migrations

Step 2: Run all tests

clj -X:test:silent 2>&1 | grep -A 5 -E "(FAIL in|ERROR in|Execution error|failed because|Ran .* tests)"

Step 3: Fix any failures

Common failure causes:

Step 4: Commit all Phase A changes

git add resources/migrations/YYYYMMDDHHMMSS-rename-ap-tables.up.sql resources/migrations/YYYYMMDDHHMMSS-rename-ap-tables.down.sql
git add -p  # stage .clj file changes
git commit -m "refactor: rename AP-specific database tables with ap_ prefix"

Phase B: Namespace Reorganization

Task 6: Move worker source files under ap/ sub-package

Namespace rename pattern: Insert .ap after workers:

Step 1: Create target directory structure

mkdir -p src/com/getorcha/workers/ap/ingestion/post_process
mkdir -p src/com/getorcha/workers/ap/ingestion/transcription
mkdir -p src/com/getorcha/workers/ap/acquisition/email
mkdir -p src/com/getorcha/workers/ap/matching

Step 2: Move source files with git mv

# Ingestion (19 files)
git mv src/com/getorcha/workers/ingestion.clj src/com/getorcha/workers/ap/ingestion.clj
git mv src/com/getorcha/workers/ingestion/classification.clj src/com/getorcha/workers/ap/ingestion/classification.clj
git mv src/com/getorcha/workers/ingestion/extraction.clj src/com/getorcha/workers/ap/ingestion/extraction.clj
git mv src/com/getorcha/workers/ingestion/fraud_detection.clj src/com/getorcha/workers/ap/ingestion/fraud_detection.clj
git mv src/com/getorcha/workers/ingestion/transcription.clj src/com/getorcha/workers/ap/ingestion/transcription.clj
git mv src/com/getorcha/workers/ingestion/transcription/layout.clj src/com/getorcha/workers/ap/ingestion/transcription/layout.clj
git mv src/com/getorcha/workers/ingestion/transcription/ocr_layout.clj src/com/getorcha/workers/ap/ingestion/transcription/ocr_layout.clj
git mv src/com/getorcha/workers/ingestion/transcription/pdfbox_layout.clj src/com/getorcha/workers/ap/ingestion/transcription/pdfbox_layout.clj
git mv src/com/getorcha/workers/ingestion/validation.clj src/com/getorcha/workers/ap/ingestion/validation.clj
git mv src/com/getorcha/workers/ingestion/vat_rules.clj src/com/getorcha/workers/ap/ingestion/vat_rules.clj
git mv src/com/getorcha/workers/ingestion/post_process.clj src/com/getorcha/workers/ap/ingestion/post_process.clj
git mv src/com/getorcha/workers/ingestion/post_process/accounts.clj src/com/getorcha/workers/ap/ingestion/post_process/accounts.clj
git mv src/com/getorcha/workers/ingestion/post_process/accruals.clj src/com/getorcha/workers/ap/ingestion/post_process/accruals.clj
git mv src/com/getorcha/workers/ingestion/post_process/common.clj src/com/getorcha/workers/ap/ingestion/post_process/common.clj
git mv src/com/getorcha/workers/ingestion/post_process/cost_center.clj src/com/getorcha/workers/ap/ingestion/post_process/cost_center.clj
git mv src/com/getorcha/workers/ingestion/post_process/financial_validation.clj src/com/getorcha/workers/ap/ingestion/post_process/financial_validation.clj
git mv src/com/getorcha/workers/ingestion/post_process/protocol.clj src/com/getorcha/workers/ap/ingestion/post_process/protocol.clj
git mv src/com/getorcha/workers/ingestion/post_process/supplier.clj src/com/getorcha/workers/ap/ingestion/post_process/supplier.clj
git mv src/com/getorcha/workers/ingestion/post_process/tax_compliance.clj src/com/getorcha/workers/ap/ingestion/post_process/tax_compliance.clj
git mv src/com/getorcha/workers/ingestion/post_process/uncertain_validations.clj src/com/getorcha/workers/ap/ingestion/post_process/uncertain_validations.clj

# Acquisition (11 files)
git mv src/com/getorcha/workers/acquisition.clj src/com/getorcha/workers/ap/acquisition.clj
git mv src/com/getorcha/workers/acquisition/email.clj src/com/getorcha/workers/ap/acquisition/email.clj
git mv src/com/getorcha/workers/acquisition/email/gmail.clj src/com/getorcha/workers/ap/acquisition/email/gmail.clj
git mv src/com/getorcha/workers/acquisition/email/oauth.clj src/com/getorcha/workers/ap/acquisition/email/oauth.clj
git mv src/com/getorcha/workers/acquisition/email/outlook.clj src/com/getorcha/workers/ap/acquisition/email/outlook.clj
git mv src/com/getorcha/workers/acquisition/email/protocol.clj src/com/getorcha/workers/ap/acquisition/email/protocol.clj
git mv src/com/getorcha/workers/acquisition/email/ses.clj src/com/getorcha/workers/ap/acquisition/email/ses.clj
git mv src/com/getorcha/workers/acquisition/email/subscription.clj src/com/getorcha/workers/ap/acquisition/email/subscription.clj
git mv src/com/getorcha/workers/acquisition/email/triage.clj src/com/getorcha/workers/ap/acquisition/email/triage.clj
git mv src/com/getorcha/workers/acquisition/html.clj src/com/getorcha/workers/ap/acquisition/html.clj
git mv src/com/getorcha/workers/acquisition/multi.clj src/com/getorcha/workers/ap/acquisition/multi.clj

# Matching (8 files)
git mv src/com/getorcha/workers/matching/worker.clj src/com/getorcha/workers/ap/matching/worker.clj
git mv src/com/getorcha/workers/matching/core.clj src/com/getorcha/workers/ap/matching/core.clj
git mv src/com/getorcha/workers/matching/candidates.clj src/com/getorcha/workers/ap/matching/candidates.clj
git mv src/com/getorcha/workers/matching/evidence.clj src/com/getorcha/workers/ap/matching/evidence.clj
git mv src/com/getorcha/workers/matching/llm_decision.clj src/com/getorcha/workers/ap/matching/llm_decision.clj
git mv src/com/getorcha/workers/matching/normalize.clj src/com/getorcha/workers/ap/matching/normalize.clj
git mv src/com/getorcha/workers/matching/reconciliation.clj src/com/getorcha/workers/ap/matching/reconciliation.clj
git mv src/com/getorcha/workers/matching/searchable_text.clj src/com/getorcha/workers/ap/matching/searchable_text.clj

# Supplier verification (1 file)
git mv src/com/getorcha/workers/supplier_verification.clj src/com/getorcha/workers/ap/supplier_verification.clj

Step 3: Update namespace declarations in ALL moved files

Global find-and-replace in moved files only:

This applies to both ns declarations and internal require references within moved files (since they reference each other).

Step 4: Update require statements in files that were NOT moved

These files reference the moved namespaces and need require updates:

Search for any remaining com.getorcha.workers.ingestion (without .ap.) in .clj files and update.

Files that stay at workers/ root (do NOT move):


Task 7: Move app HTTP and integrations under ap/

7a: Move accounts_payable.clj → ap.clj

Step 1: Move the file

git mv src/com/getorcha/app/http/documents/accounts_payable.clj src/com/getorcha/app/http/ap.clj

Step 2: Update namespace declaration

;; Old:
(ns com.getorcha.app.http.documents.accounts-payable ...)
;; New:
(ns com.getorcha.app.http.ap ...)

Step 3: Update route names

In ap.clj, all ::route-name keywords now resolve to :com.getorcha.app.http.ap/route-name instead of :com.getorcha.app.http.documents.accounts-payable/route-name. This happens automatically via :: resolution.

Update all files that reference the old fully-qualified route names:

Old New
:com.getorcha.app.http.documents.accounts-payable/list :com.getorcha.app.http.ap/list
(and any other route names from this namespace)

Key files to update:

Step 4: Update the require in documents.clj route assembly

;; Old:
[com.getorcha.app.http.documents.accounts-payable :as accounts-payable]
;; New:
[com.getorcha.app.http.ap :as ap]

And update all references from accounts-payable/ to ap/ in route definitions.

7b: Move integrations under ap/

Step 1: Move files

mkdir -p src/com/getorcha/integrations/ap
git mv src/com/getorcha/integrations/maesn.clj src/com/getorcha/integrations/ap/maesn.clj
git mv src/com/getorcha/integrations/cover_page.clj src/com/getorcha/integrations/ap/cover_page.clj

Step 2: Update namespace declarations

Step 3: Update requires in files that reference these namespaces

Key files:


Task 8: Update Integrant config and remaining cross-references

Step 1: Update config.edn

In resources/com/getorcha/config.edn, rename all worker keys:

Old Key New Key
:com.getorcha.workers.ingestion/worker-pools :com.getorcha.workers.ap.ingestion/worker-pools
:com.getorcha.workers.ingestion/orchestrator :com.getorcha.workers.ap.ingestion/orchestrator
:com.getorcha.workers.acquisition/worker-pools :com.getorcha.workers.ap.acquisition/worker-pools
:com.getorcha.workers.acquisition/orchestrator :com.getorcha.workers.ap.acquisition/orchestrator
:com.getorcha.workers.acquisition.email.subscription/renewal :com.getorcha.workers.ap.acquisition.email.subscription/renewal
:com.getorcha.workers.matching.worker/worker-pools :com.getorcha.workers.ap.matching.worker/worker-pools
:com.getorcha.workers.matching.worker/orchestrator :com.getorcha.workers.ap.matching.worker/orchestrator

Also update all #integrant/ref values that point to the old keys.

Step 2: Update ig/init-key and ig/halt-key! in moved files

These use ::keyword which resolves based on the current namespace — since the namespaces were updated in Task 6, these should already be correct. Verify by searching for ig/init-key and ig/halt-key! in moved files.

Step 3: Update remaining cross-references

Search the entire codebase for any remaining references to the old namespace names:

# Search for old namespace patterns that should have been updated
grep -r "com.getorcha.workers.ingestion[^.]" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v ".ap."
grep -r "com.getorcha.workers.acquisition[^.]" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v ".ap."
grep -r "com.getorcha.workers.matching" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v ".ap."
grep -r "com.getorcha.integrations.maesn" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v ".ap."
grep -r "com.getorcha.integrations.cover-page" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v ".ap."
grep -r "documents.accounts-payable" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn"

Fix any remaining references found.

Step 4: Update test fixture/helper references


Task 9: Move test files

Step 1: Create target test directories

mkdir -p test/com/getorcha/workers/ap/ingestion/transcription
mkdir -p test/com/getorcha/workers/ap/acquisition/email
mkdir -p test/com/getorcha/workers/ap/matching
mkdir -p test/com/getorcha/integrations/ap

Step 2: Move test files with git mv

Mirror the source file moves:

# Ingestion tests
git mv test/com/getorcha/workers/ingestion_test.clj test/com/getorcha/workers/ap/ingestion_test.clj
git mv test/com/getorcha/workers/ingestion_notifications_test.clj test/com/getorcha/workers/ap/ingestion_notifications_test.clj
git mv test/com/getorcha/workers/ingestion/classification_test.clj test/com/getorcha/workers/ap/ingestion/classification_test.clj
git mv test/com/getorcha/workers/ingestion/extraction_test.clj test/com/getorcha/workers/ap/ingestion/extraction_test.clj
git mv test/com/getorcha/workers/ingestion/fraud_detection_test.clj test/com/getorcha/workers/ap/ingestion/fraud_detection_test.clj
git mv test/com/getorcha/workers/ingestion/transcription_test.clj test/com/getorcha/workers/ap/ingestion/transcription_test.clj
git mv test/com/getorcha/workers/ingestion/transcription/layout_test.clj test/com/getorcha/workers/ap/ingestion/transcription/layout_test.clj
git mv test/com/getorcha/workers/ingestion/transcription/ocr_layout_test.clj test/com/getorcha/workers/ap/ingestion/transcription/ocr_layout_test.clj
git mv test/com/getorcha/workers/ingestion/transcription/pdfbox_layout_test.clj test/com/getorcha/workers/ap/ingestion/transcription/pdfbox_layout_test.clj
git mv test/com/getorcha/workers/ingestion/validation_test.clj test/com/getorcha/workers/ap/ingestion/validation_test.clj
git mv test/com/getorcha/workers/ingestion/vat_rules_test.clj test/com/getorcha/workers/ap/ingestion/vat_rules_test.clj

# Acquisition tests
git mv test/com/getorcha/workers/acquisition_test.clj test/com/getorcha/workers/ap/acquisition_test.clj
git mv test/com/getorcha/workers/acquisition_notifications_test.clj test/com/getorcha/workers/ap/acquisition_notifications_test.clj
git mv test/com/getorcha/workers/acquisition/email_test.clj test/com/getorcha/workers/ap/acquisition/email_test.clj
git mv test/com/getorcha/workers/acquisition/email_notifications_test.clj test/com/getorcha/workers/ap/acquisition/email_notifications_test.clj
git mv test/com/getorcha/workers/acquisition/email/ses_test.clj test/com/getorcha/workers/ap/acquisition/email/ses_test.clj
git mv test/com/getorcha/workers/acquisition/email/outlook_test.clj test/com/getorcha/workers/ap/acquisition/email/outlook_test.clj
git mv test/com/getorcha/workers/acquisition/email/subscription_test.clj test/com/getorcha/workers/ap/acquisition/email/subscription_test.clj
git mv test/com/getorcha/workers/acquisition/html_test.clj test/com/getorcha/workers/ap/acquisition/html_test.clj
git mv test/com/getorcha/workers/acquisition/triage_test.clj test/com/getorcha/workers/ap/acquisition/triage_test.clj

# Matching tests
git mv test/com/getorcha/workers/matching/worker_test.clj test/com/getorcha/workers/ap/matching/worker_test.clj
git mv test/com/getorcha/workers/matching/core_test.clj test/com/getorcha/workers/ap/matching/core_test.clj
git mv test/com/getorcha/workers/matching/candidates_test.clj test/com/getorcha/workers/ap/matching/candidates_test.clj
git mv test/com/getorcha/workers/matching/evidence_test.clj test/com/getorcha/workers/ap/matching/evidence_test.clj
git mv test/com/getorcha/workers/matching/integration_test.clj test/com/getorcha/workers/ap/matching/integration_test.clj
git mv test/com/getorcha/workers/matching/llm_decision_test.clj test/com/getorcha/workers/ap/matching/llm_decision_test.clj
git mv test/com/getorcha/workers/matching/normalize_test.clj test/com/getorcha/workers/ap/matching/normalize_test.clj
git mv test/com/getorcha/workers/matching/reconciliation_test.clj test/com/getorcha/workers/ap/matching/reconciliation_test.clj
git mv test/com/getorcha/workers/matching/searchable_text_test.clj test/com/getorcha/workers/ap/matching/searchable_text_test.clj

# Supplier verification test
git mv test/com/getorcha/workers/supplier_verification_test.clj test/com/getorcha/workers/ap/supplier_verification_test.clj

# Integration tests
git mv test/com/getorcha/integrations/maesn_test.clj test/com/getorcha/integrations/ap/maesn_test.clj
git mv test/com/getorcha/integrations/maesn_notifications_test.clj test/com/getorcha/integrations/ap/maesn_notifications_test.clj

Step 3: Update namespace declarations in all moved test files

Same pattern as source files — insert .ap after workers or integrations:

Step 4: Update require statements in test files

Both the source namespace references (now under .ap.) and any cross-test references.


Task 10: Update documentation

Step 1: Update prescriptive documentation

Files that contain code examples, query patterns, or architectural descriptions referencing old table/namespace names:

Step 2: Do NOT modify


Task 11: Lint, test, and commit Phase B

Step 1: Run linter

clj-kondo --lint src test dev

Fix all warnings/errors.

Step 2: Verify no stale references remain

# Old worker namespaces (should return nothing in .clj/.edn files)
grep -r "workers\.ingestion" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v "workers\.ap\.ingestion" | grep -v "workers\.llm"
grep -r "workers\.acquisition" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v "workers\.ap\.acquisition"
grep -r "workers\.matching" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v "workers\.ap\.matching"

# Old integration namespaces
grep -r "integrations\.maesn" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn" | grep -v "integrations\.ap\.maesn"

# Old route names
grep -r "documents\.accounts-payable" src/ test/ dev/ repl/ resources/ --include="*.clj" --include="*.edn"

Step 3: Run full test suite

clj -X:test:silent 2>&1 | grep -A 5 -E "(FAIL in|ERROR in|Execution error|failed because|Ran .* tests)"

Step 4: Commit Phase B

git add src/ test/ dev/ repl/ scripts/ resources/com/getorcha/config.edn
git commit -m "refactor: move AP workers, HTTP, and integrations under ap/ sub-packages"

Task 12: Clean up empty directories

After moving files, git may leave behind empty directories.

find src/com/getorcha/workers/ingestion -empty -type d -delete 2>/dev/null
find src/com/getorcha/workers/acquisition -empty -type d -delete 2>/dev/null
find src/com/getorcha/workers/matching -empty -type d -delete 2>/dev/null
find test/com/getorcha/workers/ingestion -empty -type d -delete 2>/dev/null
find test/com/getorcha/workers/acquisition -empty -type d -delete 2>/dev/null
find test/com/getorcha/workers/matching -empty -type d -delete 2>/dev/null
find src/com/getorcha/integrations -maxdepth 0 -empty -type d -delete 2>/dev/null