Spec und Plan 2: Entscheidungen aus der Rechtsrunde (Wechsel erst mit Zahlung, Speicher teilweise kündigen, Löschfristen, AGB)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e456c3de69
commit
91d9360dd2
2 files changed
+139
-5
No files matched your search
@@ -58,8 +58,8 @@
|
||||
|
||||
**Namen im Code**
|
||||
|
||||
- Mailvorlagen: neu sind K12 (Wechsel), K13 (Zusatzspeicher), T12 (Wechsel, intern) und T13 (Speicher-Aufgabe, intern). K11 ist schon vergeben.
|
||||
- `contractEvents.type` ist `abschluss`, `wechsel`, `speicher`, `kuendigung` oder `widerruf`. `status` ist `offen`, `erledigt` oder `widerrufen`.
|
||||
- Mailvorlagen: neu sind K12 (Wechsel), K13 (Zusatzspeicher), T12 (Wechsel, intern) und T13 (Speicher-Aufgabe, intern). K11 ist schon vergeben. Nach der Rechtsrunde kommen K14 (Wechsel nicht zustande gekommen) und T14 (Löschfristen, intern) dazu.
|
||||
- `contractEvents.type` ist `abschluss`, `wechsel`, `speicher`, `kuendigung` oder `widerruf`. `status` ist `offen`, `erledigt`, `widerrufen` oder `gescheitert` (Wechsel ohne Zahlung, nach der Rechtsrunde).
|
||||
- Stripe-Metadaten am Abo: `webklarCustomerId`, `email`, `productKey`, `termStartAt`, `termsVersion`, `termsAcceptedAt`, `earlyStartConsentAt`, `consentIp`, `consentUserAgent`, `switchedFrom`, `switchedAt`.
|
||||
- Testrabatte: `WEBKLAR-TEST-050` (Wartung, amount_off 4950, besteht schon) und `WEBKLAR-TEST-050-HOSTING` (Hosting, amount_off 1450).
|
||||
- lookup_keys werden in Stripe nie übertragen (`transfer_lookup_key`). Ein neuer Preis bekommt einen neuen lookup_key im Katalog, denn Zuordnung und Stundenregel hängen am lookup_key (Plan 1).
|
||||
@@ -360,6 +360,8 @@ Expected: PASS, Build ohne Fehler
|
||||
|
||||
> ⛔ **Gate Rechtsrunde:** Den Nutzer die Texte aus Task 1–4 prüfen lassen: `abo-bedingungen.html`, das PDF, `datenschutz.html`, die Übernahmegutschrift, den Leitfaden, die Website-Seiten und die AGB. Änderungswünsche fließen in diese Tasks zurück. Task 20 startet erst nach der Freigabe.
|
||||
|
||||
> ✅ **Rechtsrunde abgeschlossen (28.09.2026):** Der Nutzer hat alle 19 Vorschläge des Übersichtsblatts freigegeben („alle Vorschläge ok“). Die Folgen stehen als Hinweis „Rechtsrunde“ in Task 8, 9, 10, 12 und 20, im neuen Task 21 (Löschfristen) und in Spec Abschnitt 14.
|
||||
|
||||
---
|
||||
|
||||
## Block B – Server
|
||||
@@ -599,6 +601,10 @@ test('Widerrufsfristen aus den Ereignissen', async () => {
|
||||
|
||||
### Task 8: Zusatzspeicher
|
||||
|
||||
> **Rechtsrunde (28.09.2026):**
|
||||
> - Ein Minus speichert im Ereignis `speicher` keine Zustimmungsdaten (kein `consent`, also keine IP-Adresse und keine Browserkennung). Die Datenschutzerklärung verspricht Nachweisdaten nur für Bestellungen (Abschluss, Wechsel, Plus). Test: Das Ereignis eines Minus hat kein `consentIp`.
|
||||
> - `changeStorage` bekommt als vierten Parameter `options = {}` mit `viaCancellation`. Mit `viaCancellation: true` sind Reduzierungen auch bei gekündigtem Abo erlaubt (Kündigungsformular, Task 10), Erhöhungen nie. Test: gekündigtes Abo mit `viaCancellation` und weniger Paketen gibt keine 409; mit mehr Paketen gibt es 409.
|
||||
|
||||
**Files:**
|
||||
- Create: `server/services/mailStorage.js`
|
||||
- Modify: `server/routes/abo.js` (`POST /storage/preview`, `POST /storage`, Webhook `invoice.paid` ruft `recordPaidStorage`)
|
||||
@@ -692,6 +698,35 @@ test('invoice.paid: bezahlte Menge aus regulärer Speicher-Zeile', async () => {
|
||||
|
||||
### Task 9: Wechsel vom Hosting- ins Wartungs-Abo
|
||||
|
||||
> **Rechtsrunde (28.09.2026), Entscheidung 2: Der Wechsel wird erst mit der Zahlung wirksam.** Das geht vor die Beschreibung unten.
|
||||
> - **Zahlart ermitteln:** Standard-Zahlungsmethode des Abos, sonst die des Kunden (`payment_method.type`).
|
||||
> - **Karte** (`card`, ebenso `link`): Der Aufruf bleibt wie unten, nur mit `payment_behavior: 'pending_if_incomplete'`. Stripe übernimmt Preis, Anker, Metadaten und Rabatte erst, wenn die Wechselrechnung bezahlt ist. `metadata` und `discounts` sind in ausstehenden Aktualisierungen erlaubt (docs.stripe.com/billing/subscriptions/pending-updates-reference, geprüft am 28.09.2026). Eine ausstehende Aktualisierung verfällt nach spätestens 23 Stunden.
|
||||
> - **SEPA-Lastschrift** (`sepa_debit`): Stripe erlaubt dafür keine ausstehenden Aktualisierungen. Der Aufruf bleibt deshalb mit `allow_incomplete`, und der Wechsel gilt sofort. Scheitert die Lastschrift, machen wir ihn von Hand rückgängig (siehe Webhooks).
|
||||
> - **Ergebnis:**
|
||||
> - Hat das Abo danach ein `pending_update` (Karte, Zahlung nicht sofort erfolgreich, etwa wegen 3-D Secure), ist das Ereignis `wechsel` `offen`. `paymentUrl` ist die `hosted_invoice_url`, und Metadaten und Spiegel ändern sich noch nicht.
|
||||
> - Ohne `pending_update` und mit bezahlter Rechnung ist das Ereignis `erledigt`.
|
||||
> - Bei SEPA bleibt es `offen`, bis `invoice.paid` kommt.
|
||||
> - Ein zweiter Wechsel, während einer auf die Zahlung wartet, gibt 409 („Ein Wechsel wartet noch auf die Zahlung“).
|
||||
> - **Mails:**
|
||||
> - K12 geht sofort nach dem Klick raus, als Vertragsbestätigung mit PDF.
|
||||
> - Ist der Wechsel noch nicht wirksam, enthält K12 den Block `zahlung_offen`: „Der Wechsel wird wirksam, sobald die Zahlung bestätigt ist. Andernfalls läuft Ihr Hosting-Abo mit Preis und Mindestlaufzeit wie bisher weiter.“
|
||||
> - T12 geht erst raus, wenn der Wechsel wirksam ist.
|
||||
> - **Webhooks** (dort, wo die bestehenden Stripe-Ereignisse verarbeitet werden):
|
||||
> - `customer.subscription.pending_update_applied`: Abo spiegeln, Ereignis `wechsel` wird `erledigt`, T12 geht raus.
|
||||
> - `customer.subscription.pending_update_expired`: Ereignis `wechsel` wird `gescheitert`, K14 geht an den Kunden, T12 mit Block `gescheitert`.
|
||||
> - `invoice.payment_failed` für eine Wechselrechnung mit SEPA (Abo mit `switchedAt` in den letzten 30 Tagen, `billing_reason` `subscription_update`): T12 mit Block `lastschrift_gescheitert` und diesen Handgriffen:
|
||||
> - Preis ohne anteilige Verrechnung zurück auf Hosting
|
||||
> - Wechselrechnung stornieren
|
||||
> - Ereignis auf `gescheitert` setzen
|
||||
> - K14 senden
|
||||
> - Der Abbuchungstag bleibt der Wechseltag.
|
||||
> - **Tests (ergänzen):**
|
||||
> - Karte → `pending_if_incomplete`, SEPA → `allow_incomplete`.
|
||||
> - Antwort mit `pending_update` → Ereignis `offen` und `paymentUrl`.
|
||||
> - Webhook `pending_update_expired` → `gescheitert` und K14. Webhook `pending_update_applied` → `erledigt` und T12.
|
||||
> - Wechsel bei ausstehendem Wechsel → 409.
|
||||
> - **Livegang:** Die neuen Webhook-Ereignisse am Stripe-Endpunkt freischalten (Task 20).
|
||||
|
||||
**Files:**
|
||||
- Create: `server/services/planSwitch.js`
|
||||
- Modify: `server/routes/abo.js` (`POST /switch/preview`, `POST /switch`)
|
||||
@@ -765,6 +800,19 @@ test('Route: ohne earlyStart 400', async () => {
|
||||
|
||||
### Task 10: Öffentliche Kündigung und öffentlicher Widerruf mit Auswahl
|
||||
|
||||
> **Rechtsrunde (28.09.2026), Entscheidung 5: Zusatzspeicher auch teilweise kündigen.**
|
||||
> - Bei der Auswahl „Nur den E-Mail-Zusatzspeicher“ fragt `kuendigen.html` zusätzlich die Zahl der Pakete ab, die gekündigt werden sollen: Feld `packages`, ganze Zahl von 1 bis 10, leer heißt alle gebuchten. `validDeclaration` übernimmt das Feld.
|
||||
> - Mehr Pakete als gebucht heißt alle. Die Reduzierung wirkt zum Ende des Abrechnungsmonats, wie ein Minus und ohne Zustimmungsdaten.
|
||||
> - Sie geht auch, wenn das Abo schon gekündigt ist (`viaCancellation`, Task 8).
|
||||
> - Das Ereignis `kuendigung` bekommt `details: { packages, fromUnits, toUnits }`.
|
||||
> - Die Reduzierung erscheint wie jedes Minus als Speicher-Aufgabe im Admin (Task 13).
|
||||
> - K03 nennt die Zahl der Pakete (Block `zusatzspeicher` mit `{{pakete}}`), T08 ebenso.
|
||||
> - Tests (zusätzlich zu den Tests unten):
|
||||
> - 2 von 3 Paketen ergibt Menge 1.
|
||||
> - Ohne `packages` ergibt Menge 0.
|
||||
> - Gekündigtes Abo: die Menge wird trotzdem reduziert.
|
||||
> - `packages: 0` oder `11` ergibt 400.
|
||||
|
||||
**Files:**
|
||||
- Modify: `server/routes/abo.js` (`validDeclaration`, `/public/cancel`, `/public/withdraw`), `public/kuendigen.html`, `public/widerrufen.html`, `public/legal-form.js`
|
||||
- Test: `test/publicForms.test.js`
|
||||
@@ -773,7 +821,7 @@ test('Route: ohne earlyStart 400', async () => {
|
||||
- Consumes: `changeStorage` (Task 8), `listContractEvents` und `openWithdrawals` (Task 5), Mails K03, K04, T08, T09 (Task 12)
|
||||
- Produces:
|
||||
- **`validDeclaration(body)`:** hat zusätzlich `contract` (`'abo'` oder `'zusatzspeicher'`, Standard `'abo'`) und `order` (`'abschluss'`, `'wechsel'` oder `'zusatzspeicher'`, Standard `'abschluss'`).
|
||||
- **Kündigung „zusatzspeicher“:** Mit gebuchtem Speicher ruft die Route `changeStorage(customerId, 0, null)` auf. Die Kündigung wirkt zum Periodenende, dazu kommt das Ereignis `kuendigung`. Ohne gebuchten Speicher entsteht keine Änderung, die Eingangsbestätigung sagt „wir prüfen“.
|
||||
- **Kündigung „zusatzspeicher“:** Mit gebuchtem Speicher ruft die Route `changeStorage(customerId, restUnits, null, { viaCancellation: true })` auf (`restUnits` = gebuchte Pakete minus `packages`, mindestens 0; siehe Hinweis Rechtsrunde). Die Kündigung wirkt zum Periodenende, dazu kommt das Ereignis `kuendigung`. Ohne gebuchten Speicher entsteht keine Änderung, die Eingangsbestätigung sagt „wir prüfen“.
|
||||
- **Widerruf:** Liegt eine offene Frist des gewählten Typs vor, entsteht das Ereignis `widerruf` mit `details: { order, eventId }`, und das Bezugsereignis bekommt den Status `widerrufen`.
|
||||
- `abschluss`: wie heute `cancelAtPeriodEnd`.
|
||||
- `wechsel` und `zusatzspeicher`: T09 nennt die Handgriffe (Preis zurück bzw. Menge zurück, Erstattung).
|
||||
@@ -866,6 +914,18 @@ test('Offenes Angebot nur fürs passende Produkt; alte Angebote gelten als Wartu
|
||||
|
||||
### Task 12: Mails
|
||||
|
||||
> **Rechtsrunde (28.09.2026):**
|
||||
> - **Weitere Vorlagen:** T05, T06 und T08 bekommen `{{produkt}}` statt fest „Wartungs-Abo“ (Spec 9, Zeile „T05, T06, T08, T09“).
|
||||
> - **Paragraph zum Vertragsende:**
|
||||
> - K02, K03, T05 und T07 nennen den Paragraphen zum Vertragsende aus der Fassung des Kunden, über den Platzhalter `{{vertragsende_paragraph}}` aus `termsDocFor(subDoc.termsVersion)`: Fassung 3 → „§ 9“, Fassung 4 → „§ 11“. In Fassung 4 ist § 9 der Wechsel.
|
||||
> - Test: Für ein Abo mit Fassung 4 nennt keine dieser Mails „§ 9 der Vertragsbedingungen“.
|
||||
> - **Neu:**
|
||||
> - K14, Betreff „Ihr Wechsel ins WEBklar Wartungs-Abo ist nicht zustande gekommen“, Platzhalter `{{name}}` und `{{grund}}`. Der Text sagt, dass das Hosting-Abo mit Preis und Mindestlaufzeit wie vor dem Wechsel weiterläuft.
|
||||
> - K12-Block `zahlung_offen` und T12-Blöcke `gescheitert` und `lastschrift_gescheitert` (Task 9).
|
||||
> - K03- und T08-Platzhalter `{{pakete}}` im Block `zusatzspeicher` (Task 10).
|
||||
> - T14 „[Datenschutz] Löschfristen fällig“ (Task 21).
|
||||
> - **Schon erledigt:** K09 wurde in Task 3 angepasst („Ihres Abos“, Verrechnung nach einem Wechsel).
|
||||
|
||||
**Files:**
|
||||
- Modify:
|
||||
- `server/mail-templates/K01 Vertragsbestaetigung.html`, `K02 …`, `K03 …`, `K04 …`, `K05 …`, `K06 …`, `T02 Neues Wartungs-Abo.html` (umbenennen in `T02 Neues Abo.html`), `T07 Abo beendet.html`, `T09 Widerruf eingegangen.html`
|
||||
@@ -993,6 +1053,43 @@ test('Ticketsystem-Schnittstelle: Produkt und aktiv', async () => {
|
||||
|
||||
---
|
||||
|
||||
### Task 21: Löschfristen (Rechtsrunde, Entscheidung 11)
|
||||
|
||||
**Files:**
|
||||
- Create: `server/services/retention.js`, `scripts/loeschfristen.mjs`, `server/mail-templates/T14 Loeschfristen.html`
|
||||
- Test: `test/retention.test.js`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes:
|
||||
- Appwrite-Zugriff wie in `contractEvents.js` (Task 5)
|
||||
- `renderMail`, Nachbauten und `schemaKeys()` aus `test/support/`
|
||||
- Collections `subscriptions` (Felder `status`, `endedAt`, `canceledAt`, `currentPeriodEnd`, `customerId`), `contractEvents`, `takeoverCredits`
|
||||
- Produces:
|
||||
- **`findDueDeletions(now = new Date())`:** liefert `{ customers: [{ customerId, lastEndAt, subscriptionIds, eventIds }], takeover: [{ id, reason }] }`.
|
||||
- Ein Kunde ist fällig, wenn alle seine Abos beendet sind und das späteste Ende mehr als drei Jahre zurückliegt („drei Jahre nach dem Ende Ihres letzten Abos“, Datenschutzerklärung Abschnitt 7).
|
||||
- Das Ende ist `endedAt`, sonst `canceledAt`. Fehlt beides bei `status: 'canceled'`, zählt `currentPeriodEnd`.
|
||||
- Anträge auf Übernahmegutschrift sind fällig nach den Fristen in Abschnitt 7 der Datenschutzerklärung. Sie stehen dort im Absatz zur Übernahmegutschrift und werden wörtlich übernommen.
|
||||
- **`applyDeletions(plan)`:** liefert `{ deleted, manual }`.
|
||||
- Löscht die Appwrite-Dokumente in `subscriptions` und `contractEvents` der fälligen Kunden.
|
||||
- Leert bei Stripe die Metadaten `consentIp` und `consentUserAgent` ihrer Abos. Lehnt Stripe die Änderung eines beendeten Abos ab, landet es in `manual` (Hinweis im Bericht).
|
||||
- Löscht fällige Übernahme-Anträge samt hochgeladenen Nachweisen.
|
||||
- Rechnungen bleiben (Aufbewahrungspflicht, Abschnitt 9).
|
||||
- **`scripts/loeschfristen.mjs`:** läuft im Container wie das Setup-Skript.
|
||||
- Ohne Umgebungsvariable ist es ein Probelauf: Bericht auf der Konsole, es wird nichts gelöscht.
|
||||
- `LOESCHFRISTEN=mail` schickt den Bericht als T14 an das Team.
|
||||
- `LOESCHFRISTEN=apply` löscht.
|
||||
|
||||
- [ ] **Step 1: Failing test** – `test/retention.test.js` (Appwrite- und Stripe-Nachbau)
|
||||
- Abo beendet vor drei Jahren und einem Tag → fällig.
|
||||
- Abo beendet vor zwei Jahren → nicht fällig.
|
||||
- Altes beendetes Abo und ein laufendes Abo desselben Kunden → nicht fällig.
|
||||
- `applyDeletions` löscht die Dokumente und schickt an Stripe leere Metadaten (Aufruf im Nachbau geprüft). Eine abgelehnte Stripe-Änderung landet in `manual`.
|
||||
- Ein Probelauf des Skripts ändert nichts.
|
||||
- [ ] **Step 2: Run** `node --test test/retention.test.js`. Erwartet: FAIL.
|
||||
- [ ] **Step 3: Umsetzen:** Dienst, Skript und T14 (Aufbau wie die bestehenden Vorlagen).
|
||||
- [ ] **Step 4: Run** `npm test`. Erwartet: PASS.
|
||||
- [ ] **Step 5: Commit** mit der Nachricht „Löschfristen: Probelauf, Bericht ans Team, Löschen nach drei Jahren“.
|
||||
|
||||
## Block C – Oberfläche im Kundenportal
|
||||
|
||||
Alle Prüfungen laufen gegen den Fixture-Server aus Task 14, Step 1. Die Ansichten auf Desktop (1280×800) und Handy (390×844, `hasTouch`) kommen dabei auch per Pixelvergleich mit main (`build/public`).
|
||||
@@ -1182,6 +1279,13 @@ Alle Prüfungen laufen gegen den Fixture-Server aus Task 14, Step 1. Die Ansicht
|
||||
|
||||
### Task 20: Livegang (mit dem Nutzer)
|
||||
|
||||
> **Rechtsrunde (28.09.2026), zusätzlich beim Livegang:**
|
||||
> 1. Die AGB der Website bekommen „Stand <Freigabedatum>“ (Entscheidung 19).
|
||||
> 2. Mit dem neuen `takeover.conditionsVersion` wird der Schlüssel in `TAKEOVER_CONDITIONS_SHA256` (`test/legalTexts.test.js`) mitgezogen.
|
||||
> 3. Den Auftragsverarbeitungsvertrag von UptimeRobot (uptimerobot.com/dpa) herunterladen und ablegen, denn die Datenschutzerklärung bietet eine Kopie an. Die Angaben zu UptimeRobot noch einmal prüfen.
|
||||
> 4. Am Stripe-Webhook-Endpunkt `customer.subscription.pending_update_applied`, `customer.subscription.pending_update_expired` und `invoice.payment_failed` freischalten (Task 9). Das nur mit Freigabe des Nutzers.
|
||||
> 5. Die jährliche Erinnerung an die Löschfristen einrichten (Task 21). Ein Cron-Eintrag auf dem Server nur mit Freigabe des Nutzers.
|
||||
|
||||
**Files:** `server/config.js` (`abo.termsVersion`), `public/abo-bedingungen.html` (Stand), `public/datenschutz.html` (Stand), PDFs
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
@@ -119,7 +119,7 @@ Ein Paket hat 5 GB und kostet 1,00 € pro Monat. Jeder Kunde kann 0 bis 10 Pake
|
||||
|
||||
**Kündigung**
|
||||
|
||||
- Jederzeit per Minus oder über „Verträge hier kündigen“ mit der Auswahl „Nur den E-Mail-Zusatzspeicher“.
|
||||
- Jederzeit per Minus oder über „Verträge hier kündigen“ mit der Auswahl „Nur den E-Mail-Zusatzspeicher“, ganz oder mit der Zahl der Pakete (Abschnitt 14).
|
||||
- Der Zusatzspeicher endet automatisch mit dem Abo. Bei einem Wechsel ins Wartungs-Abo bleibt er unverändert.
|
||||
|
||||
### 3.5 Wechsel vom Hosting- ins Wartungs-Abo
|
||||
@@ -142,7 +142,8 @@ Ein Paket hat 5 GB und kostet 1,00 € pro Monat. Jeder Kunde kann 0 bis 10 Pake
|
||||
- Es bleibt dasselbe Stripe-Abo, der Preis wechselt von Hosting auf Wartung.
|
||||
- Der Abbuchungstag wird der Wechseltag.
|
||||
- Die ungenutzten Hosting-Tage werden auf der sofort fälligen Rechnung gutgeschrieben.
|
||||
- **Leistung:** Sie beginnt sofort. Die erste Stunde Arbeitszeit wird gutgeschrieben, sobald die Wechsel-Rechnung bezahlt ist, danach monatlich.
|
||||
- **Wirksamkeit:** Der Wechsel wird erst mit der Zahlung wirksam (Abschnitt 14).
|
||||
- **Leistung:** Sie beginnt mit dem wirksamen Wechsel. Die erste Stunde Arbeitszeit wird gutgeschrieben, sobald die Wechsel-Rechnung bezahlt ist, danach monatlich.
|
||||
- **Mindestlaufzeit:** 12 Monate ab dem Wechseltag.
|
||||
- **Widerruf des Wechsels:**
|
||||
- Das Hosting-Abo läuft zu den bisherigen Bedingungen weiter, als hätte es den Wechsel nicht gegeben, einschließlich seiner ursprünglichen Mindestlaufzeit.
|
||||
@@ -495,6 +496,35 @@ Vorbelegt mit meinem Vorschlag, bitte bestätigen oder ändern:
|
||||
|
||||
Geklärt am 27.09.2026: Wir nutzen das Hetzner-Paket M, und die Erreichbarkeit überwacht UptimeRobot.
|
||||
|
||||
## 14. Entscheidungen aus der Rechtsrunde (28.09.2026)
|
||||
|
||||
Der Nutzer hat alle 19 Vorschläge des Übersichtsblatts freigegeben. Folgen für Text und Umsetzung:
|
||||
|
||||
1. **Wechsel erst mit Zahlung wirksam.** Scheitert die Zahlung, läuft das Hosting-Abo mit Preis und Mindestlaufzeit wie vorher weiter. Der Kunde bekommt dann Mail K14.
|
||||
- Bei Karte übernimmt Stripe den Wechsel erst nach der Zahlung (`pending_if_incomplete`). Die ausstehende Aktualisierung verfällt nach spätestens 23 Stunden.
|
||||
- Bei SEPA-Lastschrift geht das nicht, also gilt der Wechsel sofort. Scheitert die Lastschrift, machen wir ihn von Hand rückgängig. Der Abbuchungstag bleibt dabei der Wechseltag.
|
||||
- Vertragsbedingungen § 2 Abs. 5 und § 9. Umsetzung: Task 9 und 12.
|
||||
2. **Zusatzspeicher auch teilweise über den Kündigungsbutton kündigen.** Das Formular fragt die Zahl der Pakete ab. Das geht auch bei gekündigtem Abo.
|
||||
- Vertragsbedingungen § 8 Abs. 7 und 8, § 10 Abs. 5. Umsetzung: Task 8, 10 und 12.
|
||||
3. **Datenschutz: Aufbewahrung „drei Jahre nach dem Ende Ihres letzten Abos“.** Dazu kommt eine Löschroutine mit Probelauf, Bericht ans Team und jährlicher Erinnerung (Task 21).
|
||||
4. **AGB der Website:**
|
||||
- Modul C Nr. 4 (Haftungsausschluss für externe Anbieter) entfällt. Für die Abos gilt § 13 der Vertragsbedingungen.
|
||||
- Alte Hosting-Jahresverträge: Nach einer automatischen Verlängerung können Verbraucher mit einer Frist von einem Monat kündigen.
|
||||
- Die AGB bekommen beim Livegang ein Stand-Datum.
|
||||
5. **Unverändert bestätigt:**
|
||||
- Wertersatz beim Widerruf eines Wechsels
|
||||
- Rückwechsel nur auf Anfrage
|
||||
- Bestandskunden bleiben bei Fassung 3
|
||||
- Formulare im Hosting-Abo nur gesondert
|
||||
- Webmail zugesagt
|
||||
- § 11 Abs. 3
|
||||
- Rechtsgrundlagen UptimeRobot (lit. b und lit. f)
|
||||
- Aufbewahrung von Kündigungs- und Widerrufserklärungen
|
||||
- Kein Verlauf im Portal
|
||||
- Gutschrift wird nach einem Wechsel weiter verrechnet
|
||||
- Gutschrift ab Beginn des ursprünglichen Abos
|
||||
- Leitfaden auf einer Seite
|
||||
|
||||
## Anhang: Dateiliste
|
||||
|
||||
**Kundenportal** (`knso/Webklar-Kundenbereich`)
|
||||
|
||||
Reference in new issue
Block a user