Use asyncio.wait with FIRST_EXCEPTION to:
- Properly name tasks for better error logging
- Cancel remaining tasks when one fails
- Log which specific manager failed before propagating the exception
Unlike JOB_RANDOM_NUMBER which is used for external job enqueueing,
JOB_FETCH_BITCOIN_PRICE is only used internally by the scheduler.
Move it to worker.py to clarify it's not part of the public job API.
- Added ASYNCPG_DATABASE_URL constant in database.py
- Updated jobs.py to import from database module
- Updated worker.py to import from database module
- Removed duplicate URL parsing logic from both files
- Add RandomNumberOutcome model to models.py
- Update worker.py to execute job logic:
- Generate random number 0-100
- Record execution duration
- Store outcome in database
- Add test_jobs.py with unit tests for job handler logic
- Add pgqueuer dependency to pyproject.toml
- Create worker.py with schema installation and job handler registration
- Add make worker command to Makefile
- Update make dev to run worker alongside backend/frontend
- Use has_table() check for idempotent schema installation
- Register 'random_number' job handler (placeholder that logs for now)