Agentur-Attribution: Plan abgehakt, Abnahme-Status 08.07. dokumentiert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3ff95bc93a
commit
d57f6b5c66
1 changed files with 142 additions and 0 deletions
142
dev/agentur-attribution/entwicklungsplan.md
Normal file
142
dev/agentur-attribution/entwicklungsplan.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# Entwicklungsplan: Agentur-Attribution → User-Profil (Umbau)
|
||||
|
||||
> Erstellt **07.07.2026** nach User-Entscheidung. Ziel: Der Firmen-Typ „Agentur"
|
||||
> verschwindet aus dem Firmen-Modell. Firmen sind ausschließlich die Newsrooms,
|
||||
> unter denen PMs veröffentlicht werden. Die Übermittler-Angabe („übermittelt
|
||||
> von …") wird eine **Profil-Eigenschaft des einliefernden Accounts**.
|
||||
> Geplanter Umfang: **1 Arbeitstag**.
|
||||
|
||||
> **Status 08.07.2026: A1–A5 UMGESETZT, Abnahme erfüllt.** Beide
|
||||
> Daten-Commands sind lokal scharf gelaufen (Reports unter
|
||||
> `storage/app/private/migration/`): 4.482 User mit `agency_name`
|
||||
> (93 Mehrfach-Fälle exakt verglichen — der Plan zählte 77 normalisiert —,
|
||||
> 10 Owner-lose nur reportet), 2.607 Agentur-Firmen umtypisiert,
|
||||
> 2.149 soft-gelöscht, 1 geschützter Fall (Zahlungsoptions-/Mitglieds-
|
||||
> Verknüpfung). Beispiel-PM zeigt die Attributions-Zeile aus dem
|
||||
> Profilfeld. Deploy-Runbook (Erst-Einrichtung, Schritt 2) ergänzt.
|
||||
> Offen: nur A6 (nachgelagert).
|
||||
|
||||
---
|
||||
|
||||
## Ausgangslage (Stand 07.07.2026)
|
||||
|
||||
**Bereits umgesetzt (07.07.):** Die Legacy-Attributions-Zeile („Original-Inhalt
|
||||
von {Firma} und übermittelt von {Agentur}") ist auf der öffentlichen
|
||||
Detailseite wieder da — aktuell noch über die Legacy-Datenstruktur:
|
||||
|
||||
- `PressRelease::submittingAgency()` — hasOne auf `companies`
|
||||
(`owner_user_id = user_id` der PM, `type = agency`, ohne PortalScope)
|
||||
- Rendering in `resources/views/web/release-detail.blade.php` (unter dem
|
||||
Pressekontakt-Block), Übersetzungen `web.detail.attribution*` (de/en)
|
||||
- Eager Loading in `ReleaseDetailPageData` + `PressReleasePreviewController`
|
||||
- 3 Tests in `tests/Feature/Web/ReleaseDetailTest.php` (Verteiler, gleichnamig,
|
||||
ohne Agentur)
|
||||
|
||||
**Datenlage (lokal geprüft 07.07.):**
|
||||
|
||||
| Fakt | Wert |
|
||||
|---|---|
|
||||
| Agentur-Firmen (`companies.type = agency`, aktiv) | 4.756 |
|
||||
| … davon selbst Newsroom (PMs mit `company_id` = Agentur) | 2.598 (7.963 PMs) |
|
||||
| … mit Pressekontakten | 27 |
|
||||
| … ohne Owner (`owner_user_id IS NULL`) | 10 |
|
||||
| User mit Agentur-Firma | 4.482 |
|
||||
| User mit **mehreren** verschieden benannten Agentur-Firmen | 77 |
|
||||
| connektar: User 14016 (`info@connektar.de`) | Agentur-Firmen 18811 (pe) + 49196 (bp24), 20.830 PMs |
|
||||
|
||||
**Kernproblem des Ist-Zustands:** Die Agentur ist eine Pseudo-Firma — im
|
||||
Kunden-Panel nicht von echten Firmen unterscheidbar, die Zuordnung
|
||||
(owner_user_id → user_id der PM) versteht niemand, und mehrere Agentur-Firmen
|
||||
pro Account sind mehrdeutig.
|
||||
|
||||
---
|
||||
|
||||
## Arbeitsregeln
|
||||
|
||||
- Test-First bei Verhaltensänderungen; Tests gezielt:
|
||||
`php artisan test --compact --filter=<Name>` (wir sind im Sail-Container).
|
||||
- Nach PHP-Änderungen: `vendor/bin/pint --dirty --format agent`.
|
||||
- Jeder Schritt = eigener, fokussierter Commit.
|
||||
- Daten-Kommandos immer mit `--dry-run` zuerst; nie überschreibend.
|
||||
- Web-Frontend-Views gehören dem User → Änderungen dort separat committen.
|
||||
|
||||
---
|
||||
|
||||
## A1 — Profilfeld `users.agency_name` (~30 min)
|
||||
|
||||
- [x] Migration: `agency_name` (string 190, nullable) auf `users`.
|
||||
- [x] `User`: fillable ergänzen; `UserFactory`-State `withAgency()`.
|
||||
- [x] Kein eigenes Agentur-Logo/Website fürs Erste (bewusst schlank —
|
||||
erweiterbar, wenn gebraucht).
|
||||
|
||||
## A2 — Daten-Übernahme Agentur-Firmen → Profil (~1–1,5 h)
|
||||
|
||||
- [x] Artisan-Command `legacy:migrate-agency-names` (`--dry-run`, Report nach
|
||||
`storage/app/private/migration/`):
|
||||
- Je User mit Agentur-Firma(en): Namen nach `users.agency_name` übernehmen.
|
||||
- **Regel Mehrfach-Fälle (77 User):** zuletzt aktualisierter Datensatz
|
||||
(`updated_at` max) gewinnt; alle Varianten in den Report.
|
||||
- Nie überschreiben, wenn `agency_name` bereits gesetzt.
|
||||
- Die 10 Owner-losen Agentur-Firmen nur reporten (manuelle Sichtung).
|
||||
- [x] Test mit Factories (Einzel-Fall, Mehrfach-Fall, bereits gesetzt).
|
||||
- [x] **Go-Live-Hinweis:** Command in die WS-7-/Deploy-Checkliste aufnehmen
|
||||
(läuft NACH dem Firmen-/User-Import).
|
||||
|
||||
## A3 — Attribution auf Profilfeld umstellen (~1 h)
|
||||
|
||||
- [x] `release-detail.blade.php`: `$agencyName = $release->user?->agency_name`
|
||||
statt `submittingAgency` (Vergleichs-/Fallback-Logik bleibt identisch:
|
||||
Name ≠ Firma → „Original-Inhalt von … und übermittelt von …";
|
||||
Name = Firma → „Inhalt übermittelt von …"; leer → „Original-Inhalt von …").
|
||||
- [x] Eager Loading umstellen: `user:id,agency_name` statt `submittingAgency`
|
||||
(`ReleaseDetailPageData`, `PressReleasePreviewController`).
|
||||
- [x] `PressRelease::submittingAgency()` entfernen.
|
||||
- [x] Tests in `ReleaseDetailTest` auf `agency_name` umschreiben; Suite-Ausschnitt
|
||||
grün (`ReleaseDetail`, `PressReleasePreview`).
|
||||
|
||||
## A4 — Firmen bereinigen: Typ „Agentur" abschaffen (~1,5 h)
|
||||
|
||||
- [x] Artisan-Command `companies:retire-agency-type` (`--dry-run`, Report):
|
||||
- Agentur-Firmen **mit** PMs oder Kontakten → `type = company` umtypen
|
||||
(bleiben Newsrooms; 2.598 + 27, Überschneidung möglich).
|
||||
- Agentur-Firmen **ohne** PMs und Kontakte → Soft-Delete (~2.100).
|
||||
Vorher prüfen: keine `company_user`-Mitgliedschaften Dritter, keine
|
||||
`user_payment_option_company`-Verknüpfung — sonst nur umtypen.
|
||||
- [x] Test mit Factories (umtypen, löschen, geschützter Fall).
|
||||
- [x] Command ebenfalls in die Deploy-Checkliste (nach A2!).
|
||||
|
||||
## A5 — UI anpassen (~1,5 h)
|
||||
|
||||
- [x] **Kunden-Panel Profil** (`livewire/customer/profile.blade.php`):
|
||||
neuer Abschnitt „Agentur-Angaben" mit Feld „Agentur-/Verteilername"
|
||||
und Erklärtext: *„Falls Sie Pressemitteilungen im Auftrag Dritter
|
||||
einreichen, erscheint diese Angabe öffentlich als Übermittler unter
|
||||
Ihren Mitteilungen."* Validierung: nullable, max 190.
|
||||
- [x] **Firma anlegen** (`customer/press-kits/create.blade.php`): Typ-Feld
|
||||
entfernen, fest `type = company`.
|
||||
- [x] **Firmen-Übersicht** (`customer/press-kits/index.blade.php`):
|
||||
Typ-Label aus der Meta-Zeile entfernen (nach A4 gibt es nur noch einen Typ).
|
||||
- [x] **Admin** (`admin/companies/create|edit.blade.php`): Typ-Auswahl
|
||||
entfernen; `admin/users/*`: Feld `agency_name` anzeigen/editierbar machen.
|
||||
- [x] Tests: Profil speichert `agency_name`; Firma-Anlegen ohne Typ-Feld.
|
||||
|
||||
## A6 — Nachgelagert (NICHT morgen)
|
||||
|
||||
- `companies.type`-Spalte + `CompanyType`-Enum komplett entfernen
|
||||
(erst wenn A4 produktiv gelaufen und verifiziert ist).
|
||||
- Optional: Agentur-Logo/-Website im Profil, falls die Attributions-Zeile
|
||||
verlinkt werden soll.
|
||||
- Admin-Auswertung „PMs je Übermittler" (Tracking-Wunsch aus dem Konzept,
|
||||
Abschnitt Distribution-Partner).
|
||||
|
||||
---
|
||||
|
||||
## Abnahme (Ende des Tages)
|
||||
|
||||
- [x] Beispiel-PM `fuehrende-laufblogger-…` zeigt weiterhin
|
||||
„Original-Inhalt von Trailbloggercamp und übermittelt von
|
||||
connektar.de Presseverteiler" — jetzt aus `users.agency_name`.
|
||||
- [x] Kunden-Panel: Agentur-Name im Profil sichtbar/änderbar; Firmenliste
|
||||
ohne Agentur-Einträge bzw. ohne Typ-Label.
|
||||
- [x] Beide Daten-Commands mit Report gelaufen (lokal), Deploy-Checkliste ergänzt.
|
||||
- [x] Testsuite grün, Pint sauber, Commits je Schritt.
|
||||
Loading…
Add table
Add a link
Reference in a new issue