Symfony 8 SPA with Doctrine ORM, Symfony Security, vanilla JS frontend. Migrated from plain PHP (delight-im/auth + raw SQL) to full Symfony stack. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
Design: Registrierung & Einladungssystem
Datum: 2026-04-21
Status: Approved
Ziel
Zieltracker für Freunde und Familie öffnen: Registrierung nur per Einladungslink, Passwort-Reset per E-Mail, Referral-Tracking pro User.
1. Konfiguration (config.js)
Neue Datei config.js, die vor app.js eingebunden wird und die zwei globalen Variablen definiert:
var PB_URL = 'https://pb.kuehn.example.com';
var APP_URL = 'https://zieltracker.kuehn.example.com';
PB_URLersetzt die bisherige Hardcodierung inapp.jsAPP_URLwird verwendet, um Einladungslinks zu bauen (APP_URL + '/?invite=' + token)- Wird einmalig auf dem Server angepasst — kein UI
2. PocketBase: invites-Collection
| Feld | Typ | Constraints |
|---|---|---|
token |
text | unique, required |
label |
text | required (z.B. "Für Mama") |
created_by |
relation → users | required |
used_by |
relation → users | optional |
used_at |
date | optional |
API-Regeln:
- Lesen (einzelner Token via Filter): public — zum Validieren beim Registrieren
- Erstellen: nur authentifizierte User (
@request.auth.id != "") - Update (
used_by,used_at): public — wird beim Registrieren gesetzt - Löschen: nur der Ersteller
3. PocketBase: E-Mail / SMTP
PocketBase Admin → Settings → Mail settings:
- Provider: Brevo oder Resend (externer SMTP-Dienst, kostenloser Tier)
- PocketBase schickt nativ: E-Mail-Verifikation nach Registrierung, Passwort-Reset-Link
- Kein eigener Code nötig
4. UI-Flows
4.1 Einladung erstellen (eingeloggter User)
Im "Daten verwalten"-Sheet (⋯-Menü):
- Neuer Button "Einladungen"
- Öffnet Sheet mit Liste aller eigenen Einladungen:
- Label + Status ("Ausstehend" oder "✓ Registriert")
- Button "Neue Einladung":
- Eingabe: Label (z.B. "Für Papa")
- Generiert Token (12 zufällige alphanumerische Zeichen)
- Schreibt Token in
invites-Collection via PocketBase API - Zeigt fertigen Link zum Kopieren:
APP_URL/?invite=TOKEN
4.2 Registrierung (Eingeladener)
- User öffnet Einladungslink:
https://zieltracker.../?invite=TOKEN - App liest
?invite-Parameter aus URL - App prüft Token gegen PocketBase (
invites-Collection, Filter:token=TOKEN && used_by="") - Ist Token gültig und ungenutzt: Login-Sheet zeigt zusätzlichen Tab "Registrieren"
- Ist Token ungültig/bereits genutzt: nur Login, kein Registrierungs-Tab
- Registrierungsformular: E-Mail, Passwort, Passwort wiederholen
- Nach Erfolg:
- PocketBase-User wird angelegt (Standard-Auth-Flow)
- Token wird als
used_by = neuer User,used_at = jetztmarkiert - User ist eingeloggt, Ziele werden geladen
4.3 Passwort vergessen
Im Login-Sheet:
- Kleiner Link "Passwort vergessen?" unter dem Anmelden-Button
- Öffnet Mini-Sheet mit E-Mail-Eingabe
- Button "Reset-Link senden"
- Ruft PocketBase-Endpoint auf:
POST /api/collections/users/request-password-reset - Zeigt Bestätigung: "E-Mail wurde gesendet" (unabhängig ob Adresse existiert)
- PocketBase verschickt den Reset-Link — kein eigener Template-Code nötig
5. Nicht im Scope
- Admin-Funktion zum Deaktivieren von Accounts
- Invite-Limit pro User
- Ablaufdatum für Einladungslinks