Files
Dimension-47/.planning/codebase/CONCERNS.md

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:

  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:

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

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