Files
tickte-system/scripts/workers-harness/build.mjs
T
ClaudeandClaude Sonnet 5.5 2652108e4c Hustler-Stufe: Prüfstand baut mit VITE_HUSTLER_STUFE=6, Notiz zum Hochsetzen beim Livegang von P4 und P6
build.mjs setzt die Stufe über define ein (Standard 6, andere Ziffer 1 bis 9 aus der Umgebung, Ungültiges bricht ab), damit die Szenarien K (Pult P4) und L (Keller) weiter laufen;
ein Test baut den Prüfstand mit Standard, 3 und ungültigen Werten. docs/superpowers/hustler-stufe.md erklärt Stufen, Sperren und die Schritte beim Hochsetzen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 10:36:52 +00:00

76 lines
3.6 KiB
JavaScript

// Baut den Prüfstand: node scripts/workers-harness/build.mjs <outDir>
// entry.jsx -> harness.js + harness.css (esbuild, Entwicklungsmodus, damit StrictMode wie in der Entwicklung zweimal einhängt), dazu index.html.
// outDir muss ein neuer oder leerer Ordner unter dem Temp-Ordner (TMPDIR, sonst /tmp) oder unter .superpowers/ im Repo sein.
// Die Schrift /fonts/* bleibt außen vor: der Server von shot.cjs liefert sie aus public/fonts.
// Drei Module der App hängen an Appwrite (Anmeldung, Mitarbeiterliste, Sitzungs-JWT) und werden nur im Prüfstand ausgetauscht, damit die
// echte Seite WorkersPage (Bildschirme Hochhaus, Pult und Keller samt Brief, Akte, ProspectPanel und Einstellungen) ohne Netz läuft: AuthContext -> stub-auth.js,
// useEmployees -> stub-employees.js, workersClient -> stub-client.js. Am Quelltext der App ändert das nichts.
// Stufen-Sperre (src/lib/hustlerStufe.js): die App zeigt P4-Aktionen im Pult erst ab Stufe 4 und den Keller (Bot-Leads) erst ab Stufe 6. Die Szenarien des Prüfstands
// (K pult-p4, L keller, die Keller-Etage im Haus) brauchen beides, deshalb baut dieses Skript standardmäßig mit VITE_HUSTLER_STUFE=6. Eine andere Stufe 1..9 kommt aus der
// Umgebung (VITE_HUSTLER_STUFE=3 node scripts/workers-harness/build.mjs <outDir> baut den Stand der Produktion); ein ungültiger Wert bricht ab.
import esbuild from 'esbuild'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const here = path.dirname(fileURLToPath(import.meta.url))
const repo = path.resolve(here, '../..')
const arg = process.argv[2]
if (!arg) {
console.error('usage: node scripts/workers-harness/build.mjs <outDir>')
process.exit(2)
}
const out = path.resolve(arg)
const tmp = path.resolve(process.env.TMPDIR || os.tmpdir())
const allowed = [tmp, path.join(repo, '.superpowers')]
if (!allowed.some((base) => out.startsWith(base + path.sep))) {
console.error(`refusing: outDir must be below ${allowed.join(' or ')}`)
process.exit(2)
}
if (fs.existsSync(out) && fs.readdirSync(out).length > 0) {
console.error('refusing: outDir must be new or empty')
process.exit(2)
}
fs.mkdirSync(out, { recursive: true })
const stufe = process.env.VITE_HUSTLER_STUFE ?? '6'
if (!/^[1-9]$/.test(stufe)) {
console.error(`refusing: VITE_HUSTLER_STUFE must be a digit 1..9 (got ${JSON.stringify(stufe)})`)
process.exit(2)
}
const STUBS = [
{ filter: /(^|\/)context\/AuthContext(\.jsx?)?$/, file: 'stub-auth.js' },
{ filter: /(^|\/)hooks\/useEmployees(\.jsx?)?$/, file: 'stub-employees.js' },
{ filter: /(^|\/)lib\/workersClient(\.jsx?)?$/, file: 'stub-client.js' },
]
const stubPlugin = {
name: 'harness-stubs',
setup(build) {
for (const stub of STUBS) {
build.onResolve({ filter: stub.filter }, () => ({ path: path.join(here, stub.file) }))
}
},
}
const result = await esbuild.build({
entryPoints: [path.join(here, 'entry.jsx')],
outfile: path.join(out, 'harness.js'),
bundle: true,
format: 'iife',
platform: 'browser',
jsx: 'automatic',
external: ['/fonts/*'],
// Bilder der Pixelwelt (url() in src/styles/hustler/*.css) landen als data:-URI im harness.css
loader: { '.png': 'dataurl' },
plugins: [stubPlugin],
define: { 'process.env.NODE_ENV': '"development"', 'import.meta.env.VITE_HUSTLER_STUFE': JSON.stringify(stufe) },
logLevel: 'warning',
metafile: true,
})
fs.copyFileSync(path.join(here, 'index.html'), path.join(out, 'index.html'))
const sizes = Object.entries(result.metafile.outputs).map(([file, info]) => `${path.basename(file)} ${info.bytes}`)
console.log(`built ${sizes.join(', ')} (Stufe ${stufe}) -> ${out}`)