b2in/dev/PARTNER-SETUP-WIZARD.md
2026-01-23 17:33:10 +01:00

90 lines
6.7 KiB
Markdown
Raw 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.

# Partner-Einladung & Setup-Wizard
Kurze Notizen zur aktuellen Einladungskette und dem Setup-Wizard, plus offene To-dos.
## Ablauf Einladung
- Admin lädt Partner über `resources/views/livewire/admin/partners/invite.blade.php` ein.
- Gültigkeit wird im Formular gewählt (14 Wochen) und als `expires_at` in `PartnerInvitation` gespeichert.
- Einladungslink: `route('partner.invitation.accept', ['token' => $token])`.
- Zusätzliche Statusseiten: `/partner/invitation/expired/{token}` und `/partner/invitation/used/{token}`.
## Routen
- `/partner/invitation/{token}` → Volt-Komponente `partner.invitation-accept`.
- `/partner/invitation/expired/{token}` und `/partner/invitation/used/{token}` → statische Blade-Views.
- `/partner/setup` → Volt-Komponente `partner.setup-wizard`, geschützt mit `auth`-Middleware.
## Setup-Wizard (partner.setup-wizard)
- Basisdaten: Partner wird über eingeloggten User geladen (`Auth::user()->partner_id`); Rolle bestimmt Icon/Label.
- Schritte je Partner-Typ:
- Retailer: `Stammdaten``Liefergebiete``Fertig`.
- Manufacturer: `Stammdaten``Marke anlegen``Fertig`.
- Estate-Agent (und Default): `Profil`/`Stammdaten``Fertig`.
- Schritt 1 (alle):
- Felder: Firmenname (pflicht), Logo-Upload (optional, 2 MB, jpg/png/webp), Kurzbeschreibung, Straße/PLZ/Stadt (pflicht), Website (optional, URL).
- Logo wird bei Upload in `public/partner-logos` gespeichert; Partner wird mit Name/Beschreibung/Logo aktualisiert.
- TODO im Code: Adresse noch separat speichern (Adresse aktuell nicht persistiert).
- Schritt 2 Retailer:
- Felder: Lieferradius km, Montageradius km (1500, pflicht).
- Speichert `delivery_radius_km` und `assembly_radius_km` im Partner; danach Abschluss.
- Schritt 2 Manufacturer:
- Felder: Markenname (pflicht), Markenlogo (optional, 2 MB), Markenbeschreibung.
- Speichert neue `Brand` mit Slug aus Namen; Logo in `public/brand-logos`.
- Abschluss:
- Partner wird `is_active=true`, `setup_completed=true`, `setup_completed_at=now()`.
- Dashboard-Button; für Nicht-Makler CTA „Erstes Produkt anlegen“ (derzeit ohne Aktion).
## Offene To-dos / Beobachtungen
- Adresse persistieren (separates Modell/JSON), wird aktuell nur validiert.
- Website-Feld wird vorausgefüllt? momentan leer trotz vorhandener Partner-Daten.
- CTA „Erstes Produkt anlegen“ ohne Link/Action; Zielseite definieren.
- Hersteller: Slug-Kollision/Mehrmarken-Handling prüfen (derzeit einfacher `Str::slug` mit create).
- Estate-Agent: Gibt es spezifische Felder? Wizard zeigt nur Schritt 1 → Fertig; klären ob ausreichend.
## QR-/Registrierungscode-Flow (neu)
- Öffentliche Landing unter `/reg/{role}` auf `b2in.test`, Rollen-Codes:
- `c` = Kunde, `e` = Makler, `m` = Hersteller, `r` = Händler.
- Gleiches Blade-Template, Inhalte/CTA dynamisch nach Role.
- QR-Codes enthalten nur den Link (`/reg/{role}`), kein Code-Query. Der Code steht z.B. auf der Visitenkarte und wird manuell eingegeben.
- Registrierungscode ist zwingend, wird einmalig eingelöst und danach als „verbraucht“ markiert.
- Validierter Code schaltet erst das passende Registrierungsformular frei (bestehender Flow wiederverwenden, kein zweites System).
- Rollen-spezifische Registrierung:
- Makler (`/reg/e`): braucht gültige Makler-Nummer (einzigartig, vorab im System hinterlegt).
- Kunde (`/reg/c`): braucht gültige Kundennummer, die einem Makler zugeordnet ist; jeder Kunde muss einem Makler zugeordnet werden (Provisions-Tracking).
- Händler (`/reg/r`) und Hersteller (`/reg/m`): eigener Flow, ebenfalls mit einmaligem Code; Hersteller haben keine Kunden, Händler pflegen Sortiment und können Kundenzugänge verschaffen.
### Vorschlag Datenmodell Codes (anzulegen)
- Tabelle `registration_codes` (oder separate `broker_codes` + `customer_codes`):
- `code` (unique), `role` (`broker|customer|retailer|manufacturer`), `status` (`available|used|expired`), `partner_id` (optional, z.B. für Händler/Hersteller), `broker_id` (für Kundennummern-Block), `used_by_user_id` (nullable), `used_at`, `expires_at` (optional), `metadata` (json für Notizen/Quelle).
- Für Maklernummern: `role=broker`, `status=available`, keine `broker_id`.
- Für Kundennummern: `role=customer`, `broker_id` Pflicht, damit Zuordnung bei Registrierung klar ist.
- Einlösung:
- Lookup `code` + `role` passend zur Route.
- Wenn `status != available` → Fehlermeldung.
- Bei Erfolg: markiere `used`, setze `used_at`, `used_by_user_id` (nach erfolgreichem User-Create), ggf. `partner_id` koppeln.
### Nummernformat / Vergabe
- Format: 8-stellige Nummern mit optional vorangestelltem Buchstaben (Alias). Beispiele: `00100001`, `M00100001`, `K01102513`.
- Buchstabenpräfixe nur Alias (Marketing), intern immer über IDs verknüpfen; Code bleibt als Alias gespeichert.
- Nummern sind fortlaufend; Kundennummern werden blockweise einem Makler zugewiesen (z.B. `K01102510``K01102560` = 50 Stück).
- Ein Code kann nur einmal eingelöst werden und wird danach als „used“ markiert.
### Umsetzung QR-/Reg-Landing (Stand)
- Neue Route `/reg/{role}` (Volt) mit Rollen-Slugs: `c` Kunde, `e` Makler, `m` Hersteller, `r` Händler.
- Gemeinsames Template `resources/views/livewire/reg/landing.blade.php`, Inhalte dynamisch nach Rolle.
- Eingabe und Prüfung des Registrierungscodes; Normalisierung (Leerzeichen/Bindestriche entfernt, uppercase).
- Valider Code (Status `available`, Rolle passend) wird in Session abgelegt (`registration_code_id`, `registration_role`) und leitet zu `reg/create-account` weiter. Verbrauch/Markierung erfolgt beim Account-Create bzw. Wizard-Abschluss.
- Neues Modell `App\Models\RegistrationCode` + Migration `registration_codes` mit Feldern für Status, Rolle, Broker-/Partner-Referenzen, Used-Infos.
### Account-Create nach Code (neu)
- Route `/reg/create-account` (Volt) nutzt `reg.create-account`-Komponente.
- Felder: Vorname, Nachname, E-Mail, Passwort + Bestätigung, AGB-Checkbox.
- Prüft Session-Code; mappt Rollen auf Partner-Typ (`broker→Estate-Agent`, `retailer→Retailer`, `manufacturer→Manufacturer`; Customer aktuell nicht unterstützt).
- Erstellt Partner (minimal), User, weist Rolle zu, markiert Code als verwendet, loggt ein, leitet in den Setup-Wizard.
### Landing-/Flow-Idee
- Route/Controller/Volt für `/reg/{role}`:
- Zeigt Rolle-spezifischen Text und Eingabefeld „Registrierungscode“.
- Nach erfolgreicher Code-Validierung: Formular mit bestehenden Feldern je Rolle anzeigen (Reuse: bestehende Registrierung/Setup-Logik).
- Kopplung mit bestehendem Einladungssystem:
- Kein zweites System; nach Code-Check wird derselbe Registrierungspfad genutzt (User/Partner anlegen, Setup-Wizard etc.).
- To-do: Admin-Oberfläche bereitstellen, um Maklernummern und Kundennummern-Blöcke zu erzeugen und einem Makler zuzuweisen.