18 KiB
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:
- Use Prisma's
includeto load equipment relationships in the initial query - Batch translation lookups: collect all unique equipment IDs, translate in one batch, then merge results
- 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 operationsCharacterHpService- HP and dying/wounded logicCharacterAlchemyService- Alchemy systemCharacterRestService- 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:
- Determine original purpose (equipment level mapping?)
- Either integrate into equipment seed system or delete
- 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.tokenor 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:
- Implement connection rate limiting per IP/user
- Add token revocation mechanism
- Consider requiring additional re-authentication for sensitive operations
- 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
limitparameter (defaults to 50, user-configurable) - No maximum limit enforced
- Accepts large pagination page numbers
traitsparameter is comma-separated without validation on count
Potential risks:
?limit=999999999could cause OOM or timeout?page=999999999999could overflow internal calculations- Unbounded trait queries could cause DoS
Fix approach:
- Set hard maximum limits:
limit≤ 500,page≤ 10000 - Validate and cap traits array length ≤ 50
- Implement pagination cursor-based approach instead of offset-based
- 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:
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 onname,summary,effectfields- 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:
- Add PostgreSQL
@@@full-text search with tsvector indexes - Add composite indexes:
(category, itemCategory),(level, name) - Use Prisma's
findRawfor complex searches with proper SQL optimization - 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:
- Pre-cache translations for common items at server startup
- Implement TTL-based cache expiration (e.g., 30 days)
- Batch missing translations when loading characters with multiple items
- 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:
- Wrap Dying/Wounded logic in Prisma transaction
- Add optimistic locking (version field) to Character model
- Consolidate HP update and condition management into single atomic operation
- 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()withisInfused: 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:
- Add unique constraint validation in service methods
- Use Prisma transactions for multi-table alchemy operations
- Add data integrity checks in rest system
- 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.tsor.spec.tsfiles- 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:
- Character death/resurrection state transitions (HIGH - bug risk)
- Authentication guards on protected endpoints (HIGH - security)
- Access control: ensure players can't edit others' characters (HIGH - security)
- Rest system calculations with various ability scores (MEDIUM)
- Alchemy vial/formula consistency (MEDIUM)
Fix approach:
- Create test files for each module:
auth.service.spec.ts,characters.service.spec.ts, etc. - Start with authentication and authorization tests (security-critical)
- Add tests for HP/Dying state transitions (highest bug risk)
- 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.tsxor.spec.tsxfiles- 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:
- Install Vitest + React Testing Library
- Create test files for critical components: HP control, Rest modal, Item search
- Test WebSocket connection/disconnection handling
- 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.tsserver/src/modules/translations/translations.service.ts
Risk points:
- No fallback if API is unavailable - character sheets fail to load with translations
- Rate limiting: high-traffic scenarios could hit Claude API limits
- Cost: unbounded - every unique item/feat/spell triggers an API call
- Latency: API calls on the critical path of character sheet loading (3+ second potential delay)
Migration plan:
- Pre-populate translations for all 5,482 equipment items on server startup
- Batch translate feats/spells during seeding
- Use Claude API only for user-created custom items
- Cache everything in database with TTL
- 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.0server/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:
- Add PostgreSQL full-text search indexes (supports millions of items)
- Implement search result caching
- Consider Elasticsearch if full-text becomes bottleneck
- 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
connectedClientsMap - 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:
- Set max connections per campaign (e.g., 500)
- Implement connection pooling/groups (watch list vs. active participants)
- Use socket.io's built-in room management more aggressively
- Monitor memory usage of
connectedClientsMap 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:
- Parse and normalize Pathbuilder data into proper database fields
- Consider storing hash of original for audit trail
- 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.tsserver/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:
- Implement secret versioning in token header
- Support multiple valid secrets during rotation period
- Add secret rotation schedule (e.g., quarterly)
- Store secrets in vaulting system, not .env
ENV File Example Status
Files:
server/.env.exampleclient/.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/docsendpoint
Concerns audit: 2026-04-27