"""Serve the REAL cockpit locally against whatever FXHNT_OPERATIONAL_DSN points to, READ-ONLY. For fast local UI testing against REAL prod data without a 9-minute Argo deploy. Deliberately constructs the repos WITHOUT calling .migrate(), so it never writes DDL to the (possibly production) DB — the cockpit pages it serves are read-only. Driven by scripts/dev-cockpit-local.sh, which sets up the port-forward + DSN. Env: FXHNT_OPERATIONAL_DSN required — e.g. postgresql+psycopg://foxhunt:@127.0.0.1:15432/fxhnt FXHNT_DEV_PORT local port to serve on (default 8801) """ import os import uvicorn from fxhnt.adapters.persistence.forward_nav import ForwardNavRepo from fxhnt.adapters.persistence.ibkr_account_repo import IbkrAccountRepo from fxhnt.adapters.persistence.paper_repo import PaperRepo from fxhnt.adapters.web.app import create_app dsn = os.environ["FXHNT_OPERATIONAL_DSN"] port = int(os.environ.get("FXHNT_DEV_PORT", "8801")) # READ-ONLY: no .migrate() — never write DDL to a prod DB we're only browsing. # Wire EVERY repo prod wires (create_app_from_settings), or a page silently degrades to an empty state that # does NOT match prod — the IBKR paper-account card in particular reads through ibkr_account_repo; without it # the /paper card renders "not connected yet" even when the real account is live (a misleading local artifact). app = create_app( ForwardNavRepo(dsn), paper_repo=PaperRepo(dsn), bybit_paper_repo=PaperRepo(dsn), ibkr_account_repo=IbkrAccountRepo(dsn), ) print(f"cockpit (read-only) on http://127.0.0.1:{port}/paper/sim?book=bybit_4edge") uvicorn.run(app, host="127.0.0.1", port=port, log_level="warning")