Das System ist seit 20.07.2026 live; die dev-Doku spiegelt jetzt den Betriebszustand statt der Release-Vorbereitung: - dev/betrieb/: Deploy-Runbook (neu: §10 Betrieb nach Go-Live mit SFTP-Deploy-Checkliste inkl. queue:restart-Pflicht und den Betriebs-Erkenntnissen der Go-Live-Woche), Legacy-API-Parität, Umami. - dev/roadmap.md: offene Nachlauf-Punkte (Go-Live-Mails, Merge nach main, Stripe-Test-Artefakte, Key-Rotation, Alt-System-Abschaltung) und Ideen-Backlog. - dev/archive/: abgeschlossene Phasen — Migration-2026-Planung, Cutover-Runbook (mit Erledigt-Vermerk), Release-Plan/QA-Checkliste, Optimierungsphasen, Frontend-Konzepte + Responsive-Audits vom 16.07., Altsystem-Reste. - dev/README.md als Wegweiser; gitignore-Pfad der SQL-Dumps mitgezogen (dev/archive/migration-2026/sql/ bleibt untracked, ebenso dev/migration/ und dev/api/). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.9 KiB
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 mitagency_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 aufcompanies(owner_user_id = user_idder PM,type = agency, ohne PortalScope)- Rendering in
resources/views/web/release-detail.blade.php(unter dem Pressekontakt-Block), Übersetzungenweb.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-runzuerst; nie überschreibend. - Web-Frontend-Views gehören dem User → Änderungen dort separat committen.
A1 — Profilfeld users.agency_name (~30 min)
- Migration:
agency_name(string 190, nullable) aufusers. User: fillable ergänzen;UserFactory-StatewithAgency().- Kein eigenes Agentur-Logo/Website fürs Erste (bewusst schlank — erweiterbar, wenn gebraucht).
A2 — Daten-Übernahme Agentur-Firmen → Profil (~1–1,5 h)
- Artisan-Command
legacy:migrate-agency-names(--dry-run, Report nachstorage/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_atmax) gewinnt; alle Varianten in den Report. - Nie überschreiben, wenn
agency_namebereits gesetzt. - Die 10 Owner-losen Agentur-Firmen nur reporten (manuelle Sichtung).
- Je User mit Agentur-Firma(en): Namen nach
- Test mit Factories (Einzel-Fall, Mehrfach-Fall, bereits gesetzt).
- 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)
release-detail.blade.php:$agencyName = $release->user?->agency_namestattsubmittingAgency(Vergleichs-/Fallback-Logik bleibt identisch: Name ≠ Firma → „Original-Inhalt von … und übermittelt von …"; Name = Firma → „Inhalt übermittelt von …"; leer → „Original-Inhalt von …").- Eager Loading umstellen:
user:id,agency_namestattsubmittingAgency(ReleaseDetailPageData,PressReleasePreviewController). PressRelease::submittingAgency()entfernen.- Tests in
ReleaseDetailTestaufagency_nameumschreiben; Suite-Ausschnitt grün (ReleaseDetail,PressReleasePreview).
A4 — Firmen bereinigen: Typ „Agentur" abschaffen (~1,5 h)
- Artisan-Command
companies:retire-agency-type(--dry-run, Report):- Agentur-Firmen mit PMs oder Kontakten →
type = companyumtypen (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, keineuser_payment_option_company-Verknüpfung — sonst nur umtypen.
- Agentur-Firmen mit PMs oder Kontakten →
- Test mit Factories (umtypen, löschen, geschützter Fall).
- Command ebenfalls in die Deploy-Checkliste (nach A2!).
A5 — UI anpassen (~1,5 h)
- 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. - Firma anlegen (
customer/press-kits/create.blade.php): Typ-Feld entfernen, festtype = company. - Firmen-Übersicht (
customer/press-kits/index.blade.php): Typ-Label aus der Meta-Zeile entfernen (nach A4 gibt es nur noch einen Typ). - Admin (
admin/companies/create|edit.blade.php): Typ-Auswahl entfernen;admin/users/*: Feldagency_nameanzeigen/editierbar machen. - 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)
- Beispiel-PM
fuehrende-laufblogger-…zeigt weiterhin „Original-Inhalt von Trailbloggercamp und übermittelt von connektar.de Presseverteiler" — jetzt aususers.agency_name. - Kunden-Panel: Agentur-Name im Profil sichtbar/änderbar; Firmenliste ohne Agentur-Einträge bzw. ohne Typ-Label.
- Beide Daten-Commands mit Report gelaufen (lokal), Deploy-Checkliste ergänzt.
- Testsuite grün, Pint sauber, Commits je Schritt.