refactor: dedupe scheduler logging/runtime, centralize SystemSetting access, fix rankings N+1
Deploy / lint (push) Successful in 7s
Deploy / test (push) Successful in 42s
Deploy / deploy (push) Successful in 27s

Behavior-preserving cleanup (345 tests pass, ruff clean):

- scheduler: replace 62 inline logger.x(json.dumps({...})) calls with a
  _log_event helper, and collapse 11 identical _job_runtime dicts into an
  _idle_runtime() factory over _JOB_NAMES.
- settings: add app/services/settings_store.py (get_setting/get_value/get_map/
  upsert_setting) and route ~13 hand-rolled SystemSetting queries + two
  identical _settings_map helpers through it.
- scoring.get_rankings: collapse the per-ticker N+1 (3-4 queries + a commit each)
  into 2 bulk reads + a single conditional commit; drop the redundant re-fetch.
  Lazy recompute-on-read is preserved. Adds first tests for get_rankings.

Net ~ -245 lines across the touched modules.
This commit is contained in:
2026-06-24 11:23:39 +02:00
parent f48d8705de
commit 437ceacfc1
11 changed files with 341 additions and 465 deletions
+3 -8
View File
@@ -27,10 +27,10 @@ from app.config import settings
from app.models.alert import AlertLog
from app.models.ohlcv import OHLCVRecord
from app.models.score import CompositeScore
from app.models.settings import SystemSetting
from app.models.sr_level import SRLevel
from app.models.ticker import Ticker
from app.models.watchlist import WatchlistEntry
from app.services import settings_store
from app.services.admin_service import get_activation_config, update_setting
from app.services.qualification import best_target_probability, setup_qualifies
from app.services.rr_scanner_service import get_trade_setups
@@ -72,14 +72,9 @@ def _as_bool(value: str | None, default: bool) -> bool:
return value.strip().lower() == "true"
async def _settings_map(db: AsyncSession) -> dict[str, str]:
keys = [KEY_ENABLED, KEY_TOKEN, KEY_CHAT_ID, KEY_QUALIFIED, KEY_SR, KEY_SCORE_DROP, KEY_DIGEST]
result = await db.execute(select(SystemSetting).where(SystemSetting.key.in_(keys)))
return {s.key: s.value for s in result.scalars().all()}
async def _resolve(db: AsyncSession) -> dict:
stored = await _settings_map(db)
keys = [KEY_ENABLED, KEY_TOKEN, KEY_CHAT_ID, KEY_QUALIFIED, KEY_SR, KEY_SCORE_DROP, KEY_DIGEST]
stored = await settings_store.get_map(db, keys)
db_token = (stored.get(KEY_TOKEN) or "").strip()
if db_token: