// Test-Hilfen für die Hustler-Regie: die 19 Worker-Kennungen, ein Dienst-Zustand (Übersicht §6.2) und Ereignisse. // IDS kommt aus der gemeinsamen Roster-Fixture (nicht aus dem Code unter Test). import { readFileSync } from 'node:fs' const roster = JSON.parse(readFileSync(new URL('../../fixtures/workers-roster.json', import.meta.url), 'utf8')) // Die 19 workerIds in Rollenreihenfolge export const IDS = Object.freeze(roster.roles.map((r) => r.workerId)) // Wie im Dienst (P1-E9) können nur die acht Such-Worker nicht angeschlossen sein const SEARCH_IDS = new Set(['rita', 'kim', 'pia', 'finn', 'ali', 'hanna', 'sven', 'lea']) const KPIS = Object.freeze({ newAbosMonth: 3, mrrNewEur: 60, dealsMonth: 3, openThreads: 7, pultOpen: 2, botLeads: 112, apiTodayUsd: 5.1, apiMonthUsd: 50, dailyBudgetUsd: 6, monthlyBudgetUsd: 150, }) /** * Zustand wie GET /api/workers/state mit 19 Workern. Standard: alle arbeiten und sind angeschlossen. * connected: false ist nur für die Such-Worker erlaubt (sonst Fehler: der Dienst meldet alle anderen als angeschlossen). */ export function makeState({ statuses = {}, connected = {}, kpis = {}, paused = false, sendingHalted = false, sendingHaltedReason = '', lastEventTs } = {}) { for (const [id, value] of Object.entries(connected)) { if (value === false && !SEARCH_IDS.has(id)) throw new Error(`makeState: ${id} ist kein Such-Worker und kann nicht getrennt sein`) } return { paused, sendingHalted, sendingHaltedReason, lastEventTs: lastEventTs ?? null, workers: IDS.map((workerId) => ({ workerId, status: statuses[workerId] ?? 'arbeitet', task: '', counters: {}, connected: connected[workerId] ?? true, })), kpis: { ...KPIS, ...kpis }, } } // Ereignis mit eindeutiger id; ts zählt je Aufruf um eine Sekunde hoch (aufsteigend wie die Dienst-API) const T0 = Date.parse('2026-10-17T20:00:00.000Z') let counter = 0 export function ev(kind, workerId, extra = {}) { counter += 1 return { id: `ev-${counter}`, ts: new Date(T0 + counter * 1000).toISOString(), workerId, kind, text: 'Text', ...extra } }