Core application code lives in src/com/getorcha. Tests mirror that structure in test/com/getorcha, with shared fixtures in test/com/getorcha/test/fixtures.clj. Runtime configuration, static assets, and database migrations live under resources/, especially resources/com/getorcha/ and resources/migrations/. REPL helpers are in dev/, automation scripts in scripts/, and longer-form design or regression notes in docs/.
Use Babashka for local environment tasks and Clojure CLI for app execution:
bb dev:up: start PostgreSQL and MiniStack for local development.bb dev:status: confirm container health.bb migrate migrate: apply pending migrations.clj -A:dev: start the development REPL; use (reset) from dev/user.clj to reload.clj -M -m com.getorcha.system: run the app directly on http://localhost:8888.clj -X:test: run the full test suite.clj -X:test:silent :nses '[com.getorcha.foo-test]': run one test namespace with quieter logs.clj-kondo --lint src test dev: run linting; fix all findings before submitting work.gh issue view <number> / gh pr view <number>: inspect GitHub issues and PRs directly from the CLI before asking the user to restate linked context.Use clj-nrepl-eval when editing Clojure code and you need a fast compile check, a targeted behavior check, or runtime inspection without restarting the app. In this repo, start an nREPL with the project aliases the user is already using; if no nREPL is running, ask before starting one. First try clj-nrepl-eval --discover-ports. If discovery does not find the live REPL, read .nrepl-port from the repo root and connect directly with clj-nrepl-eval -p <port>.
After edits, prefer reloading namespaces over restarting the session:
clj-nrepl-eval -p <port> "(require 'com.getorcha.system :reload)"clj-nrepl-eval -p <port> "(require 'user :reload) (resolve 'user/reset)"Prefer short quoted evals for single checks. Use multiline input only when the code is genuinely easier to read that way.
Use the installed playwright-cli command for manual browser verification from Codex. Do not start with npx playwright, Playwright test runners, or MCP-only assumptions. The development app normally runs at http://localhost:8888; confirm it is already up before opening the browser:
curl -sS -I http://localhost:8888/applaywright-cli listplaywright-cli open http://localhost:8888/applaywright-cli snapshotThe AP overview smoke target is /ap. A successful load has page title Orcha - Accounts Payable and a table with Received, Invoice Nr., Supplier, Total Amount, Due Date, Matches, and Status columns. Use playwright-cli snapshot to get element refs before clicking or filling controls. Use playwright-cli close when finished.
If Chromium launch fails because of profile state, retry with a temporary profile path while keeping the default browser cache:
playwright-cli open http://localhost:8888/ap --profile=/tmp/orcha-pw-profileDo not set XDG_CACHE_HOME or PLAYWRIGHT_BROWSERS_PATH unless you have also installed browsers into that location. In Codex, those variables can make playwright-cli report Browser "chromium" is not installed even when the plain command works.
This repository is Clojure-first. Use kebab-case for identifiers and reverse-domain namespaces such as com.getorcha.workers.ap.ingestion. Keep related logic in the same namespace unless reuse clearly justifies extraction. Prefer ^:private over defn-, add docstrings to public functions, alphabetize :require entries, and preserve the existing formatting style: aligned bindings and two blank lines between top-level forms. Use snake_case only where database or SQL naming requires it.
Tests use clojure.test with namespaces named after the source namespace plus -test, for example com.getorcha.link.oauth -> com.getorcha.link.oauth-test. Prefer fixture-driven integration tests over ad hoc setup, using the shared system and DB rollback helpers in test/com/getorcha/test/fixtures.clj. Add or update tests with every behavior change, and run the narrowest relevant namespace first before running the full suite.
Recent history uses short conventional subjects such as fix(edits): sync version-holder after async persist-derivation bump. Follow that pattern: <type>(<scope>): <imperative summary>, with focused commits and no mixed-purpose changes. Pull requests should explain the user-visible impact, note any schema or config changes, link the relevant issue or plan, and include screenshots only when UI behavior changed.
Do not commit secrets. Local Google Document AI credentials belong in credentials/google-docai.json. Prefer config-driven values in resources/com/getorcha/config.edn over hardcoded environment-specific constants, and use new migrations instead of editing resources/migrations/init.sql.