dudi/docs/superpowers/specs/2026-04-21-registration-invites-design.md

99 lines
3.2 KiB
Markdown
Raw Normal View History

# 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:
```js
var PB_URL = 'https://pb.kuehn.example.com';
var APP_URL = 'https://zieltracker.kuehn.example.com';
```
- `PB_URL` ersetzt die bisherige Hardcodierung in `app.js`
- `APP_URL` wird 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"**:
1. Eingabe: Label (z.B. "Für Papa")
2. Generiert Token (12 zufällige alphanumerische Zeichen)
3. Schreibt Token in `invites`-Collection via PocketBase API
4. 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:
1. PocketBase-User wird angelegt (Standard-Auth-Flow)
2. Token wird als `used_by = neuer User`, `used_at = jetzt` markiert
3. 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