Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 200 lines 11 kB view raw view rendered
1# AGENTS.md 2 3Instructions for AI coding agents working on Coop. `README.md` is for humans; this file is for machines. The nearest `AGENTS.md` to the edited file wins; explicit user prompts override everything. 4 5This file inherits from the ROOST community policy — read it once: 6- [ROOST community `AGENTS.md`](https://github.com/roostorg/community/blob/main/software-development-practices/agents.md) — pan-org agent rules (dependency approval, CI/CD approval, small diffs, PR standards). 7- [ROOST `CONTRIBUTING.md`](https://github.com/roostorg/.github/blob/main/CONTRIBUTING.md) — contribution standards (explainable, reviewable, digestible). 8 9## Architecture 10 11Four independent packages, **not an npm workspace** — each has its own `package.json` and lockfile: 12 13- `/` — root scripts, graphql-codegen, docker compose orchestration 14- `/server` — Express + Apollo GraphQL API (ESM, `"type": "module"`) 15- `/client` — React + Vite + Apollo Client frontend (Ant Design, TailwindCSS) 16- `/db` — migration runner for Postgres, ClickHouse, Scylla 17- `/migrator` — package and CLI tool for database migrations 18 19Node **24** (`.nvmrc`). Running on Node 20 produces `EBADENGINE` warnings and can fail native builds. 20 21Reference files: `README.md` (getting started), `server/bin/README.md` (utility scripts), `docs/` (architecture, ADRs). 22 23## Design 24 25- **API:** REST + GraphQL (Apollo Server); client uses Apollo Client with InMemoryCache; server resolvers live in `server/graphql/resolvers/`. 26- **GraphQL authoring:** Inline in resolver files with `/* GraphQL */` comment markers — codegen discovers queries this way. Searching for `gql` or `graphql` alone misses most of it. 27- **GraphQL codegen:** `npm run generate` (from root) regenerates `client/src/graphql/generated.ts` and `server/graphql/generated.ts`. **Never hand-edit** either `generated.ts`. **Never hand-merge** either `generated.ts` during a rebase/merge — pick one side with `git checkout --ours|--theirs <file>`, then run `npm run generate`. Hand-merging produces output that parses but drifts from the schema. 28- **Data model:** Use Knex query builder for Postgres; ClickHouse via raw SQL in `server/clickhouse/`; Scylla via Cassandra driver. 29- **Dependency injection:** Server uses BottleJS DI (wired in `server/iocContainer/`). Register services in `iocContainer`, don't export singletons from service files. Consumers receive dependencies via DI rather than importing directly. Bypassing `iocContainer` will work at runtime but breaks test mocking patterns. 30 31## Build and run 32 33Prerequisites: Node 24 (`.nvmrc`), Docker + Docker Compose v2, 8 GiB RAM recommended (running an instance requires 4 GiB, the rest will be used by development tools). 34 35```bash 36# Start backing services (Postgres, ClickHouse, Scylla, Redis) 37npm run up 38 39# Install dependencies in all packages 40npm install 41(cd client && npm install) 42(cd server && npm install) 43(cd db && npm install) 44 45# Populate .env files for /server and /db, then run migrations 46npm run db:update -- --env staging --db api-server-pg 47npm run db:update -- --env staging --db scylla 48npm run db:update -- --env staging --db clickhouse 49 50# Create organization and admin user 51npm run create-org 52 53# Start dev servers (separate terminals recommended) 54npm run client:start # React dev server 55npm run server:start # Express + GraphQL API 56npm run generate:watch # (optional) watch GraphQL changes 57``` 58 59Client: http://localhost:3001 · Server: http://localhost:3000 60 61## Testing 62 63Integration tests spin up services via docker compose. Unit tests run in-process. 64 65```bash 66# Run all tests (via docker compose) 67docker compose run --rm test 68 69# Server unit tests (no Docker) 70(cd server && npm test) 71 72# Client unit tests (no Docker) 73(cd client && npm test) 74``` 75 76Lint / format / type-check (no Docker needed): 77 78```bash 79npm run lint # lint all packages 80npm run format # format all packages 81(cd server && npm run lint) 82(cd client && npm run lint) 83``` 84 85If tests fail with database errors, check migration logs via `docker compose logs migrations`. 86 87## CI 88 89CI runs entirely via GitHub Actions (`.github/workflows/apply_pr_checks.yaml`). All PR checks are defined as `docker compose` services so you can reproduce any CI job locally. Run them in your shell (paste-as-is — each command's exit code matches the corresponding CI step's exit code): 90 91```bash 92docker compose run --rm codegen-check 93docker compose run --rm backend npm run lint 94docker compose run --rm backend npm run build 95docker compose run --rm client npm run lint 96docker compose run --rm client npm run build 97docker compose run --rm test 98``` 99 100Individual checks: 101 102| CI job | Local command | 103| --- | --- | 104| `check_generated_graphql` | `docker compose run --rm codegen-check` | 105| `check_api_server` (lint) | `docker compose run --rm backend npm run lint` | 106| `check_api_server` (build) | `docker compose run --rm backend npm run build` | 107| `run_frontend_checks_if_changed` (lint) | `docker compose run --rm client npm run lint` | 108| `run_frontend_checks_if_changed` (build) | `docker compose run --rm client npm run build` | 109| `check_api_server` (test) | `docker compose run --rm test` | 110 111Tear down: 112 113```bash 114docker compose down # stop containers, keep DB volumes 115docker compose down -v # also drop DB volumes (fresh DBs next run) 116``` 117 118Note: `check_migration_order` runs only in GitHub Actions — it's GitHub-specific and not needed locally. When adding a migration, use `date -u +"%Y.%m.%dT%H.%M.%S"` for the filename prefix. 119 120## Security 121 122- No secrets in code or committed files. Use environment variables via `.env` (gitignored). 123- Do not disable lint or type rules to silence errors. Fix the underlying issue, or use a narrowly-scoped `// eslint-disable-next-line <rule>` / `// @ts-expect-error` with a comment explaining why. 124- Before adding a new dependency, check it for known CVEs and confirm the license is compatible with `LICENSE` (Apache 2.0). 125- Default Docker bindings are `127.0.0.1`; do not change bind addresses without explicit instruction. 126 127## Code review 128 129- Keep diffs small and focused; split unrelated changes into separate PRs. 130- PR titles are descriptive and imperative ("Add X", "Fix Y"). 131- New behavior requires a test. Bug fixes require a regression test. 132- All CI checks (above) must pass before requesting review. 133 134## Code style 135 136- **TypeScript:** ESLint + Prettier (configs in `.eslintrc.cjs` and `.prettierrc` per package). Run `npm run lint` and `npm run format` from root. 137- **Naming:** Use camelCase for variables/functions; PascalCase for components/classes; SCREAMING_SNAKE_CASE for constants. 138- **GraphQL:** Type-safe resolvers and queries via codegen; never hand-edit `generated.ts`. 139- **Imports:** Absolute imports configured via `tsconfig.json` paths; prefer `@/` prefix over relative paths where configured. 140 141## Dependencies 142 143- Dependencies are declared in each package's `package.json` and locked in `package-lock.json`. Add with `npm install --save <pkg>` and commit the updated lockfile. 144- Every new or upgraded package including transitive dependencies requires human approval. Confirm the license is compatible with `LICENSE` (Apache 2.0) and that there are no known CVEs. 145- Same conflict-resolution rule applies to any `package-lock.json`: take one side with `git checkout --ours|--theirs <file>`, then run `npm install` in that package to reconcile. 146 147**Install gotchas:** 148 149CI runs `npm ci` from root. If `npm ci` hits `ERESOLVE` in any package, the lockfile has drifted from `package.json` — regenerate it against a known-good base: 150 151```bash 152git checkout main -- <pkg>/package-lock.json 153(cd <pkg> && npm install) 154``` 155 156**Do not reach for `--legacy-peer-deps`** as a fix — it papers over real peer violations and CI's `npm ci` will fail on the next agent's machine. 157 158## Codespaces 159 160Two things differ from a local dev setup: 161 1621. **Use the production client build**, not the vite dev server: `(cd client && npm run build)`, then `npm run server:start` serves the built assets. Vite's HMR websocket does not reliably traverse the Codespace port proxy. 1632. **Apollo's GraphQL URI must be relative** (`/api/v1/graphql`). Hard-coded `http://localhost:3000/...` breaks because the Codespace proxies to a different host. Source of truth is the `HttpLink` in `client/src/index.tsx`. 164 165## ROOST guiding principles 166 167- **Commands over prose.** Prefer `docker compose run --rm test` over descriptive paragraphs. 168- **Same review bar.** PRs authored with agent assistance are held to the same standards as any other PR. 169- **Boundaries with alternatives.** When stating a restriction, provide the alternative path (e.g. don't edit `generated.ts` — regenerate via `npm run generate`). 170- **Iterate over time.** Start minimal. When you give an agent the same instruction twice, add it to this file. 171- **Contributors update `AGENTS.md`.** When you find a gap, update this file as part of your PR. 172 173## Human-approval-required actions 174 175Stop and get explicit human approval before: 176 177- Changing license headers, copyright notices, or any legal text (including `LICENSE`). 178- Modifying release, signing, or deploy workflows: `.github/workflows/publish-*.yaml`, production Dockerfiles (`Dockerfile`, `client/Dockerfile`), `docker-compose.yaml`, or `package.json` `"scripts"` that affect deployment. 179- Database migrations — anything added under `db/src/scripts/<service>/` runs against real data. Confirm schema design and rollback story with a maintainer ensure to use CURRENT_USER to support any user on postgres. 180- Deleting or renaming an existing GraphQL type or field — this breaks cached Apollo client state and any downstream consumer. Additive changes are usually safe; removals need a migration plan. 181- Rewiring `server/iocContainer` in a way that changes service lifecycles or startup order — cascading effects on tests and boot. 182- Auth, session, or request middleware (under `server/api.ts`) — security-sensitive; prefer a small, reviewable PR with explicit callouts. 183- Adding, removing, or upgrading any library or package (including transitive dependencies in `package-lock.json`) — confirm licenses are compatible with Apache 2.0 and that there are no known CVEs. 184- Multi-thousand-line diffs — ROOST policy is that reviewers can digest the change. Split into reviewable PRs; regenerated codegen and lockfile bumps are the only exceptions. 185 186## Commit attribution 187 188Agent-authored commits should include a `Co-Authored-By` trailer naming the agent, e.g.: 189``` 190Co-Authored-By: <agent-name> 191``` 192Coop is open source and contributions flow upstream; attribution matters for maintainer trust. 193 194## Don't 195 196- Hand-merge `generated.ts` or lockfiles. 197- Install with `--legacy-peer-deps` as a workaround. 198- Commit `.env`, credentials, or API keys. 199- Bypass `iocContainer` by importing server singletons directly. 200- Silently modify a migration file that has already been applied to a shared environment — add a new forward migration instead.