22 KiB
Codebase Structure
Analysis Date: 2026-04-27
Directory Layout
dimension47/
├── client/ # React 19 + Vite frontend
│ ├── src/
│ │ ├── main.tsx # React root + DOM render
│ │ ├── App.tsx # Router setup (BrowserRouter, Routes)
│ │ ├── index.css # Global styles (Tailwind v4)
│ │ ├── app/ # App configuration & routing
│ │ ├── features/ # Feature modules (auth, characters, campaigns, etc.)
│ │ │ ├── auth/ # Authentication (login, register, useAuthStore)
│ │ │ │ ├── components/
│ │ │ │ │ ├── login-page.tsx
│ │ │ │ │ └── register-page.tsx
│ │ │ │ ├── hooks/
│ │ │ │ │ └── use-auth-store.ts
│ │ │ │ └── index.ts # Barrel export
│ │ │ ├── characters/ # Character sheet & inventory
│ │ │ │ ├── components/ # Modals, tabs, controls
│ │ │ │ │ ├── character-sheet-page.tsx # Main tab container
│ │ │ │ │ ├── actions-tab.tsx # PF2e actions list
│ │ │ │ │ ├── alchemy-tab.tsx # Alchemy system
│ │ │ │ │ ├── add-condition-modal.tsx # Add status effect
│ │ │ │ │ ├── add-item-modal.tsx # Equipment search & add
│ │ │ │ │ ├── add-feat-modal.tsx # Add talent
│ │ │ │ │ ├── feat-detail-modal.tsx # Talent details
│ │ │ │ │ ├── item-detail-modal.tsx # Equipment details
│ │ │ │ │ ├── hp-control.tsx # HP management
│ │ │ │ │ ├── rest-modal.tsx # Rest system
│ │ │ │ │ ├── recovery-check-modal.tsx # Dying state recovery
│ │ │ │ │ ├── dying-indicator.tsx # Dying condition display
│ │ │ │ │ ├── import-character-modal.tsx # Pathbuilder import
│ │ │ │ │ ├── create-character-modal.tsx # New character
│ │ │ │ │ ├── edit-character-modal.tsx # Edit character info
│ │ │ │ │ └── image-crop-modal.tsx # Avatar cropping
│ │ │ │ ├── utils/
│ │ │ │ │ └── export-character-html.ts # Character sheet HTML export
│ │ │ │ └── index.ts
│ │ │ ├── campaigns/ # Campaign management
│ │ │ │ ├── components/
│ │ │ │ │ ├── campaigns-page.tsx # Campaign list (home)
│ │ │ │ │ ├── campaign-detail-page.tsx # Campaign overview
│ │ │ │ │ ├── create-campaign-modal.tsx # New campaign
│ │ │ │ │ ├── edit-campaign-modal.tsx # Edit campaign info
│ │ │ │ │ └── add-member-modal.tsx # Add player to campaign
│ │ │ │ └── index.ts
│ │ │ ├── battle/ # Battle screen & real-time combat
│ │ │ │ ├── components/
│ │ │ │ │ ├── battle-page.tsx # Main battle screen
│ │ │ │ │ ├── battle-canvas.tsx # Map & token rendering
│ │ │ │ │ ├── battle-session-list.tsx # Session selection
│ │ │ │ │ └── token.tsx # Token component
│ │ │ │ ├── hooks/
│ │ │ │ │ └── use-battle-socket.ts # Battle WebSocket hook
│ │ │ │ └── index.ts
│ │ │ └── library/ # GM library (maps, combatants)
│ │ │ ├── components/
│ │ │ │ ├── library-page.tsx # Maps & combatants list
│ │ │ │ ├── upload-map-modal.tsx # Add battle map
│ │ │ │ └── create-combatant-modal.tsx # Create NPC template
│ │ │ └── index.ts
│ │ ├── shared/ # Reusable code across features
│ │ │ ├── components/
│ │ │ │ ├── layout.tsx # App wrapper (navbar, layout)
│ │ │ │ ├── protected-route.tsx # Auth enforcement wrapper
│ │ │ │ └── ui/ # shadcn/ui components
│ │ │ │ ├── button.tsx
│ │ │ │ ├── card.tsx
│ │ │ │ ├── input.tsx
│ │ │ │ ├── spinner.tsx
│ │ │ │ ├── action-icon.tsx
│ │ │ │ └── index.ts
│ │ │ ├── hooks/
│ │ │ │ ├── use-character-socket.ts # Character real-time sync
│ │ │ │ └── (battle hooks if added)
│ │ │ ├── lib/
│ │ │ │ ├── api.ts # API client (axios + token mgmt)
│ │ │ │ └── utils.ts # Utility functions
│ │ │ └── types/
│ │ │ └── index.ts # All TypeScript interfaces & types
│ │ └── assets/ # Images, fonts
│ ├── public/
│ │ ├── data/ # JSON data files (equipment, etc.)
│ │ └── icons/ # SVG/icon files
│ ├── index.html # HTML template
│ ├── vite.config.ts # Vite configuration
│ ├── tsconfig.json # TypeScript configuration
│ ├── tailwind.config.js # Tailwind CSS v4 config
│ ├── postcss.config.js # PostCSS plugins
│ ├── package.json
│ └── dist/ # Build output (generated)
│
├── server/ # NestJS backend
│ ├── src/
│ │ ├── main.ts # Server bootstrap & app setup
│ │ ├── app.module.ts # Root NestJS module (imports all features)
│ │ ├── common/ # Shared utilities across modules
│ │ │ └── decorators/
│ │ │ ├── current-user.decorator.ts # Extract user from request
│ │ │ ├── public.decorator.ts # Skip auth on endpoints
│ │ │ ├── roles.decorator.ts # Specify required roles
│ │ │ └── index.ts
│ │ ├── prisma/
│ │ │ └── prisma.service.ts # Database service wrapper
│ │ ├── modules/ # Feature modules (NestJS-style)
│ │ │ ├── auth/ # Authentication & JWT
│ │ │ │ ├── auth.controller.ts # POST /auth/login, /auth/register
│ │ │ │ ├── auth.service.ts # User validation, JWT signing
│ │ │ │ ├── auth.module.ts # Module exports & dependencies
│ │ │ │ ├── guards/
│ │ │ │ │ ├── jwt-auth.guard.ts # JWT validation (global)
│ │ │ │ │ └── roles.guard.ts # Role checking
│ │ │ │ ├── strategies/
│ │ │ │ │ └── jwt.strategy.ts # Passport JWT strategy
│ │ │ │ └── dto/
│ │ │ │ ├── login.dto.ts
│ │ │ │ └── register.dto.ts
│ │ │ ├── campaigns/ # Campaign management
│ │ │ │ ├── campaigns.controller.ts # CRUD campaigns, member management
│ │ │ │ ├── campaigns.service.ts # Campaign operations & access checks
│ │ │ │ ├── campaigns.module.ts
│ │ │ │ └── dto/
│ │ │ │ └── (campaign DTOs)
│ │ │ ├── characters/ # Character system (core feature)
│ │ │ │ ├── characters.controller.ts # Character CRUD, conditions, items, feats
│ │ │ │ ├── characters.service.ts # Character logic, HP, conditions, inventory
│ │ │ │ ├── characters.gateway.ts # WebSocket real-time sync
│ │ │ │ ├── characters.module.ts
│ │ │ │ ├── pathbuilder-import.service.ts # Pathbuilder JSON parsing
│ │ │ │ ├── alchemy.controller.ts # Alchemy endpoints
│ │ │ │ ├── alchemy.service.ts # Alchemy system logic
│ │ │ │ └── dto/
│ │ │ │ └── (character, alchemy DTOs)
│ │ │ ├── equipment/ # Equipment database
│ │ │ │ ├── equipment.controller.ts # GET /equipment (search, categories)
│ │ │ │ ├── equipment.service.ts # Equipment search & filtering
│ │ │ │ ├── equipment.module.ts
│ │ │ │ └── dto/
│ │ │ ├── feats/ # Feat database
│ │ │ │ ├── feats.controller.ts # GET /feats (search)
│ │ │ │ ├── feats.service.ts # Feat queries
│ │ │ │ ├── feats.module.ts
│ │ │ │ └── dto/
│ │ │ ├── battle/ # Battle system (maps, sessions, tokens)
│ │ │ │ ├── battle.controller.ts # POST/GET /battles
│ │ │ │ ├── battle.service.ts # Battle session logic
│ │ │ │ ├── battle.gateway.ts # WebSocket battle updates
│ │ │ │ ├── battle.module.ts
│ │ │ │ ├── battle-maps.controller.ts # Battle map CRUD
│ │ │ │ ├── battle-maps.service.ts
│ │ │ │ ├── combatants.controller.ts # NPC/monster templates
│ │ │ │ ├── combatants.service.ts
│ │ │ │ └── dto/
│ │ │ ├── translations/ # German translations cache
│ │ │ │ ├── translations.controller.ts # GET translations
│ │ │ │ ├── translations.service.ts # Cache & Claude API calls
│ │ │ │ ├── translations.module.ts
│ │ │ │ └── dto/
│ │ │ └── claude/ # Claude API integration
│ │ │ ├── claude.module.ts
│ │ │ └── claude.service.ts # Claude API wrapper
│ │ └── generated/ # Generated code (do not edit)
│ │ └── prisma/ # Prisma client types & enums
│ │ ├── client.ts
│ │ ├── models.ts
│ │ ├── enums.ts
│ │ └── ...
│ ├── prisma/ # Prisma ORM configuration
│ │ ├── schema.prisma # Database schema (tables, relations, enums)
│ │ ├── migrations/ # Versioned database migrations
│ │ │ ├── 20260118162916_init/
│ │ │ ├── 20260118225853_add_equipment_detail_fields/
│ │ │ ├── 20260119083024_add_credits_to_character/
│ │ │ └── 20260119111209_add_item_custom_fields/
│ │ ├── seed.ts # Base seed script (users, etc.)
│ │ └── data/ # JSON source data for seeding
│ │ ├── equipment.json # 5,482 PF2e equipment items
│ │ ├── feats.json # PF2e talents
│ │ ├── spells.json # PF2e spells
│ │ ├── actions.json # PF2e combat actions
│ │ ├── conditions.json # PF2e conditions (Pathfinder 2e ruleset)
│ │ └── ...
│ ├── src/generated/ # Generated Prisma types
│ ├── package.json
│ ├── tsconfig.json
│ ├── nest-cli.json
│ └── dist/ # Build output (generated)
│
├── .planning/ # Phase planning documents
│ └── codebase/ # Architecture analysis (this file)
│ ├── ARCHITECTURE.md
│ ├── STRUCTURE.md
│ ├── STACK.md
│ ├── INTEGRATIONS.md
│ ├── CONVENTIONS.md
│ ├── TESTING.md
│ └── CONCERNS.md
├── docs/ # Documentation
├── .claude/ # Claude settings & instructions
│ └── settings.local.json
├── package-lock.json # Lock file (top-level)
└── CLAUDE.md # Project guidelines (Quality > Speed)
Directory Purposes
Client Structure
client/src/features/ - Feature-based modules
- Each feature is a semi-independent domain (auth, characters, campaigns, battle, library)
- Contains components specific to that feature
- Exports public API via barrel exports (
index.ts) - Examples: AuthFeature manages login/register, CharactersFeature manages character sheet
- Pattern: Feature-based organization allows independent testing and scaling
client/src/shared/ - Cross-feature reusables
components/ui/- shadcn/ui primitive components (Button, Card, Input, etc.)components/layout.tsx- App wrapper with navbarcomponents/protected-route.tsx- Auth enforcement for routeshooks/- Custom React hooks (useCharacterSocket, etc.)lib/api.ts- HTTP client with token managementlib/utils.ts- Helper functionstypes/- All TypeScript interfaces shared across app- Pattern: Single source of truth for types, no duplication
client/public/ - Static files
data/- JSON files (if any live here, but equipment comes from backend)icons/- SVG icons used in UI
Server Structure
server/src/modules/ - NestJS modules by feature
- Each module is self-contained: controller → service → gateway
- Module exports what other modules need via
exports: []in decorator - Examples:
- CharactersModule exports CharactersService, CharactersGateway for cross-module use
- AuthModule exports AuthService, guards for other modules to use
- Pattern: Module-based organization with explicit dependency injection
server/src/common/ - Shared utilities
- Decorators: @CurrentUser, @Public, @Roles
- Guards: Shared by all modules
- Pattern: Cross-cutting concerns in one place
server/prisma/ - Database layer
schema.prisma- Single source of truth for data modelmigrations/- Versioned schema changes (never usedb push)seed.ts- Initial datadata/- JSON source files for seed scripts- Pattern: Database-first approach, all data in DB not JSON files
Key File Locations
Entry Points
Backend:
server/src/main.ts- Bootstrap NestJS app, enable pipes/guards/swagger- AppModule at
server/src/app.module.ts- Wires all modules together
Frontend:
client/src/main.tsx- React root render- Router at
client/src/App.tsx- BrowserRouter with route protection
Configuration
Environment:
server/.env- PostgreSQL, JWT_SECRET, ANTHROPIC_API_KEY, CORS_ORIGINSclient/.env- VITE_API_URL (must match server PORT)- Example files:
server/.env.example,client/.env.example
Build & Development:
- Backend:
server/nest-cli.json- NestJS CLI configserver/tsconfig.json- TypeScript settings
- Frontend:
client/vite.config.ts- Vite bundler (alias paths with@)client/tsconfig.json- TypeScript settings (strict mode)client/tailwind.config.js- Tailwind v4 customizationclient/postcss.config.js- CSS processing
Core Logic
Character System:
- Service:
server/src/modules/characters/characters.service.ts- HP, conditions, items - Gateway:
server/src/modules/characters/characters.gateway.ts- Real-time sync - Import:
server/src/modules/characters/pathbuilder-import.service.ts- Pathbuilder parsing - Alchemy:
server/src/modules/characters/alchemy.service.ts- Alchemy logic - UI:
client/src/features/characters/components/character-sheet-page.tsx- Main page
Battle System:
- Service:
server/src/modules/battle/battle.service.ts- Sessions & tokens - Gateway:
server/src/modules/battle/battle.gateway.ts- Real-time sync - Canvas:
client/src/features/battle/components/battle-canvas.tsx- Map & tokens
Equipment Database:
- Service:
server/src/modules/equipment/equipment.service.ts- Search & filtering - Controller:
server/src/modules/equipment/equipment.controller.ts- Endpoints - UI:
client/src/features/characters/components/add-item-modal.tsx- Search UI - Data:
server/prisma/data/equipment.json- 5,482 items (seeded to DB)
Authentication:
- Service:
server/src/modules/auth/auth.service.ts- Login/register/JWT - Guard:
server/src/modules/auth/guards/jwt-auth.guard.ts- Applied globally - Store:
client/src/features/auth/hooks/use-auth-store.ts- Client-side auth state - API:
client/src/shared/lib/api.ts- Token persistence (localStorage vs sessionStorage)
Testing
Backend:
- Test files:
server/src/**/*.spec.ts(not yet created - opportunity) - Config:
server/jest.config.js(if exists)
Frontend:
- Test files:
client/src/**/*.spec.tsx(not yet created - opportunity) - Config:
client/vitest.config.ts(if exists) orclient/jest.config.js
Naming Conventions
Files
Component files (React):
- Pattern: kebab-case
.tsx - Example:
character-sheet-page.tsx,add-item-modal.tsx,hp-control.tsx - Convention: Lowercase with hyphens,
.tsxfor JSX
Service files (NestJS):
- Pattern: kebab-case
.ts - Example:
characters.service.ts,pathbuilder-import.service.ts,alchemy.service.ts - Convention: Feature name + responsibility (service/controller/gateway)
Guard/Strategy files:
- Pattern: kebab-case
.ts - Example:
jwt-auth.guard.ts,jwt.strategy.ts
DTO files:
- Pattern: kebab-case
.tsinsidedto/folder - Example:
login.dto.ts,register.dto.ts
Module files:
- Pattern: Feature name +
.module.ts - Example:
auth.module.ts,characters.module.ts
Directories
Feature directories:
- Pattern: kebab-case (lowercase with hyphens)
- Example:
auth/,campaigns/,characters/,battle/,library/ - Structure: Each feature has
components/,hooks/,utils/,index.ts
Shared directories:
- Pattern: Descriptive plural or functional names
- Examples:
components/,hooks/,lib/,types/,decorators/,strategies/
Module sub-directories:
- Pattern:
guards/,strategies/,dto/(lowercase) - Convention: Consistent across all modules
Where to Add New Code
New Feature
Backend:
- Create
server/src/modules/[feature]/directory - Create files:
[feature].module.ts- NestJS module, imports dependencies[feature].controller.ts- HTTP endpoints[feature].service.ts- Business logic[feature].gateway.ts(optional) - WebSocket if real-time neededdto/folder with DTOs
- Import module in
server/src/app.module.ts
Frontend:
- Create
client/src/features/[feature]/directory - Create sub-folders:
components/- React componentshooks/- Custom hooks (if state needed)index.ts- Barrel export
- Add routes in
client/src/App.tsx
Database (if adding entities):
- Add model to
server/prisma/schema.prisma - Run:
cd server && npm run db:migrate:dev - Name migration descriptively: "add_new_feature_table"
- Seeds automatically regenerate Prisma client
New Component/Module
React Component:
- Location:
client/src/features/[feature]/components/[name].tsx - Pattern: Named export + default export
- Import shared types from
client/src/shared/types/index.ts - Use API client from
client/src/shared/lib/api.ts
NestJS Service:
- Location:
server/src/modules/[feature]/[name].service.ts - Pattern: @Injectable() class with public methods
- Inject PrismaService via constructor
- Keep business logic in service, HTTP concern in controller
WebSocket Gateway:
- Location:
server/src/modules/[feature]/[name].gateway.ts - Pattern: @WebSocketGateway() @Injectable() class
- Authenticate in handleConnection()
- Emit broadcasts to rooms via socket.server.to(room).emit()
Utilities
Shared Frontend Helpers:
- Location:
client/src/shared/lib/utils.ts - Pattern: Exported functions (no classes)
- Use for date formatting, type checks, calculations
Shared Backend Helpers:
- Location:
server/src/common/(create subdirectory if needed) - Pattern: Injectable services or utility functions
- Example: CommonService for shared operations
Special Directories
server/prisma/migrations/
- Purpose: Version control for database schema
- Generated: Auto-created by
npm run db:migrate:dev - Committed: YES (must be in git for reproducible deployments)
- Manual edits: Rarely needed, but can fix SQL if migration is broken
- Pattern: Timestamp-prefixed folders with
.sqlfiles inside
server/src/generated/
- Purpose: Prisma-generated types and client
- Generated: Auto-created by
npm run db:generate - Committed: NO (regenerated on install)
- Manual edits: DO NOT EDIT — regenerate instead
client/public/data/
- Purpose: Static JSON files (currently unused, equipment in DB)
- Generated: NO (manually added if needed)
- Committed: YES
- Pattern: Only for truly static reference data
server/dist/ and client/dist/
- Purpose: Compiled/bundled output
- Generated: YES (
npm run build) - Committed: NO (.gitignore)
- Pattern: Build artifacts, environment-specific
server/node_modules/ and client/node_modules/
- Purpose: Installed dependencies
- Generated: YES (
npm install) - Committed: NO (.gitignore)
- Pattern: Use package-lock.json for reproducibility
Structure analysis: 2026-04-27