# ows-coda

AI agent for the Abacus music royalties platform. Powered by Claude on AWS Bedrock, it answers questions about accounts, contracts, advances, revenue, and ledger balances by calling live backend services via native tool use.

Runs as a standalone Express server behind `ows-grass`, which handles JWT verification and injects identity headers.

---

## Architecture

```
Browser (React SPA)
      |  POST /api/v1/chats/:id/stream (SSE)
      v
  ows-grass  <-- JWT verification, identity header injection
      |
      v
  ows-coda   <-- this service
      |
      +-- AWS Bedrock (Claude)    <-- streaming tool-use loop
      +-- Redis                   <-- conversations (7-day TTL) + rate limiting
      +-- Snowflake               <-- agent-consumable views (key-pair auth, read-only)
      |
      +-- Downstream services
           +-- ows-abacus-account  <-- accounts, payees, tax, payments
           +-- ows-royalties       <-- contracts, advances, terms
           +-- ows-moneyhub        <-- revenue, statement periods
           +-- ows-product         <-- products by UPC / ISRC
           +-- ows-ledger          <-- balances, payable amounts, adjustments
           +-- GraphQL gateway     <-- federated schema queries
```

## Quick start

```bash
git clone git@github.com:theorchard/ows-coda.git
cd ows-coda
cp apps/server/.env.shadow apps/server/.env   # fill in server secrets
cp apps/client/.env.shadow apps/client/.env   # fill in client secrets
pnpm install
aws sso login --profile orchard-dev
pnpm dev          # backend on http://localhost:8080
pnpm dev:client   # frontend on http://localhost:5173
```

See [Getting Started](docs/getting-started.md) for the full setup walkthrough.

### Lightweight local dev

The server boots fine with **no Redis, MySQL, Snowflake, search, or platform service** — each degrades gracefully (in-memory cache, disabled tools). The two things that make local dev heavy are the 11 library build-watchers and Auth0 gating every request. For fast iteration:

```bash
cp apps/server/.env.shadow apps/server/.env   # boots offline: in-memory cache,
                                              # no DB, auth bypass on (CODA_DEV_AUTH_BYPASS=true)
pnpm install
aws sso login --profile orchard-dev           # only needed for real Bedrock/AI calls
pnpm dev:light                                 # builds libs ONCE, then watches only the server
```

- `pnpm dev:light` skips the 11 always-on `tsdown --watch` processes (run it again, or `pnpm build:libs`, after editing a `packages/*` library).
- `CODA_DEV_AUTH_BYPASS=true` (non-prod only — force-disabled in production) injects a fixed dev identity so the API works without an Auth0 token.
- Leave `REDIS_URL`, `CODA_DB_*`, and `SNOWFLAKE_*` blank to run fully in-memory.
- Docker: `pnpm docker:up` no longer starts the Langfuse stack by default (add `--profile langfuse`), and the search container defaults to deterministic embeddings (no ONNX download).

## Workspaces

### Apps (deployable services)

| Package                  | Path             | Description                                        |
| ------------------------ | ---------------- | -------------------------------------------------- |
| `@coda/server-app`       | `apps/server/`   | Express API + AI agent loop                        |
| `@coda/client-app`       | `apps/client/`   | React/Vite frontend — uses Vitest, not Jest        |
| `@coda/search-service`   | `apps/search/`   | Hybrid search microservice (ConnectRPC, BM25+HNSW) |
| `@coda/runner-service`   | `apps/runner/`   | Datasource runner service (WIP — COD-90)           |
| `@coda/platform-service` | `apps/platform/` | Platform service (auth, tenancy, permissions)      |

### Packages (shared libraries)

