Fassung 2026-09-30 · Wortgleiche Kopie der Allgemeinen Geschäftsbedingungen auf webklar.com/agb
+
+
Kaufvertrag – WEBklar (Modularer Projektvertrag)
+
+
zwischen
+
+
WEBklar (im Folgenden „Anbieter“)
+
+
und
+
+
Kunde laut Angebot (im Folgenden „Kunde“)
+
+
1. Vertragsgegenstand
+
+
(1) Gegenstand dieses Vertrages ist die Erbringung der im Angebot definierten Leistungen.
+
+
(2) Der Vertrag besteht aus diesem Grundvertrag sowie den ausgewählten Leistungsmodulen.
+
+
(3) Maßgeblich ist das jeweils angenommene Angebot von WEBklar.
+
+
2. Leistungsart
+
+
(1) Sämtliche Leistungen von WEBklar stellen Dienst- und Entwicklungsleistungen dar.
+
+
(2) Ein bestimmter wirtschaftlicher, technischer oder rechtlicher Erfolg wird nicht geschuldet.
+
+
(3) WEBklar erbringt keinen laufenden Betrieb, sofern dieser nicht explizit vereinbart wurde.
+
+
3. Leistungsmodul A – Webseite (einmalig)
+
+
(aktiv, wenn im Angebot enthalten)
+
+
(1) WEBklar erstellt eine individuelle Webseite gemäß Angebot.
+
+
(2) Die Umsetzung erfolgt nach den vom Kunden gelieferten Inhalten und Vorgaben.
+
+
(3) Zusätzliche Leistungen wie Domain, Hosting, Wartung oder SEO sind nicht Bestandteil, sofern sie nicht gesondert beauftragt wurden.
+
+
(4) Der Kunde ist nicht berechtigt, Änderungen am Quellcode selbst vorzunehmen.
+
+
(5) Änderungen erfolgen ausschließlich durch WEBklar gegen gesonderte Vergütung.
+
+
4. Leistungsmodul B – Automatisierung / Virtualisierung (einmalig)
+
+
(aktiv, wenn im Angebot enthalten)
+
+
(1) WEBklar entwickelt individuelle Automatisierungen, Apps oder Virtualisierungssysteme.
+
+
(2) Die Leistung stellt eine reine Entwicklungsleistung dar.
+
+
(3) Optional kann eine Beratungsleistung Bestandteil des Projektes sein.
+
+
(4) Ein laufender Betrieb, Monitoring oder Wartung ist nicht geschuldet, außer dies wurde explizit vereinbart.
+
+
(5) Der Kunde entscheidet über Inhalte, Daten und Prozesse und trägt dafür die rechtliche Verantwortung.
+
+
5. Leistungsmodul C – Hosting
+
+
(aktiv, wenn im Angebot enthalten)
+
+
(1) Hosting bietet WEBklar als Hosting-Abo an. Für das Hosting-Abo und das Wartungs-Abo gelten die Vertragsbedingungen für die WEBklar-Abos mit Leistungsbeschreibungen; sie gehen diesen AGB vor.
+
+
(2) Bestehende Hosting-Verträge mit jährlicher Laufzeit behalten die bei ihrem Abschluss vereinbarten Bedingungen. Abweichend davon können Verbraucher solche Verträge nach einer automatischen Verlängerung jederzeit mit einer Frist von einem Monat kündigen.
+
+
(3) WEBklar ist berechtigt, externe Anbieter (z. B. Rechenzentren) einzusetzen.
+
+
6. Quellcode und Eigentum
+
+
6.1 Webseite
+
+
(1) Der Kunde erhält ein einfaches, zeitlich unbegrenztes Nutzungsrecht an der fertigen Webseite.
+
+
(2) Der Quellcode der Webseite wird nur auf ausdrückliche Anfrage und nach Vereinbarung herausgegeben.
+
+
(3) Ohne Vereinbarung verbleibt der Quellcode bei WEBklar und wird archiviert.
+
+
6.2 Apps, Automatisierungen und Backend
+
+
(1) Der Quellcode von Apps, Automatisierungen und Backend-Systemen verbleibt vollständig bei WEBklar.
+
+
(2) Eine Herausgabe erfolgt ausschließlich nach gesonderter schriftlicher Vereinbarung.
+
+
(3) Der Kunde erhält lediglich Zugriff auf die Bedienoberfläche bzw. das Frontend.
+
+
7. Mitwirkungspflichten des Kunden
+
+
(1) Der Kunde stellt alle benötigten Inhalte, Daten und Freigaben rechtzeitig bereit.
+
+
(2) Verzögerungen durch fehlende Mitwirkung gehen nicht zu Lasten von WEBklar.
+
+
(3) WEBklar ist nicht verpflichtet, rechtliche Prüfungen der Inhalte vorzunehmen.
+
+
8. Abnahme
+
+
(1) Nach Fertigstellung wird dem Kunden die Leistung zur Abnahme bereitgestellt.
+
+
(2) Erfolgt innerhalb von 14 Tagen keine Rückmeldung, gilt die Leistung als abgenommen.
+
+
(3) Nach Abnahme sind nur noch kostenpflichtige Änderungen möglich.
+
+
9. Vergütung und Zahlung
+
+
(1) Die Vergütung ergibt sich aus dem Angebot.
+
+
(2) Wird nach Aufwand abgerechnet, erfasst WEBklar die Arbeitszeit je Arbeitsschritt in Schritten von 15 Minuten; angefangene 15 Minuten werden aufgerundet. Wirkt eine weitere Person unterstützend mit, rechnet WEBklar für sie die Hälfte der Arbeitszeit des Arbeitsschritts an, aufgerundet auf volle 15 Minuten; bei mehreren unterstützenden Personen gilt das für jede. Jeder Arbeitsschritt und jede Unterstützung ist im Kundenportal einsehbar.
+
+
(3) Projektleistungen sind nach Vereinbarung fällig.
+
+
(4) Für die Abos gelten die Vertragsbedingungen für die WEBklar-Abos.
+
+
10. Zahlungsverzug
+
+
(1) Bei Zahlungsverzug erfolgen bis zu zwei Mahnungen.
+
+
(2) Danach ist WEBklar berechtigt:
+
+
+
Leistungen zu sperren
+
Verzugszinsen zu berechnen
+
den Vertrag außerordentlich zu kündigen
+
+
+
11. Haftung
+
+
(1) WEBklar haftet unbeschränkt bei Vorsatz und grober Fahrlässigkeit, bei Verletzung von Leben, Körper oder Gesundheit, nach dem Produkthaftungsgesetz und soweit WEBklar eine Garantie übernommen hat.
+
+
(2) Bei leicht fahrlässiger Verletzung einer wesentlichen Vertragspflicht haftet WEBklar nur für den vertragstypischen, vorhersehbaren Schaden. Wesentlich sind Pflichten, deren Erfüllung die ordnungsgemäße Durchführung des Vertrags überhaupt erst ermöglicht und auf deren Einhaltung der Kunde regelmäßig vertrauen darf. Im Übrigen ist die Haftung für leichte Fahrlässigkeit ausgeschlossen.
+
+
(3) Der Kunde bewahrt Kopien der Inhalte und Daten auf, die er WEBklar übergibt oder selbst einpflegt. Für den Verlust solcher Inhalte und Daten haftet WEBklar außer in den Fällen von Absatz 1 nur in Höhe des Aufwands, der für ihre Wiederherstellung nötig gewesen wäre, wenn der Kunde diese Kopien aufbewahrt hätte.
+
+
(4) Diese Regeln gelten auch zugunsten der Mitarbeiter und Beauftragten von WEBklar.
+
+
12. Kündigung
+
+
(1) Laufzeitverträge können zum Ende der jeweiligen Laufzeit gekündigt werden. Laufzeit und Kündigung der Abos richten sich nach den Vertragsbedingungen für die WEBklar-Abos.
+
+
(2) Das Recht zur außerordentlichen Kündigung bleibt unberührt.
+
+
13. Referenzen
+
+
WEBklar darf das Projekt nur nach ausdrücklicher Zustimmung des Kunden als Referenz verwenden.
+
+
14. Schlussbestimmungen
+
+
(1) Es gilt deutsches Recht.
+
+
(2) Gerichtsstand ist der Sitz von WEBklar, soweit zulässig.
+
+
(3) Sollten einzelne Bestimmungen unwirksam sein, bleibt der Vertrag im Übrigen wirksam.
Widerrufsbelehrung und Muster-Widerrufsformular (Projektaufträge)
+
+
Fassung 2026-10-06
+
+
Das Widerrufsrecht gilt nur für Verbraucher. Wir fügen die Belehrung und das Muster-Widerrufsformular jeder Auftragsbestätigung an eine Privatperson bei und zeigen sie hier zusätzlich allen Kunden. Die Belehrung gilt für den Auftrag, den die jeweilige Auftragsbestätigung bestätigt.
+
+
Widerrufsbelehrung
+
+
Widerrufsrecht
+
+
Sie haben das Recht, binnen vierzehn Tagen ohne Angabe von Gründen diesen Vertrag zu widerrufen.
+
+
Die Widerrufsfrist beträgt vierzehn Tage ab dem Tag des Vertragsabschlusses.
+
+
Um Ihr Widerrufsrecht auszuüben, müssen Sie uns (WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, Telefon: 0176 23726355, E-Mail: support@webklar.com) mittels einer eindeutigen Erklärung (z. B. ein mit der Post versandter Brief oder eine E-Mail) über Ihren Entschluss, diesen Vertrag zu widerrufen, informieren. Sie können dafür das beigefügte Muster-Widerrufsformular verwenden, das jedoch nicht vorgeschrieben ist.
+
+
Sie können Ihr Widerrufsrecht auch online unter https://project.webklar.com/widerrufen.html ausüben. Wenn Sie diese Online-Funktion nutzen, übermitteln wir Ihnen auf einem dauerhaften Datenträger (z. B. durch eine E-Mail) unverzüglich eine Eingangsbestätigung mit Informationen zum Inhalt der Widerrufserklärung sowie dem Datum und der Uhrzeit ihres Eingangs.
+
+
Zur Wahrung der Widerrufsfrist reicht es aus, dass Sie die Mitteilung über die Ausübung des Widerrufsrechts vor Ablauf der Widerrufsfrist absenden.
+
+
Folgen des Widerrufs
+
+
Wenn Sie diesen Vertrag widerrufen, haben wir Ihnen alle Zahlungen, die wir von Ihnen erhalten haben, einschließlich der Lieferkosten (mit Ausnahme der zusätzlichen Kosten, die sich daraus ergeben, dass Sie eine andere Art der Lieferung als die von uns angebotene, günstigste Standardlieferung gewählt haben), unverzüglich und spätestens binnen vierzehn Tagen ab dem Tag zurückzuzahlen, an dem die Mitteilung über Ihren Widerruf dieses Vertrags bei uns eingegangen ist. Für diese Rückzahlung verwenden wir dasselbe Zahlungsmittel, das Sie bei der ursprünglichen Transaktion eingesetzt haben, es sei denn, mit Ihnen wurde ausdrücklich etwas anderes vereinbart; in keinem Fall werden Ihnen wegen dieser Rückzahlung Entgelte berechnet.
+
+
Haben Sie verlangt, dass die Dienstleistungen während der Widerrufsfrist beginnen soll, so haben Sie uns einen angemessenen Betrag zu zahlen, der dem Anteil der bis zu dem Zeitpunkt, zu dem Sie uns von der Ausübung des Widerrufsrechts hinsichtlich dieses Vertrags unterrichten, bereits erbrachten Dienstleistungen im Vergleich zum Gesamtumfang der im Vertrag vorgesehenen Dienstleistungen entspricht.
+
+
Muster-Widerrufsformular
+
+
(Wenn Sie den Vertrag widerrufen wollen, dann füllen Sie bitte dieses Formular aus und senden Sie es zurück.)
+
+
– An WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, E-Mail: support@webklar.com:
+
+
– Hiermit widerrufe(n) ich/wir (*) den von mir/uns (*) abgeschlossenen Vertrag über den Kauf der folgenden Waren (*)/die Erbringung der folgenden Dienstleistung (*)
+
+
– Bestellt am (*)/erhalten am (*)
+
+
– Name des/der Verbraucher(s)
+
+
– Anschrift des/der Verbraucher(s)
+
+
– Unterschrift des/der Verbraucher(s) (nur bei Mitteilung auf Papier)
+
+
– Datum
+
+
(*) Unzutreffendes streichen.
+
+
+
diff --git a/scripts/build-legal-html.mjs b/scripts/build-legal-html.mjs
index 7c5c4ed..dcf930e 100755
--- a/scripts/build-legal-html.mjs
+++ b/scripts/build-legal-html.mjs
@@ -7,8 +7,11 @@
// node scripts/build-legal-html.mjs termine --check vergleicht mit den eingecheckten Seiten (Exit 1 bei Abweichung, schreibt nichts)
// node scripts/build-legal-html.mjs shop [--check] dasselbe für Leistungsbeschreibung und AVV des Webshops (die Widerrufsbelehrung der
// Funktionen gehört zum Satz termine und wird von shop nicht angefasst)
+// node scripts/build-legal-html.mjs auftraege [--check]
+// dasselbe für die Widerrufsbelehrung der Projektaufträge (Wortlaut aus server/services/auftraege/texte.js)
+// und die AGB-Kopie (Quelle docs/rechtliches/agb.md)
//
-// Fassung = config.termine.avvVersion (Satz termine) bzw. config.shop.fassung (Satz shop). Die Ausgabe enthält keine Datumsangabe außer der Fassung und hängt nur vom Markdown und
+// Fassung = config.termine.avvVersion (Satz termine), config.shop.fassung (Satz shop) bzw. TEXTE_FASSUNG und AGB_FASSUNG (Satz auftraege). Die Ausgabe enthält keine Datumsangabe außer der Fassung und hängt nur vom Markdown und
// von der Fassung ab (zweimal erzeugen ergibt dieselben Bytes). Unterstützte Teilmenge von Markdown: Überschriften # bis ###
// (# nur als erste Zeile), Absätze, Listen mit "- ", **fett**, `code` und Tabellen (Kopfzeile, Trennzeile |---|---|, Zeilen).
// Jede andere Syntax (Codeblöcke, Zitate, Bilder, Links, rohes HTML, nummerierte Listen, Einrückungen, Trennlinien) bricht laut ab,
@@ -18,6 +21,8 @@ import { basename, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { config } from '../server/config.js'
import { legalPaths } from '../server/services/legalDocs.js'
+import { TEXTE_FASSUNG, WIDERRUFSBELEHRUNG_PROJEKT, WIDERRUFSFORMULAR } from '../server/services/auftraege/texte.js'
+import { AGB_FASSUNG } from '../server/services/auftraege/konstanten.js'
const ROOT = fileURLToPath(new URL('..', import.meta.url))
const FASSUNG_RE = /^\d{4}-\d{2}-\d{2}$/
@@ -309,25 +314,83 @@ export function shopDokumente(fassung = config.shop.fassung) {
return dokumenteDesSatzes('shop', fassung, SHOP_NAMEN)
}
+// ---------------------------------------------------------------------------------------------------------- Projektaufträge
+
+/** Einleitung der Seite zur Widerrufsbelehrung der Projektaufträge (Seitentext, nicht Teil der Belehrung nach dem Muster). */
+export const PROJEKT_WIDERRUF_EINLEITUNG =
+ 'Das Widerrufsrecht gilt nur für Verbraucher. Wir fügen die Belehrung und das Muster-Widerrufsformular jeder Auftragsbestätigung an eine Privatperson bei '
+ + 'und zeigen sie hier zusätzlich allen Kunden. Die Belehrung gilt für den Auftrag, den die jeweilige Auftragsbestätigung bestätigt.'
+
+/**
+ * Markdown der Seite „Widerrufsbelehrung und Muster-Widerrufsformular (Projektaufträge)“ aus server/services/auftraege/texte.js: Überschrift,
+ * Fassung, Einleitung, dann die Abschnitte der Belehrung und das Formular, jede Formularzeile als eigener Absatz.
+ */
+export function projektWiderrufMarkdown(fassung = TEXTE_FASSUNG, belehrung = WIDERRUFSBELEHRUNG_PROJEKT, formular = WIDERRUFSFORMULAR) {
+ const teile = [
+ '# Widerrufsbelehrung und Muster-Widerrufsformular (Projektaufträge)',
+ `**Fassung ${fassung}**`,
+ PROJEKT_WIDERRUF_EINLEITUNG,
+ `## ${belehrung.titel}`,
+ ...belehrung.abschnitte.flatMap((a) => [`### ${a.ueberschrift}`, ...a.absaetze]),
+ `## ${formular.titel}`,
+ formular.einleitung,
+ ...formular.zeilen,
+ ]
+ return `${teile.join('\n\n')}\n`
+}
+
+/**
+ * Die zwei Seiten des Satzes auftraege: die Widerrufsbelehrung der Projektaufträge (Fassung TEXTE_FASSUNG, Wortlaut aus texte.js, ohne Markdown-Datei)
+ * und die AGB-Kopie (Fassung AGB_FASSUNG, Quelle docs/rechtliches/agb.md). Beide Seiten verlinken einander. Die Adressen stehen nicht in legalDocs.js:
+ * die Mails und das PDF der Auftragsbestätigung verlinken die versionierten Dateien (public/rechtliches/-.html|pdf) unmittelbar.
+ */
+export function auftraegeDokumente(texteFassung = TEXTE_FASSUNG, agbFassung = AGB_FASSUNG) {
+ const widerrufAdresse = `/rechtliches/widerrufsbelehrung-projektauftrag-${texteFassung}.html`
+ const agbAdresse = `/rechtliches/agb-${agbFassung}.html`
+ const nav = [
+ { href: '/dashboard.html', text: '← Kundenportal' },
+ { href: '/abo-bedingungen.html', text: 'Abo-Bedingungen' },
+ { href: widerrufAdresse, text: 'Widerrufsbelehrung Projektaufträge' },
+ { href: agbAdresse, text: 'AGB' },
+ { href: '/datenschutz.html', text: 'Datenschutzerklärung' },
+ { href: 'https://webklar.com/impressum', text: 'Impressum' },
+ ]
+ return [
+ {
+ doc: 'widerruf',
+ md: null,
+ markdown: () => projektWiderrufMarkdown(texteFassung),
+ html: `public${widerrufAdresse}`,
+ meta: { fassung: texteFassung, titel: 'Widerrufsbelehrung und Muster-Widerrufsformular (Projektaufträge)', seitenkopf: 'Widerrufsbelehrung Projektaufträge', nav },
+ },
+ {
+ doc: 'agb',
+ md: 'docs/rechtliches/agb.md',
+ html: `public${agbAdresse}`,
+ meta: { fassung: agbFassung, titel: 'Allgemeine Geschäftsbedingungen', seitenkopf: 'AGB', nav },
+ },
+ ]
+}
+
/** Sätze der Kommandozeile: Name => Dokumente. */
-const SAETZE = { termine: termineDokumente, shop: shopDokumente }
+const SAETZE = { termine: termineDokumente, shop: shopDokumente, auftraege: auftraegeDokumente }
// ---------------------------------------------------------------------------------------------------------- Aufruf
/**
- * Kommandozeile: `termine|shop [--check]`. root = Wurzel des Projekts (Tests übergeben ein Verzeichnis mit Kopien).
+ * Kommandozeile: `termine|shop|auftraege [--check]`. root = Wurzel des Projekts (Tests übergeben ein Verzeichnis mit Kopien).
* => Exit-Code: 0 ok, 1 mindestens eine Seite weicht ab (nur --check), 2 falscher Aufruf
*/
export function lauf(argv, { root = ROOT, log = console.log, fehler = console.error } = {}) {
const [satz, ...optionen] = argv
const pruefen = optionen.includes('--check')
if (!Object.hasOwn(SAETZE, satz ?? '') || optionen.some((o) => o !== '--check')) {
- fehler('Aufruf: node scripts/build-legal-html.mjs termine|shop [--check]')
+ fehler('Aufruf: node scripts/build-legal-html.mjs termine|shop [--check]\n node scripts/build-legal-html.mjs auftraege [--check]')
return 2
}
let abweichungen = 0
for (const d of SAETZE[satz]()) {
- const html = render(readFileSync(join(root, d.md), 'utf8'), d.meta)
+ const html = render(d.markdown ? d.markdown() : readFileSync(join(root, d.md), 'utf8'), d.meta)
const ziel = join(root, d.html)
if (pruefen) {
const gleich = existsSync(ziel) && readFileSync(ziel, 'utf8') === html
diff --git a/test/auftraegeRechtstexte.test.js b/test/auftraegeRechtstexte.test.js
index 8de5e87..6921335 100644
--- a/test/auftraegeRechtstexte.test.js
+++ b/test/auftraegeRechtstexte.test.js
@@ -426,3 +426,126 @@ test('agb_text_gleich_website: die Kopie ist wortgleich mit der Seite AGB.tsx de
assert.ok(kopie === website, `Die AGB-Kopie weicht von den AGB der Website ab (${ersterUnterschied(kopie, website)}). Ist die Website neu, braucht die Kopie eine neue Fassung (AGB_FASSUNG, agb.md, Seite, PDF, Hash).`)
assert.equal(sha256(website), AGB_TEXT_SHA256)
})
+
+// ---------------------------------------------------------------------------------------------------------- Seiten der Widerrufsbelehrung und der AGB
+
+// jedes Dokument wird in den Tests neu geholt, damit ein fehlender Generator nur die betroffenen Tests scheitern lässt (nicht das Laden der Datei)
+const dokumente = () => gen.auftraegeDokumente()
+const klartext = (html) =>
+ html
+ .replace(/