diff --git a/docs/rechtliches/avv-terminplaner.md b/docs/rechtliches/avv-terminplaner.md new file mode 100644 index 0000000..de730ae --- /dev/null +++ b/docs/rechtliches/avv-terminplaner.md @@ -0,0 +1,145 @@ +# Auftragsverarbeitungsvertrag Terminplaner (Art. 28 DSGVO) + +**Fassung 2026-10-05** + +zwischen dem Kunden als Verantwortlichem („Kunde“) und der WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, vertreten durch die Gesellschafter Kenso Grimm und Justin Klein, als Auftragsverarbeiter („WEBklar“). + +## Vorbemerkung: Abschluss und Verhältnis zu anderen Verträgen + +(1) Der Kunde schließt diesen Vertrag, wenn er im Kundenportal die Einrichtung des Terminplaners bestellt und dabei per Haken diesem Vertrag und der Leistungsbeschreibung „Terminplaner“ („Leistungsbeschreibung“) in der angezeigten Fassung zustimmt. Das Portal speichert die Fassung, den Zeitpunkt, das Kundenkonto und die angemeldete Person. Anschließend sendet WEBklar dem Kunden eine E-Mail, die beide Texte und die Widerrufsbelehrung in dieser Fassung als PDF enthält und auf sie verlinkt. + +(2) Ein Mitarbeiter von WEBklar darf die Funktion nur einschalten, wenn der Kunde vorher in Textform (etwa im Chat des Kundenportals oder per E-Mail) erklärt hat, dass er diesem Vertrag und der Leistungsbeschreibung in der aktuellen Fassung zustimmt. WEBklar speichert die Fassung, das Datum und den Weg dieser Erklärung, den Zeitpunkt des Einschaltens und den Namen des Mitarbeiters. Der Kunde erhält die E-Mail nach Absatz 1 anschließend. + +(3) Dieser Vertrag ist ein eigener Vertrag für den Terminplaner. Er ergänzt den Auftragsverarbeitungsvertrag in Anlage 1 der Abo-Bedingungen. Für den Terminplaner geht er Anlage 1 vor; im Übrigen gilt Anlage 1 ergänzend. In Datenschutzfragen geht er den Abo-Bedingungen und der Leistungsbeschreibung vor. + +## 1. Gegenstand und Dauer + +(1) WEBklar betreibt für die öffentliche Website des Kunden ein Buchungs-Widget mit einer Verwaltung im Kundenportal („Terminplaner“) und verarbeitet dabei personenbezogene Daten der Gäste und der Beschäftigten des Kunden im Auftrag des Kunden. Den Umfang beschreibt die Leistungsbeschreibung. + +(2) Der Vertrag beginnt mit dem Einschalten der Funktion. Er endet mit dem Abschalten, spätestens mit dem Ende des Wartungs-Abos; den Terminplaner schaltet WEBklar dann spätestens am folgenden Tag ab (Nr. 8 Abs. 1 der Leistungsbeschreibung). Die Pflichten aus diesem Vertrag gelten fort, bis alle Daten nach Nummer 9 gelöscht sind. + +## 2. Art und Zweck der Verarbeitung + +(1) Art: Erheben über das Widget auf der Website des Kunden, Übermitteln an den Server von WEBklar, Speichern, Verwalten und Anzeigen im Kundenportal, Versenden von E-Mails, Bereitstellen eines Kalender-Links und einer CSV-Datei und Löschen. + +(2) Zwecke: Der Kunde soll Termine seiner Gäste verwalten. Dazu nimmt der Terminplaner Buchungen und Terminanfragen entgegen, verhindert Doppelbuchungen, bestätigt, ändert und sagt Termine ab, erinnert Gäste auf deren Wunsch und benachrichtigt den Kunden. WEBklar versendet die E-Mails im Auftrag des Kunden. Außerdem schützt WEBklar den Terminplaner für den Kunden vor Missbrauch (Mengenbegrenzung, Erkennen automatisierter Buchungen). + +(3) WEBklar verwendet die Daten für keine eigenen Zwecke, auch nicht in anonymisierter Form und nicht für Auswertungen über mehrere Kunden. Es findet keine Werbung und keine Zusammenführung mit anderen Daten statt. WEBklar bildet keine Profile einzelner Gäste. Zählungen ohne Personenbezug, die WEBklar für den sicheren Betrieb braucht (etwa die Zahl der gelöschten Buchungen je Tag oder die Länge der Versandwarteschlange), sind keine eigenen Zwecke. + +## 3. Datenarten und Betroffene + +(1) Daten der Gäste: Name und E-Mail-Adresse; auf Einstellung des Kunden außerdem Telefonnummer, eine Nachricht und Zusatzfelder, die der Kunde im Formular festlegt; die gebuchte Leistung, die Person oder der Platz und der Termin; der Status der Buchung mit den Zeitpunkten (Anlegen, Bestätigung, Annahme, Absage, Widerruf); der Nachweis der Zustimmungen als Zeitpunkt und als Hashes (Prüfsummen) der gezeigten Texte; der Wunsch nach einer Erinnerung; der Zustellstatus der E-Mails an den Gast. + +(2) Daten der Beschäftigten des Kunden: Namen oder Bezeichnungen der Personen oder Plätze, deren Arbeitszeiten und Abwesenheiten sowie ein geheimer Kalender-Link je Person oder Platz. + +(3) Besondere Kategorien personenbezogener Daten (Art. 9 DSGVO) werden nicht verarbeitet. Der Terminplaner ist nicht für den Gesundheitsbereich bestimmt; der Kunde fordert von seinen Gästen keine Gesundheitsangaben (Nummer 11 Abs. 4). + +(4) IP-Adresse und Browser-Kennzeichen (User-Agent) erhält der Server von WEBklar technisch bei jedem Abruf des Widgets und jeder Anfrage. Die Mengenbegrenzung (Missbrauchsschutz) verwendet die IP-Adresse nur im Arbeitsspeicher des Servers; ein Neustart leert sie. Mit der Buchung wird keine IP-Adresse und kein Browser-Kennzeichen gespeichert. In den Server-Protokollen stehen sie 14 Tage (Anlage 2 der Abo-Bedingungen). + +(5) Der Terminplaner setzt keine Cookies und speichert nichts im Browser des Gastes. + +(6) Betroffene: Gäste, die über die Website des Kunden Termine buchen oder anfragen, und Beschäftigte des Kunden, die im Terminplaner geführt werden. + +## 4. Weisungen + +(1) WEBklar verarbeitet die Daten nur auf dokumentierte Weisung des Kunden, auch in Bezug auf eine Übermittlung in ein Drittland oder an eine internationale Organisation. Das gilt nicht, wenn das Recht der Europäischen Union oder Deutschlands WEBklar zu einer Verarbeitung verpflichtet. In diesem Fall teilt WEBklar dem Kunden die Pflicht vorher mit, soweit das Gesetz es nicht verbietet. + +(2) Mit der Bestellung weist der Kunde WEBklar an, den Terminplaner nach seinen Einstellungen und der Leistungsbeschreibung zu betreiben. Weitere Weisungen ergeben sich aus den Einstellungen im Kundenportal (Leistungen, Personen oder Plätze, Zeiten, Felder des Formulars, Aufbewahrungsdauer, Erinnerungen, Einschalten und Ausschalten). Sonstige Weisungen erteilt der Kunde in Textform, etwa im Chat des Kundenportals. Weisungen, die über diese Einstellungen hinausgehen, setzt WEBklar nur um, wenn das technisch vorgesehen ist; sonst kann der Kunde den Terminplaner abschalten lassen (Nr. 8 Abs. 6 der Leistungsbeschreibung). + +(3) Hält WEBklar eine Weisung für rechtswidrig, weist es den Kunden unverzüglich darauf hin. WEBklar darf die Ausführung aussetzen, bis der Kunde die Weisung ändert oder die Rechtslage geklärt ist. + +## 5. Vertraulichkeit + +WEBklar setzt nur Personen ein, die zur Vertraulichkeit verpflichtet sind oder einer gesetzlichen Verschwiegenheitspflicht unterliegen. + +## 6. Technische und organisatorische Maßnahmen + +(1) WEBklar trifft die Maßnahmen nach Art. 32 DSGVO, die in der Anlage zu diesem Vertrag beschrieben sind. WEBklar darf sie an den Stand der Technik anpassen, sofern das Schutzniveau nicht sinkt. + +(2) Für den Server gelten ergänzend die Maßnahmen der Anlage 2 der Abo-Bedingungen, soweit die Anlage zu diesem Vertrag nichts anderes regelt. + +## 7. Unterauftragsverarbeiter + +(1) Der Kunde genehmigt den Einsatz der Hetzner Online GmbH, Industriestraße 25, 91710 Gunzenhausen, für den Betrieb des Servers, auf dem der Terminplaner läuft, und für dessen Sicherung (Rechenzentrum Falkenstein, Deutschland) sowie für den Versand der Buchungs-E-Mails über den SMTP-Dienst des Webhostings (Rechenzentrum Nürnberg, Deutschland). Eine Übermittlung in Drittländer findet nicht statt. + +(2) Will WEBklar einen weiteren Unterauftragsverarbeiter hinzuziehen oder einen ersetzen, teilt es das dem Kunden mindestens vier Wochen vorher in Textform mit. Der Kunde kann innerhalb von zwei Wochen nach Zugang der Mitteilung aus wichtigem datenschutzrechtlichem Grund in Textform widersprechen. WEBklar setzt den neuen Unterauftragsverarbeiter nicht vor Ablauf dieser Frist ein. Kündigt ein Unterauftragsverarbeiter von WEBklar eine eigene Änderung mit kürzerer Frist an, informiert WEBklar den Kunden unverzüglich, nachdem die Ankündigung eingegangen ist; der Kunde kann dann unverzüglich widersprechen. Einigen sich die Parteien nicht, kann der Kunde den Terminplaner abschalten lassen und WEBklar ihn für diese Website zu dem Zeitpunkt beenden, zu dem der neue Unterauftragsverarbeiter eingesetzt wird. Die Daten werden dann nach Nummer 9 gelöscht, auf Verlangen des Kunden sofort. + +(3) WEBklar verpflichtet jeden Unterauftragsverarbeiter vertraglich auf die Datenschutzpflichten nach Art. 28 Abs. 4 DSGVO. Bei der Hetzner Online GmbH ist das deren Vertrag zur Auftragsverarbeitung, den WEBklar abgeschlossen hat. Kommt ein Unterauftragsverarbeiter seinen Datenschutzpflichten nicht nach, haftet WEBklar dem Kunden für die Einhaltung dieser Pflichten (Art. 28 Abs. 4 Satz 2 DSGVO). + +(4) Die Zahlung der Einrichtung über Stripe betrifft nur den Vertrag zwischen dem Kunden und WEBklar. Daten von Gästen oder Beschäftigten des Kunden gehen nicht an Stripe. Stripe ist deshalb kein Unterauftragsverarbeiter dieses Vertrags. + +## 8. Unterstützung des Kunden, Betroffenenrechte + +(1) WEBklar leitet Anfragen von Gästen und Beschäftigten, die an WEBklar gerichtet sind, unverzüglich an den Kunden weiter. WEBklar unterstützt ihn mit geeigneten technischen und organisatorischen Maßnahmen bei der Beantwortung. + +(2) Dafür bietet das Kundenportal die Aktion „Gastdaten löschen“ und den Export der Termine als CSV-Datei. Mit „Gastdaten löschen“ leert der Kunde Name, E-Mail-Adresse, Telefonnummer, Nachricht und Zusatzfelder einer Buchung; Status und Zeiten bleiben. Noch nicht versandte E-Mails zu dieser Buchung löscht WEBklar dabei, und die Links des Gastes werden ungültig. Eine noch nicht bestätigte Buchung verfällt von selbst (Nummer 9 Abs. 1). + +(3) Verletzungen des Schutzes personenbezogener Daten meldet WEBklar dem Kunden unverzüglich, möglichst innerhalb von 24 Stunden nach Kenntnis, mit den Informationen, die zu diesem Zeitpunkt vorliegen. + +(4) WEBklar unterstützt den Kunden bei seinen Pflichten aus Art. 32 bis 36 DSGVO. Dazu gehören die Angaben, die er für sein Verzeichnis von Verarbeitungstätigkeiten und für eine etwaige Datenschutz-Folgenabschätzung braucht. + +(5) Die Buchung speichert als Nachweis der Zustimmungen nur den Zeitpunkt und die Hashes der Texte, die der Gast gesehen hat, nicht die Texte selbst. Damit sich der Wortlaut nachweisen lässt, bewahrt WEBklar jede Fassung der Gästetexte (Hinweis am Formular, Texte der Haken, Datenschutz-Absatz und Widerrufsbelehrung für Gäste) mit dem Zeitraum ihrer Verwendung auf, bis drei Jahre nach dem Ende des Terminplaners. WEBklar stellt sie dem Kunden auf Verlangen zur Verfügung. + +(6) Die Gäste informiert der Kunde (Art. 13 DSGVO; Nummer 11 Abs. 2). + +## 9. Löschung und Rückgabe + +(1) Nicht bestätigte Buchungen löscht WEBklar 48 Stunden nach Ablauf der Bestätigungsfrist von 30 Minuten. + +(2) Abgesagte und abgelehnte Termine löscht WEBklar 30 Tage nach der Absage oder Ablehnung. + +(3) Bestätigte und erledigte Termine löscht WEBklar nach der Aufbewahrungsdauer, gerechnet ab dem Ende des Termins. Der Kunde stellt sie im Kundenportal ein; die Vorgabe sind 90 Tage, einstellbar sind 14 bis 365 Tage. + +(4) In der Versandwarteschlange für E-Mails leert WEBklar die Empfängeradresse und den Inhalt einer E-Mail nach dem Versand und löscht den Eintrag 7 Tage nach dem Versand. E-Mails, die nicht zugestellt werden können, löscht WEBklar mit Empfängeradresse und Inhalt 48 Stunden nach dem endgültigen Fehlschlag. + +(5) Der Löschlauf läuft täglich; gelöscht wird frühestens nach Ablauf der jeweiligen Frist. Ist an einem Tag mehr zu löschen, als ein Lauf schafft, folgt der Rest im nächsten Lauf. + +(6) Ist der Terminplaner abgeschaltet oder das Wartungs-Abo beendet, löscht WEBklar alle Termindaten und die Einstellungen 30 Tage danach. Bis dahin kann der Kunde die Termine im Kundenportal als CSV-Datei exportieren. Beginnt innerhalb dieser Frist wieder ein Wartungs-Abo, schaltet WEBklar den Terminplaner mit den vorhandenen Daten und Einstellungen wieder ein (Nr. 8 Abs. 4 der Leistungsbeschreibung). Auf Weisung des Kunden löscht WEBklar die Daten früher. + +(7) Entwürfe aus dem Fragebogen, aus denen keine Bestellung geworden ist, löscht WEBklar 90 Tage nach der letzten Änderung. + +(8) Die Daten sind in der täglichen Vollsicherung des Servers enthalten (§ 3 Abs. 5 der Abo-Bedingungen). Gelöschte Daten bleiben dort bis zu sieben Tage erhalten und werden dann überschrieben. Wird eine Sicherung zurückgespielt, holt der tägliche Löschlauf die fälligen Löschungen nach; Löschungen auf Weisung des Kunden wiederholt WEBklar. + +(9) Gesetzliche Aufbewahrungspflichten bleiben unberührt. + +## 10. Nachweise und Kontrollen + +WEBklar stellt dem Kunden alle Informationen zur Verfügung, die zum Nachweis der Pflichten aus Art. 28 DSGVO nötig sind, und ermöglicht Überprüfungen einschließlich Inspektionen durch den Kunden oder einen von ihm beauftragten, zur Verschwiegenheit verpflichteten Prüfer. Sie finden nach Anmeldung mit angemessener Frist (in der Regel 14 Tage) zu den Servicezeiten statt, ohne den Betrieb unzumutbar zu stören. Für das Rechenzentrum genügen in der Regel die Nachweise des Betreibers (Zertifizierung der Hetzner Online GmbH nach ISO/IEC 27001). Für mehr als eine Vor-Ort-Kontrolle pro Jahr kann WEBklar eine angemessene Vergütung verlangen. + +## 11. Pflichten des Kunden + +(1) Der Kunde ist Verantwortlicher für die Verarbeitung der Daten seiner Gäste und seiner Beschäftigten im Terminplaner. + +(2) Der Kunde informiert seine Gäste nach Art. 13 DSGVO. Dazu nimmt er den Datenschutz-Absatz für die Online-Terminbuchung in seine Datenschutzerklärung auf (Nr. 4 Abs. 9 der Leistungsbeschreibung) und lässt den Datenschutz-Hinweis am Buchungsformular unverändert. + +(3) Der Kunde informiert seine Beschäftigten darüber, dass ihre Namen oder Bezeichnungen, ihre Arbeitszeiten und Abwesenheiten im Terminplaner stehen und dass es einen geheimen Kalender-Link gibt (Nr. 4 Abs. 7 der Leistungsbeschreibung). + +(4) Der Kunde setzt den Terminplaner nicht im Gesundheitsbereich ein und fordert von seinen Gästen keine Angaben zu ihrer Gesundheit, auch nicht über Zusatzfelder oder das Nachrichtenfeld (Nr. 4 Abs. 3 der Leistungsbeschreibung). + +(5) Der Kunde verändert den Haken für die Erinnerung und die Texte der übrigen Haken nicht (Nr. 4 Abs. 6 der Leistungsbeschreibung). Erinnerungen versendet der Terminplaner nur, wenn der Gast den Haken gesetzt hat. + +## 12. Haftung, Änderungen, Schlussbestimmungen + +(1) Gegenüber betroffenen Personen gilt Art. 82 DSGVO. Für die Haftung zwischen Kunde und WEBklar gilt § 13 der Abo-Bedingungen. + +(2) Eine neue Fassung dieses Vertrags oder der Leistungsbeschreibung, auch wegen geänderter Datenerhebung, teilt WEBklar dem Kunden mindestens sechs Wochen vor ihrem Wirksamwerden in Textform mit. Sie wird wirksam, wenn der Kunde ihr im Kundenportal oder in Textform zustimmt. Stimmt er nicht zu, gilt die bisherige Fassung weiter. + +(3) Ist die neue Fassung nötig, weil ein Gesetz, eine Gerichtsentscheidung oder eine Vorgabe einer Aufsichtsbehörde den Betrieb in der bisherigen Form nicht mehr zulässt, und stimmt der Kunde ihr nicht zu, darf WEBklar den Terminplaner für seine Website nach Nr. 9 Abs. 2 der Leistungsbeschreibung beenden oder nach Nr. 9 Abs. 3 der Leistungsbeschreibung aussetzen. Das Wartungs-Abo bleibt davon unberührt. + +(4) Im Übrigen gilt § 16 der Abo-Bedingungen. + +## Anlage: Technische und organisatorische Maßnahmen des Terminplaners (Art. 32 DSGVO) + +| Bereich | Maßnahmen | +|---|---| +| Übertragung | Das Widget, die Seiten der Gäste und das Kundenportal werden nur über TLS (HTTPS) übertragen. Der Einbau-Code verweist auf eine Adresse mit https://. | +| Speicher im Browser | Es werden keine Cookies gesetzt, und der Terminplaner speichert nichts im Browser des Gastes (kein lokaler Speicher, kein Sitzungsspeicher). Das Widget sendet seine Anfragen ohne Cookies, liest weder den Referrer noch die Zeitzone des Browsers und ruft nur die Schnittstelle des Terminplaners auf. | +| Zugriffskontrolle | Das Kundenportal ist nur nach Anmeldung erreichbar; jeder Kunde sieht nur die Daten seiner eigenen Projekte. Die öffentliche Schnittstelle des Widgets liefert nur für einen eingeschalteten Terminplaner Daten und ist über den Website-Schlüssel (Site-Key) adressiert; Buchungen nimmt sie nur von Seiten des Kunden und des Portals an. Der Kalender-Link enthält ein geheimes Token, das mit einem Vergleich in konstanter Zeit geprüft wird. | +| Missbrauchsschutz | Ein verstecktes Feld (Honeypot), eine Mindestzeit bis zum Absenden des Formulars mit signiertem Formular-Token und eine Mindestantwortzeit schützen vor automatisierten Buchungen. Grenzen je IP-Adresse, je Website und je E-Mail-Adresse sowie das Mailbudget je Stunde (insgesamt und je Funktion) gelten nur im Arbeitsspeicher; ein Neustart leert sie. | +| Datenminimierung | Pflicht sind immer nur Name und E-Mail-Adresse; ob Telefonnummer, Nachricht und Zusatzfelder abgefragt werden, legt der Kunde fest. Mit der Buchung werden keine IP-Adresse und kein Browser-Kennzeichen gespeichert. Der Nachweis der Zustimmungen besteht aus dem Zeitpunkt und Hashes der gezeigten Texte, nicht aus den Texten. Nach dem Versand einer E-Mail werden Empfängeradresse und Inhalt in der Warteschlange geleert. | +| Trennung | Alle Buchungen, Belegungen und Warteschlangeneinträge tragen die Kennung der Funktion (eines Terminplaners je Website-Projekt); Abfragen erfolgen nur je Funktion. Die Einstellungen liegen je Funktion in einem eigenen Dokument. | +| Löschung | Täglicher Löschlauf für Buchungen, Belegungen, Warteschlange und Entwürfe nach den Fristen der Nummer 9; Termindaten und Einstellungen abgeschalteter Funktionen 30 Tage nach dem Abschalten. Vor jeder Löschung wird der Zustand frisch gelesen; bei einem Lesefehler wird nichts gelöscht. | +| Protokolle | Die Programmprotokolle des Terminplaners und der Tagesbericht enthalten nur Zählungen und Buchungsnummern, keine Namen, E-Mail-Adressen oder Nachrichten von Gästen. Server-Protokolle des Webservers werden nach 14 Tagen gelöscht (Anlage 2 der Abo-Bedingungen). | +| Datensicherung | Tägliche Vollsicherung des Servers durch Hetzner; verfügbar sind die letzten sieben Tagessicherungen (§ 3 Abs. 5 der Abo-Bedingungen). | +| Rechenzentrum | Hetzner Online GmbH, Rechenzentren Falkenstein und Nürnberg (Deutschland). Hetzner ist nach ISO/IEC 27001 zertifiziert; der Geltungsbereich umfasst die Hosting-Dienstleistungen und die Rechenzentren. | +| Organisation | Verpflichtung aller Beteiligten auf Vertraulichkeit, Ablauf für Datenschutzverletzungen (Nummer 8 Abs. 3), Archiv der Fassungen der Gästetexte (Nummer 8 Abs. 5), Überprüfung der Maßnahmen mindestens einmal im Jahr. | diff --git a/test/termineVertragsunterlagen.test.js b/test/termineVertragsunterlagen.test.js index 1205108..11ca07a 100644 --- a/test/termineVertragsunterlagen.test.js +++ b/test/termineVertragsunterlagen.test.js @@ -1,9 +1,38 @@ -import { test } from 'node:test' +import { test, after, mock } from 'node:test' import assert from 'node:assert/strict' import { existsSync, readFileSync } from 'node:fs' -import { config } from '../server/config.js' -import { featureConfig } from '../server/services/featureRegistry.js' -import { LOESCHFRIST_TAGE } from '../server/services/termine/frist.js' +import { startAppwriteMock } from './support/appwriteMock.js' +import { mailSink } from './support/mailSink.js' +import { schemaKeys } from './support/schema.js' +import { useTestEnv } from './support/testEnv.js' +import { TERMINE_COLLECTIONS, TERMINE_DATETIMES } from '../server/services/termine/schema.js' + +// Nachbau von Appwrite fuer den Test avv_keine_ip_in_buchung (eine echte Buchung ueber halte); config erst danach importieren +const aw = await startAppwriteMock({ + schema: { + portalFeatures: schemaKeys('portalFeatures'), + termineConfig: schemaKeys('termineConfig'), + termineBookings: schemaKeys('termineBookings'), + termineClaims: schemaKeys('termineClaims'), + termineOutbox: schemaKeys('termineOutbox'), + }, + datetimes: TERMINE_DATETIMES, + defaultLimit: 25, +}) +after(() => aw.close()) +useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1' }) + +const { config } = await import('../server/config.js') +const { featureConfig } = await import('../server/services/featureRegistry.js') +const { LOESCHFRIST_TAGE } = await import('../server/services/termine/frist.js') +const { ENTWURF_TAGE } = await import('../server/services/termine/entwuerfe.js') +const { normalisiereEinstellung } = await import('../server/services/termine/einstellungen.js') +const { datenschutzAbsatz } = await import('../server/services/termine/rechtstexte.js') +const { setMailTransportForTests } = await import('../server/services/mailer.js') +const { resetOutboxForTests, warteAufVersand } = await import('../server/services/termine/outbox.js') +const { speichereEinstellung, resetKontextForTests } = await import('../server/services/termine/kontext.js') +const { halte } = await import('../server/services/termine/ablauf.js') +after(() => setMailTransportForTests(null)) // Vertragsunterlagen des Terminplaners als Markdown: Leistungsbeschreibung (Task F4), AVV (Task F5). // Die Markdown-Dateien sind die Quelle der ausgelieferten Seiten (scripts/build-legal-html.mjs, Task F6). @@ -236,3 +265,472 @@ test('lb_inhalt: Rangfolge, Gästetexte, Gesundheitsbereich, Datenschutz-Absatz, const nr10 = norm(abschnitt(LB, 10).text) assert.ok(nr10.includes('Mit dem Widerruf endet der Terminplaner.')) }) + +// ============================================================================================ AVV Terminplaner (Task F5) + +const AVV_PFAD = 'docs/rechtliches/avv-terminplaner.md' +const AVV_MD = lies(AVV_PFAD) +const AVV = lese(AVV_MD) +const ABO = lies('public/abo-bedingungen.html') +const JOBS = lies('server/services/termine/jobs.js') +const OUTBOX = lies('server/services/termine/outbox.js') + +const avvNr = (n) => norm(abschnitt(AVV, n).text) +const absatzTexte = (a) => a.text.split(/^\(\d+\) /m).slice(1).map(norm) + +test('avv_aufbau: Titel, Kopf mit Fassung, Parteien, Vorbemerkung, Nr. 1 bis 12 und Anlage', () => { + assert.deepEqual(AVV.h1, ['# Auftragsverarbeitungsvertrag Terminplaner (Art. 28 DSGVO)']) + assert.equal(AVV_MD.split('\n')[0], '# Auftragsverarbeitungsvertrag Terminplaner (Art. 28 DSGVO)') + assert.equal(AVV.kopf, `**Fassung ${V}**`) + assert.equal( + AVV_MD.split('\n')[4], + 'zwischen dem Kunden als Verantwortlichem („Kunde“) und der WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, vertreten durch die Gesellschafter Kenso Grimm und Justin Klein, als Auftragsverarbeiter („WEBklar“).', + ) + assert.deepEqual(AVV.abschnitte.map((a) => a.titel), [ + 'Vorbemerkung: Abschluss und Verhältnis zu anderen Verträgen', + '1. Gegenstand und Dauer', + '2. Art und Zweck der Verarbeitung', + '3. Datenarten und Betroffene', + '4. Weisungen', + '5. Vertraulichkeit', + '6. Technische und organisatorische Maßnahmen', + '7. Unterauftragsverarbeiter', + '8. Unterstützung des Kunden, Betroffenenrechte', + '9. Löschung und Rückgabe', + '10. Nachweise und Kontrollen', + '11. Pflichten des Kunden', + '12. Haftung, Änderungen, Schlussbestimmungen', + 'Anlage: Technische und organisatorische Maßnahmen des Terminplaners (Art. 32 DSGVO)', + ]) + // Absätze sind lückenlos nummeriert; Nr. 5 und Nr. 10 bestehen aus einem Absatz ohne Nummer, die Anlage ist eine Tabelle + for (const a of AVV.abschnitte) { + if (['5', '10'].includes(a.nummer) || a.titel.startsWith('Anlage:')) { + assert.deepEqual(a.absaetze, [], `${a.titel}: kein nummerierter Absatz`) + } else { + assert.ok(a.absaetze.length >= 1, `${a.titel}: keine Absätze`) + assert.deepEqual(a.absaetze, a.absaetze.map((_, i) => i + 1), `${a.titel}: Absätze nicht lückenlos`) + } + } + // Vorbemerkung hat drei Absätze (Abschluss, Mitarbeiter, Verhältnis zu Anlage 1) + assert.deepEqual(AVV.abschnitte[0].absaetze, [1, 2, 3]) +}) + +test('avv_sauber: keine Platzhalter, Entwurfsmarken, Kommentare oder Kanzlei-Marker', () => { + assert.doesNotMatch(AVV_MD, /ENTWURF|Entwurf|Prüfpunkt|TODO|\{\{|\}\}|