feat: cockpit
This commit is contained in:
@@ -29,10 +29,29 @@ _narrative_cache: Dict[Tuple[str, str], str] = {}
|
||||
|
||||
|
||||
def _load_configs() -> None:
|
||||
"""instruments.json is the static, git-tracked catalog (baked into the Docker image —
|
||||
reset to its git contents on every deploy rebuild). Saxo link + drivers are
|
||||
user-editable at runtime, so they're kept in SQLite (services.database's
|
||||
instrument_overrides table, on the persistent db_data volume) and merged on top here,
|
||||
rather than written back to the JSON file where a deploy would silently discard them."""
|
||||
global _configs
|
||||
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
_configs = {inst["id"]: inst for inst in data["instruments"]}
|
||||
|
||||
from services.database import get_instrument_overrides
|
||||
for uid, override in get_instrument_overrides().items():
|
||||
if uid not in _configs:
|
||||
continue
|
||||
# saxo_quote_symbol: the override row is the sole source of truth once it exists —
|
||||
# apply it even when None (an explicit unlink from a previously-linked state).
|
||||
_configs[uid]["saxo_quote_symbol"] = override.get("saxo_quote_symbol")
|
||||
# drivers: only overwrite the catalog's own default when this instrument actually
|
||||
# has a saved override (a row can exist purely for its saxo_quote_symbol, with
|
||||
# drivers_json left NULL — that must NOT blank out the catalog's base drivers).
|
||||
if override.get("drivers") is not None:
|
||||
_configs[uid]["drivers"] = override["drivers"]
|
||||
|
||||
logger.info(f"[instrument_service] Loaded {len(_configs)} instrument configs")
|
||||
|
||||
|
||||
@@ -49,7 +68,9 @@ def get_instrument(instrument_id: str) -> Optional[Dict]:
|
||||
|
||||
|
||||
def update_instrument_drivers(instrument_id: str, drivers: List[Dict]) -> None:
|
||||
"""Persist updated drivers to instruments.json and refresh in-memory config."""
|
||||
"""Persist updated drivers to the SQLite instrument_overrides table (NOT
|
||||
instruments.json — that file is baked into the Docker image and gets reset to its
|
||||
git-tracked contents on every deploy rebuild) and refresh in-memory config."""
|
||||
global _configs
|
||||
if _configs is None:
|
||||
_load_configs()
|
||||
@@ -58,26 +79,18 @@ def update_instrument_drivers(instrument_id: str, drivers: List[Dict]) -> None:
|
||||
if uid not in _configs:
|
||||
raise ValueError(f"Instrument {uid} not found")
|
||||
|
||||
# Load raw JSON, update the matching instrument, save back
|
||||
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
|
||||
raw = json.load(f)
|
||||
from services.database import set_instrument_override_drivers
|
||||
set_instrument_override_drivers(uid, drivers)
|
||||
|
||||
for inst in raw["instruments"]:
|
||||
if inst["id"] == uid:
|
||||
inst["drivers"] = drivers
|
||||
break
|
||||
|
||||
with open(CONFIG_PATH, "w", encoding="utf-8") as f:
|
||||
json.dump(raw, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# Refresh in-memory cache
|
||||
_configs[uid]["drivers"] = drivers
|
||||
logger.info(f"[instrument_service] Updated drivers for {uid} ({len(drivers)} drivers)")
|
||||
|
||||
|
||||
def update_instrument_saxo_link(instrument_id: str, saxo_symbol: Optional[str]) -> None:
|
||||
"""Persist the Saxo quote-symbol link to instruments.json and refresh in-memory config.
|
||||
saxo_symbol=None clears the link (falls back to yfinance)."""
|
||||
"""Persist the Saxo quote-symbol link to the SQLite instrument_overrides table (NOT
|
||||
instruments.json — that file is baked into the Docker image and gets reset to its
|
||||
git-tracked contents on every deploy rebuild, which is why this link kept disappearing)
|
||||
and refresh in-memory config. saxo_symbol=None clears the link (falls back to yfinance)."""
|
||||
global _configs
|
||||
if _configs is None:
|
||||
_load_configs()
|
||||
@@ -86,16 +99,8 @@ def update_instrument_saxo_link(instrument_id: str, saxo_symbol: Optional[str])
|
||||
if uid not in _configs:
|
||||
raise ValueError(f"Instrument {uid} not found")
|
||||
|
||||
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
|
||||
raw = json.load(f)
|
||||
|
||||
for inst in raw["instruments"]:
|
||||
if inst["id"] == uid:
|
||||
inst["saxo_quote_symbol"] = saxo_symbol
|
||||
break
|
||||
|
||||
with open(CONFIG_PATH, "w", encoding="utf-8") as f:
|
||||
json.dump(raw, f, ensure_ascii=False, indent=2)
|
||||
from services.database import set_instrument_override_saxo_symbol
|
||||
set_instrument_override_saxo_symbol(uid, saxo_symbol)
|
||||
|
||||
_configs[uid]["saxo_quote_symbol"] = saxo_symbol
|
||||
logger.info(f"[instrument_service] Updated Saxo link for {uid}: {saxo_symbol}")
|
||||
|
||||
Reference in New Issue
Block a user