3.9 KiB
3.9 KiB
Registrierungs-Fixes: Redirect, Error-Clearing und Role-Handling (2025-10-02)
Problem-Beschreibung
- Redirect-Fehler: Bei erfolgreicher Registrierung (free oder paid Package) wurde onSuccess in Register.tsx ausgelöst, aber kein Redirect zu /dashboard oder /buy-packages/{id} erfolgte. Ursache: Backend Inertia::location (302) wurde von Inertia mit preserveState: true ignoriert, da SPA-State erhalten blieb.
- Persistente Errors: Server-Errors (z.B. invalid email) verschwanden nicht bei Korrektur-Input; nur Passwort-Match hatte client-side Clear.
- Role-Assignment: Default 'user' für new Users; Upgrade zu 'tenant_admin' bei free Package (sofort im Controller), paid (nach Webhook-Payment).
- Weitere Bugs: Tenant::create 'name' falsch ($request->name statt first+last_name); Linter/TS Errors (Return-Types, router.visit unknown).
Fixes
Backend (MarketingRegisterController.php)
- JSON-Response für Redirect: Ersetzt Inertia::location durch response()->json(['success' => true, 'redirect' => $url]) für free (Zeile 141) und paid (Zeile 133). Kompatibel mit Inertia onSuccess (page.props.success/redirect prüfen).
- Tenant Name Fix: 'name' => $request->first_name . ' ' . $request->last_name (Zeile 71); slug entsprechend angepasst.
- Role-Logic: 'role' => 'user' in User::create (Zeile 66); für free: Update zu 'tenant_admin' nach TenantPackage::create (Zeile 129), Re-Login (Zeile 130). Für paid: Kein Upgrade bis Webhook (Paddle).
- Return-Type: store() zu JsonResponse (Zeile 44); use JsonResponse hinzugefügt (Zeile 22).
Frontend (Register.tsx)
- onSuccess-Handling: Prüfe page.props.success && router.visit(page.props.redirect as string) (Zeile 66-68); Fallback zu data.package_id ?
/buy-packages/${data.package_id}: '/dashboard' (Zeile 71-75); console.log für Debug (Zeile 67, 74). - Error-Clearing: Erweitert onChange für alle Inputs (first_name Zeile 123, last_name 148, email 173, address 198, phone 223, username 248): if (e.target.value.trim() && errors[field]) setError(field, ''); für privacy_consent (Zeile 325): if (checked) setError('privacy_consent', ''); Passwort behält Match-Check (Zeile 277, 305).
- General Errors Key: <div key={
general-errors-${Object.keys(errors).join('-')}} (Zeile 347) für Re-Render bei Error-Änderungen.
Tests (RegistrationTest.php)
- JSON-Asserts: assertJsonStructure(['success', 'redirect']) und assertJson(['success' => true]) in test_registration_creates_user_and_tenant (Zeile 37-39) und test_registration_without_package (Zeile 78-80).
- Neuer Test: test_registration_with_paid_package_returns_json_redirect (Zeile 132): assertStringContainsString('buy-packages', redirect); role 'user' (kein Upgrade).
- Validation/Email: Unverändert, assertSessionHasErrors (Zeile 107).
Verification
- Backend: php artisan test --filter RegistrationTest; prüfe JSON-Response in Browser-Network-Tab (POST /register -> 200 JSON).
- Frontend: Registrierung mit free: Redirect zu /verification.notice; paid: zu /buy-packages/10; Errors clear bei Input (z.B. invalid email -> input valid -> error gone).
- Role: DB-Check: free -> 'tenant_admin', paid -> 'user' (Upgrade via Webhook).
- Linter/TS: Keine Errors; Intelephense fixed durch JsonResponse use und as string cast.
PRP-Update (docs/prp/13-backend-authentication.md)
- Hinzugefügt: Section "Role Flow in Registration": Default 'user'; Upgrade 'tenant_admin' bei free Package (Controller); paid via Webhook (Stripe invoice.paid, Paddle IPN); JSON-Success für Inertia-Forms (preserveState + onSuccess visit).
Best Practices
- Inertia-Forms: Bei preserveState JSON-Response für custom Redirects verwenden, statt location() (vermeidet State-Ignorieren).
- Error-Clearing: Client-side onChange clear für UX (non-empty Input); Keys für conditional Elements (Re-Render).
- GDPR: Privacy-Consent required; no PII in Logs.
Date: 2025-10-02