Create services/logging.py as the canonical home for setup_logging(),
all log format constants, named loggers, and _ml_logging_enabled.
Update all route modules and lab_api.py to import logging symbols from
services.logging and all other symbols from their canonical sources
(models.state, models.requests, models.responses, services.database,
services.deck_service, services.scryfall, services.import_helpers,
services.import_service, services.precon_service, services.forge_runner).
Delete routes/shared.py — the re-export hub is no longer needed.
Closes#61
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- GET /api/lab/result: Starlette's JSONResponse uses allow_nan=False,
so NaN/Infinity floats from simulation output cause a ValueError crash.
Add _sanitize_floats() to replace non-finite floats with null before
returning. Also wrap json.load in try/except for better error reporting.
- POST /api/lab/precons/install-batch: Frontend sends {"names": [...]}
but backend expected {"fileNames": [...]}. Accept both field names.
- POST /api/lab/precons/install: Same mismatch — frontend sends {"name"}
but backend expected {"fileName"}. Accept both field names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The precon deck list was missing after the monolith refactor because
PRECON_DIR was hardcoded in services/precon_service.py with no CLI arg,
env var, or auto-resolve fallback — unlike forge_jar, forge_dir, etc.
Changes:
- Add precon_dir field to Config class (models/state.py)
- Add --precon-dir CLI arg and PRECON_DIR env var support
- Add _resolve_precon_dir() with project-root, parent-dir, and
forge_dir-relative detection; creates dir as fallback for downloads
- Refactor precon_service.py to use _get_precon_dir() helper that reads
CFG.precon_dir at runtime instead of a hardcoded module-level Path
- Update routes/precon.py to use _get_precon_dir() for install endpoints
- Wire _on_startup to resolve precon_dir for uvicorn-direct launches
- Remove unused PRECON_DIR/PRECON_INDEX imports from routes/lab.py
- Audit confirms all other CFG path fields already have fallbacks
Task 1: Move BUILTIN_COMMANDERS + load_commander_meta() to shared.py
Fix import_routes.py to use _shared.COMMANDER_META (module ref)
Task 2: Rewrite precon.py to use _shared.PRECON_INDEX (module ref)
Task 3: Add @app.on_event('startup') safety net for uvicorn --reload