Files
anouma/globals/AnalyticsSettings.ts
T
maro 65b6eeac51 Add privacy-friendly analytics and cookie consent, integrated into the CMS
Adds a first-party analytics system with no third-party trackers and no
persistent per-visitor identifiers: events are grouped into sessions via a
daily-rotating pseudonymous hash (IP+UA+host, HMAC-salted, never stored raw).

- New "Analytics" section in the Payload admin, gated by a canViewAnalytics
  permission on Users, following the existing custom-admin-view pattern
  used by the calendar feature
- Sessions, page views, unique visitors, top/entry/exit pages, events,
  device/browser breakdown, date range filter with period comparison
- Raw events and daily aggregate rollups as their own collections, with
  configurable retention and a cron endpoint that rolls up before purging
- Cookie consent banner (necessary/preferences/statistics) with categories
  and copy editable from a new CMS global; a track() helper that is a
  complete no-op without statistics consent, so nothing is ever sent
  before a visitor opts in
- track() calls wired into the booking flow, contact form, and navigation
2026-09-06 21:59:59 +02:00

46 lines
1.3 KiB
TypeScript

import type { GlobalConfig } from "payload";
import { canViewAnalytics, isAdmin } from "@/access";
/**
* Retention configuration for the analytics system, enforced by the nightly
* cleanup cron (lib/analytics/cleanup.ts) and shown in the "Analytics &
* Datenschutz" panel of the dashboard (components/admin/AdminAnalyticsView.tsx).
*/
export const AnalyticsSettings: GlobalConfig = {
slug: "analytics-settings",
label: "Analytics-Einstellungen",
admin: {
description: "Aufbewahrungsdauer für Analytics-Rohdaten und aggregierte Tagesstatistiken.",
group: "Datenschutz",
},
access: {
read: canViewAnalytics,
update: isAdmin,
},
fields: [
{
name: "rawRetentionDays",
type: "number",
label: "Rohdaten-Aufbewahrung (Tage)",
required: true,
defaultValue: 90,
min: 7,
admin: {
description:
"Wie lange einzelne Analytics-Events gespeichert bleiben. Begrenzt auch den wählbaren Zeitraum im Analytics-Dashboard.",
},
},
{
name: "aggregateRetentionMonths",
type: "number",
label: "Aggregat-Aufbewahrung (Monate)",
required: true,
defaultValue: 12,
min: 1,
admin: {
description: "Wie lange die täglichen Aggregat-Statistiken (ohne Einzel-Events) gespeichert bleiben.",
},
},
],
};