Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ jobs:
# `build:bot` actually ships, and the landing build was not run at all.
# build:all covers both plus the frontend build this step used to do.
- run: npm run build:all
# The image installs `npm ci --omit=dev` (Dockerfile) and boots
# `tsx ./src/main.ts`, so a runtime dep that drifts into devDependencies
# boots fine everywhere except production. Runs last: it wipes dev deps.
- run: npm ci --omit=dev
- run: ./node_modules/.bin/tsx --version

backend-tests:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ npm run smoke:api # boots the REAL app (STAGING,
- **Fatal startup errors**: the top-level catch in `main.ts` uses `console.error`, not `logger` — pino's worker-thread transport can't flush before `process.exit(1)`.
- **`BOT_WEBHOOK_SECRET`** is only required in webhook mode (post-parse check in `config.ts`); empty is valid in polling mode.
- **Model index conventions**: `unique: true` alone (it creates the index); single-field secondary indexes go in class-level `@index()` decorators; schemaless `meta` bags need `options: { allowMixed: Severity.ALLOW }`.
- **The image is a prod-only install**: `Dockerfile` runs `npm ci --omit=dev` and boots `tsx ./src/main.ts`, so **tsx is a runtime dependency**. Never `npm i -D` a package that already lives in `dependencies` — npm moves it, every local check still passes (they install dev deps), and the container crash-loops on deploy. The last two steps of the `quality` CI job catch it.
- **bigint in responses**: fastify's JSON serializer throws on bigint — always `.toString()` votes/costs in handler responses.

## Handler Pattern (DI)
Expand Down