90 lines
6.7 KiB
Markdown
90 lines
6.7 KiB
Markdown
# 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 (1–4 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 (1–500, 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.
|