For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Expand contract sub-types (loan, rental, insurance, subscription, purchase) and add a "financially active" concept with UI badges and filtering.
Architecture: The contract-type enum lives in JSONB structured_data, not a DB enum — so expansion requires schema + prompt changes only. The financially-active flag is derived from contract-type in code, not stored. UI gets a new badge and filter.
Tech Stack: Clojure, Malli schemas, Hiccup/HTMX, CSS, clj-kondo, cognitect test-runner
Files:
orcha/src/com/getorcha/schema/contract/structured_data.clj:5-6Step 1: Update the ContractType enum
Change lines 5-6 from:
(def ^:private ContractType
[:enum "service" "supply" "lease" "nda" "framework" "other"])
to:
(def ^:private ContractType
[:enum "loan" "lease" "rental" "insurance" "subscription" "purchase"
"service" "supply" "nda" "framework" "other"])
Step 2: Add financially-active? helper
After the ContractType def (after line 6), add:
(def financially-active-types
"Contract types with recurring financial obligations."
#{"loan" "lease" "rental" "insurance" "subscription"})
(defn financially-active?
"Returns true if the given contract-type carries recurring financial obligations."
[contract-type]
(contains? financially-active-types contract-type))
Note: Remove ^:private from ContractType so it can be referenced by the UI layer, OR keep it private and just expose financially-active? + financially-active-types. The latter is cleaner — keep ContractType private.
Step 3: Run lint
Run: cd orcha && clj-kondo --lint src/com/getorcha/schema/contract/structured_data.clj
Expected: 0 errors
Step 4: Commit
git add orcha/src/com/getorcha/schema/contract/structured_data.clj
git commit -m "feat: Expand contract-type enum and add financially-active? helper"
Files:
orcha/src/com/getorcha/workers/ingestion/classification.clj:88Step 1: Update the contract line in the classification prompt
In the defmethod workers/-prompt :classification (line 81), change line 88 from:
- contract: Legal agreements, service contracts, lease/rent agreements (Mietvertrag), NDAs, terms of service, framework agreements (Rahmenvertrag)
to:
- contract: Legal agreements including loan agreements (Darlehensvertrag, Kreditvertrag), lease contracts (Leasingvertrag), rental agreements (Mietvertrag, Pachtvertrag), insurance policies (Versicherungsvertrag), subscription/SaaS contracts, purchase agreements (Kaufvertrag), service contracts (Dienstleistungsvertrag), supply agreements (Liefervertrag), NDAs, framework agreements (Rahmenvertrag)
Also update rule 10 (line 146-148) from:
10. Rent/lease agreements (Mietvertrag, Nachtrag, Pachtvertrag) are "contract", NOT invoices -
even if they contain amounts, payment schedules, or recurring fees. Key signals: signing parties,
contract duration/term, notice period (Kündigungsfrist), landlord/tenant (Vermieter/Mieter).
to:
10. Contracts (Mietvertrag, Leasingvertrag, Darlehensvertrag, Versicherungsvertrag, Kaufvertrag,
Dienstleistungsvertrag, Liefervertrag, Pachtvertrag, Nachtrag) are "contract", NOT invoices -
even if they contain amounts, payment schedules, or recurring fees. Key signals: signing parties,
contract duration/term, notice period (Kündigungsfrist), landlord/tenant (Vermieter/Mieter),
loan terms (Zinssatz, Tilgung), insurance premiums (Prämie, Versicherungssumme).
Step 2: Run lint
Run: cd orcha && clj-kondo --lint src/com/getorcha/workers/ingestion/classification.clj
Expected: 0 errors
Step 3: Commit
git add orcha/src/com/getorcha/workers/ingestion/classification.clj
git commit -m "feat: Update classification prompt with expanded contract types"
Files:
orcha/src/com/getorcha/workers/ingestion/extraction.clj:801-807,837Step 1: Update contract type definitions in extraction prompt
Change lines 801-807 from:
8. Contract type classification:
- "service": Service agreements, consulting contracts, maintenance agreements
- "supply": Supply agreements, procurement contracts, material delivery
- "lease": Rental or leasing contracts for equipment, property, vehicles
- "nda": Non-disclosure agreements, confidentiality agreements
- "framework": Framework agreements, master agreements, blanket contracts
- "other": Any contract type not fitting the above categories
to:
8. Contract type classification:
- "loan": Loan agreements (Darlehensvertrag), credit agreements (Kreditvertrag), financing contracts
- "lease": Leasing contracts for equipment, vehicles, machinery (Leasingvertrag)
- "rental": Rental agreements for real estate, office space, property (Mietvertrag, Pachtvertrag)
- "insurance": Insurance contracts, policies (Versicherungsvertrag, Versicherungspolice)
- "subscription": SaaS agreements, recurring license agreements, maintenance contracts with periodic fees (Wartungsvertrag)
- "purchase": Purchase agreements, sale contracts (Kaufvertrag, Erwerbsvertrag)
- "service": One-off service agreements, consulting contracts (Dienstleistungsvertrag, Beratungsvertrag)
- "supply": Supply agreements, procurement contracts, material delivery (Liefervertrag)
- "nda": Non-disclosure agreements, confidentiality agreements
- "framework": Framework agreements, master agreements, blanket contracts (Rahmenvertrag)
- "other": Any contract type not fitting the above categories
Step 2: Update the JSON schema in the extraction prompt
Change line 837 from:
"contract-type": "service" | "supply" | "lease" | "nda" | "framework" | "other" | null,
to:
"contract-type": "loan" | "lease" | "rental" | "insurance" | "subscription" | "purchase" | "service" | "supply" | "nda" | "framework" | "other" | null,
Step 3: Run lint
Run: cd orcha && clj-kondo --lint src/com/getorcha/workers/ingestion/extraction.clj
Expected: 0 errors
Step 4: Commit
git add orcha/src/com/getorcha/workers/ingestion/extraction.clj
git commit -m "feat: Update extraction prompt with expanded contract-type enum"
Files:
orcha/src/com/getorcha/erp/http/document_management.clj:1-24,33-37,141-174Step 1: Add require for contract schema
In the ns form (line 1-24), add to the :require vector:
[com.getorcha.schema.contract.structured-data :as contract.schema]
Step 2: Add contract-type-labels map
After the type-labels def (after line 37), add:
(def ^:private contract-type-labels
"Human-readable labels for contract sub-types."
{"loan" "Loan"
"lease" "Lease"
"rental" "Rental"
"insurance" "Insurance"
"subscription" "Subscription"
"purchase" "Purchase"
"service" "Service"
"supply" "Supply"
"nda" "NDA"
"framework" "Framework"
"other" "Other"})
Step 3: Add badges in the document-row function
In document-row (lines 141-174), update the last [:td ...] cell (lines 165-173). Change from:
[:td (or (erp.ui.components/format-date renewal-date) "\u2014")
(when-let [cs (contract-status type structured-data)]
[:span {:class (str "badge badge-contract-" (name cs))
:style "margin-left: 8px;"}
(case cs
:active "Active"
:expiring-soon "Expiring"
:expired "Expired"
:pending "Pending")])]
to:
[:td (or (erp.ui.components/format-date renewal-date) "\u2014")
(when (= "contract" (some-> type name))
(let [ct (:contract-type structured-data)]
(list
(when ct
[:span.badge.badge-contract-subtype {:style "margin-left: 8px;"} (get contract-type-labels ct ct)])
(when (contract.schema/financially-active? ct)
[:span.badge.badge-financial {:style "margin-left: 4px;"} "Financial"]))))
(when-let [cs (contract-status type structured-data)]
[:span {:class (str "badge badge-contract-" (name cs))
:style "margin-left: 4px;"}
(case cs
:active "Active"
:expiring-soon "Expiring"
:expired "Expired"
:pending "Pending")])]
Step 4: Run lint
Run: cd orcha && clj-kondo --lint src/com/getorcha/erp/http/document_management.clj
Expected: 0 errors
Step 5: Commit
git add orcha/src/com/getorcha/erp/http/document_management.clj
git commit -m "feat: Add contract-type and financial badges to document list"
Files:
orcha/resources/erp/public/css/style.css:5246 (after contract lifecycle badges)Step 1: Add new badge styles
After line 5246 (.badge-contract-pending), add:
/* Contract sub-type badge */
.badge-contract-subtype { background: rgba(56, 139, 253, 0.15); color: #58a6ff; }
/* Financially active badge */
.badge-financial { background: rgba(31, 111, 139, 0.2); color: #3bc9db; }
Step 2: Commit
git add orcha/resources/erp/public/css/style.css
git commit -m "feat: Add CSS for contract-type and financial badges"
Files:
orcha/src/com/getorcha/erp/http/document_management.clj:244-257,366-385Step 1: Add "Financially Active" filter tab
In the status filter tabs section (lines 253-257), add a new tab after "Processing":
[:a.filter-tab {:href (tab-url "financially-active") :class (when (= status-filter "financially-active") "active")} "Financially Active"]
The full block (lines 253-257) becomes:
[:div.status-filter-tabs
[:a.filter-tab {:href (tab-url "all") :class (when (= status-filter "all") "active")} "All"]
[:a.filter-tab {:href (tab-url "completed") :class (when (= status-filter "completed") "active")} "Completed"]
[:a.filter-tab {:href (tab-url "needs-review") :class (when (= status-filter "needs-review") "active")} "Needs Review"]
[:a.filter-tab {:href (tab-url "processing") :class (when (= status-filter "processing") "active")} "Processing"]
[:a.filter-tab {:href (tab-url "financially-active") :class (when (= status-filter "financially-active") "active")} "Financial"]]
Step 2: Add filter logic in build-where
In build-where (lines 366-385), add a new clause for financially-active status. After the (= status-filter "processing") clause (line 384-385), add:
(= status-filter "financially-active")
(conj [:= [:cast :document.type :text] "contract"]
[:in [:raw "document.structured_data->>'contract-type'"]
["loan" "lease" "rental" "insurance" "subscription"]])
Step 3: Run lint
Run: cd orcha && clj-kondo --lint src/com/getorcha/erp/http/document_management.clj
Expected: 0 errors
Step 4: Commit
git add orcha/src/com/getorcha/erp/http/document_management.clj
git commit -m "feat: Add Financially Active filter tab to Document Management"
Files:
orcha/test/com/getorcha/workers/ingestion/classification_test.cljorcha/test/com/getorcha/schema/contract/structured_data_test.cljStep 1: Add financially-active? unit tests
Create orcha/test/com/getorcha/schema/contract/structured_data_test.clj:
(ns com.getorcha.schema.contract.structured-data-test
(:require [clojure.test :refer [deftest is testing]]
[com.getorcha.schema.contract.structured-data :as contract.schema]))
(deftest test-financially-active?
(testing "financially active types return true"
(doseq [t ["loan" "lease" "rental" "insurance" "subscription"]]
(is (true? (contract.schema/financially-active? t))
(str t " should be financially active"))))
(testing "non-financial types return false"
(doseq [t ["purchase" "service" "supply" "nda" "framework" "other"]]
(is (false? (contract.schema/financially-active? t))
(str t " should NOT be financially active"))))
(testing "nil returns false"
(is (false? (contract.schema/financially-active? nil)))))
(deftest test-financially-active-types
(testing "contains exactly the expected types"
(is (= #{"loan" "lease" "rental" "insurance" "subscription"}
contract.schema/financially-active-types))))
Step 2: Run the new test to verify it passes
Run: cd orcha && clojure -X:test :includes '["com.getorcha.schema.contract.structured-data-test"]'
If that syntax doesn't work with the test runner, run the full suite:
Run: cd orcha && clojure -X:test
Expected: All tests pass, 0 failures, 0 errors
Step 3: Commit
git add orcha/test/com/getorcha/schema/contract/structured_data_test.clj
git commit -m "test: Add unit tests for financially-active? helper"
Step 1: Run lint
Run: cd orcha && clj-kondo --lint src:dev:test
Expected: 0 errors (warnings OK if pre-existing)
Step 2: Run full test suite
Run: cd orcha && clojure -X:test
Expected: All tests pass, 0 failures, 0 errors
Step 3: Final commit (if any fixes needed)
Only if lint/tests required fixes.
Step 1: Create branch from master
git checkout -b financially-active-contracts master
Note: If you've been committing on master, cherry-pick or rebase the commits onto the new branch instead.
Step 2: Push and create PR
git push -u origin financially-active-contracts
gh pr create --title "feat: Support financially active contracts (#278)" --body "..."
Link PR to issue #278.