# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Integreat is a full-stack web application for accounts payable (AP) and accounting automation. It integrates with multiple financial data sources (Plaid, Yodlee, Square, Intuit QBO) to manage invoices, bank accounts, transactions, and vendor information.

**Tech Stack:**
- Backend: Clojure 1.10.1 with Ring (Jetty), Datomic database, GraphQL (Lacinia, in process of depracation)
- Frontend, two versions: 
    * ClojureScript with Reagent, Re-frame, (almost depracated)
    * Server side: HTMX, TailwindCSS, alpinejs (current)
- Java: Amazon Corretto 11 (required for Clojure 1.10.1)

## Development Commands

**Build:**
```bash
lein build              # Create uberjar
lein uberjar            # Standalone JAR
npm install             # Install Node.js dependencies (for frontend build)
```

### Development
```bash
docker-compose up -d    # Start Datomic, Solr services
lein repl               # Start Clojure REPL (nREPL on port 9000), typically one will be running for you already
lein cljfmt check       # Check code formatting
lein cljfmt fix         # Auto-format code
clj-paren-repair [FILE ...] # fix parentheses in files
clj-nrepl-eval -p PORT "(+ 1 2 3)" #  evaluate clojure code

```

Often times, if a file won't compile, first clj-paren-repair on the file, then try again. If it doesn't wor still, try cljfmt check.


**Running the Application:**

**As Web Server:**
```bash
INTEGREAT_JOB="" lein run  # Default: port 3000
# Or with custom port:
PORT=3449 lein run
```

**As Background Job:**
Set `INTEGREAT_JOB` environment variable to one of:
- `square-import-job` - Square POS transaction sync
- `yodlee2` - Yodlee bank account sync
- `plaid` - Plaid bank linking
- `intuit` - Intuit QBO sync
- `import-uploaded-invoices` - Process uploaded invoice PDFs
- `ezcater-upsert` - EZcater PO sync
- `ledger_reconcile` - Ledger reconciliation
- `bulk_journal_import` - Journal entry import
- (no job) - Run web server + nREPL

## Architecture

**Request Flow:**
1. Ring middleware pipeline processes requests
2. Authentication/authorization middleware (Buddy) wraps handlers
3. Bidi routes dispatch to handlers
4. SSR (server-side rendering) generates HTML with Hiccup for main views
5. For interactive pages, HTMX handles partial updates
6. Client-side uses alpinejs as a bonus

**Multi-tenancy:**
- Client-based filtering via `:client/code` and `:client/groups`
- Client selection via `X-Clients` header or session
- Role-based permissions: admin, standard user, vendor

**Key Directories:**
- `src/clj/auto_ap/` - Backend Clojure code
- `src/clj/auto_ap/server.clj` - Main entry point, job dispatcher, Mount lifecycle
- `src/clj/auto_ap/handler.clj` - Ring app, middleware stack
- `src/clj/auto_ap/datomic/` - Datomic schema and queries
- `src/clj/auto_ap/ssr/` - Server-side rendered page handlers (Hiccup templates)
- `src/clj/auto_ap/routes/` - HTTP route definitions
- `src/clj/auto_ap/jobs/` - Background batch jobs
- `src/clj/auto_ap/graphql/` - GraphQL type definitions and resolvers
- `src/cljs/auto_ap/` - Frontend ClojureScript for old, depracated version
- `test/clj/auto_ap/` - Unit/integration tests

## Database

- Datomic schema defined in `resources/schema.edn`
- Key entity patterns:
  - `:client/code`, `:client/groups` for multi-tenancy
  - `:vendor/*`, `:invoice/*`, `:transaction/*`, `:account/*` for standard entities
  - `:db/type/ref` for relationships, many with `:db/cardinality :db.cardinality/many`

## Configuration

- Dev config: `config/dev.edn` (set via `-Dconfig=config/dev.edn`)
- Env vars: `INTEGREAT_JOB`, `PORT`
- Docker: Uses Alpine-based Amazon Corretto 11 image

## Important Patterns

- **Middleware stack** in `handler.clj`: route matching → logging → client hydration → session/auth → idle timeout → error handling → gzip
- **Client context** added by middleware: `:identity`, `:clients`, `:client`, `:matched-route`
- **Job dispatching** in `server.clj`: checks `INTEGREAT_JOB` env var to run specific background jobs or start web server
- **Test selectors**: namespaces ending in `integration` or `functional` are selected by `lein test :integration` / `lein test :functional`

## Clojure REPL Evaluation

The command `clj-nrepl-eval` is installed on your path for evaluating Clojure code via nREPL.

**Discover nREPL servers:**

`clj-nrepl-eval --discover-ports`

**Evaluate code:**

`clj-nrepl-eval -p <port> "<clojure-code>"`

With timeout (milliseconds)

`clj-nrepl-eval -p <port> --timeout 5000 "<clojure-code>"`

The REPL session persists between evaluations - namespaces and state are maintained.
Always use `:reload` when requiring namespaces to pick up changes.
