99 lines
3.2 KiB
Markdown
99 lines
3.2 KiB
Markdown
|
|
# 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
|