Reviewer's follow-up: it's not enough to record when a user accepted the Terms; we also need to record which version of the text they saw. Changes: - journal.users gains a nullable `terms_version` text column (nullable so the three pre-existing users without a version are kept as-is). - New apps/journal/app/lib/legal.ts exports TERMS_VERSION as a single source of truth, reused by the legal pages' "Last updated" header and by the registration flow as the value to send/store. - Registration form posts `termsVersion` alongside `termsAccepted` on all three relevant steps (start, finish, register-magic-link). - API route validates that `termsVersion` is a non-empty string on any step that requires terms, and forwards it to the auth server. - auth.server finishRegistration and registerWithMagicLink now take `termsVersion` and persist it on the users row. - journal-auth spec gets a new scenario for version storage and a rejection scenario for missing version. PRIVACY_LAST_UPDATED is also exported from the same module and used by the Privacy page header, keeping both pages on a single legal.ts source of truth for "last updated" labels. Privacy is not per-user stored — it's informational, not contract. Existing users have NULL terms_version; if we ever prompt them to re-accept updated Terms, we can backfill with the version they re-accept at that point. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
229 lines
9.9 KiB
TypeScript
229 lines
9.9 KiB
TypeScript
import { TERMS_VERSION } from "~/lib/legal";
|
||
|
||
export function meta() {
|
||
return [
|
||
{ title: "Nutzungsbedingungen — trails.cool" },
|
||
{ name: "robots", content: "noindex" },
|
||
];
|
||
}
|
||
|
||
export default function TermsPage() {
|
||
return (
|
||
<div className="mx-auto max-w-2xl px-4 py-12">
|
||
<h1 className="text-3xl font-bold text-gray-900">
|
||
Nutzungsbedingungen / Terms of Service
|
||
</h1>
|
||
<p className="mt-2 text-sm text-gray-500">
|
||
Stand / Last updated: {TERMS_VERSION} • Alpha — subject to change. Die
|
||
deutsche Fassung ist maßgeblich. The German version is authoritative;
|
||
English summaries follow each section.
|
||
</p>
|
||
|
||
<section className="mt-10 space-y-6 text-gray-700">
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
1. Gegenstand und Alpha-Status
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
trails.cool ist ein experimenteller, derzeit kostenloser Dienst zur Planung
|
||
und Dokumentation von Outdoor-Aktivitäten. Der Dienst befindet sich
|
||
in aktiver Entwicklung (Alpha). Funktionen, Schnittstellen und
|
||
gespeicherte Daten können jederzeit ohne Vorankündigung geändert,
|
||
unterbrochen, gelöscht oder eingestellt werden. Eine
|
||
Verfügbarkeitsgarantie besteht nicht.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> trails.cool is an experimental service,
|
||
currently free of charge, in
|
||
active alpha development. Features, data, and availability can
|
||
change at any time without notice. No availability is guaranteed.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
2. Mindestalter
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Die Nutzung eines Journal-Kontos ist erst ab einem Alter von 16
|
||
Jahren zulässig. Anonyme Nutzung des Planners unterliegt keiner
|
||
Altersbeschränkung.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> A Journal account is available only to users
|
||
aged 16 or older. Anonymous use of the Planner has no age
|
||
requirement.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
3. Dienstverfügbarkeit
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Der Betreiber kann den Dienst jederzeit ändern, einschränken,
|
||
unterbrechen oder einstellen, auch einzelne Funktionen oder
|
||
einzelne Konten. Wartungs- und Ausfallzeiten sind möglich.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> The operator may modify, limit, interrupt, or
|
||
discontinue the service (or parts of it, or individual accounts)
|
||
at any time. Downtime and maintenance windows may occur.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
4. Zurücksetzen der Datenbank
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Während der Alpha-Phase behält sich der Betreiber ausdrücklich das
|
||
Recht vor, die gesamte Datenbank zurückzusetzen oder einzelne
|
||
Datensätze ohne vorherige Benachrichtigung zu löschen.
|
||
Nutzer:innen sollten wichtige Routen und Aktivitäten selbstständig
|
||
über die Export-Funktion (GPX bzw. JSON) sichern.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> During alpha, the operator may reset the entire
|
||
database or delete individual records without notice. Back up
|
||
anything important via the GPX / JSON export.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
5. Eigenverantwortung für Daten
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Nutzer:innen sind für die Sicherung ihrer Inhalte selbst
|
||
verantwortlich. GPX- und JSON-Exporte sind im Journal jederzeit
|
||
für jede Route und Aktivität verfügbar. Der Betreiber schuldet
|
||
keine Datenwiederherstellung.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> You are responsible for backing up your own
|
||
content. Exports are always available in the Journal; the
|
||
operator owes no data recovery.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
6. Inhalte und Nutzungsrechte
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Die von Ihnen eingestellten Inhalte (Routen, Aktivitäten,
|
||
Beschreibungen, GPX-Dateien) bleiben Ihr Eigentum. Sie räumen dem
|
||
Betreiber lediglich das einfache, nicht übertragbare Recht ein,
|
||
diese Inhalte zum Zweck des Betriebs des Dienstes zu speichern,
|
||
zu verarbeiten und Ihnen wieder anzuzeigen. Eine darüber
|
||
hinausgehende Nutzung, Veröffentlichung oder Weitergabe findet
|
||
nicht statt.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> You retain ownership of everything you upload.
|
||
You grant the operator a limited, non-transferable licence to
|
||
store, process, and display your content solely for operating the
|
||
service; no other use, publication, or sharing.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
7. Nutzungsregeln
|
||
</h2>
|
||
<ul className="mt-2 ml-6 list-disc space-y-1 text-sm">
|
||
<li>Keine Verbreitung rechtswidriger Inhalte</li>
|
||
<li>
|
||
Keine missbräuchliche Nutzung (Spam, hochfrequente automatisierte
|
||
Abfragen, Denial-of-Service)
|
||
</li>
|
||
<li>Kein Umgehen technischer Schutzmaßnahmen</li>
|
||
<li>Kein massenhaftes automatisiertes Auslesen von Daten</li>
|
||
</ul>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> No illegal content, no abuse (spam, flooding,
|
||
DoS), no circumvention of technical protections, no bulk
|
||
automated data extraction.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
8. Kontobeendigung
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Sie können Ihr Konto jederzeit über die Einstellungen löschen;
|
||
damit werden auch die zugehörigen Inhalte gelöscht. Der Betreiber
|
||
kann Konten bei Verstößen gegen diese Bedingungen nach
|
||
angemessener Interessenabwägung sperren oder löschen.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> Delete your account (and its content) any time
|
||
via settings. The operator may suspend or delete accounts that
|
||
violate these terms, balancing interests reasonably.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
9. Haftung
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Der Dienst wird ohne Gewährleistung bereitgestellt. Der Betreiber
|
||
haftet uneingeschränkt bei Vorsatz und grober Fahrlässigkeit sowie
|
||
bei Verletzung von Leben, Körper oder Gesundheit. Im Übrigen ist
|
||
die Haftung für leicht fahrlässige Pflichtverletzungen auf den
|
||
vertragstypischen, vorhersehbaren Schaden bei Verletzung
|
||
wesentlicher Vertragspflichten (Kardinalpflichten) begrenzt. Eine
|
||
darüber hinausgehende Haftung – insbesondere für Datenverlust –
|
||
ist ausgeschlossen, soweit gesetzlich zulässig.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> No warranty. Unlimited liability for intent,
|
||
gross negligence, and injury to life, body, or health. For
|
||
slight negligence, liability is limited to foreseeable damages
|
||
arising from breach of material contractual duties. Liability
|
||
beyond that — in particular for data loss — is excluded to the
|
||
extent permitted by law.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
10. Änderungen der Bedingungen
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Diese Nutzungsbedingungen können sich während der Alpha-Phase
|
||
ändern. Bei wesentlichen Änderungen werden registrierte
|
||
Nutzer:innen per E-Mail informiert und müssen die neuen
|
||
Bedingungen erneut bestätigen.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> These terms may change during alpha. Registered
|
||
users will be emailed about material changes and prompted to
|
||
re-accept.
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h2 className="text-lg font-semibold text-gray-900">
|
||
11. Anwendbares Recht
|
||
</h2>
|
||
<p className="mt-2 text-sm">
|
||
Es gilt deutsches Recht unter Ausschluss des UN-Kaufrechts. Für
|
||
Verbraucher:innen mit gewöhnlichem Aufenthalt in einem Mitgliedstaat
|
||
der Europäischen Union bleibt der zwingende Schutz des Rechts ihres
|
||
Aufenthaltslandes unberührt.
|
||
</p>
|
||
<p className="mt-2 text-xs text-gray-600">
|
||
<em>English.</em> German law applies, excluding the UN Convention
|
||
on Contracts for the International Sale of Goods. Consumers
|
||
habitually residing in an EU member state retain the mandatory
|
||
protection of their national law.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
);
|
||
}
|