Files
tickte-system/scripts/workers-harness/scripted-fetch.js
T
ClaudeandClaude Sonnet 5.5 2ed2201b22 Workers P3: Prüfstand um Freigabe, Interessenten-Panel, Anhalten-Rückfrage und Handy erweitert
Echte Seite WorkersPage im Prüfstand (Austausch-Module für Anmeldung, Mitarbeiterliste und Sitzungs-JWT), Skript-API mit Pult, Aktionen und Interessent samt Schaltern für 409, 400, Ausfall und Leerzustand, vier neue Szenarien (Freigabe, Interessent, Anhalten, Handy), jedes Szenario läuft für sich, und der Szenario Desktop bestätigt jetzt die Rückfrage vor dem Anhalten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 10:20:29 +00:00

51 lines
3.2 KiB
JavaScript

// Fetch-Weiche des Prüfstands: nimmt die Anfragen des echten API-Clients (createWorkersApi, URLs unter /api/workers) entgegen und
// beantwortet sie mit der Skript-API. Damit läuft im Prüfstand dieselbe Kette wie im Betrieb (API-Client, Feed, Board), und die
// Ausfälle lassen sich schalten: control.fault = null (gesund) | 'down' (503 ohne JSON wie eine Fehlerseite des Proxys) |
// 'session' (401) | 'hang' (die Antwort kommt nie, wie auf einer toten Verbindung). Kein Netz, kein Appwrite.
// Seit P3 auch Pult (GET /pult, POST /pult/:id/<Aktion>) und Interessent (GET /prospect/:id): Fehler der Skript-API (status + deutscher
// Satz) kommen als { error } mit diesem Status an, wie vom Dienst.
// control.calls sammelt jede Anfrage ({ method, path, jwt }), damit der Prüfstand zählen kann.
const reply = (status, body) => ({
ok: status >= 200 && status < 300,
status,
json: async () => {
if (body === undefined) throw new SyntaxError('kein JSON')
return body
},
})
export function createScriptedFetch(api, control) {
return async function scriptedFetch(url, init = {}) {
const method = init.method || 'GET'
const parsed = new URL(url, 'http://harness.invalid')
const path = parsed.pathname.replace(/^\/api\/workers/, '')
control.calls.push({ method, path, jwt: init.headers ? init.headers['X-Appwrite-JWT'] : undefined })
if (control.fault === 'hang') return new Promise(() => {})
if (control.fault === 'down') return reply(503, undefined)
if (control.fault === 'session') return reply(401, {})
try {
const body = init.body === undefined ? undefined : JSON.parse(init.body)
if (method === 'GET' && path === '/state') return reply(200, await api.state())
if (method === 'GET' && path === '/events') {
const limit = parsed.searchParams.get('limit')
return reply(200, await api.events(parsed.searchParams.get('after'), limit === null ? undefined : Number(limit)))
}
const trace = /^\/worker\/([^/]+)\/trace$/.exec(path)
if (method === 'GET' && trace) return reply(200, await api.trace(decodeURIComponent(trace[1])))
if (method === 'POST' && path === '/pause') return reply(200, await api.pause(body.paused))
if (method === 'GET' && path === '/settings') return reply(200, await api.settings())
if (method === 'PUT' && path === '/settings') return reply(200, await api.saveSettings(body))
// Freigabe-Pult und Interessent (P3); ohne ?status= gilt wie im Dienst offen,in_arbeit
if (method === 'GET' && path === '/pult') return reply(200, await api.pult(parsed.searchParams.get('status') ?? undefined))
const action = /^\/pult\/([^/]+)\/([^/]+)$/.exec(path)
if (method === 'POST' && action) return reply(200, await api.pultAction(decodeURIComponent(action[1]), action[2], body))
const prospect = /^\/prospect\/([^/]+)$/.exec(path)
if (method === 'GET' && prospect) return reply(200, await api.prospect(decodeURIComponent(prospect[1])))
return reply(404, { error: 'Unbekannter Pfad im Prüfstand.' })
} catch (err) {
return reply(err && err.status ? err.status : 500, { error: err && err.message ? err.message : 'Fehler im Prüfstand.' })
}
}
}