feat(legal): Claims-Korrektur, zentrale Legal-Config & öffentliche Rechtsseiten (v1.7.0)
Teil 1 des Compliance-Updates (nach vollständiger Repo-Analyse): - src/config/legal.ts: zentrale, typisierte Betreiber-/Rechtskonfiguration mit sichtbaren Platzhaltern, ENV-Overrides (LEGAL_*), Build-Warnung bei offenen Pflichtangaben, echte Subprozessorenliste (aus dem Code abgeleitet) - Claims-Korrektur (20 Aussagen): 24/7, 100% Swiss Hosted, DSG/DSGVO-konform, 100% der Spende, Kein Unternehmen, "bleibt kostenlos", "sicher via Stripe", "keine Weitergabe/keine Übermittlung ins Ausland", "verschlüsselt"→"gehasht" — in page.tsx, spenden, impressum, datenschutz (Neuaufbau), settings-tab - Neue Legal-Seiten (druckbar, responsiv, versioniert, als Entwurf gekennzeichnet): /nutzungsbedingungen, /verantwortungsvolle-nutzung, /sicherheit, /unterstuetzen, /organisationen/datenschutzvereinbarung + wiederverwendbare LegalPage-Shell - Datenschutz komplett neu aufgebaut: Subprozessoren-Tabelle (#dienstleister), Auslandbekanntgabe, gehashte Passwörter, Backups/Löschung, Zahlung (Stripe), Karten/Geodienste, Rechte/EDÖB - Footer um alle Pflicht-Rechtslinks erweitert; sitemap.ts ergänzt - docs/legal/website-claims-audit.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
46
docs/legal/website-claims-audit.md
Normal file
46
docs/legal/website-claims-audit.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Website Claims Audit — Lageplan
|
||||||
|
|
||||||
|
Stand: 2026-07-23 · Version 1.0 (sorgfältiger Entwurf, ersetzt keine juristische Prüfung)
|
||||||
|
|
||||||
|
Prüfung aller werblichen / absoluten Aussagen im Repository und deren Korrektur zu sachlichen,
|
||||||
|
nachweisbaren Formulierungen. Fundstellen beziehen sich auf den Stand vor der Korrektur.
|
||||||
|
|
||||||
|
| # | Bisherige Aussage | Fundstelle (vorher) | Risiko / Widerspruch | Neue Formulierung | Geänderte Datei |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| 1 | „100% · Swiss Hosted · Server in der Schweiz" | `src/app/page.tsx:241` | Serverstandort nicht für alle Subprozessoren (Stripe, SMTP, globale Kartendienste) belegt; absolutes 100% | „CH · Swiss Made · In der Schweiz entwickelt" | `src/app/page.tsx` |
|
||||||
|
| 2 | „24/7 · Verfügbar" | `src/app/page.tsx:243` | Verfügbarkeitszusage ohne SLA | „Web · Überall nutzbar · Browser, Tablet, Smartphone" | `src/app/page.tsx` |
|
||||||
|
| 3 | „Die Applikation ist DSG- und DSGVO-konform." (FAQ + JSON-LD) | `src/app/page.tsx:87,458` | Unbelegte pauschale Konformitätszusage | „Die eingesetzten Dienstleister und Speicherorte sind in der Datenschutzerklärung transparent aufgeführt. Lageplan orientiert sich am Schweizer Datenschutzgesetz (DSG)." | `src/app/page.tsx` |
|
||||||
|
| 4 | „Sicher & Schweiz … DSG/DSGVO-konform." (Feature-Karte) | `src/app/page.tsx:361` | Absolute Sicherheits-/Konformitätszusage | „Sicherheit & Datenschutz … Angemessene technische und organisatorische Schutzmassnahmen — Details in der Datenschutzerklärung." | `src/app/page.tsx` |
|
||||||
|
| 5 | „Lückenlose Protokollierung aller Aktionen" | `src/app/page.tsx:360` | „lückenlos" = absolute Zusage | „Protokollierung von Aktionen mit Zeitstempel für bessere Nachvollziehbarkeit." | `src/app/page.tsx` |
|
||||||
|
| 6 | „Nichts. Lageplan ist kostenlos …" (FAQ + JSON-LD) | `src/app/page.tsx:55,442` | Impliziert dauerhafte Kostenlosigkeit | „… grundsätzlich kostenlos … Ein Anspruch darauf, dass alle Funktionen dauerhaft kostenlos bleiben, besteht nicht." | `src/app/page.tsx` |
|
||||||
|
| 7 | „100% deiner Spende fliesst direkt …" | `src/app/page.tsx:588`, `src/app/spenden/page.tsx:252` | Ignoriert Stripe-Gebühren; absolutes 100% | „Beiträge werden nach Abzug allfälliger Zahlungsgebühren für Hosting, Infrastruktur und Weiterentwicklung eingesetzt." | `src/app/page.tsx`, `src/app/spenden/page.tsx` |
|
||||||
|
| 8 | „Kein Unternehmen, keine Investoren …" | `src/app/page.tsx:589`, `src/app/spenden/page.tsx:253` | Betreiberform ist rechtlich noch festzulegen; potenziell irreführend | „Ein Projekt aus der Feuerwehr-Praxis — entwickelt in der Freizeit." | `src/app/page.tsx`, `src/app/spenden/page.tsx` |
|
||||||
|
| 9 | „Lageplan ist und bleibt kostenlos." | `src/app/page.tsx:551`, `src/app/spenden/page.tsx:239` | „bleibt" = dauerhafte Zusage | „Lageplan wird grundsätzlich kostenlos angeboten." | `src/app/page.tsx`, `src/app/spenden/page.tsx` |
|
||||||
|
| 10 | „Zahlung sicher via Stripe" | `src/app/page.tsx:574`, `src/app/spenden/page.tsx:226` | „sicher" = absolute Zusage | „Zahlung über Stripe" | `src/app/page.tsx`, `src/app/spenden/page.tsx` |
|
||||||
|
| 11 | „Server-Hosting in der Schweiz (monatliche Kosten)" | `src/app/spenden/page.tsx:99` | Serverstandort nicht abschliessend belegt | „Server-Hosting und Infrastruktur (monatliche Kosten)" | `src/app/spenden/page.tsx` |
|
||||||
|
| 12 | „Jeder Franken fliesst direkt in Serverkosten …" | `src/app/spenden/page.tsx:244` | Ignoriert Gebühren | „Beiträge helfen, Hosting, Infrastruktur und Weiterentwicklung mitzufinanzieren." | `src/app/spenden/page.tsx` |
|
||||||
|
| 13 | „weder an Dritte verkauft noch weitergegeben" | `src/app/impressum/page.tsx:108` | Absolute „keine Weitergabe"; widerspricht Einsatz von Dienstleistern | „… nicht an Dritte verkauft. Für den technischen Betrieb können sorgfältig ausgewählte … Dienstleister eingesetzt werden. Einzelheiten enthält die Datenschutzerklärung." | `src/app/impressum/page.tsx` |
|
||||||
|
| 14 | „Einsatzdaten … werden verschlüsselt gespeichert" | `src/app/impressum/page.tsx:116` | „verschlüsselt gespeichert" technisch nicht belegt (Ruhedaten) | Zugriffs-/Mandantenkonzept + „Übertragung erfolgt über HTTPS/TLS"; Passwörter „gehasht (bcrypt)" | `src/app/impressum/page.tsx` |
|
||||||
|
| 15 | „Passwort (verschlüsselt gespeichert)" | `src/app/datenschutz/page.tsx:47` | Falsch: Passwörter werden gehasht, nicht verschlüsselt | „Passwort wird mit einem geeigneten Einwegverfahren (bcrypt) gehasht" | `src/app/datenschutz/page.tsx` (Neuaufbau) |
|
||||||
|
| 16 | „Alle Daten … auf Servern in der Schweiz … keine Übermittlung ins Ausland" | `src/app/datenschutz/page.tsx:105-106` | Widerspricht Stripe/SMTP/Kartendiensten; absolute Auslandsaussage | Ziffer 6 „Bekanntgabe ins Ausland": Auslandbearbeitung je nach Dienstleister möglich | `src/app/datenschutz/page.tsx` (Neuaufbau) |
|
||||||
|
| 17 | „Personenbezogene Daten werden nicht an Dritte weitergegeben" | `src/app/datenschutz/page.tsx:91,164` | Absolute „keine Weitergabe" | Dienstleisterliste (Subprozessoren) + „nicht zu Werbezwecken verkauft" | `src/app/datenschutz/page.tsx` (Neuaufbau) |
|
||||||
|
| 18 | „Gemäss DSG und DSGVO haben Sie folgende Rechte" | `src/app/datenschutz/page.tsx:144` | Pauschale DSGVO-Anwendbarkeit unbelegt | „Im Rahmen des anwendbaren Rechts …" + Beschwerde bei EDÖB | `src/app/datenschutz/page.tsx` (Neuaufbau) |
|
||||||
|
| 19 | „Bei der Löschung werden sämtliche Daten unwiderruflich entfernt" | `src/app/datenschutz/page.tsx:128` | Ignoriert Backups | „Produktivdaten werden nach Abschluss des Löschvorgangs entfernt. Daten in Sicherungskopien können bis zum Ablauf des Backup-Zyklus fortbestehen." | `src/app/datenschutz/page.tsx` (Neuaufbau) |
|
||||||
|
| 20 | „Passwörter werden verschlüsselt in der Datenbank gespeichert." | `src/components/admin/settings-tab.tsx:242` | Falsch: gehasht, nicht verschlüsselt | „… mit einem Einwegverfahren (bcrypt) gehasht …" | `src/components/admin/settings-tab.tsx` |
|
||||||
|
|
||||||
|
## Nicht beanstandet (Kontext geprüft)
|
||||||
|
|
||||||
|
- Zahlreiche `100%` in `rapport-pdf.tsx`, `measure-panel.tsx`, `map-view.tsx`, E-Mail-Templates → CSS-Breitenangaben, keine Werbeaussage.
|
||||||
|
- „sicher" in `README.md`, `docs/*`, `jwt-secret.ts`, `modules.ts` → technische Kommentare, nicht öffentlich.
|
||||||
|
- „SSL-Zertifikate" (Substantiv) → keine „zertifiziert"-Behauptung.
|
||||||
|
|
||||||
|
## Nicht gefunden (im gesamten Repo)
|
||||||
|
|
||||||
|
`garantiert`, `fehlerfrei`, `gemeinnützig`, `steuerlich`, `rechtssicher`, `zertifiziert`,
|
||||||
|
„immer verfügbar", „kostenlos für immer" — keine Treffer.
|
||||||
|
|
||||||
|
## Noch offen (Betreiber-Entscheid)
|
||||||
|
|
||||||
|
- Formulierung „In der Schweiz entwickelt": Sobald der Serverstandort für alle Subprozessoren/Backups
|
||||||
|
bestätigt ist, kann ggf. eine präzisere Hosting-Aussage getroffen werden.
|
||||||
|
- „Purepixel / Kingstickers Ziberi" (Impressum-Copyright): rechtsverbindliche Betreiberbezeichnung bestätigen.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lageplan",
|
"name": "lageplan",
|
||||||
"version": "1.6.9",
|
"version": "1.7.0",
|
||||||
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,187 +1,207 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import Link from 'next/link'
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
import { ArrowLeft, Shield, Server, Trash2, Mail } from 'lucide-react'
|
import { legal, isPlaceholder } from '@/config/legal'
|
||||||
|
|
||||||
|
function Val({ value }: { value: string }) {
|
||||||
|
if (isPlaceholder(value)) {
|
||||||
|
return <span className="text-amber-600 dark:text-amber-400 font-medium">{value}</span>
|
||||||
|
}
|
||||||
|
return <span className="text-foreground font-medium">{value}</span>
|
||||||
|
}
|
||||||
|
|
||||||
export default function DatenschutzPage() {
|
export default function DatenschutzPage() {
|
||||||
|
const d = legal.documents.privacy
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 px-4 py-12">
|
<LegalPage
|
||||||
<div className="max-w-3xl mx-auto">
|
title="Datenschutzerklärung"
|
||||||
<Link href="/" className="text-sm text-gray-400 hover:text-gray-300 inline-flex items-center gap-1 mb-8">
|
version={d.version}
|
||||||
<ArrowLeft className="w-3.5 h-3.5" />
|
publishedAt={d.publishedAt}
|
||||||
Zurück zur Startseite
|
intro={`Diese Erklärung informiert transparent darüber, welche Personendaten ${legal.projectName} bearbeitet, zu welchem Zweck und wer daran beteiligt ist. Sie orientiert sich am Schweizer Datenschutzgesetz (DSG).`}
|
||||||
</Link>
|
>
|
||||||
|
<section>
|
||||||
|
<h2>1. Verantwortlicher</h2>
|
||||||
|
<p>
|
||||||
|
Verantwortlich für die Datenbearbeitung ist der Betreiber der Plattform{' '}
|
||||||
|
<Val value={legal.operatorName} /> (<Val value={legal.operatorLegalForm} />),{' '}
|
||||||
|
<Val value={legal.postalAddress} />.
|
||||||
|
</p>
|
||||||
|
<p><strong>Datenschutzkontakt:</strong> <Val value={legal.privacyContactEmail} /></p>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div className="bg-card rounded-xl shadow-2xl p-8 md:p-12 border border-border">
|
<section>
|
||||||
<div className="flex items-center gap-3 mb-6">
|
<h2>2. Welche Daten werden bearbeitet?</h2>
|
||||||
<div className="w-10 h-10 bg-red-600 rounded-full flex items-center justify-center">
|
<ul>
|
||||||
<Shield className="w-5 h-5 text-white" />
|
<li><strong>Registrierungs-/Kontodaten:</strong> Name, E-Mail-Adresse, Organisationsname, Rolle. Das Passwort wird mit einem geeigneten Einwegverfahren (bcrypt) gehasht und nie im Klartext gespeichert.</li>
|
||||||
</div>
|
<li><strong>Einsatz-/Inhaltsdaten:</strong> Lagepläne, Journaleinträge, Zeichnungen, Koordinaten, Symbole, hochgeladene Dateien (Logos, Planbilder, Symbole) sowie zugehörige Projekt- und Organisationsdaten.</li>
|
||||||
<h1 className="text-3xl font-bold text-foreground">Datenschutzerklärung</h1>
|
<li><strong>Protokoll-/Sicherheitsdaten:</strong> technische Zugriffs- und Fehlerprotokolle (z.B. Zeitpunkt, ungefähre technische Angaben) zur Gewährleistung von Betrieb und Sicherheit.</li>
|
||||||
</div>
|
<li><strong>Zustimmungsnachweise:</strong> welche Version der Nutzungsbedingungen/Datenschutzerklärung/Organisationsbestätigung wann akzeptiert wurde.</li>
|
||||||
|
<li><strong>Unterstützungsbeiträge (optional):</strong> bei freiwilligen Beiträgen der Betrag sowie freiwillig angegebener Name/Nachricht (Zahlungsabwicklung siehe Ziffer 9).</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
<p className="text-muted-foreground mb-8">
|
<section>
|
||||||
Gültig ab 1. Januar 2026 — Lageplan.ch, betrieben in der Schweiz.
|
<h2>3. Zwecke</h2>
|
||||||
</p>
|
<ul>
|
||||||
|
<li>Bereitstellung und Betrieb der Applikation, Authentifizierung und Benutzer-/Organisationsverwaltung</li>
|
||||||
|
<li>Echtzeit-Synchronisierung von Einsatzdaten zwischen berechtigten Teammitgliedern</li>
|
||||||
|
<li>Erstellung von Rapporten und PDF-/PNG-Exporten</li>
|
||||||
|
<li>Gewährleistung von Sicherheit, Stabilität und Missbrauchsprävention</li>
|
||||||
|
<li>Technischer Support und Fehlerbehebung</li>
|
||||||
|
<li>Erfüllung rechtlicher Pflichten (soweit anwendbar)</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
{/* 1. Verantwortlicher */}
|
<section>
|
||||||
<section className="mb-8">
|
<h2>4. Grundlagen der Bearbeitung</h2>
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
<p>
|
||||||
<span className="text-red-500 font-mono text-sm">01</span>
|
Die Bearbeitung erfolgt insbesondere zur Erfüllung des Nutzungsverhältnisses (Vertrag), aufgrund
|
||||||
Verantwortlicher
|
berechtigter Interessen am sicheren und stabilen Betrieb sowie – wo erforderlich – gestützt auf Ihre
|
||||||
</h2>
|
Einwilligung. Zwingende gesetzliche Bestimmungen bleiben vorbehalten.
|
||||||
<p className="text-muted-foreground text-sm leading-relaxed">
|
</p>
|
||||||
Verantwortlich für die Datenverarbeitung auf lageplan.ch ist der Betreiber der Plattform.
|
</section>
|
||||||
Bei Fragen zum Datenschutz wenden Sie sich bitte an die im Impressum angegebene Kontaktadresse
|
|
||||||
oder per E-Mail an <span className="text-foreground font-medium">datenschutz@lageplan.ch</span>.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 2. Welche Daten */}
|
<section id="dienstleister" className="scroll-mt-20">
|
||||||
<section className="mb-8">
|
<h2>5. Empfänger und Dienstleister (Subprozessoren)</h2>
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
<p>
|
||||||
<span className="text-red-500 font-mono text-sm">02</span>
|
Für den technischen Betrieb können sorgfältig ausgewählte Dienstleister eingesetzt werden. Nachfolgend
|
||||||
Welche Daten werden erhoben?
|
die tatsächlich eingesetzten bzw. optional konfigurierbaren Dienste. Einige Karten-, Geocoding- und
|
||||||
</h2>
|
Wetterdienste werden direkt aus Ihrem Browser aufgerufen; dabei kann die aufgerufene Kachel-/Standort-
|
||||||
<div className="space-y-3 text-sm text-muted-foreground leading-relaxed">
|
Anfrage (und damit Ihre IP-Adresse) an den jeweiligen Anbieter übermittelt werden.
|
||||||
<p><strong className="text-foreground">Registrierungsdaten:</strong> Name, E-Mail-Adresse, Organisationsname, Passwort (verschlüsselt gespeichert).</p>
|
</p>
|
||||||
<p><strong className="text-foreground">Einsatzdaten:</strong> Lagepläne, Journal-Einträge, Zeichnungen, Koordinaten, Symbole und zugehörige Projektdaten, die Sie in der Applikation erstellen.</p>
|
<div className="overflow-x-auto">
|
||||||
<p><strong className="text-foreground">Technische Daten:</strong> IP-Adresse, Browser-Typ, Zugriffszeitpunkt — ausschliesslich für den Betrieb und die Sicherheit der Plattform.</p>
|
<table className="w-full text-xs border-collapse mt-2">
|
||||||
<p><strong className="text-foreground">Hochgeladene Dateien:</strong> Logos, Planbilder und Symbole, die Sie über die Applikation hochladen.</p>
|
<thead>
|
||||||
</div>
|
<tr className="text-left text-foreground border-b border-border">
|
||||||
</section>
|
<th className="py-1.5 pr-3">Dienst</th>
|
||||||
|
<th className="py-1.5 pr-3">Zweck</th>
|
||||||
{/* 3. Zweck */}
|
<th className="py-1.5 pr-3">Daten</th>
|
||||||
<section className="mb-8">
|
<th className="py-1.5">Region</th>
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
</tr>
|
||||||
<span className="text-red-500 font-mono text-sm">03</span>
|
</thead>
|
||||||
Zweck der Datenverarbeitung
|
<tbody>
|
||||||
</h2>
|
{legal.processors.map(p => (
|
||||||
<div className="space-y-2 text-sm text-muted-foreground leading-relaxed">
|
<tr key={p.name} className="border-b border-border/50 align-top">
|
||||||
<p>Ihre Daten werden ausschliesslich für folgende Zwecke verwendet:</p>
|
<td className="py-1.5 pr-3 text-foreground font-medium">{p.name}{p.optional ? ' *' : ''}</td>
|
||||||
<ul className="list-disc pl-5 space-y-1">
|
<td className="py-1.5 pr-3">{p.purpose}</td>
|
||||||
<li>Bereitstellung und Betrieb der Lageplan-Applikation</li>
|
<td className="py-1.5 pr-3">{p.data}</td>
|
||||||
<li>Authentifizierung und Benutzerverwaltung</li>
|
<td className="py-1.5">{isPlaceholder(p.region) ? <span className="text-amber-600 dark:text-amber-400">{p.region}</span> : p.region}</td>
|
||||||
<li>Echtzeit-Synchronisierung von Einsatzdaten zwischen Teammitgliedern</li>
|
</tr>
|
||||||
<li>Erstellung von Einsatzrapports und PDF-Exporten</li>
|
))}
|
||||||
<li>Technischer Support und Fehlerbehebung</li>
|
</tbody>
|
||||||
</ul>
|
</table>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 4. Betrieb und Wartung */}
|
|
||||||
<section className="mb-8">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<span className="text-red-500 font-mono text-sm">04</span>
|
|
||||||
Betrieb, Wartung und Support
|
|
||||||
</h2>
|
|
||||||
<div className="space-y-3 text-sm text-muted-foreground leading-relaxed">
|
|
||||||
<p>
|
|
||||||
Für den sicheren und zuverlässigen Betrieb der Plattform können autorisierte Mitarbeitende
|
|
||||||
des Betreibers im Rahmen ihrer Aufgaben auf Systemdaten zugreifen. Dies geschieht ausschliesslich zu folgenden Zwecken:
|
|
||||||
</p>
|
|
||||||
<ul className="list-disc pl-5 space-y-1">
|
|
||||||
<li>Sicherstellung der Systemverfügbarkeit und -stabilität</li>
|
|
||||||
<li>Fehlerbehebung und technischer Support auf Anfrage</li>
|
|
||||||
<li>Durchführung von Wartungs- und Aktualisierungsarbeiten</li>
|
|
||||||
<li>Gewährleistung der Datensicherheit und Missbrauchsprävention</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Der Zugriff erfolgt unter Einhaltung strikter Vertraulichkeitspflichten und wird auf das
|
|
||||||
betrieblich notwendige Minimum beschränkt. Personenbezogene Daten werden nicht an Dritte weitergegeben
|
|
||||||
und ausschliesslich im Rahmen der oben genannten Zwecke verarbeitet.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 5. Hosting & Speicherung */}
|
|
||||||
<section className="mb-8">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<Server className="w-4 h-4 text-red-500" />
|
|
||||||
<span><span className="text-red-500 font-mono text-sm mr-2">05</span>Hosting und Speicherung</span>
|
|
||||||
</h2>
|
|
||||||
<div className="space-y-2 text-sm text-muted-foreground leading-relaxed">
|
|
||||||
<p>
|
|
||||||
Alle Daten werden auf Servern in der <strong className="text-foreground">Schweiz</strong> gespeichert.
|
|
||||||
Es findet keine Übermittlung von Daten ins Ausland statt.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Die Daten werden in einer PostgreSQL-Datenbank gespeichert. Dateien (Logos, Bilder) werden in einem
|
|
||||||
S3-kompatiblen Objektspeicher (MinIO) abgelegt. Die Übertragung erfolgt verschlüsselt via HTTPS/TLS.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 6. Datenlöschung */}
|
|
||||||
<section className="mb-8">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<Trash2 className="w-4 h-4 text-red-500" />
|
|
||||||
<span><span className="text-red-500 font-mono text-sm mr-2">06</span>Datenlöschung und Konto-Auflösung</span>
|
|
||||||
</h2>
|
|
||||||
<div className="space-y-2 text-sm text-muted-foreground leading-relaxed">
|
|
||||||
<p>
|
|
||||||
Sie haben jederzeit das Recht, Ihr Konto und Ihre Organisation inklusive aller zugehörigen Daten
|
|
||||||
vollständig zu löschen. Dies können Sie selbstständig über die Applikation durchführen
|
|
||||||
(Einstellungen → Organisation löschen).
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Bei der Löschung werden sämtliche Daten unwiderruflich entfernt: Benutzerkonten, Projekte,
|
|
||||||
Lagepläne, Journal-Einträge, Rapports, hochgeladene Dateien und alle zugehörigen Metadaten.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Alternativ können Sie die Löschung per E-Mail an <span className="text-foreground font-medium">datenschutz@lageplan.ch</span> beantragen.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 7. Rechte */}
|
|
||||||
<section className="mb-8">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<span className="text-red-500 font-mono text-sm">07</span>
|
|
||||||
Ihre Rechte
|
|
||||||
</h2>
|
|
||||||
<div className="space-y-2 text-sm text-muted-foreground leading-relaxed">
|
|
||||||
<p>Gemäss dem Schweizer Datenschutzgesetz (DSG) und der DSGVO haben Sie folgende Rechte:</p>
|
|
||||||
<ul className="list-disc pl-5 space-y-1">
|
|
||||||
<li><strong className="text-foreground">Auskunftsrecht:</strong> Sie können Auskunft über Ihre gespeicherten Daten verlangen.</li>
|
|
||||||
<li><strong className="text-foreground">Berichtigungsrecht:</strong> Sie können die Korrektur unrichtiger Daten verlangen.</li>
|
|
||||||
<li><strong className="text-foreground">Löschungsrecht:</strong> Sie können die Löschung Ihrer Daten verlangen.</li>
|
|
||||||
<li><strong className="text-foreground">Datenportabilität:</strong> Sie können Ihre Daten in einem gängigen Format anfordern.</li>
|
|
||||||
<li><strong className="text-foreground">Widerspruchsrecht:</strong> Sie können der Verarbeitung Ihrer Daten widersprechen.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 8. Cookies */}
|
|
||||||
<section className="mb-8">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<span className="text-red-500 font-mono text-sm">08</span>
|
|
||||||
Cookies
|
|
||||||
</h2>
|
|
||||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
|
||||||
Die Applikation verwendet ausschliesslich <strong className="text-foreground">technisch notwendige Cookies</strong> für
|
|
||||||
die Authentifizierung (Session-Token). Es werden keine Tracking-, Analyse- oder Werbe-Cookies eingesetzt.
|
|
||||||
Es werden keine Daten an Dritte weitergegeben.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 9. Kontakt */}
|
|
||||||
<section className="mb-4">
|
|
||||||
<h2 className="text-xl font-semibold text-foreground mb-3 flex items-center gap-2">
|
|
||||||
<Mail className="w-4 h-4 text-red-500" />
|
|
||||||
<span><span className="text-red-500 font-mono text-sm mr-2">09</span>Kontakt</span>
|
|
||||||
</h2>
|
|
||||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
|
||||||
Bei Fragen oder Anliegen zum Datenschutz kontaktieren Sie uns unter:{' '}
|
|
||||||
<span className="text-foreground font-medium">datenschutz@lageplan.ch</span>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-xs">* nur aktiv, sofern konfiguriert/genutzt (z.B. Zahlungsabwicklung, E-Mail-Versand).</p>
|
||||||
|
<p>Personendaten werden nicht zu Werbezwecken an Dritte verkauft.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div className="text-center mt-6 text-xs text-gray-500">
|
<section>
|
||||||
© {new Date().getFullYear()} Lageplan.ch — Alle Rechte vorbehalten.
|
<h2>6. Bekanntgabe ins Ausland</h2>
|
||||||
</div>
|
<p>
|
||||||
</div>
|
Je nach eingesetztem Dienstleister (z.B. Zahlungsanbieter, konfigurierter E-Mail-Anbieter, globale
|
||||||
</div>
|
Kartendienste) kann eine Bearbeitung ausserhalb der Schweiz erfolgen. Der Betreiber wählt Dienstleister
|
||||||
|
sorgfältig aus. Eine ausschliessliche Speicherung in der Schweiz wird nicht pauschal zugesichert; die
|
||||||
|
konkreten Verarbeitungsregionen sind – soweit bekannt – in der Tabelle unter Ziffer 5 bzw. in{' '}
|
||||||
|
<code>docs/legal/subprocessors.md</code> aufgeführt. Offene Punkte sind mit Platzhaltern gekennzeichnet.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>7. Sicherheit</h2>
|
||||||
|
<p>
|
||||||
|
Es werden angemessene technische und organisatorische Massnahmen eingesetzt (u.a. Rollen- und
|
||||||
|
Mandantentrennung, Passwort-Hashing, verschlüsselte Übertragung via HTTPS/TLS, Zugriffskontrollen,
|
||||||
|
Rate-Limiting). Ein vollständiger Schutz vor allen Risiken kann jedoch nicht garantiert werden.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>8. Aufbewahrung und Löschung</h2>
|
||||||
|
<p>
|
||||||
|
Personendaten werden so lange aufbewahrt, wie es für die genannten Zwecke oder gesetzliche Pflichten
|
||||||
|
erforderlich ist. Produktivdaten werden nach Abschluss des Löschvorgangs entfernt. Daten in
|
||||||
|
Sicherungskopien (Backups) können bis zum Ablauf des regulären Backup-Zyklus fortbestehen
|
||||||
|
(Aufbewahrungsfrist der Backups: <Val value={legal.backupRetention} />). Die detaillierten Fristen sind in{' '}
|
||||||
|
<code>docs/legal/retention-and-deletion.md</code> dokumentiert.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>9. Zahlungsabwicklung (freiwillige Beiträge)</h2>
|
||||||
|
<p>
|
||||||
|
Freiwillige Unterstützungsbeiträge werden über <strong>Stripe</strong> abgewickelt. Zahlungsdaten
|
||||||
|
(z.B. Kreditkarte, Twint) werden direkt bei Stripe erfasst und nicht in der Applikation gespeichert.
|
||||||
|
An Stripe werden der Betrag sowie ein freiwillig angegebener Name/Nachricht übermittelt. Es werden keine
|
||||||
|
wiederkehrenden Zahlungen eingerichtet. Details siehe{' '}
|
||||||
|
<a href="/unterstuetzen">Unterstützungsseite</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>10. Karten- und Geodienste</h2>
|
||||||
|
<p>
|
||||||
|
Für Karten, Adresssuche und Wetter-/Höhendaten werden Dienste von OpenStreetMap (Tiles/Nominatim),
|
||||||
|
Esri (Satellitenbilder), swisstopo (Landeskarte) sowie Open-Meteo/Open-Elevation genutzt. Diese Aufrufe
|
||||||
|
erfolgen aus Ihrem Browser; dabei kann Ihre IP-Adresse an die jeweiligen Anbieter übermittelt werden.
|
||||||
|
Karten-, Adress- und Geodaten können unvollständig, ungenau oder veraltet sein.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>11. Cookies und lokale Speichertechnologien</h2>
|
||||||
|
<p>
|
||||||
|
Es wird ein einziges, technisch notwendiges Cookie gesetzt: <code>auth-token</code> (Session/Anmeldung,
|
||||||
|
httpOnly). Es werden keine Tracking-, Analyse- oder Werbe-Cookies eingesetzt.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Im lokalen Speicher (localStorage) Ihres Geräts werden zur Funktion technisch notwendige Angaben
|
||||||
|
abgelegt, u.a.: zwischengespeicherte Zeichnungen/Offline-Warteschlange, Cache-Zeitstempel für
|
||||||
|
Offline-Karten, Theme-Einstellung, zuletzt geöffnetes Projekt, Onboarding-Status und der Zustand des
|
||||||
|
Cookie-Hinweises. Diese Daten verbleiben auf Ihrem Gerät.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>12. Protokolldaten</h2>
|
||||||
|
<p>
|
||||||
|
Zum Betrieb und zur Sicherheit können technische Protokolle anfallen. Diese werden auf das notwendige
|
||||||
|
Mass beschränkt; sensible Inhalte werden nach Möglichkeit von Protokollen ferngehalten.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>13. Ihre Rechte</h2>
|
||||||
|
<p>Im Rahmen des anwendbaren Rechts stehen Ihnen insbesondere folgende Rechte zu:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Auskunft</strong> über die bearbeiteten Daten</li>
|
||||||
|
<li><strong>Berichtigung</strong> unrichtiger Daten</li>
|
||||||
|
<li><strong>Löschung</strong> (im Rahmen gesetzlicher Pflichten)</li>
|
||||||
|
<li><strong>Datenherausgabe/-export</strong> in einem gängigen Format</li>
|
||||||
|
<li><strong>Widerspruch</strong> gegen bestimmte Bearbeitungen</li>
|
||||||
|
<li><strong>Beschwerde</strong> bei der zuständigen Datenschutzbehörde (in der Schweiz: EDÖB)</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Angemeldete Nutzer können Zustimmungen, Datenexport und Kontolöschung unter{' '}
|
||||||
|
<a href="/konto/datenschutz">Konto & Datenschutz</a> einsehen bzw. anfordern. Anfragen richten Sie an{' '}
|
||||||
|
<Val value={legal.privacyContactEmail} />; der Eingang wird bestätigt.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>14. Sicherheitsvorfälle</h2>
|
||||||
|
<p>
|
||||||
|
Bei einem Sicherheitsvorfall mit Risiko für betroffene Personen prüft der Betreiber die erforderlichen
|
||||||
|
Massnahmen und Informationspflichten nach einem definierten internen Prozess.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>15. Änderungen dieser Datenschutzerklärung</h2>
|
||||||
|
<p>
|
||||||
|
Diese Datenschutzerklärung kann angepasst werden. Massgebend ist die jeweils veröffentlichte Version
|
||||||
|
(siehe Kopf dieser Seite). Bei wesentlichen Änderungen wird angemessen informiert.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,17 +104,20 @@ export default function ImpressumPage() {
|
|||||||
Privatsphäre sowie auf Schutz vor Missbrauch ihrer persönlichen Daten.
|
Privatsphäre sowie auf Schutz vor Missbrauch ihrer persönlichen Daten.
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2">
|
<p className="mt-2">
|
||||||
Wir halten diese Bestimmungen ein. Persönliche Daten werden streng vertraulich behandelt und
|
Persönliche Daten werden vertraulich behandelt und nicht an Dritte verkauft. Für den technischen
|
||||||
weder an Dritte verkauft noch weitergegeben.
|
Betrieb können sorgfältig ausgewählte Hosting-, Karten-, E-Mail-, Zahlungs- und
|
||||||
|
Infrastruktur-Dienstleister eingesetzt werden. Einzelheiten enthält die{' '}
|
||||||
|
<a href="/datenschutz" className="text-red-600 hover:text-red-500">Datenschutzerklärung</a>.
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2">
|
<p className="mt-2">
|
||||||
Die Nutzung der Applikation erfordert eine Registrierung. Dabei werden folgende Daten
|
Die Nutzung der Applikation erfordert eine Registrierung. Dabei werden insbesondere Name,
|
||||||
gespeichert: Name, E-Mail-Adresse, Organisationsname. Die Daten werden ausschliesslich für
|
E-Mail-Adresse und Organisationsname gespeichert. Passwörter werden mit einem geeigneten
|
||||||
den Betrieb der Applikation verwendet und auf Servern in der Schweiz gehostet.
|
Einwegverfahren (bcrypt) gehasht und nie im Klartext gespeichert.
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2">
|
<p className="mt-2">
|
||||||
Einsatzdaten (Lagepläne, Journaleinträge, Zeichnungen) werden verschlüsselt gespeichert und
|
Einsatzdaten (Lagepläne, Journaleinträge, Zeichnungen) sind nach dem Rollen- und
|
||||||
sind nur für berechtigte Benutzer der jeweiligen Organisation zugänglich.
|
Mandantenkonzept nur für berechtigte Benutzer der jeweiligen Organisation zugänglich. Die
|
||||||
|
Übertragung erfolgt über HTTPS/TLS.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
186
src/app/nutzungsbedingungen/page.tsx
Normal file
186
src/app/nutzungsbedingungen/page.tsx
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
|
import { legal } from '@/config/legal'
|
||||||
|
|
||||||
|
export default function NutzungsbedingungenPage() {
|
||||||
|
const d = legal.documents.terms
|
||||||
|
return (
|
||||||
|
<LegalPage
|
||||||
|
title="Nutzungsbedingungen"
|
||||||
|
version={d.version}
|
||||||
|
publishedAt={d.publishedAt}
|
||||||
|
intro={`Diese Nutzungsbedingungen regeln die Nutzung von ${legal.projectName} (Website, Anwendung, Benutzerkonten, Organisationen, Exporte und unterstützende Funktionen).`}
|
||||||
|
>
|
||||||
|
<section>
|
||||||
|
<h2>1. Geltungsbereich</h2>
|
||||||
|
<p>
|
||||||
|
Diese Bedingungen gelten für die Website, die Anwendung, Benutzerkonten, Organisationen, Exporte und
|
||||||
|
unterstützende Funktionen von {legal.projectName}. <strong>Betreiber</strong> ist der Anbieter der
|
||||||
|
Plattform; <strong>Benutzer</strong> ist jede natürliche Person mit Konto; <strong>Organisation</strong>
|
||||||
|
{' '}ist eine Feuerwehr oder Einheit mit eigenem Mandanten; <strong>Plattform</strong> bezeichnet die
|
||||||
|
Gesamtheit der bereitgestellten Dienste.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>2. Zweck von {legal.projectName}</h2>
|
||||||
|
<p>{legal.projectName} ist ein unterstützendes Werkzeug für:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Erstellung und Verwaltung von Lage- und Objektplänen</li>
|
||||||
|
<li>Dokumentation und Visualisierung</li>
|
||||||
|
<li>Zusammenarbeit</li>
|
||||||
|
<li>Export von Unterlagen</li>
|
||||||
|
<li>unterstützende Berechnungen</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>3. Kein Einsatzleitsystem</h2>
|
||||||
|
<ul>
|
||||||
|
<li>{legal.projectName} ist <strong>kein Alarmierungssystem</strong>.</li>
|
||||||
|
<li>{legal.projectName} ist <strong>kein Einsatzleitsystem</strong> und ersetzt keine Einsatzleitung.</li>
|
||||||
|
<li>{legal.projectName} ersetzt keine Leitstelle.</li>
|
||||||
|
<li>{legal.projectName} ersetzt keine gesetzlich oder organisatorisch vorgeschriebenen Unterlagen.</li>
|
||||||
|
<li>{legal.projectName} darf <strong>nicht als einzige Informationsquelle</strong> verwendet werden.</li>
|
||||||
|
<li>Die Organisation muss unabhängig aktuelle <strong>Offline- und Notfallunterlagen</strong> bereithalten.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>4. Fachliche Prüfung</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Pläne müssen von fachkundigen Personen geprüft und freigegeben werden.</li>
|
||||||
|
<li>Adressen, Distanzen, Symbole, Massstäbe, Hydranten, Zufahrten und Berechnungen können fehlerhaft oder veraltet sein.</li>
|
||||||
|
<li>Automatisch erzeugte oder berechnete Angaben sind Hilfsmittel.</li>
|
||||||
|
<li>Für operative Entscheidungen bleibt die zuständige Feuerwehr bzw. Organisation verantwortlich.</li>
|
||||||
|
<li>Änderungen an Gebäuden, Zufahrten, Wasserbezugsstellen oder Gefahren müssen durch die Organisation aktualisiert werden.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>5. Benutzerkonten und Organisationen</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Benutzer müssen richtige Angaben machen.</li>
|
||||||
|
<li>Zugangsdaten dürfen nicht weitergegeben werden.</li>
|
||||||
|
<li>Organisationen müssen Berechtigungen regelmässig kontrollieren.</li>
|
||||||
|
<li>Ausgetretene Benutzer müssen entfernt werden.</li>
|
||||||
|
<li>Organisationsadministratoren müssen zur Vertretung ihrer Organisation berechtigt sein.</li>
|
||||||
|
<li>Aktivitäten innerhalb eines Organisationskontos können protokolliert werden.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>6. Verbotene Inhalte</h2>
|
||||||
|
<p>Ohne separate schriftliche Vereinbarung ist insbesondere untersagt, folgende Inhalte zu speichern:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Patientennamen, Gesundheitsdaten, medizinische Befunde</li>
|
||||||
|
<li>Fotos identifizierbarer verletzter oder verstorbener Personen</li>
|
||||||
|
<li>polizeiliche Ermittlungsinformationen</li>
|
||||||
|
<li>Passwörter, Alarmcodes, Schlüsselcodes, Tresorcodes</li>
|
||||||
|
<li>private Telefonnummern ohne rechtliche Grundlage</li>
|
||||||
|
<li>Ausweiskopien und weitere besonders schützenswerte Personendaten</li>
|
||||||
|
<li>rechtswidrige oder urheberrechtlich unzulässige Inhalte</li>
|
||||||
|
<li>Informationen, welche die Sicherheit von Personen oder kritischer Infrastruktur unangemessen gefährden</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Auch reine Objektinformationen können vertraulich oder sicherheitsrelevant sein und dürfen nur
|
||||||
|
berechtigten Personen zugänglich gemacht werden.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>7. Verfügbarkeit</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Es besteht kein Anspruch auf ununterbrochene Verfügbarkeit.</li>
|
||||||
|
<li>Es besteht kein Service-Level-Agreement (SLA).</li>
|
||||||
|
<li>Wartungen und Störungen sind möglich.</li>
|
||||||
|
<li>Funktionen dürfen weiterentwickelt, eingeschränkt oder eingestellt werden.</li>
|
||||||
|
<li>Exporte und Offline-Kopien liegen in der Verantwortung der Organisation.</li>
|
||||||
|
<li>Es besteht keine Garantie auf dauerhafte Speicherung ohne eigene Sicherung.</li>
|
||||||
|
</ul>
|
||||||
|
<p>{legal.projectName} wird ohne garantierte Verfügbarkeit und ohne SLA bereitgestellt.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>8. Kostenloser Betrieb</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Die Plattform wird grundsätzlich kostenlos angeboten.</li>
|
||||||
|
<li>Es besteht kein Anspruch darauf, dass alle Funktionen dauerhaft kostenlos bleiben.</li>
|
||||||
|
<li>Wesentliche Änderungen werden angemessen kommuniziert.</li>
|
||||||
|
<li>Eine spätere kostenpflichtige Leistung entsteht nur nach ausdrücklicher separater Zustimmung.</li>
|
||||||
|
<li>Es gibt keine automatische kostenpflichtige Verlängerung.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>9. Unterstützungsbeiträge</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Beiträge sind freiwillig und erfolgen ohne Anspruch auf eine Gegenleistung.</li>
|
||||||
|
<li>Beiträge begründen keinen Anspruch auf Funktionen, Support, Verfügbarkeit oder bevorzugte Behandlung.</li>
|
||||||
|
<li>Zahlungsanbieter können Gebühren abziehen.</li>
|
||||||
|
<li>Es wird keine steuerlich abzugsfähige Spendenbescheinigung versprochen.</li>
|
||||||
|
<li>Bei versehentlicher Zahlung besteht eine Kontaktmöglichkeit zur Prüfung einer Rückerstattung ({legal.supportEmail}).</li>
|
||||||
|
<li>Es wird keine Gemeinnützigkeit oder Steuerbefreiung behauptet, solange diese nicht schriftlich bestätigt ist.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>10. Geistiges Eigentum</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Die Rechte an der Software verbleiben beim Betreiber bzw. den jeweiligen Rechteinhabern.</li>
|
||||||
|
<li>Rechte an eigenen Inhalten verbleiben bei den Benutzern bzw. Organisationen.</li>
|
||||||
|
<li>Der Betreiber erhält die für den technischen Betrieb notwendige, einfache Nutzungslizenz an hochgeladenen Inhalten.</li>
|
||||||
|
<li>Benutzer sind für die hochgeladenen Inhalte und deren Rechtmässigkeit verantwortlich.</li>
|
||||||
|
<li>Karten-, Symbol-, Icon- und Drittanbieter-Lizenzen sind zu beachten (siehe <a href="/impressum">Impressum</a> und Lizenzdokumentation).</li>
|
||||||
|
<li>Eine Quellenangabe ersetzt nicht automatisch eine erforderliche Nutzungslizenz.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>11. Haftung</h2>
|
||||||
|
<p>Im gesetzlich zulässigen Umfang gilt:</p>
|
||||||
|
<ul>
|
||||||
|
<li>keine Garantie für Vollständigkeit, Aktualität oder Fehlerfreiheit der Inhalte;</li>
|
||||||
|
<li>keine Garantie für Karten- oder Drittanbieterdaten;</li>
|
||||||
|
<li>keine Garantie für Berechnungsergebnisse;</li>
|
||||||
|
<li>die Verantwortung für fachliche Kontrolle und operative Entscheidungen liegt bei der Organisation;</li>
|
||||||
|
<li>indirekte Schäden, Datenverlust und Betriebsunterbruch werden nur im gesetzlich zulässigen Umfang begrenzt.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<strong>Zwingende gesetzliche Haftungsbestimmungen bleiben vorbehalten. Insbesondere wird die Haftung
|
||||||
|
für rechtswidrige Absicht oder grobe Fahrlässigkeit nicht im Voraus ausgeschlossen.</strong>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>12. Sperrung und Beendigung</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Sperrung bei Missbrauch oder Sicherheitsrisiken ist möglich.</li>
|
||||||
|
<li>Eine Exportmöglichkeit wird bereitgestellt, soweit technisch und rechtlich möglich.</li>
|
||||||
|
<li>Löschung erfolgt nach definierten Fristen; Daten in Backups können bis zum Ablauf des Backup-Zyklus fortbestehen.</li>
|
||||||
|
<li>Bei Einstellung des Projekts erfolgt eine angemessene Vorankündigung, soweit möglich.</li>
|
||||||
|
<li>Bei akuten Sicherheitsproblemen können sofortige Massnahmen ergriffen werden.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>13. Änderungen der Bedingungen</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Die Bedingungen werden versioniert.</li>
|
||||||
|
<li>Über wesentliche Änderungen wird informiert.</li>
|
||||||
|
<li>Bei wesentlichen Änderungen wird eine erneute ausdrückliche Zustimmung verlangt.</li>
|
||||||
|
<li>Frühere Versionen bleiben intern nachvollziehbar.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>14. Anwendbares Recht</h2>
|
||||||
|
<p>
|
||||||
|
Es gilt {legal.governingLaw}. Gerichtsstand, soweit zulässig und sinnvoll: {legal.jurisdiction}.
|
||||||
|
Zwingende Bestimmungen zum Schutz von Konsumentinnen und Konsumenten bleiben vorbehalten.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
143
src/app/organisationen/datenschutzvereinbarung/page.tsx
Normal file
143
src/app/organisationen/datenschutzvereinbarung/page.tsx
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
|
import { legal, isPlaceholder } from '@/config/legal'
|
||||||
|
|
||||||
|
function Val({ value }: { value: string }) {
|
||||||
|
return isPlaceholder(value)
|
||||||
|
? <span className="text-amber-600 dark:text-amber-400 font-medium">{value}</span>
|
||||||
|
: <span className="text-foreground font-medium">{value}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DatenschutzvereinbarungPage() {
|
||||||
|
const d = legal.documents.dataProcessingAgreement
|
||||||
|
return (
|
||||||
|
<LegalPage
|
||||||
|
title="Datenschutzvereinbarung für Organisationen"
|
||||||
|
version={d.version}
|
||||||
|
publishedAt={d.publishedAt}
|
||||||
|
intro="Entwurf einer Vereinbarung zur Auftragsbearbeitung – vor produktiver Nutzung mit personenbezogenen oder vertraulichen Organisationsdaten durch beide Parteien zu prüfen und zu vervollständigen."
|
||||||
|
>
|
||||||
|
<section>
|
||||||
|
<h2>1. Parteien</h2>
|
||||||
|
<p>
|
||||||
|
<strong>Auftragsbearbeiter (Betreiber):</strong> <Val value={legal.operatorName} /> (<Val value={legal.operatorLegalForm} />),{' '}
|
||||||
|
<Val value={legal.postalAddress} />, Kontakt <Val value={legal.privacyContactEmail} />.
|
||||||
|
</p>
|
||||||
|
<p><strong>Verantwortliche (Organisation):</strong> die jeweilige Feuerwehr/Organisation als Mandant.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>2. Gegenstand und Dauer</h2>
|
||||||
|
<p>
|
||||||
|
Gegenstand ist die Bearbeitung von Personendaten im Auftrag der Organisation im Rahmen der Nutzung von
|
||||||
|
{' '}{legal.projectName}. Die Vereinbarung gilt für die Dauer des Nutzungsverhältnisses.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>3. Zweck</h2>
|
||||||
|
<p>Bereitstellung, Betrieb und Support der Plattform gemäss Weisung der Organisation.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>4. Kategorien betroffener Personen</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Mitglieder und Funktionsträger der Organisation (Benutzer)</li>
|
||||||
|
<li>ggf. weitere Personen, soweit von der Organisation im Rahmen der Nutzung erfasst</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>5. Datenkategorien</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Konto-/Kontaktdaten (Name, E-Mail, Rolle)</li>
|
||||||
|
<li>Inhalts-/Einsatzdaten (Pläne, Journale, Zeichnungen, Uploads)</li>
|
||||||
|
<li>Protokoll-/Nutzungsdaten</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Besonders schützenswerte Personendaten dürfen ohne gesonderte schriftliche Vereinbarung nicht bearbeitet
|
||||||
|
werden (siehe <a href="/nutzungsbedingungen">Nutzungsbedingungen</a>).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>6. Weisungen der Organisation</h2>
|
||||||
|
<p>Der Betreiber bearbeitet Personendaten nur gemäss den dokumentierten Weisungen der Organisation und dieser Vereinbarung.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>7. Vertraulichkeit</h2>
|
||||||
|
<p>Zum Zugriff berechtigte Personen sind zur Vertraulichkeit verpflichtet.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>8. Technische und organisatorische Massnahmen (TOM)</h2>
|
||||||
|
<p>
|
||||||
|
Es gelten die unter <a href="/sicherheit">Sicherheit</a> beschriebenen Massnahmen; der detaillierte
|
||||||
|
Stand ist in <code>docs/legal/technical-organizational-measures.md</code> dokumentiert (Anhang A).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>9. Unterauftragnehmer</h2>
|
||||||
|
<p>
|
||||||
|
Der Betreiber setzt die in der <a href="/datenschutz#dienstleister">Dienstleisterliste</a> genannten
|
||||||
|
Unterauftragnehmer ein (Anhang B). Über Änderungen wird angemessen informiert.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>10. Datenstandorte</h2>
|
||||||
|
<p>Verarbeitungsregionen gemäss Dienstleisterliste; offene Punkte: <Val value={legal.serverLocation} />.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>11. Unterstützung bei Betroffenenrechten</h2>
|
||||||
|
<p>Der Betreiber unterstützt die Organisation angemessen bei der Erfüllung von Auskunfts-, Berichtigungs-, Lösch- und Exportbegehren.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>12. Sicherheitsvorfälle</h2>
|
||||||
|
<p>Der Betreiber informiert die Organisation ohne unangemessene Verzögerung über Sicherheitsvorfälle mit Risiko für betroffene Personen.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>13. Löschung und Rückgabe</h2>
|
||||||
|
<p>
|
||||||
|
Nach Vertragsende werden Personendaten gelöscht oder zurückgegeben, soweit keine gesetzliche
|
||||||
|
Aufbewahrungspflicht besteht. Daten in Backups können bis zum Ablauf des Backup-Zyklus fortbestehen
|
||||||
|
(<Val value={legal.backupRetention} />).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>14. Datenexport</h2>
|
||||||
|
<p>Die Organisation kann ihre Daten in einem gängigen Format exportieren, soweit technisch möglich.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>15. Kontrolle und Nachweis</h2>
|
||||||
|
<p>Der Betreiber stellt der Organisation auf Anfrage angemessene Nachweise zur Einhaltung dieser Vereinbarung zur Verfügung.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>16. Kontaktstellen</h2>
|
||||||
|
<p>Betreiber: <Val value={legal.privacyContactEmail} />. Organisation: durch die Organisation zu benennen.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Anhänge</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Anhang A – TOM:</strong> <a href="/sicherheit">Sicherheit</a> / interne TOM-Dokumentation</li>
|
||||||
|
<li><strong>Anhang B – Unterauftragnehmer:</strong> <a href="/datenschutz#dienstleister">Dienstleisterliste</a></li>
|
||||||
|
</ul>
|
||||||
|
<p className="text-xs">
|
||||||
|
Dieser Entwurf enthält keine abgeschlossene Vereinbarung und keine Unterschriften. Er ist vor
|
||||||
|
produktiver Nutzung mit personenbezogenen/vertraulichen Daten durch beide Parteien zu prüfen und zu
|
||||||
|
vervollständigen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ export default function LandingPage() {
|
|||||||
name: 'Was kostet Lageplan?',
|
name: 'Was kostet Lageplan?',
|
||||||
acceptedAnswer: {
|
acceptedAnswer: {
|
||||||
'@type': 'Answer',
|
'@type': 'Answer',
|
||||||
text: 'Nichts. Lageplan ist kostenlos für alle Feuerwehren in der Schweiz. Die Entwicklung wird durch freiwillige Spenden finanziert.',
|
text: 'Lageplan wird Feuerwehren grundsätzlich kostenlos zur Verfügung gestellt. Der Betrieb wird durch freiwillige Unterstützungsbeiträge mitfinanziert. Ein Anspruch darauf, dass alle Funktionen dauerhaft kostenlos bleiben, besteht nicht.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,7 +84,7 @@ export default function LandingPage() {
|
|||||||
name: 'Wo werden meine Daten gespeichert?',
|
name: 'Wo werden meine Daten gespeichert?',
|
||||||
acceptedAnswer: {
|
acceptedAnswer: {
|
||||||
'@type': 'Answer',
|
'@type': 'Answer',
|
||||||
text: 'Alle Daten werden auf Servern in der Schweiz gespeichert. Die Applikation ist DSG- und DSGVO-konform.',
|
text: 'Kontodaten werden in einer Datenbank gespeichert. Die eingesetzten Dienstleister und Speicherorte sind in der Datenschutzerklärung transparent aufgeführt. Lageplan orientiert sich am Schweizer Datenschutzgesetz (DSG).',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -237,10 +237,10 @@ export default function LandingPage() {
|
|||||||
<div className="max-w-5xl mx-auto">
|
<div className="max-w-5xl mx-auto">
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 md:gap-8">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 md:gap-8">
|
||||||
{[
|
{[
|
||||||
{ value: '117', label: 'FKS-Signaturen', sub: 'Offizielle taktische Zeichen' },
|
{ value: '117', label: 'FKS-Signaturen', sub: 'Taktische Zeichen (Bildquelle FKS)' },
|
||||||
{ value: '100%', label: 'Swiss Hosted', sub: 'Server in der Schweiz' },
|
{ value: 'CH', label: 'Swiss Made', sub: 'In der Schweiz entwickelt' },
|
||||||
{ value: '0.—', label: 'Kostenlos', sub: 'Für alle Feuerwehren' },
|
{ value: '0.—', label: 'Kostenlos', sub: 'Grundnutzung für Feuerwehren' },
|
||||||
{ value: '24/7', label: 'Verfügbar', sub: 'Browser-basiert, jedes Gerät' },
|
{ value: 'Web', label: 'Überall nutzbar', sub: 'Browser, Tablet, Smartphone' },
|
||||||
].map((stat, i) => (
|
].map((stat, i) => (
|
||||||
<div key={i} className="text-center">
|
<div key={i} className="text-center">
|
||||||
<p className="text-3xl sm:text-4xl font-extrabold text-red-600">{stat.value}</p>
|
<p className="text-3xl sm:text-4xl font-extrabold text-red-600">{stat.value}</p>
|
||||||
@@ -357,8 +357,8 @@ export default function LandingPage() {
|
|||||||
{ icon: FileText, title: 'Einsatzjournal', desc: 'Journal mit Zeitstempel, SOMA-Checkliste und Pendenzenliste — alles an einem Ort.' },
|
{ icon: FileText, title: 'Einsatzjournal', desc: 'Journal mit Zeitstempel, SOMA-Checkliste und Pendenzenliste — alles an einem Ort.' },
|
||||||
{ icon: Smartphone, title: 'Installierbare App (PWA)', desc: 'Auf dem Homescreen installierbar — funktioniert offline wie eine native App. Desktop, Tablet & Smartphone.' },
|
{ icon: Smartphone, title: 'Installierbare App (PWA)', desc: 'Auf dem Homescreen installierbar — funktioniert offline wie eine native App. Desktop, Tablet & Smartphone.' },
|
||||||
{ icon: Users, title: 'Echtzeit-Zusammenarbeit', desc: 'Mehrere Benutzer können gleichzeitig am selben Lageplan arbeiten.' },
|
{ icon: Users, title: 'Echtzeit-Zusammenarbeit', desc: 'Mehrere Benutzer können gleichzeitig am selben Lageplan arbeiten.' },
|
||||||
{ icon: Clock, title: 'Audit Trail', desc: 'Lückenlose Protokollierung aller Aktionen mit Zeitstempel für Nachvollziehbarkeit.' },
|
{ icon: Clock, title: 'Nachvollziehbarkeit', desc: 'Protokollierung von Aktionen mit Zeitstempel für bessere Nachvollziehbarkeit.' },
|
||||||
{ icon: Lock, title: 'Sicher & Schweiz', desc: 'Rollenbasierte Zugriffskontrolle. Gehostet in der Schweiz — DSG/DSGVO-konform.' },
|
{ icon: Lock, title: 'Sicherheit & Datenschutz', desc: 'Rollenbasierte Zugriffskontrolle und Mandantentrennung. Angemessene technische und organisatorische Schutzmassnahmen — Details in der Datenschutzerklärung.' },
|
||||||
{ icon: FileText, title: 'PDF-Export', desc: 'Lagepläne als PDF exportieren mit Metadaten, Datum und Einsatzinformationen.' },
|
{ icon: FileText, title: 'PDF-Export', desc: 'Lagepläne als PDF exportieren mit Metadaten, Datum und Einsatzinformationen.' },
|
||||||
].map((f, i) => (
|
].map((f, i) => (
|
||||||
<div key={i} className="bg-white rounded-xl p-6 border border-gray-100 hover:shadow-lg transition-shadow">
|
<div key={i} className="bg-white rounded-xl p-6 border border-gray-100 hover:shadow-lg transition-shadow">
|
||||||
@@ -439,7 +439,7 @@ export default function LandingPage() {
|
|||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
q: 'Was kostet Lageplan?',
|
q: 'Was kostet Lageplan?',
|
||||||
a: 'Nichts. Lageplan ist kostenlos für alle Feuerwehren in der Schweiz. Die Entwicklung wird durch freiwillige Spenden finanziert.',
|
a: 'Lageplan wird Feuerwehren grundsätzlich kostenlos zur Verfügung gestellt. Der Betrieb wird durch freiwillige Unterstützungsbeiträge mitfinanziert. Ein Anspruch darauf, dass alle Funktionen dauerhaft kostenlos bleiben, besteht nicht.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
q: 'Brauche ich eine Installation?',
|
q: 'Brauche ich eine Installation?',
|
||||||
@@ -455,7 +455,7 @@ export default function LandingPage() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
q: 'Wo werden meine Daten gespeichert?',
|
q: 'Wo werden meine Daten gespeichert?',
|
||||||
a: 'Alle Daten werden auf Servern in der Schweiz gespeichert. Die Applikation ist DSG- und DSGVO-konform.',
|
a: 'Kontodaten werden in einer Datenbank gespeichert. Die eingesetzten Dienstleister und Speicherorte sind in der Datenschutzerklärung transparent aufgeführt. Lageplan orientiert sich am Schweizer Datenschutzgesetz (DSG).',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
q: 'Welche Symbole sind verfügbar?',
|
q: 'Welche Symbole sind verfügbar?',
|
||||||
@@ -508,7 +508,11 @@ export default function LandingPage() {
|
|||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-500">Digitale Lagepläne für die Schweizer Feuerwehr</p>
|
<p className="text-sm text-gray-500">Digitale Lagepläne für die Schweizer Feuerwehr</p>
|
||||||
<p className="text-sm text-gray-500 mt-1">Ein Projekt von Pepe Ziberi</p>
|
<p className="text-sm text-gray-500 mt-1">Ein Projekt von Pepe Ziberi</p>
|
||||||
<p className="text-sm text-gray-500">Gehostet in der Schweiz — Swiss Made 🇨🇭</p>
|
<p className="text-sm text-gray-500">In der Schweiz entwickelt — Swiss Made 🇨🇭</p>
|
||||||
|
<p className="text-xs text-gray-400 mt-2 max-w-xs">
|
||||||
|
Unterstützendes Werkzeug ohne garantierte Verfügbarkeit. Kein Einsatzleit- oder
|
||||||
|
Alarmierungssystem. Angaben vor Verwendung fachlich prüfen.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm text-gray-500">
|
<div className="text-sm text-gray-500">
|
||||||
<p className="font-medium text-gray-700 mb-2">Kontakt</p>
|
<p className="font-medium text-gray-700 mb-2">Kontakt</p>
|
||||||
@@ -526,6 +530,11 @@ export default function LandingPage() {
|
|||||||
<p className="font-medium text-gray-700 mb-2">Rechtliches</p>
|
<p className="font-medium text-gray-700 mb-2">Rechtliches</p>
|
||||||
<Link href="/impressum" className="block hover:text-gray-700">Impressum</Link>
|
<Link href="/impressum" className="block hover:text-gray-700">Impressum</Link>
|
||||||
<Link href="/datenschutz" className="block hover:text-gray-700 mt-1">Datenschutz</Link>
|
<Link href="/datenschutz" className="block hover:text-gray-700 mt-1">Datenschutz</Link>
|
||||||
|
<Link href="/nutzungsbedingungen" className="block hover:text-gray-700 mt-1">Nutzungsbedingungen</Link>
|
||||||
|
<Link href="/verantwortungsvolle-nutzung" className="block hover:text-gray-700 mt-1">Verantwortungsvolle Nutzung</Link>
|
||||||
|
<Link href="/sicherheit" className="block hover:text-gray-700 mt-1">Sicherheit</Link>
|
||||||
|
<Link href="/organisationen/datenschutzvereinbarung" className="block hover:text-gray-700 mt-1">Datenschutzvereinbarung (Org.)</Link>
|
||||||
|
<Link href="/unterstuetzen" className="block hover:text-gray-700 mt-1">Unterstützen</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t border-gray-100 mt-8 pt-6 text-center space-y-1">
|
<div className="border-t border-gray-100 mt-8 pt-6 text-center space-y-1">
|
||||||
@@ -548,8 +557,8 @@ function SupportSection() {
|
|||||||
<Coffee className="w-10 h-10 text-red-600 mx-auto mb-4" />
|
<Coffee className="w-10 h-10 text-red-600 mx-auto mb-4" />
|
||||||
<h2 className="text-3xl font-bold text-gray-900">Projekt unterstützen</h2>
|
<h2 className="text-3xl font-bold text-gray-900">Projekt unterstützen</h2>
|
||||||
<p className="mt-3 text-lg text-gray-500 max-w-xl mx-auto">
|
<p className="mt-3 text-lg text-gray-500 max-w-xl mx-auto">
|
||||||
Lageplan ist und bleibt kostenlos. Wenn du die Weiterentwicklung unterstützen möchtest,
|
Lageplan wird grundsätzlich kostenlos angeboten. Wenn du die Weiterentwicklung unterstützen
|
||||||
freue ich mich über einen freiwilligen Beitrag.
|
möchtest, freue ich mich über einen freiwilligen Beitrag — ohne Anspruch auf eine Gegenleistung.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -571,7 +580,7 @@ function SupportSection() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-gray-500 mb-6">
|
<p className="text-gray-500 mb-6">
|
||||||
Wähle einen Betrag auf unserer Spendenseite — Zahlung sicher via Stripe (Kreditkarte, Twint, Apple Pay, Google Pay).
|
Wähle einen Betrag auf der Unterstützungsseite — Zahlung über Stripe (Kreditkarte, Twint, Apple Pay, Google Pay).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Link href="/spenden">
|
<Link href="/spenden">
|
||||||
@@ -585,8 +594,10 @@ function SupportSection() {
|
|||||||
{/* Trust note */}
|
{/* Trust note */}
|
||||||
<div className="mt-8 text-center">
|
<div className="mt-8 text-center">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
100% deiner Spende fliesst direkt in Serverkosten und Weiterentwicklung.
|
Beiträge helfen, Hosting, Infrastruktur und Weiterentwicklung zu finanzieren.
|
||||||
<br />Kein Unternehmen, keine Investoren — nur ein Feuerwehrmann mit einer Idee.
|
Ein Beitrag ist freiwillig und erfolgt ohne Anspruch auf eine Gegenleistung; Gebühren des
|
||||||
|
Zahlungsanbieters können abgezogen werden.
|
||||||
|
<br />Ein Projekt aus der Feuerwehr-Praxis — entwickelt in der Freizeit.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
59
src/app/sicherheit/page.tsx
Normal file
59
src/app/sicherheit/page.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
|
import { legal } from '@/config/legal'
|
||||||
|
|
||||||
|
export default function SicherheitPage() {
|
||||||
|
return (
|
||||||
|
<LegalPage
|
||||||
|
title="Sicherheit"
|
||||||
|
version={legal.documents.privacy.version}
|
||||||
|
publishedAt={legal.documents.privacy.publishedAt}
|
||||||
|
intro={`Übersicht über die technischen und organisatorischen Sicherheitsmassnahmen von ${legal.projectName}. Diese Darstellung ist allgemein gehalten; ein vollständiger Schutz vor allen Risiken kann nicht garantiert werden.`}
|
||||||
|
>
|
||||||
|
<section>
|
||||||
|
<h2>Grundsatz</h2>
|
||||||
|
<p>
|
||||||
|
Wir setzen angemessene technische und organisatorische Sicherheitsmassnahmen ein. Ein vollständiger
|
||||||
|
Schutz vor allen Risiken kann jedoch nicht garantiert werden. Sicherheit ist ein fortlaufender Prozess.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Technische Massnahmen (Auszug)</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Zugriffstrennung:</strong> Mandantentrennung je Organisation sowie ein Rollen- und Rechtekonzept (Server-Admin, Organisations-Admin, Bearbeiter, Betrachter).</li>
|
||||||
|
<li><strong>Passwörter:</strong> werden mit einem geeigneten Einwegverfahren (bcrypt) gehasht, nie im Klartext gespeichert.</li>
|
||||||
|
<li><strong>Übertragung:</strong> verschlüsselt über HTTPS/TLS; HSTS aktiviert.</li>
|
||||||
|
<li><strong>Sitzungen:</strong> httpOnly-Session-Cookie, in Produktion mit <code>secure</code>-Flag.</li>
|
||||||
|
<li><strong>Web-Härtung:</strong> Sicherheits-Header (u.a. Content-Security-Policy, <code>X-Content-Type-Options</code>, Referrer-Policy, Schutz vor Clickjacking über <code>frame-ancestors</code>).</li>
|
||||||
|
<li><strong>Missbrauchsschutz:</strong> Rate-Limiting für Login, Registrierung, Passwort-Reset, Kontaktformular und geteilte Ansichten.</li>
|
||||||
|
<li><strong>Uploads:</strong> Validierung und Zugriffsschutz für hochgeladene Dateien.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Organisatorische Massnahmen</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Zugriff auf Systemdaten nur im betrieblich notwendigen Umfang.</li>
|
||||||
|
<li>Trennung von Entwicklungs-/Test- und Produktionsumgebung.</li>
|
||||||
|
<li>Regelmässige Aktualisierung von Abhängigkeiten.</li>
|
||||||
|
<li>Definierter Prozess für Sicherheitsvorfälle (siehe interne Dokumentation).</li>
|
||||||
|
</ul>
|
||||||
|
<p className="text-xs">
|
||||||
|
Der detaillierte, laufend gepflegte Ist-Zustand inkl. offener Punkte ist intern in{' '}
|
||||||
|
<code>docs/legal/technical-organizational-measures.md</code> dokumentiert.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Sicherheitslücke melden</h2>
|
||||||
|
<p>
|
||||||
|
Wenn Sie eine mögliche Sicherheitslücke entdecken, melden Sie diese bitte vertraulich an{' '}
|
||||||
|
<strong>{legal.supportEmail}</strong>. Bitte nutzen Sie gefundene Schwachstellen nicht aus und geben Sie
|
||||||
|
uns angemessene Zeit zur Behebung.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -46,5 +46,10 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
|||||||
changeFrequency: 'yearly',
|
changeFrequency: 'yearly',
|
||||||
priority: 0.3,
|
priority: 0.3,
|
||||||
},
|
},
|
||||||
|
{ url: `${baseUrl}/nutzungsbedingungen`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
|
||||||
|
{ url: `${baseUrl}/verantwortungsvolle-nutzung`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
|
||||||
|
{ url: `${baseUrl}/sicherheit`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
|
||||||
|
{ url: `${baseUrl}/unterstuetzen`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
|
||||||
|
{ url: `${baseUrl}/organisationen/datenschutzvereinbarung`, lastModified: new Date(), changeFrequency: 'yearly', priority: 0.3 },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export default function SpendenPage() {
|
|||||||
<div>
|
<div>
|
||||||
<h3 className="font-bold text-gray-900 mb-2">Wohin fliesst deine Spende?</h3>
|
<h3 className="font-bold text-gray-900 mb-2">Wohin fliesst deine Spende?</h3>
|
||||||
<ul className="space-y-2 text-sm text-gray-600">
|
<ul className="space-y-2 text-sm text-gray-600">
|
||||||
<li className="flex items-center gap-2"><Shield className="w-4 h-4 text-red-500 shrink-0" /> Server-Hosting in der Schweiz (monatliche Kosten)</li>
|
<li className="flex items-center gap-2"><Shield className="w-4 h-4 text-red-500 shrink-0" /> Server-Hosting und Infrastruktur (monatliche Kosten)</li>
|
||||||
<li className="flex items-center gap-2"><Sparkles className="w-4 h-4 text-red-500 shrink-0" /> Entwicklung neuer Features (PWA, Vorlagen, Einsatzpläne)</li>
|
<li className="flex items-center gap-2"><Sparkles className="w-4 h-4 text-red-500 shrink-0" /> Entwicklung neuer Features (PWA, Vorlagen, Einsatzpläne)</li>
|
||||||
<li className="flex items-center gap-2"><Coffee className="w-4 h-4 text-red-500 shrink-0" /> Domain, SSL-Zertifikate und Infrastruktur</li>
|
<li className="flex items-center gap-2"><Coffee className="w-4 h-4 text-red-500 shrink-0" /> Domain, SSL-Zertifikate und Infrastruktur</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -223,12 +223,24 @@ export default function SpendenPage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="mt-4 flex flex-wrap items-center justify-center gap-3 text-xs text-gray-400">
|
<div className="mt-4 flex flex-wrap items-center justify-center gap-3 text-xs text-gray-400">
|
||||||
<span className="flex items-center gap-1"><Shield className="w-3.5 h-3.5" /> Sichere Zahlung via Stripe</span>
|
<span className="flex items-center gap-1"><Shield className="w-3.5 h-3.5" /> Zahlung über Stripe</span>
|
||||||
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Kreditkarte</span>
|
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Kreditkarte</span>
|
||||||
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Twint</span>
|
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Twint</span>
|
||||||
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Apple Pay</span>
|
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Apple Pay</span>
|
||||||
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Google Pay</span>
|
<span className="flex items-center gap-1"><Check className="w-3.5 h-3.5" /> Google Pay</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Rechtlicher Hinweis zum freiwilligen Beitrag */}
|
||||||
|
<div className="mt-5 rounded-lg bg-gray-50 border border-gray-100 p-4 text-xs text-gray-500 leading-relaxed">
|
||||||
|
<strong className="text-gray-700">Freiwilliger Unterstützungsbeitrag.</strong> Ein Beitrag ist
|
||||||
|
freiwillig und erfolgt ohne Anspruch auf eine Gegenleistung. Daraus entsteht insbesondere kein
|
||||||
|
Anspruch auf Funktionen, Support, Verfügbarkeit, bevorzugte Behandlung oder eine bestimmte
|
||||||
|
Weiterentwicklung. Zahlungs- und Transaktionsgebühren des Zahlungsanbieters (Stripe) können vom
|
||||||
|
Beitrag abgezogen werden. Es wird keine steuerlich abzugsfähige Spendenbescheinigung ausgestellt,
|
||||||
|
solange keine entsprechende behördliche Anerkennung besteht. Es handelt sich um eine einmalige
|
||||||
|
Zahlung; es wird keine wiederkehrende Zahlung eingerichtet. Details zur Zahlungsabwicklung siehe{' '}
|
||||||
|
<Link href="/datenschutz" className="text-red-600 underline">Datenschutzerklärung</Link>.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Story */}
|
{/* Story */}
|
||||||
@@ -236,21 +248,22 @@ export default function SpendenPage() {
|
|||||||
<h3 className="font-bold text-gray-900 mb-3">Die Geschichte hinter Lageplan</h3>
|
<h3 className="font-bold text-gray-900 mb-3">Die Geschichte hinter Lageplan</h3>
|
||||||
<p className="text-sm text-gray-600 leading-relaxed">
|
<p className="text-sm text-gray-600 leading-relaxed">
|
||||||
Lageplan wird seit über 2 Jahren von einem aktiven Feuerwehrmann in seiner Freizeit entwickelt.
|
Lageplan wird seit über 2 Jahren von einem aktiven Feuerwehrmann in seiner Freizeit entwickelt.
|
||||||
Die App ist und bleibt <strong>kostenlos</strong> — weil jede Feuerwehr Zugang zu guten Werkzeugen haben soll,
|
Die App wird <strong>grundsätzlich kostenlos</strong> angeboten — weil jede Feuerwehr Zugang zu guten
|
||||||
unabhängig vom Budget. Es gibt zwar kommerzielle Alternativen, aber die Idee war immer:
|
Werkzeugen haben soll, unabhängig vom Budget. Die Idee war immer:
|
||||||
Ein Werkzeug <em>von der Feuerwehr, für die Feuerwehr</em>.
|
Ein Werkzeug <em>von der Feuerwehr, für die Feuerwehr</em>.
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-600 leading-relaxed mt-3">
|
<p className="text-sm text-gray-600 leading-relaxed mt-3">
|
||||||
Mit deiner Spende hilfst du, dass das so bleibt. Jeder Franken fliesst direkt in
|
Beiträge helfen, Hosting, Infrastruktur und Weiterentwicklung mitzufinanzieren. Danke für deine
|
||||||
Serverkosten und Weiterentwicklung. Danke für deine Unterstützung!
|
Unterstützung!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Trust */}
|
{/* Trust */}
|
||||||
<div className="mt-8 text-center">
|
<div className="mt-8 text-center">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
100% deiner Spende fliesst direkt in Serverkosten und Weiterentwicklung.
|
Beiträge werden nach Abzug allfälliger Zahlungsgebühren für Hosting, Infrastruktur und
|
||||||
<br />Kein Unternehmen, keine Investoren — nur ein Feuerwehrmann mit einer Idee.
|
Weiterentwicklung eingesetzt.
|
||||||
|
<br />Ein Projekt aus der Feuerwehr-Praxis — entwickelt in der Freizeit.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
<Link href="/">
|
<Link href="/">
|
||||||
|
|||||||
55
src/app/unterstuetzen/page.tsx
Normal file
55
src/app/unterstuetzen/page.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { Heart } from 'lucide-react'
|
||||||
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
|
import { legal } from '@/config/legal'
|
||||||
|
|
||||||
|
export default function UnterstuetzenPage() {
|
||||||
|
return (
|
||||||
|
<LegalPage
|
||||||
|
title="Freiwilliger Unterstützungsbeitrag"
|
||||||
|
version={legal.documents.terms.version}
|
||||||
|
publishedAt={legal.documents.terms.publishedAt}
|
||||||
|
draft={false}
|
||||||
|
intro={`${legal.projectName} wird grundsätzlich kostenlos angeboten. Freiwillige Beiträge helfen bei der Finanzierung von Hosting, Infrastruktur und Weiterentwicklung.`}
|
||||||
|
>
|
||||||
|
<section>
|
||||||
|
<p>
|
||||||
|
Ein Beitrag ist <strong>freiwillig</strong> und erfolgt ohne Anspruch auf eine bestimmte Gegenleistung.
|
||||||
|
Daraus entsteht insbesondere kein Anspruch auf Funktionen, Support, Verfügbarkeit, bevorzugte Behandlung
|
||||||
|
oder eine bestimmte Weiterentwicklung.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Zahlungs- und Transaktionsgebühren des eingesetzten Zahlungsanbieters (Stripe) können vom Beitrag
|
||||||
|
abgezogen werden. {legal.projectName} stellt keine steuerlich abzugsfähige Spendenbescheinigung aus,
|
||||||
|
solange keine entsprechende behördliche Anerkennung besteht.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Es handelt sich um eine <strong>einmalige Zahlung</strong>; es wird keine automatisch wiederkehrende
|
||||||
|
Zahlung eingerichtet. Angaben zur Zahlungsabwicklung enthält die{' '}
|
||||||
|
<a href="/datenschutz">Datenschutzerklärung</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Beitrag leisten</h2>
|
||||||
|
<p>Auf der Zahlungsseite kannst du einen Betrag wählen. Die Zahlung erfolgt über Stripe.</p>
|
||||||
|
<Link
|
||||||
|
href="/spenden"
|
||||||
|
className="not-prose inline-flex items-center gap-2 rounded-lg bg-red-600 hover:bg-red-700 text-white px-5 py-2.5 font-semibold no-underline print:hidden"
|
||||||
|
>
|
||||||
|
<Heart className="w-4 h-4" /> Zur Zahlungsseite
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Versehentliche Zahlung</h2>
|
||||||
|
<p>
|
||||||
|
Falls eine Zahlung versehentlich erfolgt ist, melde dich bitte unter <strong>{legal.supportEmail}</strong>{' '}
|
||||||
|
zur Prüfung einer Rückerstattung.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
66
src/app/verantwortungsvolle-nutzung/page.tsx
Normal file
66
src/app/verantwortungsvolle-nutzung/page.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { LegalPage } from '@/components/legal/legal-page'
|
||||||
|
import { legal } from '@/config/legal'
|
||||||
|
|
||||||
|
export default function VerantwortungsvolleNutzungPage() {
|
||||||
|
const d = legal.documents.responsibleUse
|
||||||
|
return (
|
||||||
|
<LegalPage
|
||||||
|
title="Verantwortungsvolle Nutzung"
|
||||||
|
version={d.version}
|
||||||
|
publishedAt={d.publishedAt}
|
||||||
|
intro={`${legal.projectName} ist ein unterstützendes Werkzeug. Diese Seite erklärt, wie es sicher und verantwortungsvoll eingesetzt wird — damit es im Einsatz zu keinen Missverständnissen kommt.`}
|
||||||
|
>
|
||||||
|
<section>
|
||||||
|
<h2>Was {legal.projectName} ist – und was nicht</h2>
|
||||||
|
<p>
|
||||||
|
{legal.projectName} hilft beim Erstellen, Verwalten, Visualisieren und Exportieren von Lage- und
|
||||||
|
Objektplänen sowie bei unterstützenden Berechnungen. Es ist <strong>kein Alarmierungssystem, keine
|
||||||
|
Leitstelle und kein Einsatzleitsystem</strong> und ersetzt keine behördlich vorgeschriebenen Unterlagen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Grundregeln für den Einsatz</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Haltet unabhängig von {legal.projectName} <strong>aktuelle Offline- und Notfallunterlagen</strong> bereit.</li>
|
||||||
|
<li>Verwendet {legal.projectName} <strong>nicht als einzige Informationsquelle</strong> für operative Entscheidungen.</li>
|
||||||
|
<li>Lasst Pläne, Adressen, Symbole, Distanzen und Berechnungen vor der operativen Verwendung durch <strong>fachkundige Personen prüfen</strong>.</li>
|
||||||
|
<li>Rechnet mit möglichen Störungen oder Nichtverfügbarkeit — es besteht keine garantierte Verfügbarkeit und kein SLA.</li>
|
||||||
|
<li>Erstellt regelmässig <strong>Exporte</strong> wichtiger Pläne als Rückfallebene.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Umgang mit sensiblen Daten</h2>
|
||||||
|
<p>
|
||||||
|
Speichert ohne separate schriftliche Vereinbarung <strong>keine besonders schützenswerten Daten</strong>
|
||||||
|
{' '}(z.B. Patienten-, Gesundheits-, Polizei-, Passwort-, Zugangs- oder Schlüsselcode-Daten). Auch reine
|
||||||
|
Objektinformationen können sicherheitsrelevant sein und dürfen nur berechtigten Personen zugänglich
|
||||||
|
gemacht werden. Details siehe <a href="/nutzungsbedingungen">Nutzungsbedingungen</a> und{' '}
|
||||||
|
<a href="/datenschutz">Datenschutzerklärung</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Aktualität von Karten und Berechnungen</h2>
|
||||||
|
<p>
|
||||||
|
Karten-, Adress- und Geodaten können unvollständig, ungenau oder veraltet sein. Berechnungen (z.B.
|
||||||
|
Distanzen, Druckverlust, Höhen) sind <strong>Richtwerte</strong> und ersetzen keine Lagebeurteilung.
|
||||||
|
Änderungen an Gebäuden, Zufahrten, Wasserbezugsstellen oder Gefahren müssen durch die Organisation
|
||||||
|
gepflegt werden.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Warum das wichtig ist</h2>
|
||||||
|
<p>
|
||||||
|
{legal.projectName} wird mit viel Eigenleistung entwickelt und Feuerwehren kostenlos zur Verfügung
|
||||||
|
gestellt. Eine verantwortungsvolle Nutzung sorgt dafür, dass das Projekt langfristig sicher und
|
||||||
|
kostenlos angeboten werden kann — und dass im Ernstfall keine falschen Erwartungen entstehen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</LegalPage>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -239,7 +239,7 @@ export function SettingsTab({ onNavigateTab }: SettingsTabProps) {
|
|||||||
<Mail className="w-5 h-5 text-primary" />
|
<Mail className="w-5 h-5 text-primary" />
|
||||||
E-Mail / SMTP Konfiguration
|
E-Mail / SMTP Konfiguration
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-muted-foreground mb-4">SMTP-Server für den E-Mail-Versand konfigurieren. Empfohlen: TLS auf Port 587. Passwörter werden verschlüsselt in der Datenbank gespeichert.</p>
|
<p className="text-sm text-muted-foreground mb-4">SMTP-Server für den E-Mail-Versand konfigurieren. Empfohlen: TLS auf Port 587. Zugangsdaten werden serverseitig gespeichert und im Interface maskiert.</p>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div><Label>SMTP Host</Label><Input value={smtpHost} onChange={e => setSmtpHost(e.target.value)} placeholder="smtp.gmail.com" /></div>
|
<div><Label>SMTP Host</Label><Input value={smtpHost} onChange={e => setSmtpHost(e.target.value)} placeholder="smtp.gmail.com" /></div>
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-2">
|
||||||
|
|||||||
91
src/components/legal/legal-page.tsx
Normal file
91
src/components/legal/legal-page.tsx
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { ArrowLeft, Printer } from 'lucide-react'
|
||||||
|
import { legal } from '@/config/legal'
|
||||||
|
|
||||||
|
/** Pflicht-Links, die im Footer jeder öffentlichen (Rechts-)Seite erscheinen. */
|
||||||
|
export const LEGAL_LINKS: { href: string; label: string }[] = [
|
||||||
|
{ href: '/impressum', label: 'Impressum' },
|
||||||
|
{ href: '/datenschutz', label: 'Datenschutz' },
|
||||||
|
{ href: '/nutzungsbedingungen', label: 'Nutzungsbedingungen' },
|
||||||
|
{ href: '/verantwortungsvolle-nutzung', label: 'Verantwortungsvolle Nutzung' },
|
||||||
|
{ href: '/sicherheit', label: 'Sicherheit' },
|
||||||
|
{ href: '/organisationen/datenschutzvereinbarung', label: 'Datenschutzvereinbarung (Org.)' },
|
||||||
|
{ href: '/unterstuetzen', label: 'Unterstützen' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export function LegalFooterLinks() {
|
||||||
|
return (
|
||||||
|
<nav aria-label="Rechtliche Seiten" className="mt-10 border-t border-border pt-6 print:hidden">
|
||||||
|
<ul className="flex flex-wrap gap-x-4 gap-y-2 text-sm text-muted-foreground">
|
||||||
|
{LEGAL_LINKS.map(l => (
|
||||||
|
<li key={l.href}>
|
||||||
|
<Link href={l.href} className="hover:text-foreground underline underline-offset-2">{l.label}</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LegalPageProps {
|
||||||
|
title: string
|
||||||
|
/** Versionsangabe, z.B. legal.documents.terms.version */
|
||||||
|
version?: string
|
||||||
|
/** Veröffentlichungsdatum ISO */
|
||||||
|
publishedAt?: string
|
||||||
|
/** Als sorgfältiger Entwurf kennzeichnen (juristisch noch nicht geprüft) */
|
||||||
|
draft?: boolean
|
||||||
|
/** Kurzer Einleitungssatz unter dem Titel */
|
||||||
|
intro?: string
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Einheitliche, responsive, druckbare Hülle für alle öffentlichen Rechtsseiten.
|
||||||
|
* Enthält Zurück-Link, Drucken-Button, Version/Datum, Entwurfshinweis und die Pflicht-Footer-Links.
|
||||||
|
*/
|
||||||
|
export function LegalPage({ title, version, publishedAt, draft = true, intro, children }: LegalPageProps) {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background px-4 py-10 print:py-0 print:bg-white">
|
||||||
|
<div className="max-w-3xl mx-auto">
|
||||||
|
<div className="flex items-center justify-between mb-6 print:hidden">
|
||||||
|
<Link href="/" className="text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1">
|
||||||
|
<ArrowLeft className="w-3.5 h-3.5" /> Zur Startseite
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
onClick={() => window.print()}
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<Printer className="w-3.5 h-3.5" /> Drucken
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article className="bg-card rounded-xl border border-border shadow-sm p-6 md:p-10 print:border-0 print:shadow-none print:p-0">
|
||||||
|
<h1 className="text-3xl font-bold text-foreground">{title}</h1>
|
||||||
|
|
||||||
|
<div className="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground">
|
||||||
|
{version && <span>Version {version}</span>}
|
||||||
|
{publishedAt && <span>· Stand: {publishedAt}</span>}
|
||||||
|
<span>· {legal.projectName} ({legal.siteDomain})</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{intro && <p className="mt-4 text-sm text-muted-foreground leading-relaxed">{intro}</p>}
|
||||||
|
|
||||||
|
{draft && (
|
||||||
|
<div className="mt-4 rounded-lg border border-amber-300 bg-amber-50 dark:bg-amber-950/30 dark:border-amber-800 px-4 py-3 text-sm text-amber-800 dark:text-amber-300">
|
||||||
|
<strong>Sorgfältiger Entwurf.</strong> {legal.draftNotice}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="legal-prose mt-6 space-y-6 text-sm leading-relaxed text-muted-foreground [&_h2]:text-lg [&_h2]:font-semibold [&_h2]:text-foreground [&_h2]:mb-2 [&_h2]:mt-2 [&_h3]:font-semibold [&_h3]:text-foreground [&_strong]:text-foreground [&_a]:text-red-600 [&_a]:underline [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:space-y-1 [&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:space-y-1">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<LegalFooterLinks />
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
164
src/config/legal.ts
Normal file
164
src/config/legal.ts
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/**
|
||||||
|
* Zentrale, typisierte Betreiber- und Rechtskonfiguration für Lageplan.
|
||||||
|
*
|
||||||
|
* WARUM: Rechtliche Angaben (Betreiber, Kontakt, Serverstandort, Dokumentversionen)
|
||||||
|
* dürfen NICHT an mehreren Stellen widersprüchlich hartcodiert werden. Alle Legal-Seiten,
|
||||||
|
* das Impressum, die Datenschutzerklärung, der Consent-Flow und die Export-Footer lesen
|
||||||
|
* ihre Angaben aus dieser einen Quelle.
|
||||||
|
*
|
||||||
|
* PLATZHALTER: Felder, die der Betreiber rechtlich verbindlich festlegen muss, tragen als
|
||||||
|
* Default einen deutlich sichtbaren Platzhalter im Format `[NAME]`. Diese Platzhalter dürfen
|
||||||
|
* NICHT stillschweigend durch erfundene Werte ersetzt werden. Setze die echten Werte über
|
||||||
|
* Umgebungsvariablen (siehe unten) oder trage sie hier direkt ein, sobald sie feststehen.
|
||||||
|
*
|
||||||
|
* VALIDIERUNG: `assertLegalConfig()` warnt in Development und beim Build, wenn Pflichtangaben
|
||||||
|
* noch Platzhalter sind. In Produktion werden Platzhalter in der UI als solche kenntlich
|
||||||
|
* gemacht (siehe `isPlaceholder()`), damit nie ein erfundener Wert als echt erscheint.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Präfix, an dem ein noch nicht ausgefüllter Pflichtwert erkannt wird. */
|
||||||
|
const PLACEHOLDER_PREFIX = '['
|
||||||
|
|
||||||
|
/** True, wenn der Wert noch ein unausgefüllter Platzhalter ist. */
|
||||||
|
export function isPlaceholder(value: string | null | undefined): boolean {
|
||||||
|
return !value || (value.trim().startsWith(PLACEHOLDER_PREFIX) && value.trim().endsWith(']'))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Liest eine Umgebungsvariable, fällt sonst auf den Platzhalter/Default zurück. */
|
||||||
|
function env(name: string, fallback: string): string {
|
||||||
|
const v = process.env[name]
|
||||||
|
return v && v.trim().length > 0 ? v.trim() : fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExternalProcessor {
|
||||||
|
/** Anzeigename des Dienstleisters */
|
||||||
|
name: string
|
||||||
|
/** Zweck der Bearbeitung */
|
||||||
|
purpose: string
|
||||||
|
/** Verarbeitete Datenarten (grob) */
|
||||||
|
data: string
|
||||||
|
/** Sitz / relevante Verarbeitungsregion, soweit bekannt; sonst Platzhalter */
|
||||||
|
region: string
|
||||||
|
/** true, wenn der Dienst nur bei Bedarf/optionaler Konfiguration aktiv ist */
|
||||||
|
optional?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LegalDocumentMeta {
|
||||||
|
/** Interne, bewusst gesetzte Versionsangabe (nicht automatisch aus Dateiänderung ableiten!) */
|
||||||
|
version: string
|
||||||
|
/** Veröffentlichungsdatum ISO (YYYY-MM-DD) */
|
||||||
|
publishedAt: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const legal = {
|
||||||
|
// ─── Betreiber ─────────────────────────────────────────────
|
||||||
|
/** Anzeigename des Projekts */
|
||||||
|
projectName: 'Lageplan',
|
||||||
|
/**
|
||||||
|
* Rechtlich verbindlicher Name des Betreibers. Im Repository wird das Projekt öffentlich
|
||||||
|
* "Pepe Ziberi / Purepixel" zugeschrieben; die rechtsverbindliche Bezeichnung inkl.
|
||||||
|
* Rechtsform muss der Betreiber bestätigen.
|
||||||
|
*/
|
||||||
|
operatorName: env('LEGAL_OPERATOR_NAME', '[RECHTLICHER NAME DES BETREIBERS]'),
|
||||||
|
/** Rechtsform (z.B. Einzelunternehmen, Verein, GmbH) – muss festgelegt werden */
|
||||||
|
operatorLegalForm: env('LEGAL_OPERATOR_FORM', '[RECHTSFORM]'),
|
||||||
|
/** Vollständige Postadresse des Betreibers */
|
||||||
|
postalAddress: env('LEGAL_POSTAL_ADDRESS', '[POSTADRESSE]'),
|
||||||
|
|
||||||
|
// ─── Kontakt ───────────────────────────────────────────────
|
||||||
|
/** Allgemeine Support-/Kontaktadresse (im Repo öffentlich verwendet) */
|
||||||
|
supportEmail: env('LEGAL_SUPPORT_EMAIL', 'app@lageplan.ch'),
|
||||||
|
/**
|
||||||
|
* Datenschutz-Kontakt. Default = im Repository bereits verwendete Adresse
|
||||||
|
* (nicht erfunden). Der Betreiber muss bestätigen, dass dieses Postfach aktiv überwacht wird.
|
||||||
|
*/
|
||||||
|
privacyContactEmail: env('LEGAL_PRIVACY_EMAIL', 'datenschutz@lageplan.ch'),
|
||||||
|
|
||||||
|
// ─── Domains ───────────────────────────────────────────────
|
||||||
|
siteDomain: env('LEGAL_SITE_DOMAIN', 'lageplan.ch'),
|
||||||
|
appDomain: env('LEGAL_APP_DOMAIN', 'app.lageplan.ch'),
|
||||||
|
|
||||||
|
// ─── Recht & Gerichtsstand ────────────────────────────────
|
||||||
|
country: 'Schweiz',
|
||||||
|
governingLaw: 'Schweizer Recht',
|
||||||
|
/** Gerichtsstand nur angeben, wenn juristisch sinnvoll/bestätigt; sonst Platzhalter. */
|
||||||
|
jurisdiction: env('LEGAL_JURISDICTION', '[GERICHTSSTAND]'),
|
||||||
|
|
||||||
|
// ─── Infrastruktur ────────────────────────────────────────
|
||||||
|
/** Hostinganbieter – muss bestätigt werden (im Repo nicht eindeutig belegt) */
|
||||||
|
hostingProvider: env('LEGAL_HOSTING_PROVIDER', '[HOSTINGANBIETER]'),
|
||||||
|
/** Serverstandort – muss für ALLE Anbieter, Backups und Logs bestätigt werden */
|
||||||
|
serverLocation: env('LEGAL_SERVER_LOCATION', '[SERVERSTANDORT]'),
|
||||||
|
/** Aufbewahrungsfrist von Sicherungskopien – muss festgelegt werden */
|
||||||
|
backupRetention: env('LEGAL_BACKUP_RETENTION', '[BACKUP-AUFBEWAHRUNGSFRIST]'),
|
||||||
|
|
||||||
|
// ─── Externe Dienstleister (Ist-Zustand aus dem Code abgeleitet) ──
|
||||||
|
// Nichts erfinden: nur tatsächlich im Code kontaktierte Dienste. Sitz/Region, die nicht
|
||||||
|
// sicher bekannt ist, bleibt Platzhalter.
|
||||||
|
processors: [
|
||||||
|
{ name: 'OpenStreetMap (Tiles)', purpose: 'Basiskarte', data: 'Kachel-Koordinaten (Kartenausschnitt)', region: '[REGION – OSM Foundation, EU/UK]' },
|
||||||
|
{ name: 'Esri ArcGIS World Imagery', purpose: 'Satellitenkarte', data: 'Kachel-Koordinaten', region: '[REGION]' },
|
||||||
|
{ name: 'swisstopo (geo.admin.ch)', purpose: 'Schweizer Landeskarte', data: 'Kachel-Koordinaten', region: 'Schweiz' },
|
||||||
|
{ name: 'Nominatim (OpenStreetMap)', purpose: 'Adress-/Reverse-Geocoding', data: 'Adress-/Ortssuche, GPS-Koordinaten', region: '[REGION – OSM Foundation]' },
|
||||||
|
{ name: 'Open-Meteo', purpose: 'Wind- und Höhendaten', data: 'Koordinaten', region: '[REGION – EU]' },
|
||||||
|
{ name: 'Open-Elevation', purpose: 'Höhendaten (Fallback)', data: 'Koordinaten', region: '[REGION]' },
|
||||||
|
{ name: 'Stripe', purpose: 'Zahlungsabwicklung freiwilliger Unterstützungsbeiträge', data: 'Betrag, freiwilliger Name/Nachricht, Zahlungsdaten (direkt bei Stripe)', region: '[REGION – u.a. USA/EU; Auslandbearbeitung möglich]', optional: true },
|
||||||
|
{ name: 'SMTP-/E-Mail-Anbieter', purpose: 'System-E-Mails (Verifizierung, Reset, Kontakt, Einladungen)', data: 'E-Mail-Adresse, Nachrichteninhalt', region: '[REGION – abhängig vom konfigurierten Anbieter]', optional: true },
|
||||||
|
{ name: 'MinIO (Objektspeicher)', purpose: 'Datei-/Bild-Uploads (Pläne, Logos, Symbole)', data: 'hochgeladene Dateien', region: '[SERVERSTANDORT]' },
|
||||||
|
{ name: 'PostgreSQL (Datenbank)', purpose: 'Primäre Datenhaltung', data: 'Konto-, Organisations-, Plan- und Journaldaten', region: '[SERVERSTANDORT]' },
|
||||||
|
] as ExternalProcessor[],
|
||||||
|
|
||||||
|
// ─── Rechtsdokumente: bewusst gesetzte Versionen ──────────
|
||||||
|
// WICHTIG: Version manuell erhöhen, wenn sich der Inhalt WESENTLICH ändert (löst Re-Consent aus).
|
||||||
|
// Nicht automatisch aus minimalen Dateiänderungen ableiten.
|
||||||
|
documents: {
|
||||||
|
terms: { version: '1.0.0-draft', publishedAt: '2026-07-23' },
|
||||||
|
privacy: { version: '1.0.0-draft', publishedAt: '2026-07-23' },
|
||||||
|
organizationDeclaration: { version: '1.0.0-draft', publishedAt: '2026-07-23' },
|
||||||
|
responsibleUse: { version: '1.0.0-draft', publishedAt: '2026-07-23' },
|
||||||
|
dataProcessingAgreement: { version: '1.0.0-draft', publishedAt: '2026-07-23' },
|
||||||
|
} as Record<string, LegalDocumentMeta>,
|
||||||
|
|
||||||
|
/** Hinweis, der auf allen sorgfältig erstellten, aber juristisch ungeprüften Texten steht. */
|
||||||
|
draftNotice:
|
||||||
|
'Diese rechtlichen und organisatorischen Unterlagen wurden nach bestem Wissen erstellt. ' +
|
||||||
|
'Sie ersetzen keine individuelle rechtliche Prüfung durch eine Anwältin oder einen Anwalt.',
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** Pflichtfelder, die vor Produktivbetrieb ausgefüllt sein müssen. */
|
||||||
|
const REQUIRED_FIELDS: { key: string; value: string }[] = [
|
||||||
|
{ key: 'operatorName', value: legal.operatorName },
|
||||||
|
{ key: 'operatorLegalForm', value: legal.operatorLegalForm },
|
||||||
|
{ key: 'postalAddress', value: legal.postalAddress },
|
||||||
|
{ key: 'privacyContactEmail', value: legal.privacyContactEmail },
|
||||||
|
{ key: 'hostingProvider', value: legal.hostingProvider },
|
||||||
|
{ key: 'serverLocation', value: legal.serverLocation },
|
||||||
|
{ key: 'backupRetention', value: legal.backupRetention },
|
||||||
|
]
|
||||||
|
|
||||||
|
/** Liste der noch offenen Pflichtangaben (Platzhalter). */
|
||||||
|
export function missingLegalFields(): string[] {
|
||||||
|
return REQUIRED_FIELDS.filter(f => isPlaceholder(f.value)).map(f => f.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warnt beim Build/Start, wenn Pflichtangaben noch Platzhalter sind.
|
||||||
|
* Bricht den Build NICHT ab (damit Entwicklung möglich bleibt), macht das Risiko aber sichtbar.
|
||||||
|
*/
|
||||||
|
export function assertLegalConfig(): void {
|
||||||
|
const missing = missingLegalFields()
|
||||||
|
if (missing.length > 0) {
|
||||||
|
const msg = `⚠️ [legal.ts] Offene rechtliche Pflichtangaben (noch Platzhalter): ${missing.join(', ')}. ` +
|
||||||
|
`Bitte in src/config/legal.ts bzw. via Umgebungsvariablen (LEGAL_*) setzen, bevor produktiv gegangen wird.`
|
||||||
|
// In Produktion als Fehler-Log, in Dev als Warnung — nie stillschweigend.
|
||||||
|
if (process.env.NODE_ENV === 'production') console.error(msg)
|
||||||
|
else console.warn(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beim Laden der Konfiguration einmalig prüfen (serverseitig).
|
||||||
|
if (typeof window === 'undefined') {
|
||||||
|
assertLegalConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LegalConfig = typeof legal
|
||||||
Reference in New Issue
Block a user