# Contributing to ows-coda

## Prerequisites

- **Node >= 24** and **pnpm**
- **AWS SSO credentials** with `bedrock:InvokeModel` permission
- (Optional) Redis for conversation persistence locally
- (Optional) Docker for containerized dev/test

## Setup

```bash
git clone git@github.com:theorchard/ows-coda.git
cd ows-coda
for d in server client search runner platform; do cp apps/$d/.env.shadow apps/$d/.env; done
pnpm install
aws sso login --profile orchard-dev
pnpm dev          # backend on http://localhost:8080
pnpm dev:client   # Vite on http://localhost:5173 (proxies /api to backend)
pnpm dev:all      # both concurrently
```

See [Getting Started](docs/getting-started.md) for the full walkthrough including Docker, Claude Code, and MCP setup.

## Development workflow

| Command             | What it does                                |
| ------------------- | ------------------------------------------- |
| `pnpm dev`          | Hot-reload backend (tsx, loads `.env`)      |
| `pnpm dev:client`   | Hot-reload frontend (Vite)                  |
| `pnpm dev:all`      | Run both concurrently                       |
| `pnpm lint`         | ESLint across all packages                  |
| `pnpm typecheck`    | `tsc --noEmit` across all packages          |
| `pnpm format`       | Prettier auto-fix                           |
| `pnpm format:check` | Prettier check (CI uses this)               |
| `pnpm test`         | Lint + unit tests with coverage             |
| `pnpm test:unit`    | Vitest only (no lint)                       |
| `pnpm build`        | Build db → server                           |
| `pnpm build:api`    | Build just `@coda/core-api`                 |
| `pnpm build:client` | Build client (assumes api is already built) |
| `pnpm docker:up`    | Full Docker dev environment                 |

## Adding a new tool

See [docs/guides/adding-a-tool.md](docs/guides/adding-a-tool.md).

## Adding a new library package

Library packages live in `packages/<name>/`. See [docs/guides/adding-a-package.md](docs/guides/adding-a-package.md) for the full scaffolding guide including package.json, config files, Dockerfile tiers, and validation steps.

## Adding a new app

Apps live in `apps/<name>/`. See [docs/guides/adding-an-app.md](docs/guides/adding-an-app.md) for the full scaffolding guide including package.json, config files, Dockerfile setup, deploy gates, and validation steps.

## Scaffolding reference

### What's automatic (no manual steps needed)

- **`pnpm-workspace.yaml`** — uses `apps/*` / `packages/*` globs, auto-discovers
- **`detect-changes.sh`** — discovers packages dynamically from the filesystem
- **Dockerfile `deps` stage** — uses `COPY --parents apps/*/package.json packages/*/package.json`
- **`lint-staged`** — uses `apps/*/src/**` / `packages/*/src/**` globs

### Checklist

| Step                                      | Library | App  | App + own Dockerfile |
| ----------------------------------------- | ------- | ---- | -------------------- |
| `package.json` + `src/`                   | x       | x    | x                    |
| `tsconfig.json` (extends lib or app base) | x       | x    | x                    |
| `tsconfig.test.json`                      | x       | x    | x                    |
| `eslint.config.mjs`                       | x       | x    | x                    |
| `.prettierignore`                         | x       | x    | x                    |
| `vitest.config.ts`                        | x       | x    | x                    |
| `tsdown.config.ts`                        | x       | x    | x                    |
| Dockerfile `dev-deps` COPY                | x       | x    | —                    |
| Dockerfile `test-base` COPY               | auto    | auto | —                    |
| Dockerfile tier build `--filter`          | x       | —    | —                    |
| Own `Dockerfile`                          | —       | —    | x                    |
| Deploy gate in `detect-changes.sh`        | —       | —    | x                    |
| Jenkinsfile build/deploy stages           | —       | —    | x                    |
| `validate-workspace-sync.sh` passes       | x       | x    | x                    |

## Workflow

### Tickets

Create a Jira ticket for each logical piece of work before starting it. For features large enough to span multiple tickets, create a Jira Epic first, then sub-tasks or child tickets per logical chunk. Always include `labels: ["Coda"]`. **Project key: COD**

### Branch naming

Use the Jira ticket ID as prefix: `COD-1234_short_description`. For non-ticket work, use `NOTICKET_description`.

### Commit messages

Prefix with the Jira ticket number: `COD-1234 type(scope): message`. Use `NOTICKET type(scope): message` only when genuinely no ticket exists.

When squashing plan steps or multi-step work, combine into logical groups (or a single commit) rather than one commit per task — fewer commits simplifies rebasing.

### PR titles

Prefix with the ticket number: `COD-1234: Short description`. If the PR implements an entire Epic, use the Epic ticket number.

## PR process

### Pre-commit hooks

Husky + lint-staged runs automatically on `git commit`:

- Prettier formatting on staged files
- ESLint on staged `.ts` files

### Post-commit hooks

Husky runs automatically after each `git commit`:

- Auto-formats committed files (catches formatting missed after rebase)
- Amends the commit if any files changed

### Pre-push hooks

Husky runs automatically on `git push`:

- Validates the push range and computes the affected package set
- Runs concurrently: audit (manifest changes only), format check, lint, typecheck, and unit tests for all affected packages + transitive dependents

### CI pipeline (Jenkins)

Every PR runs in parallel: compliance checks, SAST, SonarQube, Docker-based lint + typecheck + unit tests.

On merge to `master`, Jenkins also builds the client, creates a Docker image, pushes to ECR, scans for vulnerabilities, and deploys to QA via Fargate. See [Deployment](docs/operations/deployment.md) for details.

### Review checklist

- `pnpm typecheck` passes with zero errors
- `pnpm test` passes with adequate coverage
- No `any` types (use `unknown` + type guards instead)
- New tools have tests and updated documentation

## Code conventions

See the full [Code Style Guide](docs/guides/code-style.md) for design principles, naming, patterns, and examples.

Build and module conventions:

- **CommonJS output** for the server (required for dd-trace compatibility)
- **ESM output** for shared packages (`api/`, `db/`, `common/`, `extensions/`, `search-api/`) — dual ESM/CJS via tsdown
- **Prettier** for formatting, **ESLint** for linting (flat config in `eslint.config.mjs`)
- Keep `.env` out of git — use `.env.shadow` as the template
