8.9 KiB
CLAUDE.md - Codebase Documentation for Claude Code
This file helps Claude understand the Deathwatch Roller codebase and provide
better assistance. Prefer the live code and package.json over older docs
when they disagree. For a deep, feature-by-feature guide, see AGENTS.md —
it is the most detailed and up-to-date reference in the repo.
Project Overview
Deathwatch Roller is a Create React App + Express application for running Deathwatch tabletop RPG sessions.
Main Features:
- Player login, character sheets, and player management (GM)
- Dice roller (skill checks and combat) with fate-point support
- Mission play (GM/player views) and simulation lab
- Requisition shop (buy gear with RP), gated by renown
- Bestiary, rules search, and weapon references
- GM Kit reference tables and user-submitted error reports
Tech Stack:
- Frontend: React 18 (plain JavaScript/JSX, not TypeScript) via Create React App
- Backend: Node.js + Express (
database/server.js) - Database: MariaDB via
mysql2/promise(some legacy SQLite artifacts remain) - Styling: Tailwind CSS + component CSS
Architecture
The repo is a single-root JavaScript app — there is no backend/ or
frontend/ directory (older docs that mention them are stale).
dwroller/
├── src/ # React frontend (App.js, components/, utils/, tests/)
├── database/ # Express backend (server.js, routes/, mariadb.js, ...)
├── scripts/ # Import, cleanup, validation, generation, CI helpers
├── public/ # Static data/assets + printable pages (cards.html, print.html)
├── data/ # Static data and assets
└── docs/ # Documentation (some structure docs are stale)
Key Files and Locations
Frontend (src/)
src/App.js- main app, login/session state, tab wiring (tabstate),logUserAction()src/components/- feature UI componentssrc/components/DeathwatchRoller.jsx- combat dice roller (weapon mapping, attack/damage, hit locations, history, presets, tracker)src/components/SkillRoller.jsx- sheet-driven skill checks, manual d100, target overridessrc/components/rollHelpers.js- shared d100, DoS/DoF, ids, fate helpers (applyFateToTest())src/components/FateControls.jsx,src/components/useFate.js- fate UI and persistence (POST /api/players/:name/spend-fate)src/components/MissionTab.jsx- active mission play (GM/player views)src/components/SimulationTab.jsx- simulation report UI and controlssrc/components/MissionSimTab.jsx- older/generated mission simulator; check routing before extendingsrc/utils/diceRoller.js- mission-safe dice helpers,MISSION_ROLL_CONTEXT_KEYsrc/tests/- Jest unit tests
Backend (database/)
database/server.js- Express entrypoint and route mountingdatabase/routes/- API routes (players, sessions, shop, rules, bestiary, weapons, missions, simulations, staging, errors)database/routes/missionRoutes.js- mission CRUD, active mission,playerScene()safe projection, active-scene patching, shared roll feeddatabase/routes/simulationRoutes.js- backend simulation engine and report CRUDdatabase/mariadb.js- MariaDB pool, schema creation/patchingdatabase/sessionModel.js- session storage helpersdatabase/shop-helpers.js- requisition/shop business logic
Development Workflow
Run commands from the repository root unless noted.
npm install
npm start # CRA dev server on http://localhost:3000
npm run server:notest # backend only (cd database && node server.js) on :5000
npm run test:unit # frontend Jest unit tests
Scripts (see package.json for the full list)
npm start- frontend dev server (CRA proxies /api to :5000)npm run server- runs unit tests first, thendatabase/server.jsnpm run server:notest- backend without running tests firstnpm run build- runs unit tests, thenreact-scripts buildnpm run build:fast- build thenpm2:reload(skips tests)npm run test:integration- starts PM2, runs integration Jest, stops PM2npm run pm2:start/pm2:reload/pm2:stop- PM2 process control./scripts/local-ci.sh- local CI helper
Ports: frontend 3000, backend API 5000 (CRA proxy points at 5000).
App Tabs
Tabs are selected in src/App.js via the tab state (see AGENTS.md for the
full per-tab breakdown of components, endpoints, and behavior):
| Tab key | Component | Availability |
|---|---|---|
mission (default) |
MissionTab.jsx |
All; GM/player views differ |
roller |
DeathwatchRoller.jsx |
All |
shop |
RequisitionShop.jsx |
All; GM controls for gm |
| (fallback) | PlayerTab.jsx (Character Sheet) |
All; GM edit tools for gm |
rules |
RulesTab.jsx |
All |
weapons |
WeaponsTab.jsx |
All |
errors |
ErrorReports.jsx |
All; GM sees/resolves all |
bestiary |
BestiaryTab.jsx |
GM-only |
players |
PlayerManagement.jsx |
GM-only |
gmkit |
GMKit.jsx |
GM-only |
simulation |
SimulationTab.jsx |
GM-only |
External utility pages public/cards.html (nav Kort) and public/print.html
(nav Print) are static printable pages, not React tabs.
API Surface
Mounted prefixes in database/server.js:
| Prefix | Description |
|---|---|
/api/players |
Players, GM player ops, fate, avatars |
/api/sessions |
Session management |
/api/shop |
Requisition shop and purchases |
/api/rules |
Rules categories/search/random (/api/rules/staging for staging) |
/api/weapons |
Weapon references |
/api/bestiary |
Bestiary full/reload/enemies |
/api/missions |
Mission CRUD, active mission, safe scene, roll feed |
/api/simulations |
Run and manage simulation reports |
/api/errors |
User-submitted error reports |
/api/gmkit/list, /api/gmkit/upload |
GM kit assets |
/api/copy-bestiary |
Bestiary copy utility |
/api/narrate |
Ollama narration (OLLAMA_BASE, NARRATOR_MODEL) |
Static serving includes /gmkit, /weapon-images, and /avatars.
Authentication
- Sessions use an
x-session-idheader; backend usesrequireSession - GM endpoints check
x-gm-secret/GM_SECRET(falls back todefaultsecret) - Some GM upload auth falls back to defaults — see route files
Environment And Runtime Notes
- Backend loads env via
dotenvfrom its working directory.server:notestruns fromdatabase/, sodatabase/.envis the relevant file. - MariaDB defaults are hard-coded in
database/mariadb.js: host192.168.1.113, userdeathwatch, databasedeathwatch, port3307, password fromDB_PASSWORDordefaultpassword. - Backend may load rules/weapons/bestiary from MariaDB first, then fall back to
JSON files under
public/anddatabase/. - The backend can serve
build/statically when a production build exists.
Data Sources
- Rules index:
database/rules/rules-database.json - Skills:
database/deathwatch_skills_p94_107.csv - Armoury/shop:
public/deathwatch-armoury.json - Bestiary:
public/deathwatch-bestiary-extracted.json(+database/copy)
Code Style & Conventions
- Plain JavaScript/JSX — match surrounding style; do not introduce TypeScript unless a migration is explicitly requested.
- Prefer existing React hook/component patterns in
src/components/. - Frontend API calls use relative
/api/...URLs through the CRA proxy. - Keep
localStoragekeys stable. Known keys include:dw:shop:authedPlayer,dw:shop:sessionId,dw:shop:playerData,dw:shop:players:v1,dw:presets:v3,dw:history:v2,dw:weapons:v3,dw:tracker:v1,dw:mission:rollContext,dw:enemies:v1,dw:rules:recent,dw:warning-dismiss-until:v1. - Keep DB writes parameterized through
mysql2APIs. - Preserve backend response shapes and
tabInfoshape used by components/tests. - Keep d100/DoS behavior aligned across mission, skill, and combat rolls.
Testing
npm run test:unitfor normal frontend changes; target a file withnpm test -- src/tests/login.test.js.npm run test:integrationonly when backend/API behavior changes and PM2/MariaDB are available.- If tests fail because MariaDB, PM2, Ollama, or local services are unavailable, report that explicitly rather than masking it.
Files To Treat Carefully
- Do not commit or churn runtime logs (
database/backend.log,database/server.log). - Do not overwrite database files, backups, generated JSON, PDFs, OCR output, or imported rulebook data unless the user specifically asks for data work.
- Inspect
git status --shortbefore editing; avoid reverting unrelated local work. - Do not paste long rulebook passages into UI/docs — summarize in original wording and link/search the local rules DB.
Documentation
Full docs are in docs/ (note: some structure docs are stale and still refer
to non-existent backend//frontend/ dirs). See also README.md,
DEVELOPMENT_GUIDE.md, and especially AGENTS.md for the detailed guide.