"""Probe-Backend mit Anmeldung: die echte App mit Attrappe, Wegwerf-Register und Wegwerf-Zugang. Koordinator-Werkzeug zu Teil 10, nicht fuers Repo. Kein Broker-Aufruf, kein Ereignis im echten Register, keine echte Zugangsdatei. Der Wegwerf-Zugang traegt ein bekanntes Passwort und das Beispielgeheimnis der TOTP-Literatur; beides steht in zugang.json im Ausgabeordner, damit angriffe.py und der Browser-Lauf sich anmelden koennen. Aufruf aus dem Projektordner (oder einer Kopie davon): python start_probe_zugang.py [mit-paperstatus] [zwei-benutzer] Mit zwei-benutzer kommt ein zweiter Wegwerf-Benutzer "zweiter" dazu (eigenes TOTP-Geheimnis, in zugang2.json), damit sich pruefen laesst, dass das Entfernen des einen den anderen nicht trifft. """ import dataclasses import json import sys from datetime import UTC from datetime import datetime from pathlib import Path import uvicorn from trading.broker.attrappe import BrokerAttrappe from trading.dashboard.app import erzeuge_app from trading.dashboard.config import lade_dashboard_config from trading.dashboard.zugang import Benutzer from trading.dashboard.zugang import schreibe_benutzer from trading.dashboard.zugang import setze_passwort from trading.killswitch.killswitch import lade_killswitch_config from trading.registry.registry import Registry BENUTZER = "probe" PASSWORT = "nur-fuer-die-probe-2026" GEHEIMNIS = "JBSWY3DPEHPK3PXP" port = int(sys.argv[1]) ordner = Path(sys.argv[2]) ordner.mkdir(parents=True, exist_ok=True) mit_status = "mit-paperstatus" in sys.argv[3:] zwei_benutzer = "zwei-benutzer" in sys.argv[3:] ZWEITER = "zweiter" GEHEIMNIS_ZWEITER = "KRUGS4ZANFZSAYJA" zugang_datei = ordner / "zugang.toml" benutzer = {BENUTZER: Benutzer(name=BENUTZER, passwort=setze_passwort(PASSWORT), totp_geheimnis=GEHEIMNIS)} if zwei_benutzer: benutzer[ZWEITER] = Benutzer(name=ZWEITER, passwort=setze_passwort(PASSWORT), totp_geheimnis=GEHEIMNIS_ZWEITER) (ordner / "zugang2.json").write_text( json.dumps({"benutzer": ZWEITER, "passwort": PASSWORT, "geheimnis": GEHEIMNIS_ZWEITER}), encoding="utf-8", ) schreibe_benutzer(zugang_datei, benutzer) (ordner / "zugang.json").write_text( json.dumps({"benutzer": BENUTZER, "passwort": PASSWORT, "geheimnis": GEHEIMNIS}), encoding="utf-8", ) paper_ordner = ordner / "paper" paper_ordner.mkdir(exist_ok=True) status_datei = ordner / "status.json" if mit_status: protokoll = paper_ordner / "2026-09-18T131502-paper.jsonl" zeilen = [ {"art": "kopf", "modus": "paper"}, {"art": "takt", "schritt": 1, "phase": "handelt", "position": 10, "zielposition": 10}, ] protokoll.write_text("\n".join(json.dumps(z) for z in zeilen) + "\n", encoding="utf-8") status_datei.write_text( json.dumps( { "zeit": datetime.now(UTC).isoformat(), "modus": "paper", "phase": "handelt", "agent": { "quelle": "register", "name": "aapl-minute-ppo", "version": "v20260907-074410", "status": "paper", }, "instrument": "AAPL.XNAS", "killswitch": "aktiv", "position": 10, "zielposition": 10, "letzte_aktion": {"zeit": datetime.now(UTC).isoformat(), "aktion": 3, "stufe": 1}, "letzte_kerze": datetime.now(UTC).replace(second=0, microsecond=0).isoformat(), "orders": 1, "kontowert": 100012.5, "startkapital": 100000.0, "hinweis": None, "protokoll": str(protokoll), "pid": 1, } ), encoding="utf-8", ) config = dataclasses.replace( lade_dashboard_config("config/dashboard.toml"), port=port, broker_wahl="attrappe", sendeintervall_s=2.0, erlaubte_hosts=(f"127.0.0.1:{port}", f"localhost:{port}"), anmeldung_pflicht=True, mfa_pflicht=True, zugang_datei=str(zugang_datei), zugang_protokoll=str(ordner / "anmeldungen.jsonl"), paper_status_datei=str(status_datei), paper_protokoll_ordner=str(paper_ordner), ) app = erzeuge_app( broker=BrokerAttrappe(), registry=Registry(db_pfad=ordner / "registry.db", artefakt_wurzel=ordner / "artifacts"), config=config, killswitch_config=lade_killswitch_config("config/killswitch.toml"), dist=Path("dashboard/dist"), ) print(f"Probe-Backend mit Anmeldung auf 127.0.0.1:{port}, Ablage {ordner}", flush=True) uvicorn.run(app, host="127.0.0.1", port=port, log_level="warning", server_header=False, proxy_headers=False)