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.
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Split documents.clj and document_management.clj into a com.getorcha.erp.http.documents.* namespace tree with grouped handlers, unified URLs, and deduplicated shared code.
Architecture: Pure refactoring with one behavior change (add list SSE to management). Create ~12 new namespace files, wire routes through parent assembler, update all external references, redistribute tests, delete old files.
Tech Stack: Clojure, Reitit routing, HTMX/Hiccup, HoneySQL, core.async (SSE)
Design doc: docs/plans/2026-02-25-documents-module-split-design.md
Old route names → new route names. Every external reference must be updated.
| Old Route Name | New Route Name |
|---|---|
:com.getorcha.erp.http.documents/list |
:com.getorcha.erp.http.documents.accounts-payable/list |
:com.getorcha.erp.http.documents/list-events |
:com.getorcha.erp.http.documents.accounts-payable/list-events |
:com.getorcha.erp.http.documents/search |
:com.getorcha.erp.http.documents.accounts-payable/search |
:com.getorcha.erp.http.documents/upload |
:com.getorcha.erp.http.documents.upload/upload |
:com.getorcha.erp.http.documents/detail |
:com.getorcha.erp.http.documents.view/detail |
:com.getorcha.erp.http.documents/detail-events |
:com.getorcha.erp.http.documents.view/detail-events |
:com.getorcha.erp.http.documents/by-hash |
:com.getorcha.erp.http.documents/by-hash (stays in parent) |
:com.getorcha.erp.http.documents/bulk-toggle |
:com.getorcha.erp.http.documents.accounts-payable/bulk-toggle |
:com.getorcha.erp.http.documents/bulk-toggle-all |
:com.getorcha.erp.http.documents.accounts-payable/bulk-toggle-all |
:com.getorcha.erp.http.documents/bulk-deselect-all |
:com.getorcha.erp.http.documents.accounts-payable/bulk-deselect-all |
:com.getorcha.erp.http.documents/bulk-export-datev |
:com.getorcha.erp.http.documents.accounts-payable/bulk-export-datev |
:com.getorcha.erp.http.documents/reingest |
:com.getorcha.erp.http.documents.view/reingest |
:com.getorcha.erp.http.documents/export-datev |
:com.getorcha.erp.http.documents.view.invoice/export-datev |
:com.getorcha.erp.http.documents/datev-export-status |
:com.getorcha.erp.http.documents.view.invoice/datev-export-status |
:com.getorcha.erp.http.documents/add-to-qa-dataset |
:com.getorcha.erp.http.documents.view.invoice/add-to-qa-dataset |
:com.getorcha.erp.http.document-management/list |
:com.getorcha.erp.http.documents.management/list |
:com.getorcha.erp.http.document-management/detail |
:com.getorcha.erp.http.documents.view/detail (unified) |
:com.getorcha.erp.http.document-management/detail-events |
:com.getorcha.erp.http.documents.view/detail-events (unified) |
:com.getorcha.erp.http.document-management/upload |
:com.getorcha.erp.http.documents.upload/upload (unified) |
:com.getorcha.erp.http.document-management/search |
:com.getorcha.erp.http.documents.management/search |
:com.getorcha.erp.http.document-management/reingest |
:com.getorcha.erp.http.documents.view/reingest (unified) |
These files (outside the two being split) reference old route names and need updating:
| File | Lines | Reference | Update To |
|---|---|---|---|
src/com/getorcha/erp/http.clj |
49-50 | Both routes calls |
Single erp.http.documents/routes |
src/com/getorcha/erp/ui/layout.clj |
39-40 | Sidebar nav links to documents list + doc-mgmt list | New AP + management route names |
src/com/getorcha/erp/http/profile.clj |
33 | Redirect to documents list | New AP list route name |
src/com/getorcha/erp/http/login.clj |
242, 313, 394 | Post-login redirect to documents list | New AP list route name |
src/com/getorcha/erp/http/
├── documents.clj (REWRITE: route assembly + by-hash + 404)
├── documents/
│ ├── shared.clj (NEW)
│ ├── upload.clj (NEW)
│ ├── accounts_payable.clj (NEW)
│ ├── management.clj (NEW)
│ └── view.clj (NEW: route assembly + get-document dispatch)
│ └── view/
│ ├── shared.clj (NEW)
│ ├── invoice.clj (NEW)
│ ├── notice.clj (NEW)
│ ├── contract.clj (NEW)
│ ├── purchase_order.clj (NEW)
│ └── goods_received_note.clj (NEW)
├── document_management.clj (DELETE)
test/com/getorcha/erp/http/
├── documents_test.clj (REWRITE: route assembly tests only)
├── documents/
│ ├── upload_test.clj (NEW)
│ ├── accounts_payable_test.clj (NEW)
│ ├── management_test.clj (NEW)
│ └── view_test.clj (NEW)
│ └── view/
│ ├── invoice_test.clj (NEW)
│ └── contract_test.clj (NEW)
├── document_management_test.clj (DELETE)
During this phase, old files remain untouched and functional. New namespaces are created but not route-wired. Verify each compiles in the REPL.
documents.sharedFiles:
src/com/getorcha/erp/http/documents/shared.cljWhat moves here (from documents.clj unless noted):
| Function | Source Lines | Notes |
|---|---|---|
document-builder-fn |
docs:51-52, dm:61-62 | Identical in both files |
legal-entity-ids |
docs:55-58, dm:65-67 | Identical in both files |
primary-legal-entity-id |
docs:61-64 | docs only |
excel-content-type? |
docs:103-108, dm:1228-1232 | Identical |
excel-file? |
docs:111-117 | docs only |
display-file-path |
docs:120-132 | docs only, used in detail views |
wants-json? |
docs:96-100 | Used in list + detail handlers |
lateral-joins |
docs:1309-1326 | SQL fragments for ingestion/export status |
sortable-th |
docs:534-558, dm:132-154 | Near-duplicate — generalize, take filter-params builder as arg |
pagination-url |
docs:561-569, dm:201-210 | Near-duplicate — generalize with filter-params arg |
pagination-controls |
dm:213-226 | docs builds inline; extract from DM |
New functions to create:
make-list-events-handler — parameterized list SSE factory:
(defn make-list-events-handler
"Creates a list-events SSE handler. Takes:
- `type-filter` — set of document type keywords to include (nil = all)
- `row-renderer` — fn of [router opts document] → hiccup row"
[type-filter row-renderer]
(fn [{:keys [db-pool identity document-events ::reitit/router] :as request}
respond _raise]
;; Same pub/sub pattern as current list-events in documents.clj (lines 2389-2474)
;; but with type-filter check: skip events where doc type not in filter set
;; and delegate row rendering to row-renderer
...))
Step 1: Create the file with all shared functions. Make all functions public (they're cross-namespace now).
Step 2: Verify it compiles:
(require 'com.getorcha.erp.http.documents.shared :reload)
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/shared.clj
git commit -m "refactor(documents): create shared namespace with deduplicated helpers"
documents.uploadFiles:
src/com/getorcha/erp/http/documents/upload.cljWhat moves here:
The upload handler from documents.clj:1723-1778. This is the single unified upload handler.
Key change: the HX-Redirect on single file upload should point to the new unified detail route ::view/detail instead of ::detail. Since the upload namespace can't reference the view namespace's route name at compile time (circular), use path-for with the fully qualified keyword :com.getorcha.erp.http.documents.view/detail.
(defn routes [_config]
["/upload"
{:name ::upload
:post {:summary "Upload document(s)"
:parameters {:multipart [:map-of :keyword :any]}
:handler #'upload}}])
Step 1: Create the file. Require documents.shared for legal-entity-ids, excel-content-type?.
Step 2: Verify it compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/upload.clj
git commit -m "refactor(documents): create upload namespace with unified handler"
Files:
src/com/getorcha/erp/http/documents/view/invoice.cljsrc/com/getorcha/erp/http/documents/view/notice.cljsrc/com/getorcha/erp/http/documents/view/contract.cljsrc/com/getorcha/erp/http/documents/view/purchase_order.cljsrc/com/getorcha/erp/http/documents/view/goods_received_note.cljview.invoice — from documents.clj:
| Function | Source Lines | Notes |
|---|---|---|
invoice-detail-view |
922-964 | UI component |
datev-export-status->class |
200-206 | Helper for DATEV badge CSS |
datev-export-section |
209-286 | DATEV export UI |
export-datev |
1836-1889 | Handler |
datev-export-status |
2157-2230 | Handler (poll/update) |
add-to-qa-dataset |
2233-2303 | Handler |
in-qa-dataset? |
135-142 | Helper |
This module also defines its own sub-routes (mounted under the view routes):
(defn routes [_config]
[""
["/export/datev"
{:name ::export-datev
:post {:handler #'export-datev}}]
["/export/datev/status"
{:name ::datev-export-status
:get {:handler #'datev-export-status}}]
["/add-to-qa-dataset"
{:name ::add-to-qa-dataset
:post {:handler #'add-to-qa-dataset}}]])
Public functions needed by other modules:
invoice-detail-view — called by view dispatcherdatev-export-section — called by detail SSE on :export eventsview.notice — from documents.clj:
| Function | Source Lines |
|---|---|
notice-type-labels |
883-886 |
notice-detail-view |
889-919 |
Public: notice-detail-view
No routes — purely a rendering module.
view.contract — from document_management.clj:
| Function | Source Lines |
|---|---|
contract-type-labels |
dm:41-53 |
type-icons |
dm:55-59 |
contract-status |
dm:87-103 |
date-delta-label |
dm:106-122 |
contract-detail-view |
dm:568-713 |
Public: contract-detail-view
No routes.
view.purchase-order — from document_management.clj:
| Function | Source Lines |
|---|---|
po-detail-view |
dm:716-779 |
Public: po-detail-view
No routes.
view.goods-received-note — from document_management.clj:
| Function | Source Lines |
|---|---|
grn-detail-view |
dm:782-865 |
Public: grn-detail-view
No routes.
Step 1: Create all five files.
Step 2: Verify each compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/view/
git commit -m "refactor(documents): create type-specific detail view modules"
documents.view.sharedFiles:
src/com/getorcha/erp/http/documents/view/shared.cljWhat moves here:
| Function | Source | Notes |
|---|---|---|
excel-preview-banner |
docs:967-978 | UI |
detail-page-content |
docs:981-1215, dm:868-1038 | Merge both; dispatch to type-specific view based on doc type |
detail-area-content |
docs:1218-1241, dm:868-1038 | Merge; unified SSE connector |
detail-page |
docs:1244-1302, dm:1041-1118 | Merge; unified layout |
get-adjacent-document-ids |
docs:1329-1374, dm:1121-1152 | Merge (DM version is simpler) |
reingest |
docs:1781-1833, dm:1280-1310 | Merge; use the docs version (returns rendered HTML, better UX) |
detail-events |
docs:2306-2386, dm:1313-1379 | Merge; unified SSE, no cross-type redirects |
Key design for the merged detail-page-content: dispatch rendering by doc type:
(case (some-> (:document/type document) name)
"invoice" (view.invoice/invoice-detail-view ...)
"financial-notice" (view.notice/notice-detail-view ...)
"contract" (view.contract/contract-detail-view ...)
"purchase-order" (view.purchase-order/po-detail-view ...)
"goods-received-note" (view.goods-received-note/grn-detail-view ...)
;; default/unknown: show raw structured data or placeholder
nil)
Key design for merged detail-events: remove the cross-type redirect. On terminal ingestion, just re-render detail-area-content with the document. On :export events, delegate to view.invoice/datev-export-section.
Key design for merged reingest: use the documents.clj version which returns rendered detail-area-content HTML (stays on page with SSE progress). The DM version just does HX-Redirect which is inferior UX.
Step 1: Create the file.
Step 2: Verify it compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/view/shared.clj
git commit -m "refactor(documents): create shared detail view with unified SSE and dispatch"
documents.viewFiles:
src/com/getorcha/erp/http/documents/view.cljWhat moves here:
The get-document handler — merged from documents.clj:1596-1703 and document_management.clj:1155-1224. This is the dispatcher that loads the document and delegates to the type-specific view via view.shared/detail-page.
Also: get-document-by-hash from documents.clj:1706-1720 — stays here since it's a document-level lookup, not type-specific. Actually, per the design this goes to the parent. Move it there in Task 7.
Route assembly:
(defn routes [_config]
["/view/:document-id"
[""
{:name ::detail
:get {:summary "Document detail view"
:parameters {:path {:document-id :uuid}}
:handler #'get-document}}]
["/events"
{:name ::detail-events
:get {:summary "SSE events for document detail"
:parameters {:path {:document-id :uuid}}
:handler #'view.shared/detail-events}}]
["/reingest"
{:name ::reingest
:post {:summary "Re-ingest document"
:parameters {:path {:document-id :uuid}}
:handler #'view.shared/reingest}}]
(view.invoice/routes _config)])
Step 1: Create the file.
Step 2: Verify it compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/view.clj
git commit -m "refactor(documents): create view namespace with route assembly and type dispatch"
documents.accounts-payableFiles:
src/com/getorcha/erp/http/documents/accounts_payable.cljWhat moves here (all from documents.clj):
| Function | Source Lines | Notes |
|---|---|---|
selection-session-key |
35-37 | Bulk selection |
sort-session-key |
39-41 | List sort persistence |
get-selection |
44-48 | Bulk selection helper |
default-from-date |
67-70 | Date range default |
default-to-date |
73-76 | Date range default |
date-range-params |
79-83 | URL builder |
filter-params |
86-93 | URL builder |
has-any-warnings |
293-308 | SQL fragment |
needs-review-where |
311-329 | SQL fragment |
has-errors-where |
332-342 | SQL fragment |
status-priority-order |
345-377 | SQL ORDER BY |
order-by-for-sort |
380-398 | SQL ORDER BY |
document-row |
405-499 | UI |
document-status-filter |
502-521 | UI |
column-default-dir |
524-531 | UI helper |
bulk-actions-bar |
148-171 | UI |
select-all-cell |
174-193 | UI |
list-page |
572-880 | UI |
list-documents |
1377-1537 | Handler |
search-documents |
1540-1593 | Handler |
fetch-exportable-ids |
1892-1914 | Bulk helper |
bulk-toggle |
1917-1966 | Handler |
bulk-toggle-all |
1969-2023 | Handler |
bulk-deselect-all |
2026-2071 | Handler |
bulk-export-datev |
2074-2154 | Handler |
list-events |
2389-2474 | Handler (or use make-list-events-handler from shared) |
List events: either move list-events directly (it has AP-specific logic like bulk selection rendering and DATEV status) or call shared/make-list-events-handler with AP config. Given the AP list-events has bulk selection and DATEV-specific logic interleaved, it's cleaner to keep it as a direct handler here rather than trying to parameterize all that.
Route definition:
(defn routes [_config]
["/accounts-payable"
[""
{:name ::list
:get {:summary "List AP documents"
:parameters {:query [...]}
:handler #'list-documents}}]
["/events"
{:name ::list-events
:get {:summary "SSE events for AP list"
:handler #'list-events}}]
["/search"
{:name ::search
:get {:summary "Search AP documents"
:parameters {:query [:map [:q {:optional true} :string]]}
:handler #'search-documents}}]
["/bulk"
["/toggle/:document-id"
{:name ::bulk-toggle
:post {:summary "Toggle document selection"
:parameters {:path {:document-id :uuid}}
:handler #'bulk-toggle}}]
["/toggle-all"
{:name ::bulk-toggle-all
:post {:handler #'bulk-toggle-all}}]
["/deselect-all"
{:name ::bulk-deselect-all
:post {:handler #'bulk-deselect-all}}]
["/export-datev"
{:name ::bulk-export-datev
:post {:handler #'bulk-export-datev}}]]])
Important: Update all internal path-for calls to use new route names. For example, document-row generates links to ::detail which must become :com.getorcha.erp.http.documents.view/detail.
Step 1: Create the file.
Step 2: Verify it compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/accounts_payable.clj
git commit -m "refactor(documents): create accounts-payable namespace with list, bulk, and SSE"
documents.managementFiles:
src/com/getorcha/erp/http/documents/management.cljWhat moves here (all from document_management.clj):
| Function | Source Lines | Notes |
|---|---|---|
per-page |
dm:29 | |
managed-types |
dm:31-33 | |
type-labels |
dm:35-39 | |
type-icon |
dm:125-129 | UI |
display-fields |
dm:70-84 | |
document-row |
dm:157-198 | UI (different from AP row) |
type-filter-dropdown |
dm:229-250 | UI |
list-page |
dm:253-372 | UI |
lateral-join-ingestion |
dm:379-388 | SQL |
build-where |
dm:391-414 | SQL |
build-order-by |
dm:417-426 | SQL |
list-documents |
dm:429-517 | Handler |
search-documents |
dm:520-561 | Handler |
New: Add list-events SSE handler. Use shared/make-list-events-handler with management's type filter and row renderer:
(def ^:private list-events
(shared/make-list-events-handler
managed-types ;; #{:contract :purchase-order :goods-received-note :other}
document-row)) ;; management's row renderer
If the parameterized approach is too awkward due to management-specific query/rendering needs, write a dedicated handler modeled on the AP one but filtering to management types.
Route definition:
(defn routes [_config]
["/management"
[""
{:name ::list
:get {:summary "List managed documents"
:parameters {:query [...]}
:handler #'list-documents}}]
["/events"
{:name ::list-events
:get {:summary "SSE events for management list"
:handler #'list-events}}]
["/search"
{:name ::search
:get {:summary "Search managed documents"
:parameters {:query [:map [:q {:optional true} :string]]}
:handler #'search-documents}}]])
Important: Same as AP — update all path-for calls to use new route names. Detail links in document-row → :com.getorcha.erp.http.documents.view/detail.
Step 1: Create the file.
Step 2: Verify it compiles.
Step 3: Commit:
git add src/com/getorcha/erp/http/documents/management.clj
git commit -m "refactor(documents): create management namespace with list, search, and SSE"
documents.clj as route assemblerFiles:
src/com/getorcha/erp/http/documents.cljRewrite the file entirely. It becomes a thin route assembler (~30 lines):
(ns com.getorcha.erp.http.documents
"Document routes — assembles all document sub-module routes."
(:require [com.getorcha.erp.http.documents.accounts-payable :as accounts-payable]
[com.getorcha.erp.http.documents.management :as management]
[com.getorcha.erp.http.documents.shared :as shared]
[com.getorcha.erp.http.documents.upload :as upload]
[com.getorcha.erp.http.documents.view :as view]
[com.getorcha.db.sql :as db.sql]
[ring.util.http-response :as ring.resp]))
(defn ^:private get-document-by-hash
"Get document by content hash."
[{:keys [db-pool parameters] :as request} respond _raise]
(let [hash (get-in parameters [:path :document-hash])
document (db.sql/execute-one!
db-pool
{:select [:*]
:from [:document]
:where [:and
[:= :content-hash hash]
[:in :legal-entity-id (shared/legal-entity-ids request)]]}
{:builder-fn shared/document-builder-fn})]
(if document
(respond (ring.resp/ok document))
(respond (ring.resp/not-found {:error "Document not found"})))))
(defn routes [_config]
["/documents"
["" {:get {:handler (fn [_ respond _] (respond (ring.resp/not-found "")))}}]
["/by-hash/:document-hash"
{:name ::by-hash
:get {:summary "Get document by content hash"
:parameters {:path {:document-hash :string}}
:handler #'get-document-by-hash}}]
(upload/routes _config)
(accounts-payable/routes _config)
(management/routes _config)
(view/routes _config)])
Step 1: Rewrite the file.
Step 2: Verify it compiles.
Step 3: Do NOT commit yet — tests will fail until external references are updated.
Files:
src/com/getorcha/erp/http.clj — remove document-management require, keep single documents requiresrc/com/getorcha/erp/ui/layout.clj:39-40 — update sidebar nav route namessrc/com/getorcha/erp/http/profile.clj:33 — update redirect route namesrc/com/getorcha/erp/http/login.clj:242,313,394 — update post-login redirect route namessrc/com/getorcha/erp/http/document_management.cljerp/http.clj changes:
[com.getorcha.erp.http.document-management :as erp.http.document-management](erp.http.document-management/routes config)(erp.http.documents/routes config) (now assembles everything)erp/ui/layout.clj changes (lines 39-40):
;; Old:
(erp.http.routes/path-for router :com.getorcha.erp.http.documents/list)
(erp.http.routes/path-for router :com.getorcha.erp.http.document-management/list)
;; New:
(erp.http.routes/path-for router :com.getorcha.erp.http.documents.accounts-payable/list)
(erp.http.routes/path-for router :com.getorcha.erp.http.documents.management/list)
erp/http/profile.clj change (line 33):
;; Old:
(erp.http.routes/path-for router :com.getorcha.erp.http.documents/list)
;; New:
(erp.http.routes/path-for router :com.getorcha.erp.http.documents.accounts-payable/list)
erp/http/login.clj changes (lines 242, 313, 394):
;; Old (all 3 occurrences):
(erp.http.routes/path-for router :com.getorcha.erp.http.documents/list)
;; New:
(erp.http.routes/path-for router :com.getorcha.erp.http.documents.accounts-payable/list)
Also update the require alias in login.clj if it uses ::erp.http.documents/list shorthand — it does on line 242. Either switch to fully qualified keyword or update the alias.
Step 1: Make all changes.
Step 2: Delete document_management.clj.
Step 3: Verify all source files compile:
(require 'com.getorcha.erp.http :reload-all)
Step 4: Commit:
git add src/com/getorcha/erp/http.clj \
src/com/getorcha/erp/http/documents.clj \
src/com/getorcha/erp/ui/layout.clj \
src/com/getorcha/erp/http/profile.clj \
src/com/getorcha/erp/http/login.clj
git rm src/com/getorcha/erp/http/document_management.clj
git commit -m "refactor(documents): wire new route structure, remove old document-management"
Files:
test/com/getorcha/erp/http/documents/upload_test.cljtest/com/getorcha/erp/http/documents/accounts_payable_test.cljtest/com/getorcha/erp/http/documents/management_test.cljtest/com/getorcha/erp/http/documents/view_test.cljtest/com/getorcha/erp/http/documents/view/invoice_test.cljRedistribute from existing tests. Route name references must be updated throughout.
upload_test.clj — from documents_test.clj:
upload-document-test (lines 45-123) — update route refs from ::http.documents/upload to ::http.upload/upload, ::http.documents/by-hash to ::http.documents/by-hashaccounts_payable_test.clj — from documents_test.clj:
list-documents-test (lines 126-144) — update ::http.documents/list → ::http.ap/listbulk-toggle-test (lines 604-671) — update all ::http.documents/bulk-* → ::http.ap/bulk-*bulk-toggle-all-test (lines 674-721) — samebulk-export-datev-test (lines 724-741) — samelist-sse-sends-event-on-status-transition-test (lines 418-468) — update route refsview_test.clj — from both test files:
get-document-test (docs_test:147-190) — update ::http.documents/detail → ::http.view/detailsse-events-test (docs_test:193-236) — split: list SSE tests go to AP, detail SSE tests stay heredetail-sse-sends-event-on-status-change-test (docs_test:292-342) — update refsdisplay-file-path-test (docs_test:345-415) — update refstenant-isolation-test (docs_test:471-545) — update refsdetail-document-test (dm_test:134-156) — merge into view testsdetail-sse-test (dm_test:200-236) — merge into view testsnavigation-preserves-filters-test (dm_test:242-256) — update pathmanagement_test.clj — from document_management_test.clj:
list-documents-test (dm_test:88-128) — update ::http.dm/list → ::http.management/listsearch-documents-test (dm_test:285-292) — update pathview/invoice_test.clj — if any DATEV export tests exist in documents_test, move them here. Currently none exist as standalone tests, but display-file-path-test touches DATEV. Keep it in view_test.clj for now.
Shared test helpers (temp-file, purge-queue!, read-sse-events, update-ingestion-status!, mark-ingestion-completed!) — put in a shared test helper namespace or duplicate in each test file that needs them. Prefer a shared test helper:
test/com/getorcha/erp/http/documents/test_helpers.clj for shared test utilitiesStep 1: Create all test files with redistributed tests and updated route references.
Step 2: Run tests:
clj -X:test:silent :nses '[com.getorcha.erp.http.documents.upload-test
com.getorcha.erp.http.documents.accounts-payable-test
com.getorcha.erp.http.documents.management-test
com.getorcha.erp.http.documents.view-test]'
Step 3: Fix any failures.
Step 4: Delete old test files:
git rm test/com/getorcha/erp/http/documents_test.clj
git rm test/com/getorcha/erp/http/document_management_test.clj
Step 5: Commit:
git add test/com/getorcha/erp/http/documents/
git rm test/com/getorcha/erp/http/documents_test.clj
git rm test/com/getorcha/erp/http/document_management_test.clj
git commit -m "refactor(documents): redistribute tests to match new namespace structure"
Step 1: Run all tests:
clj -X:test:silent 2>&1 | grep -A 5 -E "(FAIL in|ERROR in|Execution error|failed because|Ran .* tests)"
Step 2: Fix any failures. Common issues:
path-for calls using old route names in Hiccup templatesStep 3: Grep for any remaining old references:
# Should return zero results
grep -r "erp.http.document-management" src/ test/
grep -r "erp.http.documents/" src/ test/ | grep -v "erp.http.documents\." | grep -v documents.clj
Step 4: Commit any fixes:
git commit -m "fix(documents): resolve remaining references after module split"
Step 1: Start the system: (reset) in REPL.
Step 2: Verify in browser:
/documents → 404/documents/accounts-payable → AP list page loads/documents/management → DM list page loads/documents/view/:uuid loads correct detail view/documents/view/:uuidStep 3: Fix any issues found.
Step 4: Final commit if needed.