MBO-Tech-IT-Webseite/modules/03-analytics/TEMPLATE.md

182 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Modul: Analytics (Seitenaufrufe + Phone-Click-Tracking)
> DSGVO-konformes Tracking ohne externe Dienste: Seitenaufrufe mit Verweildauer, Browser/OS/Gerät-Erkennung, anonymisierte IP (letztes IPv4-Oktett → 0). Zusätzlich automatisches Tracking aller `tel:`-Link-Klicks nach Quelle/Element. Admin-Dashboard mit KPI-Cards, Zeitreihen und Top-Seiten.
---
## Enthaltene Dateien
| Ziel im neuen Projekt | Inhalt |
|---|---|
| `lib/analytics.ts` | Bot-Filter, IP-Anonymisierung, Device/Browser/OS-Parser |
| `components/analytics/PageTracker.tsx` | Client-Komponente: Seitenaufruf + Verweildauer + Phone-Click-Tracking |
| `app/api/analytics/track/route.ts` | POST: Seitenaufruf speichern (öffentlich, kein Auth) |
| `app/api/analytics/track-phone-click/route.ts` | POST: Telefon-Click speichern (öffentlich) |
| `app/api/admin/analytics/phone-calls/route.ts` | GET: Aggregierte Phone-Click-Daten (requireAdmin) |
| `app/admin/analytics/page.tsx` | Admin-Dashboard mit Tabs: Seitenaufrufe + Phone-Calls |
| `migrations/MIGRATIONS_PAGE_VIEWS.sql` | Tabelle `page_views` |
| `migrations/MIGRATIONS_PHONE_CLICKS.sql` | Tabelle `phone_clicks` |
---
## Voraussetzungen
Keine zusätzlichen npm-Pakete. Benötigt:
- `lib/supabase.ts` (Service Client)
- `lib/admin-auth.ts` (für `requireAdmin` im Admin-Endpunkt, aus Modul 02)
---
## Umgebungsvariablen
Keine zusätzlichen. Nutzt bestehende Supabase-Variablen.
---
## Datenbank-Migrationen (Supabase)
```
migrations/MIGRATIONS_PAGE_VIEWS.sql → Tabelle page_views
migrations/MIGRATIONS_PHONE_CLICKS.sql → Tabelle phone_clicks
```
Tabellen-Übersicht:
```
page_views: path, timestamp, ip_anon, device_type, browser, os, referrer, session_id, duration_ms, is_bot
phone_clicks: phone_number, source_page, source_element, session_id, ip_anonymized, device_type, browser, os, timestamp
```
Supabase-Typen (`lib/supabase.ts`) ergänzen:
```ts
page_views: { Row: { id: string; path: string; timestamp: string; ip_anon: string | null; device_type: string | null; browser: string | null; os: string | null; referrer: string | null; session_id: string; duration_ms: number | null; is_bot: boolean } }
phone_clicks: { Row: { id: number; phone_number: string; source_page: string; source_element: string; session_id: string | null; ip_anonymized: string | null; device_type: string | null; browser: string | null; os: string | null; timestamp: string } }
```
---
## Einbindung Schritt für Schritt
### 1. Dateien kopieren
### 2. PageTracker in Root-Layout einbinden (`app/layout.tsx`)
```tsx
import { PageTracker } from "@/components/analytics/PageTracker";
export default function RootLayout({ children }) {
return (
<html>
<body>
<PageTracker />
{children}
</body>
</html>
);
}
```
### 3. Tel-Links mit `data-source-element` versehen
Der PageTracker hört automatisch auf Klicks von `<a href="tel:...">`. Damit die Quelle erfasst wird, muss das Attribut gesetzt sein:
```tsx
<a href="tel:+49123456789" data-source-element="header">Anrufen</a>
```
Empfohlene Element-Namen (Konvention: lowercase, kebab-case):
- `header`, `footer`, `hero`, `cta-banner`, `kontakt-form`, `sidebar`
### 4. Admin-Dashboard verlinken
```tsx
// In Admin-Navigation
<Link href="/admin/analytics">Analytics</Link>
```
### 5. Admin-Routen aus Tracking ausschließen
`PageTracker.tsx` filtert bereits `/admin/*` und `/api/*` keine Anpassung nötig.
---
## Anpassungspunkte
| Was | Wo |
|---|---|
| Ausgeschlossene Pfade | `components/analytics/PageTracker.tsx``EXCLUDED_PATHS` |
| Datenaufbewahrung (13 Monate) | Supabase Cron: `DELETE FROM page_views WHERE timestamp < now() - interval '13 months'` |
| Bot-Filter-Pattern | `lib/analytics.ts``BOT_PATTERNS` Array |
| Dashboard-Zeiträume | `app/admin/analytics/page.tsx` → Filter-Buttons |
| Geo-Lookup aktivieren | `app/api/analytics/track-phone-click/route.ts``GEO_LOOKUP_ENABLED` env var |
---
## Integrations-Prompt
Kopiere diesen Prompt in eine neue KI-Konversation, nachdem du die `files/` in dein Projekt kopiert hast. Ersetze alle `[PLATZHALTER]`.
```
Ich integriere das Analytics-Modul (DSGVO-konforme Seitenaufrufe + Phone-Click-Tracking) in mein Next.js/Supabase-Projekt.
PROJEKT-KONTEXT:
- Admin-Auth-Modul (02) ist bereits integriert (requireAdmin verfügbar)
- lib/supabase.ts mit Service Client vorhanden
- Admin-Bereich unter /admin
BEREITS KOPIERTE DATEIEN (aus modules/03-analytics/files/):
- lib/analytics.ts
- components/analytics/PageTracker.tsx
- app/api/analytics/track/route.ts
- app/api/analytics/track-phone-click/route.ts
- app/api/admin/analytics/phone-calls/route.ts
- app/admin/analytics/page.tsx
AUFGABEN führe sie der Reihe nach aus:
1. SUPABASE-MIGRATIONEN: Führe diese SQLs im Supabase SQL-Editor aus:
-- Aus migrations/MIGRATIONS_PAGE_VIEWS.sql:
CREATE TABLE IF NOT EXISTS page_views (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
path text NOT NULL, timestamp timestamptz NOT NULL DEFAULT now(),
ip_anon text, device_type text CHECK (device_type IN ('desktop','tablet','mobile')),
browser text, os text, referrer text,
session_id text NOT NULL, duration_ms int, is_bot boolean NOT NULL DEFAULT false
);
CREATE INDEX IF NOT EXISTS idx_pv_timestamp ON page_views (timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_pv_path ON page_views (path);
CREATE INDEX IF NOT EXISTS idx_pv_session ON page_views (session_id);
ALTER TABLE page_views ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Service-Role Vollzugriff" ON page_views USING (true) WITH CHECK (true);
-- Aus migrations/MIGRATIONS_PHONE_CLICKS.sql:
CREATE TABLE IF NOT EXISTS phone_clicks (
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
phone_number TEXT NOT NULL, source_page TEXT NOT NULL,
source_element TEXT NOT NULL, session_id TEXT, ip_anonymized TEXT,
device_type TEXT, browser TEXT, os TEXT, timestamp TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_phone_clicks_timestamp ON phone_clicks(timestamp DESC);
ALTER TABLE phone_clicks DISABLE ROW LEVEL SECURITY;
2. SUPABASE-TYPEN: Lies lib/supabase.ts und ergänze in Database.public.Tables:
page_views: { Row: { id: string; path: string; timestamp: string; ip_anon: string | null; device_type: string | null; browser: string | null; os: string | null; referrer: string | null; session_id: string; duration_ms: number | null; is_bot: boolean } }
phone_clicks: { Row: { id: number; phone_number: string; source_page: string; source_element: string; session_id: string | null; ip_anonymized: string | null; device_type: string | null; browser: string | null; os: string | null; timestamp: string } }
3. PAGE-TRACKER einbinden: Lies app/layout.tsx.
Füge den Import und die Komponente im <body> hinzu (vor {children}):
import { PageTracker } from "@/components/analytics/PageTracker";
// Im JSX:
<PageTracker />
4. TEL-LINKS mit Tracking versehen: Suche im gesamten Projekt nach href="tel:
Füge bei jedem gefundenen Link das Attribut data-source-element="[ELEMENT_NAME]" hinzu.
Konvention für [ELEMENT_NAME]: header, footer, hero, cta-banner, kontakt-form (lowercase, kebab-case)
5. ADMIN-NAV ergänzen: Lies die Admin-Navigations-Datei (meist components/admin/AdminNav.tsx).
Füge einen Link zu /admin/analytics hinzu.
6. TEST:
a) Dev-Server starten, /kontakt oder eine andere Seite aufrufen
b) Supabase → Table page_views → neuer Eintrag sollte erscheinen
c) Auf eine Telefonnummer klicken → Supabase → Table phone_clicks → neuer Eintrag
d) /admin/analytics aufrufen → KPI-Cards sollten Daten zeigen
Lies jede Datei vor dem Bearbeiten. Melde wenn alle Schritte abgeschlossen sind.
```