Monorepo root files for documentation and unified Docker Compose that brings up all three services (db, api, front, intra) together. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
CrowMate Nest is a community platform for Headless Hazard, an indie game. It consists of three monorepo sub-projects:
nest-backend/: REST API (Express + TypeScript + PostgreSQL/Prisma)nest-front/: Public-facing community website (React + Vite, port 5173)nest-intra/: Staff-only internal portal (React + Vite, port 5174)
Development Commands
Backend (nest-backend/)
npm run dev # ts-node-dev with auto-restart
npm run build # TypeScript compilation to dist/
npm start # Run compiled dist/index.js
npm run db:push # Push Prisma schema changes (no migration file)
npm run db:migrate # Create and apply a migration
npm run db:seed # Run prisma/seed.ts
npm run db:studio # Open Prisma Studio UI
Frontend & Intranet (nest-front/ and nest-intra/)
npm run dev # Vite dev server
npm run build # tsc + vite build
npm run lint # ESLint
npm run preview # Serve built output locally
Environment Setup (Backend)
Copy .env.example to .env. Key variables:
DATABASE_URL="postgresql://user:password@localhost:5432/nest_db"
JWT_SECRET="..."
PORT=3000
ADMIN_USERNAME / ADMIN_EMAIL / ADMIN_PASSWORD # Auto-creates admin on startup
FRONT_ORIGIN / INTRA_ORIGIN # Production CORS origins
Architecture
Backend
Tech: Express 4, TypeScript 5.6, Prisma 5.22, PostgreSQL, JWT (7d), bcryptjs, Zod
Request pipeline: authenticate() → requireStaff() / requireAdmin() middleware, then route handler. JWT payload includes { userId, role, isAdmin }.
Route groups (all under /api/):
auth: login, register, /meusers: CRUD + ban/unban (admin)forum: categories, threads (paginated), repliesbugs: bug reports with uniqueCode (HH-XXXX), comments, internal notes, me-too votingfeed: staff-only post feedevents: announcements/updates/milestones/polls with votingteam: team member profiles
Key patterns:
- All request bodies validated with Zod (
schema.safeParse()) - Response shaping via format helpers (
formatBug(),formatMember(), etc.) insrc/lib/ - Prisma eager-loads relations to avoid N+1
- Composite primary keys for
MeTooBug(userId + bugReportId) andPollVote(userId + pollOptionId)
Frontends (nest-front & nest-intra)
Tech: React 19, Vite 7, Tailwind CSS 4, React Router 6, TypeScript 5.9
Both frontends currently use mock data — no real API calls are wired up yet. Auth state is simulated with MOCK_USERS in src/contexts/AuthContext.tsx and persisted to localStorage.
nest-frontuses storage keycrowmate_auth_user; all roles (user,dev,com) can log innest-intrauses storage keycrowmate_intra_user; blocksrole === 'user'at login — staff only (dev/com)
Shared structure (both React projects mirror each other):
src/
App.tsx # Route definitions, React.lazy() imports
contexts/
AuthContext.tsx # Auth state, role helpers, localStorage
components/
layout/ # Page wrapper with nav/sidebar
shared/ # ProtectedRoute, PageLoader, DevRoleSwitcher
pages/ # Page components (lazy loaded)
types/index.ts # All TypeScript interfaces
utils/format.ts # formatDate(), timeAgo(), truncate()
data/mockData.ts # Mock users, forum, bugs, events, team
DevRoleSwitcher component (nest-front only): floating UI to switch auth roles instantly without logging out — for development testing only.
User Roles & Access
| Role | Access |
|---|---|
user |
Public site features only |
dev / com |
Staff features (feed, intranet, bug triage, event creation) |
isAdmin: true |
User management, forum moderation, destructive operations |
Data Models Summary
User: id, username, email, password (hashed), role, isAdmin, isBanned, avatarUrl
Forum: ForumCategory → ForumThread → ForumReply (cascade deletes on thread)
BugReport: uniqueCode (HH-XXXX auto-generated), severity, status, assignedTo; with BugComment (public), BugReportNote (staff-only), MeTooBug
Events: EventPost (type: announcement | update | milestone | poll) → Poll → PollOption → PollVote (composite key)
Team: TeamMember standalone profiles
Docker
Each sub-project has its own Dockerfile and docker-compose.yml. The backend uses multi-stage builds; frontends use Nginx to serve the Vite build output (nginx.conf included).
Key Implementation Notes
- The backend auto-creates an admin user on startup if
ADMIN_USERNAME/EMAIL/PASSWORDenv vars are set prisma/seed.tspopulates sample data for developmentnest-intra/public/services.jsondefines quick-link cards for dev tools (GitHub, Plane, Jenkins, Proxmox, etc.) shown on the/intranet/servicespage- Both frontends'
types/index.tsandutils/format.tsare near-identical — changes often need to be mirrored - When integrating real API calls, replace mock auth in
contexts/AuthContext.tsxand mock data indata/mockData.ts