Move database initialization logic from shell script to Python application
lifespan, following separation of concerns and improving maintainability.
Benefits:
- Single source of truth for database initialization (api/main.py lifespan)
- Better testability - Python code vs shell scripts
- Clearer logging with structured messages
- Easier to debug and maintain
- Infrastructure (entrypoint.sh) focuses on service orchestration
- Application (api/main.py) owns its data layer
Changes:
- Removed database init from entrypoint.sh
- Enhanced lifespan function with detailed logging
- Simplified entrypoint script (now 4 steps instead of 5)
- All tests pass (28/28 API endpoint tests)
- Update entrypoint.sh to check DEPLOYMENT_MODE before initializing database
- DEV mode: calls initialize_dev_database() which resets the database
- PROD mode: calls initialize_database() which preserves existing data
- Adds clear logging to show which mode is being used
This ensures the dev database is properly reset on container startup,
matching the behavior of the lifespan function in api/main.py.
Update all shell scripts to use the new AI-Trader-Server naming throughout.
Changes:
- main.sh: Update comments and echo statements
- entrypoint.sh: Update startup message
- scripts/validate_docker_build.sh: Update title, container name references,
and docker image tag from ai-trader-test to ai-trader-server-test
- scripts/test_api_endpoints.sh: Update title and docker-compose command
Part of Phase 4: Internal Configuration & Metadata (Task 19)
- Move trap setup before uvicorn (was after, never executed)
- Use exec to replace bash with uvicorn process (better signal handling)
- Ensures uvicorn stays running as PID 1 in container
Removes dual-mode deployment complexity, focusing on REST API service only.
Changes:
- Removed batch mode from docker-compose.yml (now single ai-trader service)
- Deleted scripts/test_batch_mode.sh validation script
- Renamed entrypoint-api.sh to entrypoint.sh (now default)
- Simplified Dockerfile (single entrypoint, removed CMD)
- Updated validation scripts to use 'ai-trader' service name
- Updated documentation (README.md, TESTING_GUIDE.md, CHANGELOG.md)
Benefits:
- Eliminates port conflicts between batch and API services
- Simpler configuration and deployment
- API-first architecture aligned with Windmill integration
- Reduced maintenance complexity
Breaking Changes:
- Batch mode no longer available
- All simulations must use REST API endpoints
Streamline the data preparation workflow by having get_daily_price.py
automatically invoke merge_jsonl.py after fetching all stock prices.
Changes:
- Modified get_daily_price.py to call merge_jsonl.py automatically
- Updated entrypoint.sh to remove redundant merge_jsonl.py call
- Updated main.sh to remove redundant merge_jsonl.py call
- Fixed import order for linting compliance
Benefits:
- Single command now handles both fetching and merging
- Ensures merged.jsonl is always created after price updates
- Simplifies Docker container startup process
- Prevents missing merged.jsonl errors in production
Preserve existing merged.jsonl to avoid data loss and API rate limits.
Only fetch new data if merged.jsonl is missing or empty.
Problem:
- Entrypoint always fetched fresh data from Alpha Vantage on every start
- Overwrote existing mounted data directory
- Caused API rate limit issues and data inconsistencies
- Lost historical data needed for backtesting specific date ranges
Solution:
- Check if merged.jsonl exists and has content before fetching
- Display stock count when using existing data
- Provide manual refresh instructions for when updates are needed
Benefits:
- Faster container startup (no API calls if data exists)
- Avoids Alpha Vantage rate limits (5 calls/min, 500/day)
- Preserves user's existing historical datasets
- Enables reliable backtesting with consistent data
To refresh data: rm data/merged.jsonl && docker-compose restart
Implement automatic detection of custom_config.json for simpler Docker usage.
No environment variables or command-line arguments needed for most users.
Changes:
- entrypoint.sh: Add smart config detection (custom_config.json > CLI arg > default_config.json)
- docker-compose.yml: Add configs volume mount for editing without rebuilds
- docs/DOCKER.md: Update documentation with simplified workflow
- .gitignore: Add custom_config.json to prevent accidental commits
Usage:
cp configs/default_config.json configs/custom_config.json
nano configs/custom_config.json
docker-compose up # Automatically uses custom_config.json
Simplifies user experience by following convention over configuration principle.
- Clarify OPENAI_API_BASE can be left empty for default endpoint
- Increase initial wait time from 3s to 5s
- Add health checking for all MCP services (ports 8000-8003)
- Retry up to 10 times with 1s intervals
- Install netcat for port checking
- Display warnings if services aren't ready
Helps diagnose and prevent MCP client initialization errors.
Run MCP service manager from /app instead of /app/agent_tools
to ensure services can import from tools module.
Changes:
- entrypoint.sh: Run start_mcp_services.py from /app directory
- start_mcp_services.py: Use absolute paths for service scripts
- start_mcp_services.py: Set working directory to /app for services
Fixes ModuleNotFoundError: No module named 'tools' in price.log
Add validation at startup to check required environment variables:
- OPENAI_API_KEY
- ALPHAADVANTAGE_API_KEY
- JINA_API_KEY
If any are missing, display clear error message with setup
instructions and exit immediately (no restart loop).
Change restart policy from 'unless-stopped' to 'on-failure:3'
to limit restart attempts and prevent endless loops on
configuration errors.
Move get_daily_price.py and merge_jsonl.py to /app/scripts
to prevent volume mount from overlaying the scripts.
Scripts run from /app/data context to output correctly.
Fixes container startup error where scripts were not found
after ./data volume mount replaced container's /app/data.