## Device Tracking (conversation-service)
- Add DeviceInfoDto class for validating device information
- Extract client IP from X-Forwarded-For and X-Real-IP headers
- Capture User-Agent header automatically on conversation creation
- Support optional fingerprint and region from client
- Pass deviceInfo through service layer to entity for persistence
Files changed:
- conversation.controller.ts: Add extractClientIp() method and header capture
- conversation.dto.ts: Add DeviceInfoDto with validation decorators
- conversation.service.ts: Update CreateConversationParams interface
## Build Optimization (admin-client)
- Implement code splitting via Rollup manualChunks
- Separate vendor libraries into cacheable chunks:
- vendor-react: react, react-dom, react-router-dom (160KB)
- vendor-antd: antd, @ant-design/icons (1013KB)
- vendor-charts: recharts (409KB)
- vendor-data: @tanstack/react-query, axios, zustand (82KB)
- Main bundle reduced from 1732KB to 61KB (96% reduction)
- Set chunkSizeWarningLimit to 1100KB for antd
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Both user-service and evolution-service need the same JWT_SECRET
to verify admin tokens correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend (user-service):
- Add admin user management APIs (list, search, statistics, detail)
- Add pagination and filtering support for user queries
- Add JWT token authentication for admin endpoints
Frontend (admin-client):
- Add UsersPage with user list, search, filters and statistics
- Add SettingsPage with admin profile, password change, system info
- Update App.tsx routes to use new pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move specific routes (logs/actions, logs/entity-types) before
parameterized route (logs/:id) to prevent NestJS from matching
'actions' and 'entity-types' as UUID parameters.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The useEvolutionStatistics and useSystemHealth hooks call endpoints that
depend on a non-existent knowledge-service internal API. Removed these
calls and the related UI sections to prevent 500 errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend (evolution-service):
- Add analytics module with scheduled statistics aggregation
- Implement daily_statistics aggregation (OVERALL, CHANNEL, CATEGORY)
- Add monthly financial report generation and management
- Create audit log service for operation tracking
- Schedule cron jobs for automatic data aggregation
Frontend (admin-client):
- Replace dashboard mock data with real API calls
- Add analytics page with trend charts and dimension breakdown
- Add financial reports page with confirm/lock workflow
- Add audit logs page with filtering and detail view
- Update navigation with analytics submenu
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TransactionService for atomic database operations with optimistic lock retry
- Implement pessimistic locking in payment callback handling to prevent race conditions
- Add idempotency check via transactionId unique index to prevent duplicate processing
- Add version columns to PaymentORM and OrderORM for optimistic locking
- Add composite indexes for performance (order_status, transaction_id)
- Optimize connection pool settings for both payment and conversation services
- Update init-db.sql with version columns and new indexes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add configure_system_nginx_ssl() function to generate nginx HTTPS config
- HTTP 80 redirects to HTTPS, HTTPS 443 proxies to Docker nginx 8080
- Include TLS 1.2/1.3, secure ciphers, HSTS headers
- Update renew_ssl_cert() to reload both system and Docker nginx
- Update auto-renew cron to reload system nginx
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add file-service to SERVICE_PORTS (port 3006)
- Add file-service to SERVICE_DIRS and DOCKER_SERVICES mappings
- Include file-service in build, start, stop, restart commands
- Update rebuild service name mapping
- Include file-service in db migrate command
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed nuke command to only delete iConsulting project resources:
- Only project containers (via docker-compose down)
- Only project images (iconsulting-*, *-service)
- Only project volumes (postgres_data, redis_data, etc.)
- Only project networks (iconsulting-network)
Does NOT affect other projects on the same Docker host.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add nuclear option to completely remove:
- All Docker containers
- All Docker images
- All Docker volumes (database data)
- All Docker networks
- All build cache
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Follow proper microservices architecture:
- knowledge-service owns system_experiences table
- evolution-service uses KnowledgeClient API to save experiences
- Deleted SystemExperienceORM from evolution-service
- Added internal API endpoints in knowledge-service
- Disabled synchronize in all services for safety
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Breaking change: evolution-service no longer directly accesses
conversations and messages tables.
Changes:
- Add internal API endpoints to conversation-service for service-to-service calls
- Create ConversationClient in evolution-service to call conversation-service API
- Remove ConversationORM and MessageORM from evolution-service
- Update evolution.service to use ConversationClient
This follows microservices best practices:
- Each service owns its data
- Services communicate via API, not shared tables
TODO: Apply same pattern to system_experiences (knowledge-service)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing V2 fields to init-db.sql to match conversation.entity.ts:
- consulting_stage
- consulting_state
- collected_info
- recommended_programs
- conversion_path
- device_info
Also add indexes for the new fields.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use init-db.sql for schema management instead of TypeORM auto-sync.
synchronize:true is dangerous in production and causes conflicts
when multiple services share tables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @Index decorators for conversation_id, created_at, role
- Set created_at to timestamptz type to match database
- Set columns nullable to match database schema
This prevents synchronize:true from trying to modify columns
that have dependent indexes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add input_tokens and output_tokens columns that evolution-service
defines to prevent synchronize:true from trying to drop them.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add columns that evolution-service defines to prevent synchronize:true
from trying to drop them:
- userMessageCount, assistantMessageCount
- totalInputTokens, totalOutputTokens
- rating, feedback, hasConverted
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- rebuild now uses cache by default
- only ignores cache when --no-cache is explicitly passed
Usage:
./deploy.sh rebuild conversation # uses cache
./deploy.sh rebuild conversation --no-cache # ignores cache
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add do_rebuild function to rebuild Docker images without cache.
Supports rebuilding individual services or all services at once.
Usage:
./deploy.sh rebuild conversation # rebuild single service
./deploy.sh rebuild all # rebuild all services
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove image deletion and rebuild steps
- Only delete database volumes and restart services
- TypeORM synchronize:true handles schema creation
- Much faster: no recompilation needed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove migration-based approach which kept failing
- Enable synchronize:true to auto-sync Entity with database
- Schema will always match Entity definition on startup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add migrations path to TypeORM config
- Set migrationsRun: true to run pending migrations on startup
- This ensures V2 columns are created automatically when app starts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add data-source.prod.ts for compiled JS migrations
- Add migration:run:prod script to package.json
- Update deploy.sh to try prod migration first, fallback to dev
- Keep SQL fallback in full-reset as safety net with proper indexes
This ensures migrations work in Docker where ts-node may not be available.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SQL to create consulting_stage, consulting_state, collected_info,
recommended_programs, conversion_path, device_info columns
- Runs after migration step in full-reset to ensure V2 features work
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add do_full_reset function that deletes all data and rebuilds system
- Preserves SSL certificates (stored in /etc/letsencrypt/)
- Requires explicit YES confirmation before proceeding
- Includes: stop services, clean Docker, rebuild, migrate, restart
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch ConversationService to use ClaudeAgentServiceV2
- Pass consultingState and deviceInfo from conversation to context
- Handle state_update chunks and save updated state to database
- Move dotenv to dependencies for migration runtime
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 8-stage consulting workflow (greeting → handoff)
- Create StrategyEngineService for state management and transitions
- Add ClaudeAgentServiceV2 with integrated strategy guidance
- Support old user recognition via get_user_context tool
- Add device info (IP, fingerprint) for new user icebreaking
- Extend ConversationEntity with consulting state fields
- Add database migration for new JSONB columns
Stages: greeting, needs_discovery, info_collection, assessment,
recommendation, objection_handling, conversion, handoff
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix Usage type cast by using unknown intermediate type
- Add PricingTier interface and proper Record type for PRICING
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TokenUsageEntity to store per-request token consumption
- Add TokenUsageService with cost calculation and statistics APIs
- Record input/output/cache tokens per API call
- Calculate estimated cost based on Claude pricing
- Provide user/conversation/global stats aggregation
- Support daily stats and top users ranking
- Integrate token tracking in ClaudeAgentService
- Track latency, tool calls, response length
- Accumulate tokens across tool loop iterations
- Add token_usages table to init-db.sql with proper indexes
This enables:
- Per-user token consumption tracking
- Cost analysis and optimization
- Future billing/quota features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduce tokensPerChar from 2 to 1.8 for more accurate Chinese token estimation
- Use min() instead of max() to enforce upper limits on token counts
- CHAT: max 200 tokens (was min 256)
- SIMPLE_QUERY: max 600 tokens (was min 512)
- CLARIFICATION: max 300 tokens (was min 256)
- CONFIRMATION: max 400 tokens (was min 384)
- DEEP_CONSULTATION: 800-1600 tokens (was 1024-4096)
- ACTION_NEEDED: 500-1000 tokens (was 768-2048)
This should result in more concise AI responses that better match
the intent classifier's suggested length limits.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>