201 lines
8.9 KiB
Markdown
201 lines
8.9 KiB
Markdown
# 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 (`tab` state),
|
|
`logUserAction()`
|
|
- `src/components/` - feature UI components
|
|
- `src/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 overrides
|
|
- `src/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 controls
|
|
- `src/components/MissionSimTab.jsx` - older/generated mission simulator;
|
|
check routing before extending
|
|
- `src/utils/diceRoller.js` - mission-safe dice helpers, `MISSION_ROLL_CONTEXT_KEY`
|
|
- `src/tests/` - Jest unit tests
|
|
|
|
### Backend (`database/`)
|
|
- `database/server.js` - Express entrypoint and route mounting
|
|
- `database/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 feed
|
|
- `database/routes/simulationRoutes.js` - backend simulation engine and report CRUD
|
|
- `database/mariadb.js` - MariaDB pool, schema creation/patching
|
|
- `database/sessionModel.js` - session storage helpers
|
|
- `database/shop-helpers.js` - requisition/shop business logic
|
|
|
|
## Development Workflow
|
|
|
|
Run commands from the repository root unless noted.
|
|
|
|
```bash
|
|
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, then `database/server.js`
|
|
- `npm run server:notest` - backend without running tests first
|
|
- `npm run build` - runs unit tests, then `react-scripts build`
|
|
- `npm run build:fast` - build then `pm2:reload` (skips tests)
|
|
- `npm run test:integration` - starts PM2, runs integration Jest, stops PM2
|
|
- `npm 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-id` header; backend uses `requireSession`
|
|
- GM endpoints check `x-gm-secret` / `GM_SECRET` (falls back to `defaultsecret`)
|
|
- Some GM upload auth falls back to defaults — see route files
|
|
|
|
## Environment And Runtime Notes
|
|
|
|
- Backend loads env via `dotenv` from its working directory. `server:notest`
|
|
runs from `database/`, so `database/.env` is the relevant file.
|
|
- MariaDB defaults are hard-coded in `database/mariadb.js`: host `192.168.1.113`,
|
|
user `deathwatch`, database `deathwatch`, port `3307`, password from
|
|
`DB_PASSWORD` or `defaultpassword`.
|
|
- Backend may load rules/weapons/bestiary from MariaDB first, then fall back to
|
|
JSON files under `public/` and `database/`.
|
|
- 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 `localStorage` keys 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 `mysql2` APIs.
|
|
- Preserve backend response shapes and `tabInfo` shape used by components/tests.
|
|
- Keep d100/DoS behavior aligned across mission, skill, and combat rolls.
|
|
|
|
## Testing
|
|
|
|
- `npm run test:unit` for normal frontend changes; target a file with
|
|
`npm test -- src/tests/login.test.js`.
|
|
- `npm run test:integration` only 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 --short` before 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.
|