Prüfstand: entry.jsx zeigt nur noch die echte Seite WorkersPage (BrowserRouter, Adresse mit ?tab= lesbar); shot.cjs neu mit den Szenarien A–M (Hochhaus, Regie, Handy, weniger Bewegung, Notbremse, Ausfall, Detail, Etagen, Pause, Pult P3, Pult P4, Keller, Handy Pult/Keller), harte Prüfungen und Bildern mit Szenario-Vorsilbe; Befunde an der App stehen getrennt von den Verstößen. Skript-API: Gründe der Bot-Leads wörtlich wie im Dienst. Kopfzeile am Handy: zwei Reihen (Geld + Pause/Zahnrad, dann die fünf Kennzahlen), schmaler Panel-Rand, 40-px-Knöpfe, Querformat unter 500 px Höhe in einer Reihe; hustlerKopf.test um die Zusicherungen dazu ergänzt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
3.5 KiB
React
65 lines
3.5 KiB
React
// Einstiegspunkt des Prüfstands: die echte Seite WorkersPage der Pixelwelt (Hochhaus, Pult, Keller) mit der Skript-API, ohne Anmeldung und ohne Appwrite.
|
|
// Drumherum steht dieselbe Hülle wie in der App (Menüleiste links, Seitenrand), damit die Welt genauso groß wird wie im echten Betrieb.
|
|
// Der Router ist ein BrowserRouter: ?tab=… und ?bot=… stehen in der echten Adresse des Browsers, ein Wechsel des Bildschirms (Etage Freigabe, „◂ Hochhaus“)
|
|
// ändert sie wie in der App; die Adresse lässt sich also lesen und prüfen. Die Parameter des Prüfstands selbst werden nur beim Laden gelesen.
|
|
// AuthContext, useEmployees und workersClient sind durch stub-*.js ersetzt (build.mjs); die Seite bekommt ihre API über harness-bridge.js.
|
|
// Parameter (alle optional):
|
|
// ?tab=hochhaus|freigabe|botleads öffnet den Bildschirm gleich (Deep-Link wie aus dem Ereignisstrom); mit &bot=<Id> den Einzelfall im Keller
|
|
// ?halted=1 startet mit gesetzter Bounce-Notbremse (Banner „Versand gestoppt“)
|
|
// ?fault=none|down|session|hang die Seite läuft über den echten API-Client (createWorkersApi) und die Fetch-Weiche scripted-fetch.js;
|
|
// window.__wk.control.fault lässt sich zur Laufzeit auf null | 'down' | 'session' | 'hang' setzen (Ausfall).
|
|
// Ohne den Parameter bekommt die Seite die Skript-API direkt.
|
|
// ?p4=1 nimmt für das Pult den Datensatz der Gespräche und der Werkstatt (als Mensch antworten, Vorschau freigeben und
|
|
// bauen, Antwort des Kunden einfügen) statt der P3-Einträge
|
|
// ?botleads=leer die Bot-Lead-Liste ist leer (Leerzustand ohne Filter)
|
|
// window.__wk = { api, control }: die Skript-API (Schalter faults, pultEmpty, pultCalls, prospectCalls, pauseCalls, botleadCalls …) und die Steuerung der
|
|
// Fetch-Weiche (fault, calls, jwts) für shot.cjs.
|
|
import { StrictMode } from 'react'
|
|
import { createRoot } from 'react-dom/client'
|
|
import { BrowserRouter } from 'react-router-dom'
|
|
import '../../src/styles/global.css'
|
|
import WorkersPage from '../../src/pages/WorkersPage'
|
|
import { createWorkersApi } from '../../src/lib/workersApi.js'
|
|
import { createScriptedApi } from './scripted-api.js'
|
|
import { createScriptedFetch } from './scripted-fetch.js'
|
|
import { holder } from './harness-bridge.js'
|
|
|
|
const params = new URLSearchParams(window.location.search)
|
|
const scripted = createScriptedApi({
|
|
now: () => performance.now(),
|
|
base: Date.now(),
|
|
halted: params.get('halted') === '1',
|
|
pult: params.get('p4') === '1' ? 'p4' : true,
|
|
botleadsEmpty: params.get('botleads') === 'leer',
|
|
})
|
|
const fault = params.get('fault')
|
|
const control = { fault: fault && fault !== 'none' ? fault : null, calls: [], jwts: [] }
|
|
// Zeitgrenze im Prüfstand kurz (1,5 s statt 20 s), damit der Ausfall „Antwort kommt nie“ in Sekunden sichtbar wird
|
|
const api = fault === null
|
|
? scripted
|
|
: createWorkersApi({
|
|
getJwt: async (options) => {
|
|
control.jwts.push(Boolean(options && options.fresh))
|
|
return 'harness-jwt'
|
|
},
|
|
fetchImpl: createScriptedFetch(scripted, control),
|
|
timeoutMs: 1500,
|
|
})
|
|
window.__wk = { api: scripted, control }
|
|
holder.api = api
|
|
|
|
createRoot(document.getElementById('root')).render(
|
|
<StrictMode>
|
|
<BrowserRouter>
|
|
<div className="shell">
|
|
<div className="sidebar" aria-hidden="true" />
|
|
<div className="main">
|
|
<main id="inhalt">
|
|
<WorkersPage />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</BrowserRouter>
|
|
</StrictMode>,
|
|
)
|