# The Sunken Reach — D&D 5e Campaign Manager A web app for a D&D 5e Dungeon Master and their players to run a campaign together: campaign management, a guided dice-roll character builder, live character sheets, a mid-combat "quick stats" panel, weapons/inventory/spells, monsters, and a real-time encounter/combat tracker. See `CLAUDE_BUILD_PROMPT.md` and `/docs` for the full spec this was built from (`GAME_RULES_REFERENCE.md` is the authoritative rules/math reference; `ROLL_YOUR_CHARACTER.md` is the character-builder flow spec). ## Stack - **Backend:** Node.js + Express, JavaScript, Prisma ORM, PostgreSQL, Socket.io, JWT auth (bcrypt + jsonwebtoken), zod validation. - **Frontend:** React + Vite + TypeScript, React Router, TanStack Query, socket.io-client. ## Prerequisites - Node.js 18+ (tested on Node 22) - A running PostgreSQL instance (local install, Docker, or a hosted service like Neon/Supabase) ## First-time setup ```bash npm install # installs both workspaces (backend + frontend) # Backend: point at your Postgres instance and run migrations cd backend cp .env.example .env # edit DATABASE_URL and JWT_SECRET npx prisma migrate dev --name init npx prisma db seed # creates a demo campaign + demo users (see output for login/invite code) # Frontend cd ../frontend cp .env.example .env # defaults to http://localhost:4000, adjust if needed ``` ## Running in dev In two terminals, from the repo root: ```bash npm run dev:backend # Express + Socket.io on http://localhost:4000 npm run dev:frontend # Vite dev server, prints its own port (5173 by default) ``` Open the frontend URL, register an account (or log in with the seeded demo users — see the seed script's console output for credentials and invite code), and start playing. ## Tests ```bash cd backend npm test ``` The calculation engine (`src/game/calculations.js`) is fully unit tested and runs with no external dependencies. The route-level integration tests in `src/routes/api.integration.test.js` need a real, migrated database reachable via `DATABASE_URL` — they skip themselves gracefully (with a console warning) if the DB isn't reachable, so `npm test` still passes in an environment with no database configured. ## Project layout ``` /backend — Express + Prisma API, Socket.io server /prisma — schema.prisma, seed.js /seed-data — reference JSON (weapons seeded per-campaign; species/classes/skills are ported into src/game/data/*.js and used directly by the calculation engine, not stored as DB rows) /src /game — calculations.js (the ONLY place D&D formulas live) + buildFlow.js /middleware — auth + campaign/character authorization /routes — auth, campaigns, characters, encounters, notes /sockets — Socket.io room wiring /frontend — React + Vite + TypeScript app /docs — game rules & character-builder specs (reference material) ```