Website-Analyse Fassung 6: Hosting- und Wartungs-Abo, Leistungsbeschreibung und AVV (Entwurf)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-16 16:04:58 +00:00
1 parent 9e7db59326
commit f25b7608b4
5 files changed
+652

No files matched your search

+44
View File
@@ -90,3 +90,47 @@ test('Webshop und Buchungskalender v6: Überschriften wie Fassung 5, Nr. 9 neu b
}
assert.ok(lies(`docs/rechtliches/${LB.shop.slug}-v6.md`).includes(LB.shop.nurBetrieb))
})
const BA = {
voraussetzung: 'Die Funktion ist in beiden Abos enthalten. Sie setzt ein laufendes Hosting-Abo oder Wartungs-Abo voraus.',
einrichtung: 'Die Einrichtung der Website-Analyse ist für den Kunden kostenlos. WEBklar rechnet sie weder auf ein Stundenkontingent an noch berechnet WEBklar sie gesondert.',
ende: 'Die Website-Analyse läuft, solange das Abo läuft, das sie enthält. Endet es, schaltet WEBklar sie spätestens am folgenden Tag ab. Wechselt der Kunde vom Wartungs- ins Hosting-Abo, bleibt die Website-Analyse; das Gleiche gilt, wenn er den Wechsel ins Wartungs-Abo widerruft.',
widerruf: 'Das Einschalten der Website-Analyse ist Teil des Abos und kein eigener Vertrag. Für den Widerruf gilt die Widerrufsbelehrung der Abo-Bedingungen.',
}
test('Website-Analyse v6 (Leistungsbeschreibung): in beiden Abos, Einrichtung kostenlos, Ende mit dem Abo, Zielgruppenregel bleibt', () => {
const md = lies('docs/rechtliches/leistungsbeschreibung-website-analyse-v6.md')
assert.match(md.split('\n')[2], /^\*\*Fassung 2026-10-16\*\* · (Entwurf – Prüfung durch Kanzlei offen · )?Zusatzbedingungen zum Hosting-Abo und zum Wartungs-Abo$/)
assert.doesNotMatch(md, /€|per Haken|[a-zäöüß,;:] Sie\b|Im Hosting-Abo ist die Website-Analyse nicht enthalten|Sie ist im Wartungs-Abo ohne Aufpreis|im Kundenportal bestellt/)
assert.ok(md.includes(B.geltung.replaceAll('{N}', 'Kunde')))
for (const t of Object.values(BA)) assert.ok(md.includes(t), t.slice(0, 40))
for (const s of ['Sie ist im Hosting-Abo und im Wartungs-Abo ohne Aufpreis enthalten.', 'Der Kunde hat ein laufendes Hosting-Abo oder Wartungs-Abo.',
'Der Kunde kann das Abo dann innerhalb von 30 Tagen nach der Mitteilung zum Zeitpunkt der Einstellung kündigen',
'Weil für die Website-Analyse kein Aufpreis berechnet wird, ändert ihre Einstellung den Preis des Abos nicht.',
'Richtet sich die Website auch gezielt an Kinder unter 16 Jahren']) assert.ok(md.includes(s), s) // letzter Satz: Zielgruppenregel (Nr. 3 Abs. 4) bleibt
assert.deepEqual(abschnitte(md).map((a) => a.kopf), abschnitte(lies('docs/rechtliches/leistungsbeschreibung-website-analyse.md')).map((a) => a.kopf))
})
LB.analyse = { slug: 'leistungsbeschreibung-website-analyse', partei: 'kunde' } // nur für die Querverweise in Task 10
const AVV = { // [alt, neu] je Datei; der Rest ab "## 1." ist sonst wortgleich mit der Bestandsfassung
analyse: [['spätestens mit dem Ende des Wartungs-Abos; den Messdienst schaltet WEBklar dann spätestens am folgenden Tag ab', 'spätestens mit dem Ende des Abos, das die Website-Analyse enthält (Hosting-Abo oder Wartungs-Abo); endet nur das Wartungs-Abo und läuft ein Hosting-Abo weiter, läuft dieser Vertrag weiter. Den Messdienst schaltet WEBklar bei Vertragsende spätestens am folgenden Tag ab'],
['(Ausschalten oder Ende des Wartungs-Abos)', '(Ausschalten oder Ende des Abos, das sie enthält)'],
['Das Wartungs-Abo bleibt davon unberührt.', 'Das Abo bleibt davon unberührt.']],
}
const KOPF_AVV = ENTWURF ? '**Fassung 2026-10-16** · Entwurf – Prüfung durch Kanzlei offen' : '**Fassung 2026-10-16**'
const AVV_FUNKTION = { termine: 'Terminplaner', shop: 'Webshop', unterkunft: 'Buchungskalender', analyse: 'Website-Analyse' }
const avvVorbemerkung = (funktion, fassung) => `Der Kunde schließt diesen Vertrag, wenn er im Kundenportal die Funktion „${funktion}“ einschaltet und die dort angezeigte Zeile „Es gelten Leistungsbeschreibung und Auftragsverarbeitung (Fassung ${fassung})“ mit dem Klick auf „Einschalten“ bestätigt; diesem Vertrag und der Leistungsbeschreibung „${funktion}“ („Leistungsbeschreibung“) in der angezeigten Fassung stimmt er damit zu. Das Portal speichert den Wortlaut der angezeigten Zeile, die Fassungen, den Zeitpunkt, das Kundenkonto und die angemeldete Person. Anschließend sendet WEBklar dem Kunden eine E-Mail, die beide Texte in dieser Fassung als PDF enthält und auf sie verlinkt.`
function pruefeAvv(key, slug) {
const v5 = lies(`docs/rechtliches/${slug}.md`), v6 = lies(`docs/rechtliches/${slug}-v6.md`)
assert.equal(v6.split('\n')[2], KOPF_AVV)
assert.ok(v6.includes(`(1) ${avvVorbemerkung(AVV_FUNKTION[key], '2026-10-16')}`))
assert.doesNotMatch(v6, /per Haken|Mit der Bestellung weist|Vertrag über den Betrieb der Website|keine Bestellung geworden/)
let erwartet = v5.replace(/^\*\*Fassung \d{4}-\d{2}-\d{2}\*\*.*$/m, KOPF_AVV)
erwartet = erwartet.replace(/^\(1\) Der Kunde schließt diesen Vertrag[^\n]*$/m, `(1) ${avvVorbemerkung(AVV_FUNKTION[key], '2026-10-16')}`)
for (const [alt, neu] of AVV[key]) { assert.ok(erwartet.includes(alt), `Bestand enthält: ${alt.slice(0, 40)}`); erwartet = erwartet.replaceAll(alt, neu) }
assert.equal(v6, erwartet, `${slug}-v6.md = Bestandsfassung mit genau diesen Ersetzungen`)
}
test('AVV Website-Analyse v6', () => { pruefeAvv('analyse', 'avv-website-analyse') })
test('Analyse-Seiten sind genau render(Markdown)', () => {
for (const doc of ['analyse-lb', 'analyse-avv']) {
const d = funktionen6Dokumente().find((x) => x.doc === doc)
assert.equal(lies(d.html), render(lies(d.md), d.meta), d.html)
}
})