FIX: Render brach ab - RSI-Zeile griff im falschen Scope zu (Dashboard kaputt)
User-Screenshot: sechs leere "—"-Zeilen in der M15-Karte unter Gate ④ und eine
komplett leere Breakout-Karte.
URSACHE, mein Fehler von heute Abend: `renderM15(s)` bekommt NUR `m15_setup`.
Meine RSI-Zeile griff aber auf `d.market.rsi_m15` zu - `d` existiert in diesem
Scope nicht. ReferenceError mitten im Render: alles ab der Fehlerstelle blieb
auf dem Initialwert "—", und die danach gerufenen Renderer (u.a. renderBrk)
liefen gar nicht mehr. Genau die Signatur im Screenshot.
⚠⚠ WARUM DIE PIPELINE ES DURCHGELASSEN HAT: `node --check` prueft nur SYNTAX.
Ein ReferenceError ist syntaktisch einwandfrei. Python hat dafuer ruff F821 -
fuer JS gab es nichts Vergleichbares. Das ist die Luecke, nicht ein
Einzelversehen: es ist der ZWEITE Fall derselben Klasse heute (vorhin `d5.m5`
statt `s.m5`, den hatte ich beim Bauen selbst bemerkt).
BEHOBEN: renderM15(s, snap) bekommt den vollen Snapshot mit, Aufrufer angepasst,
Zugriff auf ((snap||{}).market||{}).rsi_m15. Ein Kommentar an der Signatur haelt
fest, warum `d.` dort verboten ist.
NEU: tools/render_check.mjs - laesst renderM15 und renderBrk gegen ein
Minimal-DOM mit einem ECHTEN Snapshot laufen und meldet jede Exception.
Mutationsprobe bestanden: Fehler zurueckgebaut -> "❌ d is not defined",
zurueck -> gruen. Alle vier Zeilen rendern wieder korrekt (RSI, M5-Kontext,
Gate ③b, BRK-Position).
v=188, damit der Browser das Update sicher zieht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
621c82bab8
commit
95b22e2add
@@ -0,0 +1,34 @@
|
||||
// Render-Probe: laesst renderM15 + renderBrk gegen ein Minimal-DOM laufen.
|
||||
//
|
||||
// ⚠⚠ WARUM ES DAS GIBT (2026-08-19): `node --check` prueft nur die SYNTAX. Ein
|
||||
// ReferenceError (falsche Variable im falschen Scope) ist syntaktisch
|
||||
// einwandfrei und faellt erst im Browser auf - dort bricht er aber den
|
||||
// GESAMTEN Render ab: alles ab der Fehlerstelle bleibt auf "—", und die
|
||||
// danach gerufenen Renderer laufen gar nicht mehr. Real passiert: die
|
||||
// RSI-Zeile griff in `renderM15(s)` auf `d.market` zu; das Dashboard zeigte
|
||||
// sechs leere Zeilen und eine komplett leere Breakout-Karte.
|
||||
// Python hat dafuer `ruff F821` - fuer JS gab es nichts Vergleichbares.
|
||||
//
|
||||
// Aufruf: node tools/render_check.mjs <snapshot.json>
|
||||
// Snapshot holen: curl -s http://127.0.0.1:8000/api/snapshot > snap.json
|
||||
import fs from "fs";
|
||||
const snap = JSON.parse(fs.readFileSync(process.argv[2], "utf-8"));
|
||||
const src = fs.readFileSync("web/app.js", "utf-8");
|
||||
const store = {};
|
||||
const mk = (id) => ({ id, set textContent(v){ store[id]=v; }, get textContent(){return store[id]||"";},
|
||||
set className(v){}, get className(){return "";}, classList:{add(){},remove(){},toggle(){}},
|
||||
style:{}, value:"", title:"", addEventListener(){}, blur(){}, focus(){} });
|
||||
const cache = {};
|
||||
global.document = { getElementById: (id) => (cache[id] ||= mk(id)),
|
||||
querySelectorAll: () => [], querySelector: () => null, addEventListener(){},
|
||||
get activeElement(){return null;}, createElement: () => mk("_") };
|
||||
const m = src.match(/function renderM15\([\s\S]*?\n\}/);
|
||||
const b = src.match(/function renderBrk\([\s\S]*?\n\}/);
|
||||
const helfer = 'const _F=document.createElement("span");' +
|
||||
'const $=(id)=>document.getElementById(id)||_F; const $streng=(id)=>document.getElementById(id);';
|
||||
const fn = new Function("snapshot", helfer + "\n" + m[0] + "\n" + (b?b[0]:"function renderBrk(){}") +
|
||||
"\nrenderM15(snapshot.m15_setup, snapshot); renderBrk(snapshot);");
|
||||
try { fn(snap); console.log(" ✅ renderM15 + renderBrk laufen OHNE Exception durch"); }
|
||||
catch (e) { console.log(" ❌ EXCEPTION: " + e.message); process.exit(1); }
|
||||
for (const k of ["m15-rsi","m15-m5","m15-motor","brk-pos","brk-state"])
|
||||
console.log(" " + k.padEnd(12) + " = " + (store[k] || "(leer)"));
|
||||
+8
-3
@@ -252,7 +252,12 @@ function renderBrk(d) {
|
||||
}
|
||||
}
|
||||
|
||||
function renderM15(s) {
|
||||
function renderM15(s, snap) {
|
||||
// ⚠⚠ `snap` = der VOLLE Snapshot. `s` ist nur `m15_setup` — wer hier auf
|
||||
// `d.` zugreift, erzeugt einen ReferenceError, der den GESAMTEN Render
|
||||
// abbricht: alles ab der Fehlerstelle bleibt auf "—" stehen, und die
|
||||
// danach gerufenen Renderer (u. a. `renderBrk`) laufen gar nicht mehr.
|
||||
// Genau das ist am 19.08. passiert (RSI-Zeile griff auf `d.market`).
|
||||
const st = $("m15-status");
|
||||
if (!s) { st.className = "m15-status"; st.textContent = "— keine Daten"; return; }
|
||||
const f = (v, d = 2) => (v == null ? "—" : (+v).toFixed(d));
|
||||
@@ -410,7 +415,7 @@ function renderM15(s) {
|
||||
// Ueberdehnungs-Anzeige, die aus demselben Grund "Ueberdehnung" heisst und
|
||||
// nicht "Bounce".
|
||||
const rsiEl = $("m15-rsi");
|
||||
const rv = (d.market || {}).rsi_m15;
|
||||
const rv = ((snap || {}).market || {}).rsi_m15;
|
||||
if (rv == null) {
|
||||
rsiEl.textContent = "RSI · —";
|
||||
} else {
|
||||
@@ -1079,7 +1084,7 @@ function render(d) {
|
||||
}
|
||||
|
||||
// ── Gesamtempfehlung (aggregiert) ───────
|
||||
renderM15(d.m15_setup);
|
||||
renderM15(d.m15_setup, d);
|
||||
renderBrk(d);
|
||||
renderKontext(d);
|
||||
renderCircuitBreaker(d.circuit_breaker);
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@
|
||||
⚠ LOKAL eingebunden, kein CDN: die PWA laeuft ueber WireGuard
|
||||
und muss offline funktionieren. -->
|
||||
<link rel="stylesheet" href="pico.min.css?v=1">
|
||||
<link rel="stylesheet" href="style.css?v=187">
|
||||
<link rel="stylesheet" href="style.css?v=188">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Modul-Menü (ganz oben) -->
|
||||
@@ -392,6 +392,6 @@
|
||||
</div>
|
||||
<div id="toast" class="toast hidden"></div>
|
||||
|
||||
<script src="app.js?v=187"></script>
|
||||
<script src="app.js?v=188"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user