| Package                 | Path                        | Description                                                   |
| ----------------------- | --------------------------- | ------------------------------------------------------------- |
| `@coda/async`           | `packages/async/`           | Async patterns: circuit breaker, retry, semaphore, throttlers |
| `@coda/data-structures` | `packages/data-structures/` | Data structures (heaps, lists, trees) and algorithms          |
| `@coda/search`          | `packages/search/`          | Search engine: BM25, HNSW, trie, hybrid search, scoring       |
| `@coda/common`          | `packages/common/`          | Graph, storage, redis, crypto, utilities                      |
| `@coda/sandbox`         | `packages/sandbox/`         | Isolated code execution engine (isolated-vm)                  |
| `@coda/api-common`      | `packages/api-common/`      | Shared pagination protos, RPC utilities (callRpc, RpcResult)  |
| `@coda/core-api`        | `packages/core-api/`        | REST types, HTTP client, proto-generated ConnectRPC services  |
| `@coda/admin-api`       | `packages/admin-api/`       | Admin ConnectRPC services (access, identity, tenancy, RBAC)   |
| `@coda/search-api`      | `packages/search-api/`      | Search ConnectRPC client + proto definitions                  |
| `@coda/runner-api`      | `packages/runner-api/`      | Runner ConnectRPC client + proto definitions                  |
| `@coda/tools-api`       | `packages/tools-api/`       | Tool service proto definitions                                |
| `@coda/datasources-api` | `packages/datasources-api/` | Datasource service proto definitions                          |
| `@coda/dashboards-api`  | `packages/dashboards-api/`  | Dashboard service proto definitions                           |
| `@coda/db`              | `packages/db/`              | Prisma ORM (Aurora MySQL)                                     |
| `@coda/extensions`      | `packages/extensions/`      | Domain glossary data (GraphQL + Snowflake)                    |

Build order: `packages/db/` → `packages/core-api/` → apps can build independently.

## Common commands

| Command           | Description                          |
| ----------------- | ------------------------------------ |
| `pnpm dev`        | Hot-reload backend (tsx)             |
| `pnpm dev:client` | Hot-reload frontend (Vite)           |
| `pnpm dev:all`    | Run both concurrently                |
| `pnpm build`      | Build db → api → server              |
| `pnpm test`       | Lint + unit tests with coverage      |
| `pnpm test:unit`  | Jest/Vitest only                     |
| `pnpm docker:up`  | Full Docker dev environment with HMR |

## Documentation

| Doc                                         | What it covers                                                   |
| ------------------------------------------- | ---------------------------------------------------------------- |
| [Getting Started](docs/getting-started.md)  | Onboarding, prerequisites, setup, Claude Code                    |
| [Architecture](ARCHITECTURE.md)             | System design, request flow, design decisions, project structure |
| [Contributing](CONTRIBUTING.md)             | Workflow, conventions, PR process, adding tools                  |
| [API Reference](docs/api/server.md)         | Endpoints, SSE events, models, attachments                       |
| [Tool Catalog](docs/api/tool-catalog.md)    | All 9 tool categories + 5 skills                                 |
| [Testing](docs/guides/testing.md)           | Vitest, mocking patterns, writing tests                          |
| [Deployment](docs/operations/deployment.md) | Jenkins pipeline, Docker stages, environments                    |
| [Docker](docs/guides/docker.md)             | Local Docker environment, commands, troubleshooting              |
| [Runbook](docs/operations/runbook.md)       | Troubleshooting common issues                                    |
| [Snowflake Views](docs/snowflake-views.md)  | Agent-consumable views playbook                                  |

### Design specs

| Spec                                                                            | Status      |
| ------------------------------------------------------------------------------- | ----------- |
| [Database Package Extraction](docs/decisions/trds/db-package-extraction.md)     | Implemented |
| [Docker Compose Environment](docs/decisions/trds/docker-compose-environment.md) | Implemented |
| [Offline Client](docs/decisions/prds/offline-client-cursor-pagination.md)       | Draft       |

## Links

| Resource   | URL                                                                                     |
| ---------- | --------------------------------------------------------------------------------------- |
| Jira board | [COD Kanban](https://theorchard.atlassian.net/jira/software/c/projects/COD/boards/1318) |
| Slack      | `#abacus-devs`                                                                          |
