Kundenansicht neu P10: Korrekturen aus der Pruefung (Task 6)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
30adafd779
commit
1312745195
1 file changed
+73
@@ -12,3 +12,76 @@ test('Überschriften in der Reihenfolge der Spec 5.10', () => {
|
||||
test('nennt die Befehle und die Stopps', () => {
|
||||
for (const s of ['kundenart-bestand.mjs --pruefen', '--ausfuehren', 'KUNDENANSICHT_NEU=on', 'KUNDENANSICHT_NEU=off', 'docker compose up -d --no-deps kundenbereich-server', '--erwartet=neu', 'docker-compose.yml', 'Stop: Inhaber-OK nötig', 'kein Rückweg per Schalter']) assert.ok(doc.includes(s), s)
|
||||
})
|
||||
|
||||
// Regeln der Checkliste (Prüfung): Die zwei Tests oben suchen nur Wörter irgendwo im Text. Hier hängen die Zusagen an ihrem Abschnitt.
|
||||
const STOPP = 'Stop: Inhaber-OK nötig'
|
||||
const abschnitt = (d, n) => { const von = d.indexOf(KOEPFE[n - 1]); const bis = n < KOEPFE.length ? d.indexOf(KOEPFE[n]) : d.length; return von < 0 || bis < 0 ? '' : d.slice(von, bis) }
|
||||
const anzahl = (s, t) => s.split(t).length - 1
|
||||
const vor = (s, a, b) => s.indexOf(a) > -1 && s.indexOf(b) > s.indexOf(a)
|
||||
function regelverstoesse(d) {
|
||||
const v = []
|
||||
const a = (n) => abschnitt(d, n)
|
||||
const soll = (ok, was) => { if (!ok) v.push(was) }
|
||||
// Stopps: insgesamt mindestens acht, in den Abschnitten mit Live-Schritten je mindestens einer, in 8 zwei (Offline-Seite, Festschreiben)
|
||||
soll(anzahl(d, STOPP) >= 8, 'weniger als 8 Stopps')
|
||||
for (const [n, min] of [[1, 1], [2, 1], [3, 1], [5, 1], [6, 1], [8, 2]]) soll(anzahl(a(n), STOPP) >= min, `Abschnitt ${n}: Stopp fehlt`)
|
||||
soll(vor(a(5), STOPP, 'sed -i') && vor(a(5), 'cp -n', 'sed -i') && vor(a(5), STOPP, 'docker compose up'), 'Abschnitt 5: Sicherung und Stopp stehen nicht vor dem Schreiben der .env')
|
||||
soll(vor(a(2), STOPP, '--ausfuehren'), 'Abschnitt 2: Stopp steht nicht vor --ausfuehren')
|
||||
// Push nur mit Stopp, auf main, nie erzwungen
|
||||
for (const l of d.split('\n').filter((z) => z.includes('git push'))) soll(l.includes(STOPP) && l.includes('refs/heads/main') && !/--force|\s-f\s/.test(l), 'Push ohne Stopp oder erzwungen')
|
||||
// Kundenart-Skript: Protokoll mit tee, Ausführen mit Bestätigung und pipefail (sonst verschluckt tee den Exit-Code)
|
||||
const art = a(2).split('\n').filter((l) => l.includes('kundenart-bestand.mjs'))
|
||||
soll(art.length === 2 && art.every((l) => l.includes('| tee /root/reports/kundenansicht-neu-2026-10-15/umschalten/')), 'Abschnitt 2: Protokoll mit tee fehlt')
|
||||
soll(art.some((l) => l.includes('--ausfuehren') && l.includes('--bestaetigung="Kundenart unternehmen setzen: <N>"') && l.includes('set -o pipefail')), 'Abschnitt 2: --ausfuehren ohne Bestätigung oder pipefail')
|
||||
// Neustart nur für den Server und nur mit --no-deps; in Abschnitt 5 und im Rückweg
|
||||
const neustarts = d.match(/docker compose up[^`\n]*/g) || []
|
||||
soll(neustarts.length >= 3 && neustarts.every((c) => /^docker compose up -d --no-deps kundenbereich-server(?: |$)/.test(c)), 'Neustart ohne --no-deps oder nicht nur kundenbereich-server')
|
||||
for (const n of [5, 7]) soll(/docker compose up -d --no-deps kundenbereich-server/.test(a(n)), `Abschnitt ${n}: Neustart fehlt`)
|
||||
// Ruhezustand (1) und Rückweg (7) prüfen auf alt, Nachprüfung (6) und Festschreiben (8) auf neu
|
||||
soll(anzahl(d, '--erwartet=alt') >= 2, 'weniger als 2 Prüfungen auf alt')
|
||||
for (const [n, e] of [[1, 'alt'], [7, 'alt'], [6, 'neu'], [8, 'neu']]) soll(a(n).includes(`--erwartet=${e}`), `Abschnitt ${n}: --erwartet=${e} fehlt`)
|
||||
// Rückweg und Schalter
|
||||
for (const s of ['KUNDENANSICHT_NEU=off', 'bleiben gültig', 'Fassung 6']) soll(a(7).includes(s), `Abschnitt 7: ${s} fehlt`)
|
||||
soll(a(5).includes('KUNDENANSICHT_NEU=on') && a(5).includes('docker-compose.yml'), 'Abschnitt 5: Schalter oder Compose fehlt')
|
||||
soll(a(6).includes('Version 6'), 'Abschnitt 6: Version 6 fehlt')
|
||||
soll(a(8).includes('kein Rückweg per Schalter'), 'Abschnitt 8: kein Rückweg per Schalter fehlt')
|
||||
// Beobachtungszeit: Datei in 6, Zeitraum in 6 und 8
|
||||
soll(a(6).includes('/umschalten/beobachtung.txt') && a(6).includes('Beobachtungszeit') && a(8).includes('Beobachtungszeit'), 'Beobachtungszeit fehlt in Abschnitt 6 oder 8')
|
||||
// je Abschnitt höchstens zehn Zeilen, in der du-Form
|
||||
for (let n = 1; n <= KOEPFE.length; n++) soll(a(n).split('\n').slice(1).filter((l) => l.trim()).length <= 10, `Abschnitt ${n}: mehr als 10 Zeilen`)
|
||||
soll(!/\bSie\b|\bIhr/.test(d) && /\bDu hast\b/.test(d), 'nicht in der du-Form')
|
||||
return v
|
||||
}
|
||||
// Jede Änderung unten bricht eine Zusage der Checkliste; die Regeln müssen sie bemerken
|
||||
const imAbschnitt = (n, f) => (d) => { const s = abschnitt(d, n); return d.replace(s, f(s)) }
|
||||
const ERSTE = (t, neu) => (d) => d.replace(t, neu)
|
||||
const ALLE = (t, neu) => (d) => d.replaceAll(t, neu)
|
||||
const BRUCH = {
|
||||
'alle Stopps bis auf einen entfernt': (d) => { let i = 0; return d.replaceAll(STOPP, () => (i++ === 0 ? STOPP : 'Hinweis')) },
|
||||
'Stopp vor dem Schreiben der .env entfernt': imAbschnitt(5, (s) => s.replace(STOPP, 'Hinweis')),
|
||||
'Stopp vor --ausfuehren entfernt': imAbschnitt(2, (s) => s.replace(STOPP, 'Hinweis')),
|
||||
'Stopp vor dem Festschreiben-Push entfernt': imAbschnitt(8, (s) => s.replace(`6. **${STOPP}**`, '6. **Hinweis**')),
|
||||
'Push erzwungen': ERSTE("git push origin 'kn-p10-a", "git push --force origin 'kn-p10-a"),
|
||||
'Sicherung der .env entfernt': ERSTE('cp -n', 'ls'),
|
||||
'Rückweg ohne --erwartet=alt': imAbschnitt(7, (s) => s.replace('--erwartet=alt', '--erwartet=neu')),
|
||||
'keine Prüfung auf alt': ALLE('--erwartet=alt', '--erwartet=neu'),
|
||||
'Rückweg ohne --no-deps': imAbschnitt(7, (s) => s.replace(' --no-deps', '')),
|
||||
'Neustart von preview-portal': ERSTE('up -d --no-deps kundenbereich-server', 'up -d --no-deps preview-portal'),
|
||||
'Schalter nie auf off': ALLE('KUNDENANSICHT_NEU=off', 'KUNDENANSICHT_NEU=aus'),
|
||||
'Verträge unter Fassung 6 nicht mehr gültig': ALLE('bleiben gültig', 'sind hinfällig'),
|
||||
'Beobachtungsdatei entfernt': ALLE('beobachtung.txt', 'notiz.txt'),
|
||||
'Beobachtungszeit entfernt': ALLE('Beobachtungszeit', 'Wartezeit'),
|
||||
'Sie statt du': ALLE('Du hast', 'Sie haben'),
|
||||
'--ausfuehren ohne Bestätigung': ALLE('--bestaetigung', '--ja'),
|
||||
'--ausfuehren ohne pipefail': ALLE('set -o pipefail; ', ''),
|
||||
'Protokolle entfernt': ALLE(' | tee ', ' > '),
|
||||
'Abschnitt 5 zu lang': imAbschnitt(5, (s) => `${s}9. a\n10. b\n11. c\n`),
|
||||
}
|
||||
test('die echte Checkliste hält alle Regeln', () => { assert.deepEqual(regelverstoesse(doc), []) })
|
||||
for (const [name, aendern] of Object.entries(BRUCH)) {
|
||||
test(`Regeln bemerken: ${name}`, () => {
|
||||
const kaputt = aendern(doc)
|
||||
assert.notEqual(kaputt, doc, 'die Änderung greift nicht')
|
||||
assert.ok(regelverstoesse(kaputt).length > 0, 'unbemerkt')
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user