presseportale/dev/archive/agentur-attribution/entwicklungsplan.md
Kevin Adametz 6a4c4d8837 docs: dev-Doku für den Live-Betrieb neu sortiert — Archiv + Betrieb + Roadmap
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>
2026-07-21 07:52:38 +00:00

6.9 KiB
Raw Blame History

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)

  • Migration: agency_name (string 190, nullable) auf users.
  • User: fillable ergänzen; UserFactory-State withAgency().
  • 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 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).
  • 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_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 …").
  • Eager Loading umstellen: user:id,agency_name statt submittingAgency (ReleaseDetailPageData, PressReleasePreviewController).
  • PressRelease::submittingAgency() entfernen.
  • Tests in ReleaseDetailTest auf agency_name umschreiben; 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 = 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.
  • 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, fest type = 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/*: Feld agency_name anzeigen/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 aus users.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.