# Codebase Concerns **Analysis Date:** 2026-04-27 ## Tech Debt ### Debug Console Logging in Production Code **Issue:** Production code contains debug console.log statements that should be removed before deployment **Files:** - `server/src/modules/characters/characters.service.ts` (4 console.log statements in updateHp method, lines 263, 283, 303, 310) - `client/src/features/battle/hooks/use-battle-socket.ts` (3 console.log statements) - `client/src/features/characters/components/alchemy-tab.tsx` (3 console.log statements) - `client/src/features/characters/components/character-sheet-page.tsx` (1 console.log statement) - `client/src/shared/hooks/use-character-socket.ts` (4 console.log statements) **Impact:** Exposes internal logic and data in browser/server console. Can leak sensitive information and degrade performance in high-volume operations. **Fix approach:** Implement proper structured logging (Winston, Pino, or similar) for development vs. production environments. Remove or replace all console.log statements with conditional logging. --- ### N+1 Query Problem in Character Details Endpoint **Issue:** The findOne method in CharactersService performs multiple sequential async API calls for translation enrichment, causing N+1 query pattern **Files:** `server/src/modules/characters/characters.service.ts` (lines 186-222) **Problem Details:** - Fetches items, formulas, and preparedItems from database (3 queries) - For EACH item, formula, and prepared item, calls `enrichEquipmentWithTranslations()` which queries the Translations table or Claude API - If a character has 50 items, this results in 50+ additional Prisma queries (or Claude API calls) **Impact:** Dramatically slow character sheet loading. Creates rate-limiting pressure on Claude API. Potential timeout on high-inventory characters. **Fix approach:** 1. Use Prisma's `include` to load equipment relationships in the initial query 2. Batch translation lookups: collect all unique equipment IDs, translate in one batch, then merge results 3. Consider caching translations at the service layer for repeated requests --- ### Oversized Service Class **Issue:** CharactersService is 1,454 lines - violates single responsibility principle and makes testing difficult **Files:** `server/src/modules/characters/characters.service.ts` **Contains:** - Character CRUD operations - HP management with dying/wounded condition logic - Item management - Condition management - Resource management - Rest system logic - Alchemy system logic (vials, formulas, prepared items) - Multiple helper methods (getDyingConditions, getDeathThreshold, etc.) **Impact:** Hard to locate code, difficult to test individual features, increased risk of bugs when modifying one feature affecting another. **Fix approach:** Split into multiple focused services: - `CharactersCoreService` - CRUD operations - `CharacterHpService` - HP and dying/wounded logic - `CharacterAlchemyService` - Alchemy system - `CharacterRestService` - Rest and recovery logic --- ## Known Issues ### Missing Level-Up System **Issue:** Level progression is mentioned in CLAUDE.md as "Noch zu implementieren" but no implementation exists **Files:** No implementation - feature completely absent **Impact:** Cannot advance character levels, blocking career progression mechanic. **Workaround:** Level can be updated via direct database manipulation or API patching, but no UI or validation logic. **Priority:** High - Critical gameplay feature --- ### Unused equipmentlevel.json File at Project Root **Issue:** File `equipmentlevel.json` (250KB+) exists at project root but is not referenced by any code **Files:** `/c/Users/ZielonkaA/Documents/Dimension-47/equipmentlevel.json` **Impact:** - Takes up disk space - Ignored by git, clogs project root - Suggests abandoned equipment import/level-mapping system - Unknown purpose - may be partial/corrupted data **Fix approach:** 1. Determine original purpose (equipment level mapping?) 2. Either integrate into equipment seed system or delete 3. Check git history to understand why it was abandoned --- ## Security Considerations ### WebSocket Gateway Authentication is Minimal **Issue:** Token validation in WebSocket connection handler is basic but lacks some best practices **Files:** `server/src/modules/characters/characters.gateway.ts` (lines 60-93) **Current implementation:** - Extracts token from `client.handshake.auth.token` or Authorization header - Verifies token signature with JWT_SECRET - Verifies user exists in database - No rate limiting on connection attempts - No IP whitelisting or additional authentication layers **Potential risks:** - Rapid connection attempts could brute-force token validation or create connection storms - No tracking of legitimate vs. malicious connection attempts - Token rotation/revocation not supported (token valid until expiry) **Recommendations:** 1. Implement connection rate limiting per IP/user 2. Add token revocation mechanism 3. Consider requiring additional re-authentication for sensitive operations 4. Log suspicious connection patterns --- ### Input Validation on Equipment Search Query **Issue:** Equipment search endpoint accepts query parameters without upper bounds, potentially enabling resource exhaustion **Files:** `server/src/modules/equipment/equipment.controller.ts` (lines 23-42) **Current implementation:** - Takes `limit` parameter (defaults to 50, user-configurable) - No maximum limit enforced - Accepts large pagination page numbers - `traits` parameter is comma-separated without validation on count **Potential risks:** - `?limit=999999999` could cause OOM or timeout - `?page=999999999999` could overflow internal calculations - Unbounded trait queries could cause DoS **Fix approach:** 1. Set hard maximum limits: `limit` ≤ 500, `page` ≤ 10000 2. Validate and cap traits array length ≤ 50 3. Implement pagination cursor-based approach instead of offset-based 4. Add rate limiting per user/IP on search endpoint --- ### CORS Configuration Overly Permissive in Development **Issue:** Development CORS allows all localhost origins, which is standard but could leak requests to unintended local services **Files:** `server/src/main.ts` (lines 26-47) **Current implementation:** ```typescript if (nodeEnv === 'development' && /^https?:\/\/localhost(:\d+)?$/.test(origin)) { return callback(null, true); } ``` **Impact:** Any localhost service can make cross-origin requests to the API. Low risk in pure development, but could leak credentials or data if other services run on localhost. **Fix approach:** In development, explicitly list expected origins (e.g., `http://localhost:5173`) rather than wildcard localhost. --- ## Performance Bottlenecks ### Equipment Database with 5,482 Items - Unindexed Search **Issue:** Full-text search on Equipment table lacks proper indexing for performance **Files:** - `server/src/modules/equipment/equipment.service.ts` (search implementation) - `server/prisma/schema.prisma` (Equipment model definition) - `server/prisma/seed-equipment.ts` (5,482 items) **Current queries use:** - `.contains()` filters on `name`, `summary`, `effect` fields - No full-text search index - No composite indexes for common filter combinations **Impact:** - Search queries on large equipment set may be slow - If multiple users search simultaneously, database load spikes - Trait filtering requires collection of all results then filtering in application code (N+1 pattern with filters) **Improvement path:** 1. Add PostgreSQL `@@@` full-text search with tsvector indexes 2. Add composite indexes: `(category, itemCategory)`, `(level, name)` 3. Use Prisma's `findRaw` for complex searches with proper SQL optimization 4. Consider search caching with Redis for common queries --- ### Translation Caching at Item Retrieval Time **Issue:** Translations are fetched on-demand during character detail retrieval, causing repeated Claude API calls for same items **Files:** `server/src/modules/characters/characters.service.ts` (lines 126-147, 186-222) **Current behavior:** - First time a character's item is viewed: cache miss, Claude API called - If multiple characters have same item: Claude API called multiple times - No cache invalidation strategy or TTL **Impact:** - Increased Claude API costs and latency - Rate limiting pressure if many characters queried - Slow character sheet loads **Fix approach:** 1. Pre-cache translations for common items at server startup 2. Implement TTL-based cache expiration (e.g., 30 days) 3. Batch missing translations when loading characters with multiple items 4. Cache at equipment level, not at character level --- ## Fragile Areas ### Character Death/Resurrection State Management **Issue:** Dying/Wounded conditions interact with HP changes in complex ways that could have race conditions **Files:** `server/src/modules/characters/characters.service.ts` (lines 262-406) **Fragile interactions:** - When HP drops to 0: checks Wounded/Doomed values, calculates Dying value, adds/updates condition, broadcasts update - When HP increases from 0: removes Dying, adds/increments Wounded, broadcasts update - Multiple async operations between checking and updating - No transaction wrapping **Risks:** - If two updates happen simultaneously (WebSocket + rest endpoint), conditions could get corrupted - Wounded value calculation depends on database state that could change between read and write - Broadcasting happens after database update, potential sync issues if broadcast fails **Safe modification:** 1. Wrap Dying/Wounded logic in Prisma transaction 2. Add optimistic locking (version field) to Character model 3. Consolidate HP update and condition management into single atomic operation 4. Test scenarios: multiple simultaneous HP changes, network race conditions **Test coverage:** Currently untested (no test files in server codebase) --- ### Alchemy System State Consistency **Issue:** Alchemy state (vials, formulas, prepared items) spans multiple database models with complex interdependencies **Files:** - `server/src/modules/characters/characters.service.ts` (alchemy methods ~200+ lines) - `server/prisma/schema.prisma` (CharacterAlchemyState, CharacterFormula, CharacterPreparedItem, CharacterResource) **Fragile points:** - Prepared items created by `createPreparedItem()` with `isInfused: true`, then deleted by rest system - Versatile vials count stored in CharacterAlchemyState but actual vials tracked in CharacterResource - Formula learning updates both CharacterFormula and CharacterResource - No constraint ensuring consistency between these tables **Risk:** Orphaned records, inconsistent vial counts, invalid formula states **Safe modification:** 1. Add unique constraint validation in service methods 2. Use Prisma transactions for multi-table alchemy operations 3. Add data integrity checks in rest system 4. Create migration to validate existing data --- ## Test Coverage Gaps ### No Backend Tests **Issue:** Server codebase has zero test files - all business logic untested **Files:** - `server/src/` directory contains no `.test.ts` or `.spec.ts` files - Test infrastructure exists (Jest, @nestjs/testing configured) but unused **Untested functionality:** - Authentication and authorization guards - Character CRUD with access control - HP updates with Dying/Wounded condition logic (most critical) - Rest system with conditional resource resets - Alchemy system with formula learning and vial tracking - WebSocket message handlers (race conditions, auth) - Equipment search with filtering **Priority areas for testing:** 1. Character death/resurrection state transitions (HIGH - bug risk) 2. Authentication guards on protected endpoints (HIGH - security) 3. Access control: ensure players can't edit others' characters (HIGH - security) 4. Rest system calculations with various ability scores (MEDIUM) 5. Alchemy vial/formula consistency (MEDIUM) **Fix approach:** 1. Create test files for each module: `auth.service.spec.ts`, `characters.service.spec.ts`, etc. 2. Start with authentication and authorization tests (security-critical) 3. Add tests for HP/Dying state transitions (highest bug risk) 4. Use Prisma's test database pattern for integration tests --- ### No Frontend Tests **Issue:** Client codebase has zero test files - no component or hook testing **Files:** - `client/src/` directory contains no `.test.tsx` or `.spec.tsx` files - Test infrastructure missing (no Jest/Vitest config, no testing-library) **Untested components:** - Character sheet tabs (Inventory, Alchemy, Actions, Talents) - HP control component with temporary/current/max interactions - Condition management modal - Rest modal with preview calculation - WebSocket hooks for real-time sync - Item search and filtering UI **Impact:** Cannot verify UI correctly reflects data, no regression protection, refactoring is risky **Fix approach:** 1. Install Vitest + React Testing Library 2. Create test files for critical components: HP control, Rest modal, Item search 3. Test WebSocket connection/disconnection handling 4. Add snapshot tests for data-heavy components (character sheet) --- ## Missing Critical Features ### Level-Up System **Issue:** Character advancement is incomplete **Problem:** - Level field exists in database and UI, but no level-up mechanics - Cannot allocate ability score increases at certain levels - Cannot select new feats when leveling - Cannot add/remove skills when leveling **Files:** No implementation exists **Blocks:** Full character progression gameplay --- ## Dependencies at Risk ### Claude API Integration as Critical Path **Issue:** German translation system depends on Claude API for on-demand translation calls **Files:** - `server/src/modules/claude/claude.service.ts` - `server/src/modules/translations/translations.service.ts` **Risk points:** 1. No fallback if API is unavailable - character sheets fail to load with translations 2. Rate limiting: high-traffic scenarios could hit Claude API limits 3. Cost: unbounded - every unique item/feat/spell triggers an API call 4. Latency: API calls on the critical path of character sheet loading (3+ second potential delay) **Migration plan:** 1. Pre-populate translations for all 5,482 equipment items on server startup 2. Batch translate feats/spells during seeding 3. Use Claude API only for user-created custom items 4. Cache everything in database with TTL 5. Implement graceful degradation: show English names if translation fails --- ### Prisma 7.2.0 - Check for Security/Critical Updates **Files:** - `server/package.json` - `@prisma/client: ^7.2.0` - `server/prisma/schema.prisma` - Using latest client **Note:** Version is recent (January 2025+) but "^" allows minor updates. Monitor for critical patches in Prisma security advisories. --- ## Scaling Limits ### Equipment Search at 5,482 items **Current capacity:** Linear search with `.contains()` filters **Limit:** Performance degrades beyond ~10,000 items, potential timeout at 50,000+ **Scaling path:** 1. Add PostgreSQL full-text search indexes (supports millions of items) 2. Implement search result caching 3. Consider Elasticsearch if full-text becomes bottleneck 4. Pagination already uses `take/skip`, good foundation --- ### WebSocket Connections per Campaign **Issue:** No connection pooling limits, no per-campaign connection quota **Files:** `server/src/modules/characters/characters.gateway.ts` **Current behavior:** - Each connection stores socket in `connectedClients` Map - Broadcasts go to all sockets in character room - No limits on concurrent connections per campaign or globally **Potential issue:** If campaign has 100 characters and each has 10 connected users watching, that's 1,000 broadcast operations per update. At scale this causes CPU/memory pressure. **Scaling recommendations:** 1. Set max connections per campaign (e.g., 500) 2. Implement connection pooling/groups (watch list vs. active participants) 3. Use socket.io's built-in room management more aggressively 4. Monitor memory usage of `connectedClients` Map for leaks --- ## Database Schema Concerns ### Character pathbuilderData Stored as JSON Blob **Issue:** Original Pathbuilder export is stored unstructured as JSON **Files:** `server/prisma/schema.prisma` (line 198: `pathbuilderData Json?`) **Potential issues:** - Cannot query Pathbuilder fields directly - Data validation relies on application code, not schema - Difficult to report or audit what data came from imports - No versioning if Pathbuilder export format changes **Impact:** Low - used primarily for reference, but limits data flexibility **Improvement path:** 1. Parse and normalize Pathbuilder data into proper database fields 2. Consider storing hash of original for audit trail 3. Add migration to extract key fields from JSON for querying --- ## Environmental Configuration ### JWT_SECRET Management **Issue:** JWT_SECRET passed via environment variable with no rotation mechanism **Files:** - `server/src/modules/auth/strategies/jwt.strategy.ts` - `server/src/modules/characters/characters.gateway.ts` **Concern:** - If secret is leaked, all existing tokens become invalid - No way to rotate secret without invalidating all sessions - No secret versioning **Recommendation:** 1. Implement secret versioning in token header 2. Support multiple valid secrets during rotation period 3. Add secret rotation schedule (e.g., quarterly) 4. Store secrets in vaulting system, not .env --- ### ENV File Example Status **Files:** - `server/.env.example` - `client/.env.example` **Status:** Confirmed present in CLAUDE.md - properly structured **Verification:** Users can reference templates when setting up environment --- ## API Documentation ### Swagger API Docs Enabled but may Expose Sensitive Operations **Files:** `server/src/main.ts` (lines 49-64) **Current state:** - Swagger UI enabled at `/api/docs` - Available to all users with API access - Could expose internal API structure to unauthorized users **Recommendation:** - In production: require ADMIN role to view Swagger - In development: keep open for debugging - Add basic authentication to `/api/docs` endpoint --- *Concerns audit: 2026-04-27*