Doku: Status-Sync 11./12.06., Decision-Update Preisstruktur und Phase-9-Plan
- Decision-Update Preisstruktur & Veroeffentlichungs-Flow aufgenommen (Launch-Tarife, Slot-Verbrauch bei Veroeffentlichung, Submit-Gate, Launch-Credits) inkl. Klarstellung 12.06.: Gelb geht direkt live, keine manuelle Pruef-Queue, nur Rot wird abgelehnt - Alle Status-Dokumente auf den Code-Stand gezogen: README-Index, STATUS-ABGLEICH (KI-Pipeline, Bilder/Lizenzen, Pricing), Checkliste (KI- und Titelbild-Bloecke, Launch-To-dos), Admin-User, user-zusammenhaenge (Datenmodell-Delta), Entwicklungsplan KI-Pruefung (Phase 0 abgehakt, Decision-Abgleich) - Ueberschriebene Tarif-Abschnitte in Konzept-Update 1/2 und Relaunch-Konzept mit Superseded-/IST-Hinweisen markiert - Neues Plan-Dokument PHASE-9-FLOW-UND-TARIFE-PLAN.md (9A-9J) - Phase-8-Roadmap-Doku (20-PHASE-8-USER-PANEL.md) + PROGRESS-Eintraege Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a000238ca8
commit
8d8d957884
17 changed files with 2231 additions and 172 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# User Backend und Admin Backend
|
||||
|
||||
> **Stand der Doku**: 21.05.2026 — Phase 1 + Phase 7 (PM-Form-Refactor) sind umgesetzt.
|
||||
> **Stand der Doku**: 11.06.2026 — Phase 1, Phase 7 (PM-Form-Refactor), Phase 8 (User-Panel-Konsolidierung) und die KI-Pruef-Pipeline (Klassifikation + Content-Score) sind abgeschlossen.
|
||||
> Aktueller Code-vs-Konzept-Abgleich: [`docs/STATUS-ABGLEICH-USER-PANEL.md`](../STATUS-ABGLEICH-USER-PANEL.md).
|
||||
> Plan der naechsten Schritte: [`docs/PHASE-8-USER-PANEL-PLAN.md`](../PHASE-8-USER-PANEL-PLAN.md).
|
||||
> Naechster Block (Zahlung/Tarife, Veroeffentlichungs-Flow): [`docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md`](../Decision-Update%20Preisstruktur%20&%20Ver%C3%B6ffentlichungs-Flow.md).
|
||||
|
||||
Dieses Konzept beschreibt das gemeinsame Backend aus zwei Perspektiven:
|
||||
|
||||
|
|
@ -66,16 +66,27 @@ Zusammenfassung:
|
|||
- **Background-Job** `php artisan press-releases:publish-scheduled` veröffentlicht geplante PMs (alle 5 Minuten via Scheduler).
|
||||
- **UX**: `Flux::toast()` für alle Erfolg/Fehler-Meldungen, Smooth-Scroll zum ersten Validation-Fehler nach Save, `presubmitChecks` als kompakte Pflichtfeld-Übersicht im Sidebar.
|
||||
|
||||
## Geplante Phase 8
|
||||
## Phase 8 (abgeschlossen 29.05.2026)
|
||||
|
||||
Plan-Doku: `docs/PHASE-8-USER-PANEL-PLAN.md`. Schwerpunkte:
|
||||
|
||||
1. Show-Page-Lücken aus Phase 7 schließen (Subtitle, Scheduling, Embargo, Boilerplate-Override).
|
||||
2. Listen-Indikatoren für geplante Veröffentlichung und Embargo.
|
||||
3. Firmen-Liste auf Mockup-Niveau (Counter-Strip, Saved-Views, Filter-Chips, Card/List-Toggle, Rollen-Legende).
|
||||
4. SVG-Platzhalter-Set für PM-Titelbilder + Auswahl-Modal.
|
||||
5. FluxUI `flux:file-upload` im Image-Manager inkl. Pflichtfeldern für Urheber/Lizenz/Rechte.
|
||||
6. Veröffentlichungs-Modal mit rechtlichen Hinweisen und einem Kontingent-Stub (das echte Tarif-System kommt später).
|
||||
1. ✅ Show-Page-Lücken aus Phase 7 schließen (Subtitle, Scheduling, Embargo, Boilerplate-Override) — Customer + Admin (8A).
|
||||
2. ✅ Listen-Indikatoren für geplante Veröffentlichung und Embargo (8B).
|
||||
3. ✅ Pressekontakt-Warn-Box in der Form-Sidebar, wenn kein Kontakt gewählt (8C).
|
||||
4. ✅ Firmen-Liste auf Mockup-Niveau (Counter-Strip, Saved-Views, Filter-Chips, Card/List-Toggle, Rollen-Legende) (8E).
|
||||
5. ✅ SVG-Platzhalter-Set für PM-Titelbilder + Auswahl-Modal + Cover-Resolver (8F/8G).
|
||||
6. ✅ Image-Manager mit Lizenz-Pflichtfeldern (Urheber/Lizenztyp/Lizenz-URL/Rechte-Bestätigung) (8H).
|
||||
7. ✅ Veröffentlichungs-Modal mit rechtlichen Hinweisen und Kontingent-Stub (8I/8J; das echte Tarif-System kommt später).
|
||||
|
||||
## KI-Prüfung & Veröffentlichung (abgeschlossen 11.06.2026)
|
||||
|
||||
Detail-Doku: `Entwicklungsplan KI-Pruefung und Veroeffentlichung.md`. Kurzfassung:
|
||||
|
||||
- Jede Einreichung (Customer-Form **und** API) läuft durch denselben Funnel: Blacklist-Hard-Filter → asynchrone KI-Klassifikation (Rot/Gelb/Grün, OpenAI mit deterministischem Fallback) → Status-Routing.
|
||||
- Rot → abgelehnt + Begründung per Mail; Gelb → manuelle Admin-Review-Queue; Grün → Auto-Publish (sofort oder zum geplanten Termin).
|
||||
- Jede KI-Entscheidung wird in `ki_audits` protokolliert; Admin sieht Badge, Begründung und kann nach Klassifikation filtern. On-Demand-Prüfung über den „Prüfung"-Button im Admin-Editor.
|
||||
- Zusätzlich Content-Score 0–100 → Stufe Standard/Geprüft/Hochwertig mit Editor-Panel und Badges.
|
||||
- Parallel umgesetzt (10./11.06.): ein Titelbild pro PM (Cover 1280×580), erweitertes Lizenz-/Rechteformular, Termine in Europe/Berlin (Speicherung UTC), Embargo aus der Form-UI entfernt — siehe `Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md`.
|
||||
|
||||
## Topbar
|
||||
|
||||
|
|
@ -123,7 +134,7 @@ Stand 21.05.2026:
|
|||
- **Anhaenge** sind im UI deaktiviert (Security-Review). Tabelle `press_release_attachments` und Service `PressReleaseAttachmentStorage` bleiben erhalten.
|
||||
- **Filter-Presets** sind weiterhin **Gelb** (Tabelle existiert, UI noch nicht aktiv).
|
||||
|
||||
Phase: **Gruen** fuer Liste, Detail, Statusverlauf, Firmenpflicht, Untertitel, Scheduling, Embargo und Boilerplate-Override. **Gelb** fuer Filter-Presets. **Rot/Spaeter** fuer KI-Vorpruefung, Notice-and-Action und Korrektur-/Update-Hinweis-System (siehe `Presseportal – Konzept für Relaunch.md`).
|
||||
Phase: **Gruen** fuer Liste, Detail, Statusverlauf, Firmenpflicht, Untertitel, Scheduling und Boilerplate-Override. **Umgesetzt (11.06.)**: KI-Pruefung bei Einreichung (Klassifikation + Content-Score, siehe `Entwicklungsplan KI-Pruefung und Veroeffentlichung.md`); Embargo wurde aus der Form-UI entfernt. **Gelb** fuer Filter-Presets. **Rot/Spaeter** fuer Vorab-KI-Pruefung ohne Einreichung, Notice-and-Action und Korrektur-/Update-Hinweis-System (siehe `Presseportal – Konzept für Relaunch.md`).
|
||||
|
||||
**3. Firmen** Klar strukturierter Detailbereich pro Firma, weil hier am meisten dranhängt:
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,524 @@
|
|||
# Entwicklungsplan: KI-Prüfung & Veröffentlichungs-Pipeline
|
||||
|
||||
Stand: 11.06.2026 — **Phasen 0–5 abgeschlossen**, Phase 6 (Trust-Score) offen.
|
||||
|
||||
Dieser Plan definiert die schrittweise Umsetzung der automatisierten Prüfung
|
||||
und Veröffentlichung von Pressemitteilungen (PM). Er ist so geschnitten, dass
|
||||
jede Phase einzeln umgesetzt, getestet und ausgeliefert werden kann.
|
||||
|
||||
> **Abgleich mit dem Decision-Update (11.06.2026)**: Das
|
||||
> [`Decision-Update Preisstruktur & Veröffentlichungs-Flow`](../Decision-Update%20Preisstruktur%20&%20Ver%C3%B6ffentlichungs-Flow.md)
|
||||
> setzt auf dieser Pipeline auf und ergänzt zum Launch drei noch offene
|
||||
> Flow-Regeln, die **nicht** Teil dieses Plans waren:
|
||||
>
|
||||
> 1. **Submit-Gate**: „Zur Prüfung einreichen" wird hinter eine aktive
|
||||
> Buchung gelegt (das Modal zeigt ohne Buchung einen Buchungs-Hinweis).
|
||||
> 2. **Slot-Verbrauch bei Veröffentlichung** statt bei Einreichung —
|
||||
> rot abgelehnte PMs verbrauchen keinen Slot. Der aktuelle Quota-Stub
|
||||
> zählt noch beim Einreichen (`submitForReview`) und muss umgestellt werden.
|
||||
> 3. **Kein Re-Check zum Launch**: eine Einreichung = eine Prüfung;
|
||||
> Nachbessern + erneut prüfen kommt erst in Phase 2.
|
||||
> 4. **Gelb-Routing geändert (Entscheidung 12.06.2026)**: Gelb geht zum
|
||||
> Launch **direkt live** wie Grün — keine manuelle Review-Queue mehr.
|
||||
> Nur Rot wird abgelehnt (mit Begründung an den Autor). Phase 4 unten
|
||||
> beschreibt das ursprünglich gebaute Verhalten (Gelb → manuelle Queue);
|
||||
> die Umstellung erfolgt im Phase-9-Plan
|
||||
> (`docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md`, Päckchen 9A).
|
||||
|
||||
## Ziel & Leitprinzip
|
||||
|
||||
Jede eingehende PM wird **automatisch von einer KI geprüft**. Nur in
|
||||
**äußersten Fällen** erfolgt eine manuelle redaktionelle Prüfung. Zwei
|
||||
Einreichungsstellen müssen denselben Prüf-Pfad durchlaufen:
|
||||
|
||||
1. **Web-Formular** (Customer- und Admin-Editor)
|
||||
2. **API** (`/api/v1/press-releases`)
|
||||
|
||||
Es gibt zwei voneinander unabhängige Bewertungen (Konzept-Update 1, Abschnitt 15):
|
||||
|
||||
- **Klassifikations-Score (Grün/Gelb/Rot)** — der „Red Flag": entscheidet, ob
|
||||
überhaupt veröffentlicht wird. **Jetzt umzusetzen.**
|
||||
- **Content-Score (0–100) → Stufe (Standard/Geprüft/Hochwertig)** — die
|
||||
Qualitätsbewertung („Scoring"). **Spätere Phase.**
|
||||
|
||||
## Konzept-Grundlage
|
||||
|
||||
- `docs/konzept/Konzept-Update 1 – Überarbeitete Abschnitte.md`, §15.1
|
||||
(Klassifikations-Score) und §15.2 (Content-Score).
|
||||
- `docs/konzept/Konzept-Update 2 – Score-Stufen-System.md` (Stufen-Mapping,
|
||||
`content_tier`, Außenkommunikation).
|
||||
|
||||
Klassifikations-Score laut Konzept §15.1:
|
||||
|
||||
| Klassifikation | Bedeutung | Auswirkung |
|
||||
|---|---|---|
|
||||
| **Grün** | unauffällig | direkte Veröffentlichung (optional 5–10 Min. Verzögerung) |
|
||||
| **Gelb** | unklar/grenzwertig | manuelle Review-Queue (nicht boostbar) |
|
||||
| **Rot** | unzulässig | zurück an Autor mit Begründung, keine Veröffentlichung |
|
||||
|
||||
Faktoren (Red Flags): Werbung statt PM, beleidigend/diskriminierend, rechtlich
|
||||
heikel, Spam-Muster, unseriöse Versprechen. Speicherung laut Konzept:
|
||||
`press_releases.classification` plus Audit-Log `ki_audits`.
|
||||
|
||||
## Ist-Zustand (Bestandsaufnahme)
|
||||
|
||||
- **Statuswerte** (`App\Enums\PressReleaseStatus`): `draft`, `review`,
|
||||
`published`, `rejected`, `archived`.
|
||||
- **Web-Einreichung**: `App\Services\PressRelease\PressReleaseService::submitForReview()`
|
||||
prüft nur eine wortbasierte Blacklist (`config/blacklist.php` via
|
||||
`BlacklistService`), setzt sonst Status `review`, erhöht das Quota und
|
||||
schreibt ein `PressReleaseStatusLog`.
|
||||
- **Veröffentlichung**: `PressReleaseService::publish()` (Admin-Aktion) und der
|
||||
Cron `App\Console\Commands\PublishScheduledPressReleases` (publiziert
|
||||
`review`-PMs mit fälligem `scheduled_at`). Beide prüfen erneut nur die
|
||||
Blacklist.
|
||||
- **API**: `App\Http\Controllers\Api\V1\PressReleaseController::store()` /
|
||||
`update()` schreiben `status` direkt aus dem Request (erlaubt: `draft`,
|
||||
`review`) und rufen `submitForReview` **nicht** auf. Eine API-PM mit
|
||||
`status=review` landet damit **ohne** Blacklist-/Quota-/Log-Prüfung in der
|
||||
Queue.
|
||||
- **UI-Einreichung (Prozess-Start)**:
|
||||
- Detailansicht ([show.blade.php]): vollständiges Modal `confirm-submit-review`
|
||||
mit rechtlichen Hinweisen, Quota-Anzeige und Bestätigungs-Checkboxen →
|
||||
ruft `submitForReview`.
|
||||
- Bearbeiten ([edit.blade.php]): Button „Speichern & zur Prüfung" mit nur
|
||||
`wire:confirm` (Browser-Dialog), **kein** Modal.
|
||||
- Erstellen ([create.blade.php]): Button „Zur Prüfung senden" ohne Modal.
|
||||
- **Kein** Datenmodell für Klassifikation/Score: keine Spalten
|
||||
`classification`, `content_score`, `content_tier`, keine Tabelle `ki_audits`.
|
||||
|
||||
## Lücken & Risiken
|
||||
|
||||
- **L1 — API-Bypass**: Einreichung über die API umgeht jede Prüfung.
|
||||
- **L2 — Keine echte Inhaltsprüfung**: nur eine triviale Wort-Blacklist; keine
|
||||
Erkennung von Werbung, Spam, rechtlich heiklen oder unseriösen Inhalten.
|
||||
- **L3 — Auto-Publish ohne Klassifikation**: geplante PMs werden vom Cron
|
||||
veröffentlicht, ohne dass eine inhaltliche Bewertung stattgefunden hat.
|
||||
- **L4 — Uneinheitlicher Prozess-Start**: das Bestätigungs-Modal existiert nur
|
||||
in der Detailansicht, nicht beim Bearbeiten/Erstellen.
|
||||
- **L5 — Kein Audit**: KI-Entscheidungen wären ohne `ki_audits` nicht
|
||||
nachvollziehbar (DSGVO / Nachweispflicht).
|
||||
|
||||
## Zielarchitektur
|
||||
|
||||
```
|
||||
Einreichung (Formular ODER API)
|
||||
│
|
||||
▼
|
||||
SubmissionService.submit() ← ein einziger Funnel
|
||||
│
|
||||
├─ Hard-Filter: Blacklist (synchron, deterministisch)
|
||||
▼
|
||||
ClassificationService.classify() ← KI (Claude), mit Fallback
|
||||
│
|
||||
├─ Rot → status=rejected, Begründung an Autor
|
||||
├─ Gelb → status=review (manuelle Queue, „äußerste Fälle")
|
||||
└─ Grün → Veröffentlichungspfad (sofort / geplant)
|
||||
│
|
||||
▼
|
||||
ki_audits (vollständiges Audit-Log jeder KI-Entscheidung)
|
||||
+
|
||||
press_releases.classification / classified_at
|
||||
+
|
||||
(später) content_score / content_tier
|
||||
```
|
||||
|
||||
Kernregeln:
|
||||
|
||||
- Formular **und** API rufen ausschließlich `SubmissionService.submit()` auf.
|
||||
Die API darf `status` nicht mehr frei setzen; `published` ist über die API
|
||||
nie erreichbar.
|
||||
- Re-Klassifikation bei jeder Änderung einer PM (Konzept §15.1: „Bei Änderung
|
||||
der PM wird neu klassifiziert").
|
||||
- Schwellen/Verhalten sind konfigurierbar (`config/scoring.php`), damit sie
|
||||
ohne Code-Änderung kalibriert werden können.
|
||||
|
||||
---
|
||||
|
||||
## Entwicklungsschritte
|
||||
|
||||
### Phase 0 — Prozess-Start im UI vereinheitlichen — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Das bestehende Einreichungs-Modal erscheint überall dort, wo eine PM
|
||||
eingereicht wird — auch beim Bearbeiten (Button „Speichern & zur Prüfung") und
|
||||
beim Erstellen (Button „Zur Prüfung senden"). Reiner UI-Schritt, kein Backend.
|
||||
|
||||
**Umsetzung:** Das Modal `confirm-submit-review` (rechtliche Hinweise, Quota,
|
||||
Bestätigungs-Checkboxen) wird in Customer-Show, -Create **und** -Edit über
|
||||
`flux:modal.trigger` geöffnet; bestätigt ruft es wie geplant
|
||||
`submitForReview` bzw. `saveAndSubmit`/`save('review')`.
|
||||
|
||||
**Umfang:**
|
||||
|
||||
- Modal `confirm-submit-review` aus `show.blade.php` in eine wiederverwendbare
|
||||
Blade-/Volt-Komponente extrahieren (z. B.
|
||||
`resources/views/livewire/components/press-release-submit-modal.blade.php`).
|
||||
- In `edit.blade.php` den `wire:confirm`-Button durch einen
|
||||
`flux:modal.trigger` ersetzen; bei Bestätigung wird wie bisher
|
||||
`saveAndSubmit` ausgeführt (erst speichern, dann einreichen).
|
||||
- In `create.blade.php` denselben Modal-Trigger vor `save('review')` schalten.
|
||||
- Texte/Checkboxen identisch zur Detailansicht halten (rechtliche Hinweise,
|
||||
Quota, Bestätigungen).
|
||||
|
||||
**Betroffene Dateien:** `resources/views/livewire/customer/press-releases/{show,edit,create}.blade.php`,
|
||||
neue Komponente unter `resources/views/livewire/components/`.
|
||||
|
||||
**Done:** In allen drei Ansichten (Customer: show/edit/create) öffnet derselbe
|
||||
Bestätigungsdialog; Tests für Edit/Create-Submit grün.
|
||||
|
||||
**Admin-Editor (`/admin/press-releases/`) — bewusst ausgenommen:** Der
|
||||
Admin-Editor behält sein bisheriges Verhalten (`wire:confirm`). Begründung: Wenn
|
||||
eine PM beim Admin landet, hat die vorgelagerte User-Prüfung (Einreichungs-Modal
|
||||
im Customer-Flow) bereits stattgefunden. Der Admin braucht hier keinen erneuten
|
||||
Bestätigungsdialog. Stattdessen erhält der Admin-Editor in einer späteren Phase
|
||||
einen zusätzlichen **„Prüfung"-Button** (siehe Phase 4: On-Demand-KI-Prüfung).
|
||||
|
||||
**Tests:** Volt-Tests, die das Öffnen des Modals und den Submit-Pfad
|
||||
(`saveAndSubmit` / `save('review')`) abdecken.
|
||||
|
||||
### Phase 1 — Einreichungs-Funnel & API-Absicherung — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Beide Einreichungsstellen laufen durch einen Pfad; die API-Lücke (L1)
|
||||
wird geschlossen. Noch ohne KI — nur Vereinheitlichung.
|
||||
|
||||
**Umsetzung:**
|
||||
|
||||
- `PressReleaseService::submitForReview()` ist der alleinige Einreichungs-Einstieg
|
||||
(Web-Formular **und** API rufen dieselbe Methode). Auf eine separate
|
||||
`SubmissionService`-Fassade wurde bewusst verzichtet — `submitForReview` ist
|
||||
bereits die stabile Schnittstelle, in die Phase 3 die KI-Klassifikation
|
||||
einhängt.
|
||||
- API: `status` aus den Validierungsregeln von `StorePressReleaseRequest` und
|
||||
`UpdatePressReleaseRequest` entfernt (inkl. ungenutzter Imports). `store()`
|
||||
erzeugt jetzt **immer** `PressReleaseStatus::Draft`; ein übergebenes `status`
|
||||
wird ignoriert. `update()` kann den Status nicht mehr setzen.
|
||||
- Neue explizite Route `POST /api/v1/press-releases/{pressRelease}/submit`
|
||||
(`press-releases.submit`) → `PressReleaseController::submit()`. Diese prüft
|
||||
`press-releases:write`, Ownership und erlaubt nur `draft`/`rejected`
|
||||
(sonst 409); ruft `submitForReview()`; eine `BlacklistViolationException`
|
||||
wird als **422** mit Begründung zurückgegeben. Damit greifen Blacklist-,
|
||||
Quota- und Status-Log-Behandlung auch für API-Einreichungen.
|
||||
- `published` ist über die API weiterhin nie erreichbar (nur Admin-Aktion/Cron).
|
||||
|
||||
**Betroffene Dateien:** `app/Http/Controllers/Api/V1/PressReleaseController.php`,
|
||||
`app/Http/Requests/Api/V1/{Store,Update}PressReleaseRequest.php`,
|
||||
`routes/api.php`. `PressReleaseService` blieb unverändert (Schnittstelle
|
||||
ausreichend).
|
||||
|
||||
**Done:** API kann keine PM mehr ungeprüft in `review` heben; eine PM-Einreichung
|
||||
verhält sich über API und Formular identisch.
|
||||
|
||||
**Tests:** `tests/Feature/Api/V1/PressReleaseSubmitApiTest.php` (Create erzeugt
|
||||
immer Draft & ignoriert `status`; Submit-Route hebt nach `review`, zählt Quota,
|
||||
schreibt Log; Blacklist → 422 + `rejected`; fehlende Schreibrechte → 403;
|
||||
bereits in `review` → 409; fremde PM → 403). Alle grün.
|
||||
|
||||
### Phase 2 — Datenmodell & Audit — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Persistenz für Klassifikation und vollständiges KI-Audit. Noch ohne
|
||||
Verhaltensänderung (alle Felder nullable).
|
||||
|
||||
**Umsetzung:**
|
||||
|
||||
- Migration `add_classification_to_press_releases`: Spalten `classification`
|
||||
(string(16), nullable, nach `status`) und `classified_at` (timestamp,
|
||||
nullable) plus Index auf `classification`. `content_score`/`content_tier`
|
||||
bewusst **erst in Phase 5** (siehe Datenmodell-Anhang).
|
||||
- Migration `create_ki_audits_table`: `press_release_id` (FK, cascade),
|
||||
`type`, `provider` (nullable), `model` (nullable), `result` (nullable),
|
||||
`reason` (text, nullable), `raw_response` (json, nullable),
|
||||
`created_at` (useCurrent), Index `(press_release_id, type)`. Kein
|
||||
`updated_at` (append-only Log).
|
||||
- Model `App\Models\KiAudit` (`$timestamps = false`, Cast `raw_response` →
|
||||
array, Konstanten `TYPE_CLASSIFICATION`/`TYPE_CONTENT_SCORE`, Relation
|
||||
`pressRelease()`), Relation `PressRelease::kiAudits()` (neueste zuerst).
|
||||
- Enum `App\Enums\PressReleaseClassification` (Green/Yellow/Red + `label()`),
|
||||
in `PressRelease::casts()` für `classification` registriert.
|
||||
- `config/scoring.php`: Anbieter/Modell-Auswahl (`CLASSIFICATION_PROVIDER`,
|
||||
Default `deterministic`, `CLASSIFICATION_MODEL`), Timeout, Grün-Verzögerung
|
||||
(Minuten), Gelb→manuelle-Queue-Flag sowie Content-Score-Stufen-Schwellen
|
||||
(Phase 5).
|
||||
- `KiAuditFactory` mit States `classification()` / `contentScore()`.
|
||||
|
||||
**Betroffene Dateien:** zwei neue Migrationen unter `database/migrations/`,
|
||||
`app/Models/PressRelease.php`, `app/Models/KiAudit.php`,
|
||||
`app/Enums/PressReleaseClassification.php`, `config/scoring.php`,
|
||||
`database/factories/KiAuditFactory.php`.
|
||||
|
||||
**Done:** Migrationen laufen; Modelle/Casts/Relation vorhanden; keine bestehende
|
||||
Funktionalität verändert (alle Felder nullable).
|
||||
|
||||
**Tests:** `tests/Feature/PressReleaseClassificationModelTest.php` (Enum-/
|
||||
Datetime-Cast, Default null, `kiAudits()`-Reihenfolge, `raw_response`-Array-Cast
|
||||
+ Relation, Cascade-Delete). Alle grün.
|
||||
|
||||
### Phase 3 — KI-Klassifikation (Red Flag) — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Echte inhaltliche Prüfung jeder Einreichung; Ergebnis asynchron als
|
||||
Klassifikation gespeichert und auditiert.
|
||||
|
||||
**Entscheidungen (11.06.2026):** Erster aktiver Anbieter ist **OpenAI** (Key/
|
||||
Budget vorhanden); Anthropic/Gemini folgen über dieselbe Treiber-Schnittstelle.
|
||||
Klassifikation läuft **asynchron über die Queue** (synchron wäre später nicht
|
||||
handelbar). Zum Testen ohne Dauer-Worker gibt es einen Drain-Befehl.
|
||||
|
||||
**Umsetzung:**
|
||||
|
||||
- **Provider-agnostische Treiber-Architektur** unter
|
||||
`app/Services/PressRelease/Classification/`:
|
||||
- Interface `Contracts\ClassificationDriver::classify(PressRelease): ClassificationResult`.
|
||||
- `ClassificationResult` (Value Object: Enum-Klassifikation, `reasons[]`,
|
||||
`provider`, `model`, `rawResponse`, `reasonText()`).
|
||||
- `Drivers\OpenAiClassificationDriver` — OpenAI Chat-Completions via
|
||||
`Http`-Client, liest `config/services.openai` (Key/URL/Modell/Timeout),
|
||||
erzwingt `response_format: json_object` und parst
|
||||
`{classification, reasons[]}`. Wirft bei fehlendem Key / HTTP-Fehler /
|
||||
ungültigem JSON.
|
||||
- `Drivers\DeterministicClassificationDriver` — Blacklist → Rot/Grün
|
||||
(nie Gelb), als Fallback ohne externe API.
|
||||
- `ClassificationManager` (Laravel-Manager) löst den Treiber aus
|
||||
`config('scoring.classification.provider')` auf
|
||||
(`createOpenaiDriver`/`createDeterministicDriver`).
|
||||
- **Asynchroner Job** `app/Jobs/ClassifyPressRelease` (Queue `classification`,
|
||||
`tries=3`): klassifiziert über den aktiven Treiber, bei Ausfall **Fallback**
|
||||
auf den deterministischen Treiber (mit `Log::warning`), schreibt
|
||||
`press_releases.classification`/`classified_at` und einen `ki_audits`-Eintrag
|
||||
(inkl. `provider`/`model`/`reason`/`raw_response`).
|
||||
- **Einbindung in den Funnel:** `PressReleaseService::submitForReview()` stößt
|
||||
nach dem synchronen Blacklist-Hard-Filter und dem Statuswechsel den Job an
|
||||
(`ClassifyPressRelease::dispatch(...)->onQueue('classification')`). Greift für
|
||||
Formular **und** API (gemeinsamer Einstieg aus Phase 1).
|
||||
- **Drain-Befehl** `php artisan classification:work` (Option `--once`): arbeitet
|
||||
die Queue einmalig ab und beendet sich (`queue:work --stop-when-empty`) — zum
|
||||
Testen ohne permanenten Worker.
|
||||
- **Konfig:** `config/scoring.php` Default-Provider auf `openai` gesetzt
|
||||
(`CLASSIFICATION_PROVIDER`); Modell leer ⇒ `config('services.openai.model')`.
|
||||
- **Test-Isolation:** `phpunit.xml` erzwingt `CLASSIFICATION_PROVIDER=deterministic`
|
||||
und leeren `OPENAI_API_KEY`, damit die Suite keine echten OpenAI-Calls macht;
|
||||
der OpenAI-Pfad wird gezielt mit `Http::fake()` getestet.
|
||||
|
||||
**Noch offen (bewusst):** Re-Klassifikation bei jeder PM-Änderung (Update über
|
||||
Formular/API) ist noch **nicht** verdrahtet — Phase 3 klassifiziert beim
|
||||
Einreichen. Nachzuziehen, wenn das Status-Routing (Phase 4) steht. Anthropic-/
|
||||
Gemini-Treiber + SDK folgen separat.
|
||||
|
||||
**Betroffene Dateien:** `app/Services/PressRelease/Classification/*`,
|
||||
`app/Jobs/ClassifyPressRelease.php`,
|
||||
`app/Console/Commands/RunClassificationQueue.php`,
|
||||
`app/Services/PressRelease/PressReleaseService.php`, `config/scoring.php`,
|
||||
`phpunit.xml`.
|
||||
|
||||
**Done:** Jede Einreichung (Formular + API) stößt asynchron eine Klassifikation
|
||||
an, erzeugt einen `ki_audits`-Eintrag; bei KI-Ausfall greift der deterministische
|
||||
Fallback nachvollziehbar. Status-Routing folgt in Phase 4.
|
||||
|
||||
**Tests:** `tests/Feature/PressReleaseClassificationJobTest.php` (OpenAI grün/gelb
|
||||
mit `Http::fake`, Fallback bei HTTP-500, deterministisch Rot bei Blacklist,
|
||||
Dispatch auf Queue `classification` via `Queue::fake`). Alle grün; volle Suite
|
||||
416 grün (2 vorbestehende WIP-Failures unverändert).
|
||||
|
||||
### Phase 4 — Routing, Auto-Publish & Review-Queue — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Die Klassifikation steuert den Status. Manuelle Prüfung nur noch bei
|
||||
Gelb.
|
||||
|
||||
**Umsetzung:**
|
||||
|
||||
- **Routing im Job** über `PressReleaseService::routeByClassification()`
|
||||
(vom `ClassifyPressRelease`-Job nach dem Klassifizieren aufgerufen):
|
||||
- **Rot** → `reject(..., source: 'ki')`: `status=rejected`, KI-Begründung per
|
||||
Mail an den Autor (`PressReleaseRejected`, wie bei Blacklist).
|
||||
- **Gelb** → keine Aktion, bleibt `review` (manuelle Admin-Queue).
|
||||
- **Grün** → `autoPublishGreen()`: ohne Termin sofort veröffentlichen,
|
||||
optional mit Sicherheitsfenster `scoring.classification.green_delay_minutes`
|
||||
(über `published_at`-Override); mit zukünftigem `scheduled_at` bleibt die PM
|
||||
in `review` und der Scheduler publiziert zum Termin.
|
||||
- Greift nur, solange die PM noch `review` ist (manuelle Admin-Eingriffe haben
|
||||
Vorrang). `publish()` erhielt einen `?Carbon $publishedAtOverride`-Parameter,
|
||||
`reject()` einen `string $source`-Parameter.
|
||||
- **Scheduler** `PublishScheduledPressReleases`: Kandidaten-Query um
|
||||
`where('classification', 'green')` erweitert — nur **grüne** fällige PMs
|
||||
werden automatisch publiziert; gelbe warten immer auf den Admin. Geplante
|
||||
Termine werden weiterhin respektiert.
|
||||
- **Admin-Review-Queue:** Index- und Show-Ansicht zeigen ein KI-Klassifikations-
|
||||
Badge (grün/gelb/rot); der Index hat einen **Klassifikations-Filter**
|
||||
(`classificationFilter`, inkl. URL-Param, Active-Chip, Reset) — damit „nur
|
||||
Gelb" filterbar. Die Show-Ansicht blendet im Review-Block den **KI-Hinweis**
|
||||
(Begründung aus dem jüngsten `ki_audits`-Eintrag) ein.
|
||||
|
||||
**Test-Isolation (wichtig):** Da Tests mit `sync`-Queue den Job inline ausführen,
|
||||
wurde der Klassifikations-Job in den „submit→review"-Tests via `Queue::fake()`
|
||||
entkoppelt (Workflow, PublishModal, API-Submit). Die Scheduler-Tests setzen jetzt
|
||||
`classification = green` für Publish-Kandidaten; neuer Test: fällige **gelbe** PM
|
||||
bleibt `review`.
|
||||
|
||||
**Betroffene Dateien:** `app/Services/PressRelease/PressReleaseService.php`,
|
||||
`app/Jobs/ClassifyPressRelease.php`,
|
||||
`app/Console/Commands/PublishScheduledPressReleases.php`, Admin-Views
|
||||
`resources/views/livewire/admin/press-releases/{index,show}.blade.php`.
|
||||
|
||||
**Done:** Grüne PMs gehen automatisch live (sofort/zum Termin), rote werden
|
||||
abgelehnt + Autor benachrichtigt, nur gelbe landen in der manuellen Queue; Admin
|
||||
sieht Klassifikation + KI-Begründung und kann nach Gelb filtern.
|
||||
|
||||
**Tests:** Routing in `PressReleaseClassificationJobTest` (Rot→rejected+Mail,
|
||||
Grün-sofort→published+Mail, Grün-geplant→bleibt review, Gelb→bleibt review);
|
||||
Scheduler in `PressReleaseSchedulingTest` (grün fällig→published, gelb
|
||||
fällig→review); Admin-UI in `PressReleaseIndexPhase8bTest` (KI-Badge,
|
||||
Klassifikations-Filter). Volle Suite 423 grün (2 vorbestehende WIP-Failures).
|
||||
|
||||
**Admin „Prüfung"-Button (On-Demand-KI-Prüfung)** — ✅ erledigt (11.06.2026):
|
||||
|
||||
- Im Admin-Editor gibt es oben den Button **„Prüfung"**, der ein Modal
|
||||
`admin-ki-check` öffnet: auswählbare Klassifikation (Content-Score als
|
||||
„in Vorbereitung" deaktiviert) und ein **Anbieter-Override** (Konfiguriert /
|
||||
OpenAI / Deterministisch).
|
||||
- `runKiCheck()` dispatcht `ClassifyPressRelease` auf der Queue `classification`
|
||||
**mit `route: false`** und optionalem `providerOverride`. Das ist eine
|
||||
nachgelagerte Re-Check-Prüfung: sie aktualisiert nur `classification` +
|
||||
`ki_audits`, **ohne** den Status zu ändern (kein Auto-Publish/Reject) — die
|
||||
Entscheidung bleibt beim Admin (Ergebnis sichtbar in der Detailansicht).
|
||||
- Dafür erhielt `ClassifyPressRelease` die Parameter `bool $route = true` und
|
||||
`?string $providerOverride = null`.
|
||||
|
||||
**Tests:** `tests/Feature/Admin/AdminKiCheckTest.php` (Button/Modal sichtbar;
|
||||
Dispatch mit `route=false` + Provider-Override; Abbruch ohne Auswahl;
|
||||
Re-Check-Job aktualisiert Bewertung, lässt Status unverändert).
|
||||
|
||||
**Re-Klassifikation bei Änderung** (Konzept §15.1) — ✅ erledigt (11.06.2026):
|
||||
|
||||
- Neue Service-Methode `reclassifyIfClassified()`: dispatcht – nur wenn die PM
|
||||
bereits klassifiziert ist – `ClassifyPressRelease` mit `route: false`
|
||||
(Re-Check ohne Statusänderung).
|
||||
- Eingehängt überall dort, wo Inhalt geändert wird, und nur bei tatsächlicher
|
||||
Änderung von Titel/Text (`wasChanged(['title', 'text'])`):
|
||||
Customer-Editor `save()`, Admin-Editor `save()`, API `update()`.
|
||||
Beim Einreichen übernimmt weiterhin `submitForReview` die (routende)
|
||||
Klassifikation.
|
||||
|
||||
**Tests:** `tests/Feature/PressReleaseReclassifyTest.php` (Service dispatcht nur
|
||||
bei vorhandener Klassifikation; API-Update klassifiziert neu bei Text-Änderung,
|
||||
nicht bei reiner Keyword-Änderung).
|
||||
|
||||
**Noch offen / Folgearbeiten:**
|
||||
|
||||
- **Live-Aktualisierung der Ansicht** nach Abschluss des Hintergrund-Jobs
|
||||
(Polling/Event) wäre ein optionales UX-Upgrade; aktuell erscheint das Ergebnis
|
||||
nach Reload/Navigation.
|
||||
- **Content-Score-Option** im Prüfungs-Modal — ✅ mit Phase 5 aktiviert (s. u.).
|
||||
|
||||
### Phase 5 — Content-Score & Stufen — ✅ erledigt (11.06.2026)
|
||||
|
||||
**Ziel:** Qualitätsbewertung 0–100 → Stufe Standard/Geprüft/Hochwertig
|
||||
(Konzept-Update 2).
|
||||
|
||||
**Umsetzung:**
|
||||
|
||||
- **Datenmodell:** Migration `add_content_score_to_press_releases` —
|
||||
`content_score` (tinyint, nullable), `content_tier` (string, nullable, Index),
|
||||
`scored_at`. Enum `App\Enums\PressReleaseContentTier`
|
||||
(Standard/Geprueft/Hochwertig) mit `fromScore()` (Schwellen aus
|
||||
`config/scoring.php`), `label()` und `isPubliclyBadged()` (Standard wird laut
|
||||
Update 2 nicht beworben). In `PressRelease` als Cast registriert.
|
||||
- **Schwellen** (`config/scoring.php`): Geprüft ≥ 60, Hochwertig ≥ 80 (Update 2),
|
||||
kalibrierbar; plus Anbieter/Modell/Timeout für den Score.
|
||||
- **Treiber-Architektur** unter `app/Services/PressRelease/ContentScore/`
|
||||
analog zur Klassifikation: `Contracts\ContentScoreDriver`, `ContentScoreResult`,
|
||||
`Drivers\OpenAiContentScoreDriver` (gewichtete Faktoren §15.2 als JSON
|
||||
`{score, breakdown}`), `Drivers\DeterministicContentScoreDriver`
|
||||
(regelbasierte Heuristik: Länge, Bild, Quelle, Headline, Vollständigkeit),
|
||||
`ContentScoreManager`.
|
||||
- **Job** `app/Jobs/ScorePressRelease` (Queue `classification`, Fallback auf
|
||||
deterministisch): schreibt `content_score` + abgeleitete `content_tier` +
|
||||
`scored_at` und `ki_audits` (type=content_score). Optionaler
|
||||
`providerOverride`.
|
||||
- **Berechnung** bei Einreichung (`submitForReview` dispatcht Klassifikation
|
||||
**und** Score) und bei Inhaltsänderung (`rescoreIfScored()` in Customer-/
|
||||
Admin-Editor und API-`update()`, analog zur Re-Klassifikation).
|
||||
- **Anzeige:**
|
||||
- Customer-Editor: Score-Panel (Punktzahl, Stufe, „noch X Punkte bis zur
|
||||
nächsten Stufe") — der produktive Editor-Score laut Update 2.
|
||||
- Admin-Index & -Show: Stufen-/Score-Badge (intern inkl. Punktzahl).
|
||||
- Customer-Detailansicht: öffentliches Stufen-Badge (✓ Geprüft / ★ Hochwertig;
|
||||
Standard ohne Badge).
|
||||
- **Admin-Prüfungs-Modal:** Content-Score-Option aktiviert; `runKiCheck()`
|
||||
dispatcht zusätzlich `ScorePressRelease`.
|
||||
|
||||
**Done:** Score wird bei Einreichung/Änderung berechnet, Stufe abgeleitet,
|
||||
auditiert und überall sichtbar.
|
||||
|
||||
**Tests:** `tests/Feature/PressReleaseContentScoreTest.php` (Tier-Mapping,
|
||||
öffentliche Badges, OpenAI-Score→Tier+Audit, Fallback, Dispatch bei Submit,
|
||||
Re-Score nur wenn bereits bewertet); Editor-Panel in
|
||||
`CustomerPressReleaseEditPhase7Test`; Stufen-Badge in `PressReleaseIndexPhase8bTest`;
|
||||
Content-Score-Dispatch in `AdminKiCheckTest`. Volle Suite 440 grün.
|
||||
|
||||
**Noch offen / Folgearbeiten:**
|
||||
|
||||
- **Public Web-Frontend** (presseecho/businessportal24): Stufen-Badges in den
|
||||
öffentlichen Listen/Detailseiten gemäß Update 2 ergänzen (bisher nur im
|
||||
Portal/Backend und der Customer-Ansicht).
|
||||
- **Score-History & Breakdown-Ansicht** (Publisher-Dashboard) und Boost-
|
||||
Eligibilität (Abschnitt 16) sind eigene spätere Ausbaustufen.
|
||||
|
||||
### Phase 6 — Trust-Score (später)
|
||||
|
||||
Account-/Firmen-Ebene (Konzept §15.3): lockert die KI-Freigabe-Schwelle für
|
||||
zuverlässige Publisher. Eigene spätere Ausbaustufe; hier nur als Ausblick
|
||||
vermerkt.
|
||||
|
||||
---
|
||||
|
||||
## Datenmodell-Anhang (Zielzustand)
|
||||
|
||||
```
|
||||
press_releases (Ergänzungen)
|
||||
+ classification enum(green,yellow,red) NULL
|
||||
+ classified_at timestamp NULL
|
||||
+ content_score tinyint NULL (Phase 5)
|
||||
+ content_tier enum(standard,gepruft,hochwertig) NULL (Phase 5)
|
||||
|
||||
ki_audits (neu)
|
||||
- id
|
||||
- press_release_id FK
|
||||
- type enum(classification,content_score)
|
||||
- provider string (z. B. anthropic)
|
||||
- model string (z. B. claude-opus-4-8)
|
||||
- result string/json
|
||||
- reason text NULL
|
||||
- raw_response json/longtext
|
||||
- created_at timestamp
|
||||
```
|
||||
|
||||
## Offene Entscheidungen
|
||||
|
||||
- **Anbieter & Modell** — ✅ entschieden (11.06.2026): Erster aktiver Anbieter
|
||||
ist **OpenAI** (`CLASSIFICATION_PROVIDER=openai`, Modell aus
|
||||
`config/services.openai`). Architektur provider-agnostisch; Anthropic/Gemini
|
||||
folgen. Offen bleibt, ob später mehrere Anbieter parallel (Primär + Fallback
|
||||
jenseits des deterministischen) laufen sollen.
|
||||
- **Synchron vs. Queue** — ✅ entschieden (11.06.2026): **Queue** (asynchron,
|
||||
Queue-Name `classification`). Drain zum Testen: `php artisan classification:work`.
|
||||
- **Dependency**: OpenAI-Treiber nutzt den nativen `Http`-Client (kein neues
|
||||
Composer-Paket). Anthropic PHP-SDK (`anthropic-ai/sdk`) ist **freigegeben**;
|
||||
für Gemini je ein offizielles/etabliertes SDK oder HTTP-Client bei Umsetzung
|
||||
des Treibers.
|
||||
- **Grün-Verzögerung**: 0 Min. (sofort) oder 5–10 Min. (Konzept-Option) als
|
||||
Sicherheitsfenster — konfigurierbar über
|
||||
`scoring.classification.green_delay_minutes`, Default noch festzulegen.
|
||||
- **Gelb-Verhalten**: ausschließlich manuelle Queue, oder zusätzlich
|
||||
automatische Benachrichtigung des Autors.
|
||||
- **DSGVO**: Aufbewahrung/Anonymisierung der `raw_response` in `ki_audits`.
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
Phasen 0–5 sind umgesetzt (Suite grün). Es folgen:
|
||||
|
||||
1. **Launch-Block aus dem Decision-Update** (siehe Abgleich-Box oben):
|
||||
Submit-Gate hinter Buchung, Slot-Verbrauch bei Veröffentlichung,
|
||||
Tarif-/Zahlungs-Modul.
|
||||
2. **Betrieb**: Queue-Worker für `classification` im Produktions-Setup
|
||||
(Test-Drain: `php artisan classification:work`).
|
||||
3. **Folgearbeiten**: Live-Aktualisierung des KI-Ergebnisses in der UI,
|
||||
Stufen-Badges im öffentlichen Web-Frontend, Anthropic-/Gemini-Treiber.
|
||||
4. **Phase 6**: Trust-Score (eigene Ausbaustufe).
|
||||
207
docs/user-admin/Lizenztyp Bildupload.md
Normal file
207
docs/user-admin/Lizenztyp Bildupload.md
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
Ich würde das Formular inhaltlich klarer machen und stärker gegen typische Bildrechts-Probleme absichern. Der aktuelle Ansatz ist gut, aber bei Presseportalen würde ich etwas präziser zwischen **Urheberrecht**, **Nutzungsrecht**, **Personenrechten** und **Quelle/Nachweis** unterscheiden.
|
||||
|
||||
## **1. Lizenztyp-Auswahl überarbeiten**
|
||||
|
||||
Aktuell hast du:
|
||||
|
||||
- Eigene Aufnahme
|
||||
- CC-Lizenz
|
||||
- Kommerzielle Lizenz erworben
|
||||
- Einwilligung des Urhebers
|
||||
- Sonstiges
|
||||
|
||||
Ich würde daraus eher machen:
|
||||
|
||||
### **Empfohlene Lizenztypen**
|
||||
|
||||
|**Option**|**Wann verwenden?**|
|
||||
|---|---|
|
||||
|**Eigene Aufnahme**|Der Uploadende hat das Bild selbst erstellt|
|
||||
|**Vom Urheber / Fotografen freigegeben**|Direkte schriftliche Erlaubnis liegt vor|
|
||||
|**Agentur-/Stockbild-Lizenz**|Bild wurde z. B. über Adobe Stock, Shutterstock, Getty etc. lizenziert|
|
||||
|**Creative-Commons-Lizenz**|Bild steht unter CC BY, CC BY-SA, CC0 etc.|
|
||||
|**Presse-/PR-Bild mit Nutzungsfreigabe**|Bild wurde z. B. von Unternehmen, Veranstaltern, Agenturen oder Pressestellen bereitgestellt|
|
||||
|**Gemeinfrei / Public Domain / CC0**|Keine oder sehr weitgehende Nutzungsbeschränkungen|
|
||||
|**Sonstige Lizenz / Sondervereinbarung**|Freitext erforderlich|
|
||||
|
||||
„Einwilligung des Urhebers“ würde ich nicht als eigenen Lizenztyp stehen lassen, sondern eher als **„Vom Urheber/Fotografen freigegeben“** formulieren. Das ist verständlicher.
|
||||
|
||||
## **2. Bei Creative Commons zusätzliche Felder anzeigen**
|
||||
|
||||
Wenn jemand **CC-Lizenz** auswählt, sollte nicht nur „CC-Lizenz“ gespeichert werden. Du brauchst genauer:
|
||||
|
||||
- CC0
|
||||
- CC BY
|
||||
- CC BY-SA
|
||||
- CC BY-ND
|
||||
- CC BY-NC
|
||||
- CC BY-NC-SA
|
||||
- CC BY-NC-ND
|
||||
|
||||
Wichtig: **NC** bedeutet „nicht-kommerziell“ und kann für ein Presseportal problematisch sein, besonders wenn die Seite werbefinanziert ist oder kommerziell betrieben wird. **ND** erlaubt keine Bearbeitung, also eventuell auch keinen Beschnitt als Titelbild.
|
||||
|
||||
Daher würde ich bei CC-Lizenzen automatisch Hinweise anzeigen, zum Beispiel:
|
||||
|
||||
Diese Lizenz kann Einschränkungen enthalten. Bitte prüfen, ob kommerzielle Nutzung, Bearbeitung und Veröffentlichung als Titelbild erlaubt sind.
|
||||
|
||||
## **3. „Urheber / Fotograf“ verpflichtender machen**
|
||||
|
||||
Das Feld **Urheber / Fotograf** sollte in den meisten Fällen Pflicht sein, außer vielleicht bei eigener Aufnahme, wenn der Name des Uploadenden automatisch hinterlegt wird.
|
||||
|
||||
Besser wäre:
|
||||
|
||||
**Urheber / Fotograf / Rechteinhaber**
|
||||
|
||||
Denn nicht immer ist der Fotograf auch der Rechteinhaber. Bei Agenturen oder Unternehmen können die Rechte woanders liegen.
|
||||
|
||||
## **4. „Copyright / Quelle“ klarer benennen**
|
||||
|
||||
Das Feld „Copyright / Quelle“ ist etwas gemischt. Ich würde es aufteilen oder klarer formulieren:
|
||||
|
||||
- **Copyright-Hinweis / Bildnachweis**
|
||||
- **Quelle des Bildes**
|
||||
- **Lizenz- oder Nachweis-URL**
|
||||
|
||||
Beispiel:
|
||||
|
||||
**Bildnachweis, wie er angezeigt werden soll**
|
||||
`Foto: Max Mustermann / Beispiel GmbH`
|
||||
|
||||
**Quelle / Fundstelle**
|
||||
`https://...`
|
||||
|
||||
**Lizenz-URL / Nachweis-URL**
|
||||
`https://creativecommons.org/licenses/by/4.0/` oder Link zur Stocklizenz / Presseseite
|
||||
|
||||
So vermeidest du, dass jemand nur „Internet“ oder „Google“ einträgt.
|
||||
|
||||
## **5. Datei-Upload um Pflicht-Hinweise ergänzen**
|
||||
|
||||
Beim Upload würde ich neben Dateityp und Größe noch einen kurzen Warnhinweis ergänzen:
|
||||
|
||||
Bitte laden Sie nur Bilder hoch, für die Sie die erforderlichen Nutzungsrechte besitzen. Bilder aus Google, Social Media, Messenger-Gruppen oder fremden Websites dürfen nicht ohne ausdrückliche Erlaubnis verwendet werden.
|
||||
|
||||
Das ist sehr hilfreich, weil genau dort viele Fehler passieren.
|
||||
|
||||
## **6. Personenrechte besser abfragen**
|
||||
|
||||
Dein Feld „Einwilligung abgebildeter Personen liegt vor“ ist gut, aber ich würde es differenzierter machen.
|
||||
|
||||
Statt nur einem Schalter:
|
||||
|
||||
**Sind Personen auf dem Bild erkennbar?**
|
||||
|
||||
- Nein
|
||||
- Ja, und die Einwilligung liegt vor
|
||||
- Ja, aber es handelt sich um eine öffentliche Veranstaltung / redaktionelle Berichterstattung
|
||||
- Unsicher
|
||||
|
||||
Wenn „Ja“ oder „Unsicher“ gewählt wird, kannst du einen Hinweis anzeigen:
|
||||
|
||||
Bei erkennbaren Personen können zusätzlich Persönlichkeits- oder Datenschutzrechte betroffen sein. Bitte stellen Sie sicher, dass eine Veröffentlichung zulässig ist.
|
||||
|
||||
Der aktuelle Toggle „Einwilligung liegt vor“ ist gut, aber er setzt voraus, dass der Nutzer selbst erkennt, ob Personenrechte relevant sind.
|
||||
|
||||
## **7. Property Rights / Marken / Kunstwerke ergänzen**
|
||||
|
||||
Neben Personen sind auch diese Fälle kritisch:
|
||||
|
||||
- Logos und Marken
|
||||
- Kunstwerke
|
||||
- private Innenräume
|
||||
- Gebäude, Architektur, Museen
|
||||
- Fahrzeuge mit Kennzeichen
|
||||
- Veranstaltungsplakate oder Screenshots
|
||||
|
||||
Ich würde daher ergänzen:
|
||||
|
||||
**Enthält das Bild erkennbare Marken, Kunstwerke, geschützte Werke oder private Orte?**
|
||||
|
||||
- Nein
|
||||
- Ja, Rechte/Nutzung sind geklärt
|
||||
- Unsicher
|
||||
|
||||
Das schützt besonders bei PR-, Event- und Pressebildern.
|
||||
|
||||
## **8. Rechtebestätigung präziser formulieren**
|
||||
|
||||
Aktuell:
|
||||
|
||||
Ich bestätige, dass ich zur Nutzung dieses Bildes berechtigt bin und alle Rechte geklärt sind.
|
||||
|
||||
Ich würde es ausführlicher und rechtlich klarer machen:
|
||||
|
||||
Ich bestätige, dass ich über die erforderlichen Rechte zur Veröffentlichung dieses Bildes verfüge. Dies umfasst insbesondere Urheberrechte, Nutzungsrechte, Persönlichkeitsrechte abgebildeter Personen sowie gegebenenfalls Marken-, Eigentums- oder sonstige Rechte Dritter. Ich bin berechtigt, das Bild auf diesem Presseportal veröffentlichen zu lassen.
|
||||
|
||||
Optional zusätzlich:
|
||||
|
||||
Mir ist bewusst, dass ich für fehlerhafte oder unvollständige Angaben verantwortlich bin.
|
||||
|
||||
Je nach Portal kannst du das etwas freundlicher formulieren, aber inhaltlich sollte es klar sein.
|
||||
|
||||
## **9. Lizenznachweis als Datei-Upload ermöglichen**
|
||||
|
||||
Sehr sinnvoll wäre ein optionaler Upload:
|
||||
|
||||
**Nachweis / Freigabe hochladen**
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
- Lizenzbestätigung
|
||||
- E-Mail-Freigabe
|
||||
- Model Release
|
||||
- Vertrag
|
||||
- Screenshot der Lizenzseite
|
||||
- Pressefreigabe
|
||||
|
||||
Das muss nicht öffentlich sichtbar sein, aber intern gespeichert werden.
|
||||
|
||||
## **10. Sichtbarer Bildnachweis im Frontend**
|
||||
|
||||
Ich würde im Formular klar anzeigen:
|
||||
|
||||
**Dieser Bildnachweis wird öffentlich angezeigt:**
|
||||
`Foto: Max Mustermann / Beispiel GmbH`
|
||||
|
||||
Viele Nutzer verstehen besser, was sie eintragen müssen, wenn sie sehen, wo es später erscheint.
|
||||
|
||||
## **11. Meine empfohlene Struktur**
|
||||
|
||||
So würde ich das Formular aufbauen:
|
||||
|
||||
1. **Bild hochladen**
|
||||
2. **Titel / Alt-Text**
|
||||
3. **Bildnachweis, öffentlich sichtbar**
|
||||
4. **Urheber / Fotograf / Rechteinhaber**
|
||||
5. **Lizenztyp**
|
||||
6. **Lizenzdetails je nach Auswahl**
|
||||
7. **Quelle / Lizenz-URL**
|
||||
8. **Personen auf dem Bild?**
|
||||
9. **Marken, Kunstwerke oder private Orte sichtbar?**
|
||||
10. **Nachweis/Freigabe hochladen**
|
||||
11. **Rechte bestätigen**
|
||||
|
||||
Zusätzlich würde ich **Alt-Text** ergänzen. Nicht primär wegen Recht, sondern wegen Barrierefreiheit und SEO.
|
||||
|
||||
## **Konkrete Anpassung deiner Felder**
|
||||
|
||||
Aus deinem Screenshot würde ich ändern:
|
||||
|
||||
**„Copyright / Quelle“**→ **„Öffentlicher Bildnachweis“**
|
||||
|
||||
**„Urheber / Fotograf“**→ **„Urheber / Fotograf / Rechteinhaber“**
|
||||
|
||||
**„Lizenz-URL optional“**→ **„Quelle oder Lizenznachweis-URL“**
|
||||
|
||||
**„Einwilligung abgebildeter Personen liegt vor“**
|
||||
→ ersetzen durch Auswahl:
|
||||
**„Sind erkennbare Personen abgebildet?“**
|
||||
|
||||
**„Bildrechte bestätigt“**
|
||||
→ Pflicht-Checkbox mit ausführlicher Bestätigung.
|
||||
|
||||
## **Besonders wichtig**
|
||||
|
||||
Ich würde **„Sonstiges“ nie ohne Pflicht-Freitext erlauben**. Wenn jemand „Sonstiges“ wählt, sollte zwingend erklärt werden müssen, warum die Nutzung erlaubt ist.
|
||||
|
||||
Außerdem würde ich bei riskanten Angaben wie **CC-NC**, **CC-ND**, **Unsicher**, **Sonstiges** oder fehlender Lizenz-URL entweder eine Warnung anzeigen oder eine manuelle Prüfung durch die Redaktion auslösen.
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
|
||||
|
||||
> **Stand der Doku**: 21.05.2026 — dieses Konzept beschreibt den Zielzustand
|
||||
> der Plattform. Mehrere Themen (KI-Vorprüfung, externe Meldungen, Tarife,
|
||||
> Magic-Link-Flow, Korrektur-Hinweise, Score-System) sind konzeptuell hier
|
||||
> ausgearbeitet, aber noch nicht oder nur rudimentär gebaut. Welcher Teil
|
||||
> in welchem Zustand ist, steht jeweils in einer **„IST-Stand"-Box** am
|
||||
> Anfang des betroffenen Abschnitts.
|
||||
> **Stand der Doku**: 11.06.2026 — dieses Konzept beschreibt den Zielzustand
|
||||
> der Plattform. Umgesetzt sind inzwischen die KI-Prüfung (§1, §15.1/15.2)
|
||||
> und Bilder/Lizenzen (§2); offen bleiben externe Meldungen, Magic-Link-Flow,
|
||||
> Korrektur-Hinweise und Trust-Score. Welcher Teil in welchem Zustand ist,
|
||||
> steht jeweils in einer **„IST-Stand"-Box** am Anfang des Abschnitts.
|
||||
>
|
||||
> **Für Tarife/Credits (§8–10) gilt das
|
||||
> [`Decision-Update Preisstruktur & Veröffentlichungs-Flow`](../Decision-Update%20Preisstruktur%20&%20Ver%C3%B6ffentlichungs-Flow.md).**
|
||||
>
|
||||
> Aktueller Code-vs-Konzept-Abgleich: [`docs/STATUS-ABGLEICH-USER-PANEL.md`](../STATUS-ABGLEICH-USER-PANEL.md).
|
||||
|
||||
|
|
@ -14,14 +16,21 @@
|
|||
|
||||
## 1. KI-Freigabe-Workflow für Pressemitteilungen
|
||||
|
||||
> **IST-Stand 21.05.2026**: Die hier beschriebene KI-Vorpruefung ist noch
|
||||
> nicht implementiert. Aktuell laeuft beim Submit zur Pruefung lediglich ein
|
||||
> Blacklist-Check (`PressReleaseService::submitForReview` wirft
|
||||
> `BlacklistViolationException` bei Treffern). Die Freigabe selbst erfolgt
|
||||
> manuell durch einen Admin/Editor ueber die Admin-PM-Show-Page (Status:
|
||||
> `draft → review → published | rejected | archived`).
|
||||
> Der hier beschriebene Drei-Stufen-Workflow mit KI-Klassifikation,
|
||||
> JSON-Antwort und Logging ist ein Phase-2/3-Thema.
|
||||
> **IST-Stand 11.06.2026**: Der Drei-Stufen-Workflow ist **umgesetzt**
|
||||
> (Detail-Doku: `Entwicklungsplan KI-Pruefung und Veroeffentlichung.md`,
|
||||
> Phasen 0–5):
|
||||
>
|
||||
> - Jede Einreichung (Formular + API) laeuft durch den Blacklist-Hard-Filter
|
||||
> und wird anschliessend asynchron KI-klassifiziert (Rot/Gelb/Gruen,
|
||||
> OpenAI-Treiber mit deterministischem Fallback, Queue `classification`).
|
||||
> - Routing: Rot → `rejected` + Mail mit Begruendung, Gelb → manuelle
|
||||
> Admin-Queue, Gruen → Auto-Publish (sofort oder zum geplanten Termin).
|
||||
> - Jede Entscheidung wird in `ki_audits` protokolliert (Provider, Modell,
|
||||
> Begruendung, Raw-Response); Re-Klassifikation bei Titel-/Text-Aenderung.
|
||||
> - Zusaetzlich umgesetzt: Content-Score 0–100 → Stufe (§15.2).
|
||||
>
|
||||
> Offen: Trust-Score (§15.3), Live-Anzeige des Ergebnisses ohne Reload,
|
||||
> DSGVO-Aufbewahrungsregel fuer `raw_response`.
|
||||
|
||||
### Ziel
|
||||
|
||||
|
|
@ -90,19 +99,19 @@ KI-Prüfungen müssen nachvollziehbar sein, dürfen aber nicht unbegrenzt und un
|
|||
|
||||
## 2. Bilder & Lizenzen
|
||||
|
||||
> **IST-Stand 21.05.2026**: Der Bild-Upload ist nur teilweise umgesetzt.
|
||||
> Aktuell:
|
||||
> **IST-Stand 11.06.2026**: Lizenz-/Rechteerfassung und Titelbild sind
|
||||
> umgesetzt (Phase 8F–8H + Umbau 10./11.06., Detail-Doku:
|
||||
> `Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md`,
|
||||
> Fachvorgabe: `Lizenztyp Bildupload.md`):
|
||||
>
|
||||
> - Nur Quelle „Eigenes Bild hochladen". Stock und KI sind nicht angebunden.
|
||||
> - Im `press-release-images-manager` werden bisher nur `title` und
|
||||
> `copyright` als Freitext erfasst — die im folgenden geforderten
|
||||
> Pflichtfelder (Urheber, Lizenz-Typ, Lizenz-URL, Personen-Einwilligung,
|
||||
> Rechte-Bestaetigung) sind in Phase 8H eingeplant.
|
||||
> - Variantenbildung (`thumb` / `medium` / `large`) erfolgt automatisch
|
||||
> ueber `App\Services\Image\ImageService`.
|
||||
> - `is_preview`-Flag im Modell `PressReleaseImage` ist da; jede PM kann
|
||||
> genau ein Vorschaubild haben. Default-SVG-Platzhalter fuer PMs ohne
|
||||
> Titelbild sind in Phase 8F/8G in Planung.
|
||||
> - Ein **Titelbild pro PM** (Cover-Variante 1280×580, Original wird nach
|
||||
> Verarbeitung geloescht) oder SVG-Platzhalter aus dem zentralen Set
|
||||
> (`App\Enums\PressReleasePlaceholder`, `PressReleaseCoverImage`-Resolver).
|
||||
> - Vollstaendiges Rechteformular: Urheber, 7 Lizenztypen, Lizenzdetails,
|
||||
> Lizenz-/Quell-URL, Personen- und Sachrechte-Status, interne Notizen,
|
||||
> Rechte-Bestaetigung; bedingte Pflichtfelder + Risikohinweise.
|
||||
> - Nur Quelle „Eigenes Bild hochladen". **Stock und KI sind nicht
|
||||
> angebunden** (weiterhin offen, ebenso der KI-Wasserzeichen-Check).
|
||||
|
||||
### Upload-Workflow
|
||||
|
||||
|
|
@ -515,19 +524,24 @@ Eigene Statistiken trennen:
|
|||
|
||||
## 8. Preismodell – Tarife (überarbeitet)
|
||||
|
||||
> **IST-Stand 21.05.2026**: Das Tarif- und Credit-System ist noch nicht
|
||||
> **⚠️ Ueberschrieben (11.06.2026)**: Die Abschnitte 8, 9 und 10 sind durch
|
||||
> das [`Decision-Update Preisstruktur & Veröffentlichungs-Flow`](../Decision-Update%20Preisstruktur%20&%20Ver%C3%B6ffentlichungs-Flow.md)
|
||||
> ersetzt. Wichtigste Aenderungen: Kontingente Pro 25 / Agency 60 (statt
|
||||
> 60/150), Jahrespreis als „2 Monate gratis", Bonus-Credits aus der
|
||||
> Tarif-Tabelle entfernt, Launch-Credits auf Extra-PM / Boost /
|
||||
> PDF-Nachweis reduziert, Slot-Verbrauch erst bei Veroeffentlichung.
|
||||
> Der folgende Text bleibt als urspruengliche Zielvorstellung erhalten.
|
||||
>
|
||||
> **IST-Stand 11.06.2026**: Das Tarif- und Credit-System ist noch nicht
|
||||
> implementiert. Es gibt:
|
||||
>
|
||||
> - Eine Tabelle `user_payment_options` (mit Pivot zu `companies`).
|
||||
> - Eine Tabelle `invoices` (aktuell + Legacy ueber `legacy_invoices`).
|
||||
> - Keine Tarif-Stufen, kein Kontingent-Counter pro User, keine
|
||||
> Stripe-Anbindung, kein Auto-Refill.
|
||||
>
|
||||
> Phase 8 (siehe `docs/PHASE-8-USER-PANEL-PLAN.md`) bereitet die
|
||||
> Kontingent-Anzeige im Veroeffentlichungs-Modal vor — mit zwei
|
||||
> temporaeren Spalten auf `users` (`press_release_quota`,
|
||||
> `press_release_quota_used_this_month`) als Stub, damit das echte
|
||||
> Tarif-Modell spaeter ohne UI-Aenderung andocken kann.
|
||||
> - Keine Tarif-Stufen, keine Stripe-Anbindung, kein Auto-Refill.
|
||||
> - Den Phase-8-**Quota-Stub** auf `users` (`press_release_quota`,
|
||||
> `press_release_quota_used_this_month`) samt Kontingent-Anzeige im
|
||||
> Veroeffentlichungs-Modal — zaehlt aktuell beim Einreichen, laut
|
||||
> Decision-Update kuenftig bei Veroeffentlichung.
|
||||
|
||||
### Grundlogik
|
||||
|
||||
|
|
@ -854,6 +868,11 @@ retention_policies
|
|||
|
||||
## Abschnitt 15: Score-Architektur
|
||||
|
||||
> **IST-Stand 11.06.2026**: §15.1 (Klassifikations-Score Rot/Gelb/Grün) und
|
||||
> §15.2 (Content-Score 0–100 → Stufe) sind **umgesetzt** — siehe
|
||||
> `Entwicklungsplan KI-Pruefung und Veroeffentlichung.md` (Phasen 2–5).
|
||||
> §15.3 (Trust-Score) ist weiterhin offen (Phase 3).
|
||||
|
||||
Die Plattform arbeitet mit drei voneinander unabhängigen Scores. Sie haben unterschiedliche Funktionen, werden unterschiedlich berechnet und an unterschiedlichen Stellen wirksam. Die Trennung ist zentral, weil sie unterschiedliche Datenmodelle und Update-Logiken betrifft.
|
||||
|
||||
### 15.1 Klassifikations-Score (Eintritts-Filter)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,277 @@
|
|||
# Umsetzung Pressemitteilung bearbeiten: Titelbild, Rechte, Veröffentlichung
|
||||
|
||||
Stand: 11.06.2026
|
||||
|
||||
Diese Notiz dokumentiert die zuletzt umgesetzten Anpassungen an der Bearbeitung von Pressemitteilungen im User Panel und an den parallel genutzten Admin-Formularen.
|
||||
|
||||
## Betroffener Bereich
|
||||
|
||||
- Customer Create/Edit: `resources/views/livewire/customer/press-releases/create.blade.php`
|
||||
- Customer Edit: `resources/views/livewire/customer/press-releases/edit.blade.php`
|
||||
- Admin Create/Edit: `resources/views/livewire/admin/press-releases/create.blade.php`, `resources/views/livewire/admin/press-releases/edit.blade.php`
|
||||
- Show/Index (Customer + Admin) für die Termin-Anzeige: `resources/views/livewire/customer/press-releases/{show,index}.blade.php`, `resources/views/livewire/admin/press-releases/{show,index}.blade.php`
|
||||
- Model (Zeitzonen-Konstante + Accessoren): `app/Models/PressRelease.php`
|
||||
- Titelbild-Manager: `resources/views/livewire/components/press-release-images-manager.blade.php`
|
||||
- Platzhalter-Auswahl: `resources/views/livewire/components/press-release-placeholder-picker.blade.php`
|
||||
- Platzhalter-Dateien: `public/images/press-release-placeholders`
|
||||
- Layout-CSS: `resources/css/shared/hub-components.css`
|
||||
|
||||
## Titelbild-Platzhalter
|
||||
|
||||
Die Platzhalter für Pressemitteilungs-Titelbilder wurden erweitert.
|
||||
|
||||
- Die Varianten werden über `App\Enums\PressReleasePlaceholder` verwaltet.
|
||||
- Die SVG-Dateien liegen lokal unter `public/images/press-release-placeholders`.
|
||||
- Der Picker lädt die lokalen Varianten in `resources/views/livewire/components/press-release-placeholder-picker.blade.php`.
|
||||
- Das Modal wurde für mehr Varianten verbreitert und mit einer scrollbaren Grid-Darstellung versehen.
|
||||
|
||||
Ziel: Wenn noch kein eigenes Titelbild vorhanden ist, kann ein optisch passender Platzhalter gewählt werden.
|
||||
|
||||
## Titelbild-Upload
|
||||
|
||||
Der Upload wurde auf ein einzelnes Titelbild begrenzt.
|
||||
|
||||
- Es kann vorerst nur ein Titelbild pro Pressemitteilung hochgeladen werden.
|
||||
- Wenn ein Titelbild vorhanden ist, wird die Platzhalter-Card ausgeblendet.
|
||||
- Das Upload-Formular wird ebenfalls ausgeblendet, solange ein Titelbild existiert.
|
||||
- Das vorhandene Titelbild wird in einer eigenen Bild-Card angezeigt.
|
||||
- In der Bild-Card werden Titel, Größe und Bildnachweis/Copyright angezeigt.
|
||||
- Das Titelbild kann gelöscht werden; danach erscheinen Platzhalter und Upload-Formular wieder.
|
||||
|
||||
Das Upload-Formular ist einklappbar:
|
||||
|
||||
- Im Ausgangszustand erscheint nur der Hinweis, dass ein Titelbild fehlt.
|
||||
- Über „Eigenes Titelbild hochladen" wird das Formular geöffnet.
|
||||
- Über „Abbrechen" wird das Formular wieder geschlossen und zurückgesetzt.
|
||||
|
||||
## Bildverarbeitung und Speicherverhalten
|
||||
|
||||
Die Bildverarbeitung wurde auf die Titelbild-Nutzung optimiert.
|
||||
|
||||
- Erlaubte Formate: JPG, PNG, WebP.
|
||||
- Maximale Dateigröße: 16 MB.
|
||||
- Nicht previewfähige Dateien wie TIFF lösen keine Livewire-Preview-Exception mehr aus; sie werden über die Validierung abgefangen.
|
||||
- Für Pressemitteilungsbilder wird eine Cover-Variante erzeugt: 1280 x 580 px.
|
||||
- Der kanonische Bildpfad zeigt auf die Cover-Variante.
|
||||
- Das Original wird nach der Variantenerzeugung gelöscht, um Speicherplatz zu sparen.
|
||||
- Breite und Höhe in der Oberfläche beziehen sich auf die gespeicherte Cover-Version, nicht auf das Original.
|
||||
|
||||
Relevante Datei: `app/Services/Image/ImageService.php`.
|
||||
|
||||
## Lizenz- und Rechteformular
|
||||
|
||||
Das Formular wurde an die Vorgaben aus `docs/user-admin/Lizenztyp Bildupload.md` angepasst.
|
||||
|
||||
Erfasste Felder:
|
||||
|
||||
- Titel / Alt-Text über das bestehende `title`-Feld.
|
||||
- Öffentlicher Bildnachweis über das bestehende `copyright`-Feld.
|
||||
- Urheber / Fotograf / Rechteinhaber über `author`.
|
||||
- Lizenztyp über `license_type`.
|
||||
- Lizenzdetails über `license_detail`.
|
||||
- Lizenz-URL über `license_url`.
|
||||
- Quelle / Fundstelle über `source_url`.
|
||||
- Personenrechte über `people_rights_status`.
|
||||
- Marken, Kunstwerke, geschützte Werke oder private Orte über `property_rights_status`.
|
||||
- Interne Notizen über `rights_notes`.
|
||||
- Rechtebestätigung über `rights_confirmed_at`.
|
||||
|
||||
Lizenztypen:
|
||||
|
||||
- Eigene Aufnahme
|
||||
- Creative-Commons-Lizenz
|
||||
- Agentur-/Stockbild-Lizenz
|
||||
- Vom Urheber / Fotografen freigegeben
|
||||
- Presse-/PR-Bild mit Nutzungsfreigabe
|
||||
- Gemeinfrei / Public Domain / CC0
|
||||
- Sonstige Lizenz / Sondervereinbarung
|
||||
|
||||
Wichtige Regeln:
|
||||
|
||||
- „Bitte wählen" ist der Ausgangszustand.
|
||||
- „Unsicher" wurde aus den Auswahlmöglichkeiten entfernt.
|
||||
- Am Ende muss der Uploadende die Verantwortung für die Rechte bestätigen.
|
||||
- Creative-Commons-Lizenzen erfassen zusätzlich die konkrete CC-Variante.
|
||||
- CC-, Stock-/Agentur- und Presse-/PR-Lizenzen verlangen eine Lizenz- oder Nachweis-URL.
|
||||
- „Sonstige Lizenz / Sondervereinbarung" verlangt einen Pflicht-Freitext.
|
||||
- Risikohinweise werden bei eingeschränkten oder unklaren Lizenzfällen angezeigt.
|
||||
|
||||
Relevante Dateien:
|
||||
|
||||
- `app/Enums/ImageLicenseType.php`
|
||||
- `app/Models/PressReleaseImage.php`
|
||||
- `database/migrations/2026_06_10_154249_add_rights_detail_fields_to_press_release_images_table.php`
|
||||
- `resources/views/livewire/components/press-release-images-manager.blade.php`
|
||||
|
||||
## Veröffentlichung
|
||||
|
||||
Die Veröffentlichungs-Box wurde vereinfacht.
|
||||
|
||||
Sichtbar sind nur noch:
|
||||
|
||||
- Sofort nach Freigabe
|
||||
- Geplanter Termin
|
||||
|
||||
Embargo / Sperrfrist wurde in den Formularen aus der Oberfläche entfernt, weil es aktuell noch keine sinnvolle Anwendung im User-Flow gibt.
|
||||
|
||||
Technisches Verhalten:
|
||||
|
||||
- `scheduled_at` bleibt erhalten und wird weiterhin gespeichert.
|
||||
- `embargo_at` wird in den betroffenen Formularen nicht mehr gesetzt und beim Speichern auf `null` geführt.
|
||||
- Für den geplanten Termin wird `flux:date-picker` für das Datum verwendet.
|
||||
- Für die Uhrzeit wird `flux:time-picker` verwendet.
|
||||
- Intern werden Datum und Uhrzeit wieder zu `scheduledAt` kombiniert.
|
||||
- Der geplante Termin muss mindestens 5 Minuten in der Zukunft liegen.
|
||||
- Bei zu frühem Termin wird direkt ein Fehler gesetzt; beim Speichern greift die Validierung ebenfalls.
|
||||
|
||||
Betroffene Properties:
|
||||
|
||||
- `scheduledDate`
|
||||
- `scheduledTime`
|
||||
- `scheduledAt`
|
||||
|
||||
## Zeitzonen-Handling für geplante Veröffentlichung
|
||||
|
||||
Stand: 11.06.2026 (nachgezogen)
|
||||
|
||||
Die Anwendung läuft serverseitig in UTC (`config/app.php` → `timezone = 'UTC'`).
|
||||
Geplante Termine werden aber von Redaktion und Kunden in **deutscher Zeit**
|
||||
gedacht. Vorher wurde die im Formular eingegebene Uhrzeit naiv als UTC
|
||||
interpretiert, wodurch die Veröffentlichung um den Berlin-Offset (im Sommer
|
||||
+2 h) verschoben stattfand. Das ist behoben.
|
||||
|
||||
Grundprinzip:
|
||||
|
||||
- Eingabe und Anzeige erfolgen in **Europe/Berlin**.
|
||||
- Gespeichert wird weiterhin **UTC**.
|
||||
- Wichtig: Laravel konvertiert beim Speichern **nicht** automatisch nach UTC.
|
||||
Deshalb wird der eingegebene Wert beim Parsen explizit als Berlin
|
||||
interpretiert und mit `->utc()` umgewandelt; beim Laden wird umgekehrt von
|
||||
UTC nach Berlin gewandelt.
|
||||
|
||||
Zentrale Stelle:
|
||||
|
||||
- `App\Models\PressRelease::DISPLAY_TIMEZONE` (`'Europe/Berlin'`) ist die
|
||||
Single Source of Truth.
|
||||
- `PressRelease::scheduledAtLocal()` und `PressRelease::embargoAtLocal()`
|
||||
liefern die Termine in der Anzeige-Zeitzone für alle Views.
|
||||
|
||||
Verhalten in den Formularen (Customer **und** Admin, Create **und** Edit):
|
||||
|
||||
- Helper `scheduledAtUtc()`: parst die naiven Eingabefelder als Berlin und
|
||||
gibt den UTC-Zeitpunkt für die Speicherung zurück.
|
||||
- Die „mind. 5 Minuten in der Zukunft"-Prüfung läuft jetzt über eine
|
||||
zeitzonenbewusste Closure-Regel statt über die naive `after:`-Regel.
|
||||
- Beim Bearbeiten (`mount`) wird `scheduled_at` von UTC nach Berlin gewandelt,
|
||||
bevor Datum/Uhrzeit in die Eingabefelder gefüllt werden.
|
||||
|
||||
Anzeige (lokalisiert auf Berlin):
|
||||
|
||||
- Customer-Show/-Index und Admin-Show/-Index: geplanter Termin und Embargo
|
||||
werden über `scheduledAtLocal()` / `embargoAtLocal()` ausgegeben.
|
||||
|
||||
Bewusst (noch) nicht umgestellt:
|
||||
|
||||
- `published_at`, `created_at` und die Status-Log-Zeitstempel werden weiterhin
|
||||
in UTC angezeigt. Eine vollständige Anzeige-Lokalisierung dieser Felder ist
|
||||
als Folgeschritt vorgesehen.
|
||||
|
||||
## Aufräumung: Scheduling-Logik und Queries
|
||||
|
||||
Im Zuge der Zeitzonen-Umstellung wurden zwei Altlasten in allen vier
|
||||
PM-Formularen bereinigt:
|
||||
|
||||
- **Doppelte Termin-Synchronisierung entfernt:** Die Termin-Logik lief vorher
|
||||
sowohl im generischen `updated()`-Hook als auch in den spezifischen
|
||||
`updated{PublishMode,ScheduledDate,ScheduledTime}`-Hooks – also doppelt.
|
||||
`updated()` enthält jetzt nur noch die generische Re-Validierung bereits
|
||||
fehlerhafter Felder; die Synchronisierung liegt ausschließlich in den
|
||||
spezifischen Hooks.
|
||||
- **Redundante Queries reduziert:** Im Customer-Edit wird die geladene
|
||||
Pressemitteilung pro Request memoisiert (`mount()`, `with()` und `save()`
|
||||
greifen sonst jeweils mit einer eigenen Query auf dieselbe PM zu).
|
||||
|
||||
## Responsive Layout
|
||||
|
||||
Das Layout der Pressemitteilungsformulare wurde entkoppelt von der globalen Sidebar-Logik.
|
||||
|
||||
Die globale Flux-Sidebar bleibt im stabilen Standardzustand:
|
||||
|
||||
- `flux:sidebar sticky stashable`
|
||||
- Header- und Toggle-Sichtbarkeit weiter über `lg:hidden`
|
||||
|
||||
Das eigentliche Formularlayout wird über eigene Klassen gesteuert:
|
||||
|
||||
- `.pr-editor-layout`
|
||||
- `.pr-editor-side`
|
||||
|
||||
Regel in `resources/css/shared/hub-components.css`:
|
||||
|
||||
```css
|
||||
@media (min-width: 1180px) {
|
||||
.pr-editor-layout {
|
||||
grid-template-columns: minmax(0, 1fr) 360px;
|
||||
}
|
||||
|
||||
.pr-editor-side {
|
||||
position: sticky;
|
||||
top: 1rem;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Verhalten:
|
||||
|
||||
- Unter 1180 px steht die rechte Formularbox unterhalb des Hauptinhalts.
|
||||
- Ab 1180 px steht die rechte Formularbox wieder rechts.
|
||||
- Die rechte Box wird ab 1180 px sticky.
|
||||
- Die globale linke Navigation bleibt davon unberührt.
|
||||
|
||||
## Button-Varianten
|
||||
|
||||
Sekundäre `variant="ghost"`-Buttons in Blade-Views wurden breit auf `variant="filled"` umgestellt, weil die Ghost-Buttons optisch zu wenig als Buttons erkennbar waren.
|
||||
|
||||
Umfang:
|
||||
|
||||
- Alle Blade-Views unter `resources/views` wurden auf verbleibende `variant="ghost"` geprüft.
|
||||
- Markdown-Dokumentation wurde dabei nicht als UI geändert.
|
||||
|
||||
## Tests und Verifikation
|
||||
|
||||
Ergänzte bzw. angepasste Tests:
|
||||
|
||||
- `tests/Feature/PressReleasePlaceholderTest.php`
|
||||
- `tests/Feature/PressReleaseImageLicenseTest.php`
|
||||
- `tests/Feature/CustomerPressReleaseSchedulingFormTest.php`
|
||||
- `tests/Feature/Admin/AdminPressReleaseSchedulingTest.php`
|
||||
|
||||
Für die Zeitzonen-Umstellung zusätzlich angepasst (Assertions auf
|
||||
Berlin-Werte umgestellt):
|
||||
|
||||
- `tests/Feature/PressReleaseShowPhase8aTest.php`
|
||||
- `tests/Feature/Admin/AdminPressReleaseShowTest.php`
|
||||
|
||||
Zuletzt erfolgreich ausgeführte Checks:
|
||||
|
||||
- `php artisan test --compact tests/Feature/CustomerPressReleaseSchedulingFormTest.php tests/Feature/Admin/AdminPressReleaseSchedulingTest.php tests/Feature/Admin/AdminPressReleaseShowTest.php tests/Feature/PressReleaseShowPhase8aTest.php tests/Feature/PressReleaseIndexPhase8bTest.php`
|
||||
- `vendor/bin/pint --dirty --format agent`
|
||||
- Volle Suite: 400 passed (die zwei roten Tests `PressReleaseImageApiTest` und
|
||||
`CustomerPressReleaseCreatePhase7Test` sind vorbestehende, unabhängige WIP-
|
||||
Failures – per Stash-Test verifiziert, dass sie auch ohne diese Änderungen
|
||||
scheitern).
|
||||
|
||||
Vorher zusätzlich grün gelaufen:
|
||||
|
||||
- `php artisan test --compact tests/Feature/PressReleasePlaceholderTest.php tests/Feature/PressReleaseImageLicenseTest.php tests/Feature/CustomerPressReleaseEditPhase7Test.php`
|
||||
- Phase-8-nahe Show-/Index-/Attachment-/Admin-Tests.
|
||||
|
||||
## Bewusst noch nicht umgesetzt
|
||||
|
||||
- Optionaler Upload von Lizenznachweisen oder Freigabe-Dokumenten.
|
||||
- Reaktivierung des separaten Anhang-Managers.
|
||||
- Manuelle redaktionelle Prüf-Workflows für riskante Lizenzfälle.
|
||||
- Vollständige Medienbibliothek statt einzelnes Titelbild.
|
||||
- Frontend-Ausgabe des Bildnachweises außerhalb der Bearbeitungsoberfläche, sofern noch nicht separat angebunden.
|
||||
- Anzeige-Lokalisierung von `published_at`, `created_at` und Status-Log-Zeitstempeln (aktuell weiterhin UTC).
|
||||
- Klärung/Anpassung der Auto-Publish-Policy: geplante PMs (Status `review` + fälliger `scheduled_at`) werden vom Scheduler-Command automatisch veröffentlicht – ohne separate redaktionelle Freigabe. Wird in einem eigenen Schritt geprüft.
|
||||
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
# Checkliste User Backend
|
||||
|
||||
Stand: 21.05.2026 (Phase 7 abgeschlossen, Phase 8 in Planung)
|
||||
Stand: 11.06.2026 (Phase 7 + Phase 8 + KI-Pruef-Pipeline abgeschlossen; naechster Block: Zahlung/Tarife + Veroeffentlichungs-Flow laut Decision-Update)
|
||||
|
||||
Diese Checkliste fasst den aktuellen Stand des User Backends zusammen und trennt erledigte Punkte von den naechsten sinnvollen Umsetzungsschritten.
|
||||
|
||||
Begleitende Dokumente:
|
||||
|
||||
- `docs/STATUS-ABGLEICH-USER-PANEL.md` — Konzept-vs-Code-Abgleich pro Page.
|
||||
- `docs/PHASE-8-USER-PANEL-PLAN.md` — Detail-Plan der naechsten Sub-Paeckchen.
|
||||
- `docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md` — verbindliche Launch-Entscheidungen zu Tarifen, Kontingenten und Flow.
|
||||
- `docs/user-admin/Entwicklungsplan KI-Pruefung und Veroeffentlichung.md` — KI-Klassifikation + Content-Score (Phasen 0–5 erledigt).
|
||||
- `docs/user-admin/Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md` — Titelbild/Lizenzformular/Zeitzonen-Umbau (10./11.06.).
|
||||
- `docs/PHASE-8-USER-PANEL-PLAN.md` — Phase-8-Plan (abgeschlossen).
|
||||
- `dev/frontend/hub-flux/19-PHASE-7-PRESS-RELEASE-FORM.md` — Phase-7-Abschluss.
|
||||
- `dev/frontend/hub-flux/PROGRESS.md` — Tagebuch der Hub-Migration.
|
||||
|
||||
|
|
@ -71,42 +74,83 @@ Begleitende Dokumente:
|
|||
- [x] Smooth-Scrolling zum ersten Validation-Fehler nach Save (`resources/js/portal-form-hooks.js`).
|
||||
- [x] Pre-Submit-Check-Liste (`@computed presubmitChecks`) zeigt vor dem Einreichen offene Pflichtfelder und Empfehlungen.
|
||||
|
||||
## Phase 8 — User-Panel-Konsolidierung (in Planung)
|
||||
## Phase 8 — User-Panel-Konsolidierung (abgeschlossen)
|
||||
|
||||
Vollstaendiger Plan: `docs/PHASE-8-USER-PANEL-PLAN.md`.
|
||||
Vollstaendiger Plan: `docs/PHASE-8-USER-PANEL-PLAN.md`. Roadmap-Abschluss:
|
||||
`dev/frontend/hub-flux/20-PHASE-8-USER-PANEL.md`.
|
||||
|
||||
- [ ] Show-Page-Luecken schliessen (Subtitle, Scheduling, Embargo, Boilerplate-Override) — Customer + Admin (8A).
|
||||
- [ ] Listen-Indikatoren fuer geplante Veroeffentlichung und Embargo (8B).
|
||||
- [ ] Pressekontakt-Warn-Box in Sidebar-Card, wenn kein Kontakt gewaehlt (8C).
|
||||
- [ ] Doku-Pflege: `docs/user-admin/*` an IST-Stand ziehen (8D, dieses Dokument).
|
||||
- [ ] Firmen-Liste auf Mockup-Niveau (Counter-Strip, Saved-Views, Filter-Chips, Card/List-Toggle, Rollen-Legende) (8E).
|
||||
- [ ] Set wiederverwendbarer SVG-Platzhalter fuer PM-Titelbilder + Auswahl-Modal (8F).
|
||||
- [ ] Titelbild-Schema in `press_releases` (Default-Platzhalter pro PM, `PressReleaseCoverImage`-Resolver) (8G).
|
||||
- [ ] FluxUI `flux:file-upload` im Image-Manager inkl. Pflichtfelder fuer Urheber, Lizenz-Typ, Lizenz-URL, Rechte-Bestaetigung (8H).
|
||||
- [ ] Veroeffentlichungs-Modal mit rechtlichen Hinweisen + Kontingent-Anzeige (Customer) (8I).
|
||||
- [ ] Kontingent-Stub im Datenmodell (Spalten auf `users`, monatlicher Reset-Command) als Vorbereitung fuer das Tarif-Modul (8J).
|
||||
- [ ] Tests, Pint, Build, Roadmap-Update (8K).
|
||||
- [x] Show-Page-Luecken schliessen (Subtitle, Scheduling, Embargo, Boilerplate-Override) — Customer + Admin (8A).
|
||||
- [x] Listen-Indikatoren fuer geplante Veroeffentlichung und Embargo (8B).
|
||||
- [x] Pressekontakt-Warn-Box in Sidebar-Card, wenn kein Kontakt gewaehlt (8C).
|
||||
- [x] Doku-Pflege: `docs/user-admin/*` an IST-Stand ziehen (8D, dieses Dokument).
|
||||
- [x] Firmen-Liste auf Mockup-Niveau (Counter-Strip, Saved-Views, Filter-Chips, Card/List-Toggle, Rollen-Legende) (8E) — Tests: `CustomerPressKitIndexPhase8eTest`, `CustomerPressKitCreatePhase8eTest`.
|
||||
- [x] Set wiederverwendbarer SVG-Platzhalter fuer PM-Titelbilder + Auswahl-Modal (8F) — `App\Enums\PressReleasePlaceholder`, `<x-portal.press-release-placeholder>`, Picker `components.press-release-placeholder-picker`.
|
||||
- [x] Titelbild-Schema in `press_releases` (`placeholder_variant`, deterministischer Default, `PressReleaseCoverImage`-Resolver, Hero in Customer-/Admin-Show) (8G).
|
||||
- [x] Bild-Upload mit Lizenz-Pflichtfeldern (Urheber, Lizenz-Typ, Lizenz-URL bedingt, Personen-Einwilligung, Rechte-Bestaetigung) im Image-Manager (8H). Hinweis: Upload-Control bleibt `flux:input type=file` statt `flux:file-upload` (Stabilitaet); Lizenzerfassung vollstaendig.
|
||||
- [x] Veroeffentlichungs-Modal mit rechtlichen Hinweisen (Platzhalter, anwaltlich zu pruefen) + Kontingent-Anzeige (Customer-Show) (8I).
|
||||
- [x] Kontingent-Stub im Datenmodell (`users.press_release_quota` + `..._used_this_month`, Decrement in `submitForReview`, monatlicher `press-releases:reset-monthly-quota`-Command) (8J).
|
||||
- [x] Tests, Pint, Build, Roadmap-Update (8K).
|
||||
|
||||
## KI-Pruef-Pipeline — Klassifikation & Content-Score (abgeschlossen 11.06.2026)
|
||||
|
||||
Vollstaendiger Plan mit Phasen-Details: `docs/user-admin/Entwicklungsplan KI-Pruefung und Veroeffentlichung.md`.
|
||||
|
||||
- [x] Einreichungs-Modal vereinheitlicht: `confirm-submit-review` in Customer-Show, -Create und -Edit (Phase 0).
|
||||
- [x] API-Absicherung: `status` nicht mehr per API setzbar, eigene Submit-Route durch denselben Funnel (Phase 1).
|
||||
- [x] Datenmodell: `press_releases.classification`/`classified_at`, `ki_audits`-Audit-Tabelle (Phase 2).
|
||||
- [x] KI-Klassifikation Rot/Gelb/Gruen, asynchron ueber Queue `classification`, OpenAI-Treiber + deterministischer Fallback (Phase 3).
|
||||
- [x] Status-Routing: Rot → abgelehnt + Mail, Gelb → manuelle Admin-Queue, Gruen → Auto-Publish (sofort/zum Termin); Scheduler publiziert nur gruene PMs (Phase 4).
|
||||
- [x] Admin: KI-Badge + Klassifikations-Filter im Index, KI-Begruendung in der Show, On-Demand-„Pruefung"-Button mit Anbieter-Override.
|
||||
- [x] Re-Klassifikation und Re-Score bei Titel-/Text-Aenderung (Customer, Admin, API).
|
||||
- [x] Content-Score 0–100 → Stufe Standard/Geprueft/Hochwertig inkl. Editor-Panel und Badges (Phase 5).
|
||||
|
||||
## Titelbild, Lizenzen & Termin-Handling (abgeschlossen 10./11.06.2026)
|
||||
|
||||
Details: `docs/user-admin/Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md`.
|
||||
|
||||
- [x] Upload auf ein Titelbild pro PM begrenzt; Cover-Variante 1280×580, Original wird nach Verarbeitung geloescht.
|
||||
- [x] Lizenz-/Rechteformular nach `Lizenztyp Bildupload.md` erweitert (7 Lizenztypen, Personen-/Sachrechte-Status, Quelle, Notizen, Risikohinweise).
|
||||
- [x] Veroeffentlichungs-Box vereinfacht: nur „Sofort nach Freigabe" und „Geplanter Termin"; Embargo aus der Form-UI entfernt (`embargo_at` bleibt im Schema).
|
||||
- [x] Zeitzonen-Handling: Eingabe/Anzeige Europe/Berlin, Speicherung UTC (`PressRelease::DISPLAY_TIMEZONE`, `scheduledAtLocal()`).
|
||||
- [x] PM-Editor-Layout responsive entkoppelt (`.pr-editor-layout`); Ghost-Buttons auf `filled` umgestellt.
|
||||
|
||||
## Naechster Block — Zahlung, Tarife & Veroeffentlichungs-Flow (Launch)
|
||||
|
||||
Verbindliche Entscheidungen: `docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md`. Umsetzungsplan: `docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md`.
|
||||
|
||||
- [ ] Gelb-Routing auf Direkt-Live umstellen (Entscheidung 12.06.: Gelb geht wie Gruen online, keine manuelle Queue; nur Rot wird abgelehnt).
|
||||
- [ ] Tarif-Datenmodell + Checkout/Zahlung (Starter/Business/Pro/Agency, Einzel-PM 19 €, Jahrespreis „2 Monate gratis").
|
||||
- [ ] Submit-Gate: „Speichern & zur Pruefung einreichen" hinter aktiver Buchung; „Speichern" bleibt immer frei.
|
||||
- [ ] Slot-Verbrauch von Einreichung auf **Veroeffentlichung** umstellen (Rot = kein Slot-Verbrauch); Quota-Stub abloesen.
|
||||
- [ ] Tageslimit je Tier (Business 2 / Pro 3 / Agency 5), gilt auch fuer Extra-PMs.
|
||||
- [ ] Launch-Credits: Extra-PM, Boost (nur gruene PMs), Veroeffentlichungsnachweis-PDF; Credit-Anker 1 Credit = 1 €.
|
||||
- [ ] Einzel→Abo-Bruecke (19 € Anrechnung innerhalb 30 Tagen).
|
||||
- [ ] Rechtstexte im Einreichungs-Modal anwaltlich pruefen lassen (Platzhalter, Go-Live-Blocker).
|
||||
- [ ] Queue-Worker fuer `classification` im Produktions-Setup verankern.
|
||||
|
||||
## Phase 2 / spaeter
|
||||
|
||||
- [ ] Vorab-KI-Pruefung, Redigieren/Nachbessern + Re-Check-Loop, Pruefzaehler und Credit-Overflow (Decision-Update §7).
|
||||
- [ ] Magic-Link-Zugriff fuer Firmen-E-Mail-Adressen konzipieren und umsetzen.
|
||||
- [ ] Separate `token_requests`-Tabelle fuer nicht-userbasierte Zugriffe anlegen.
|
||||
- [ ] Zugriff per Firmen-E-Mail so begrenzen, dass nur passende Firmen und Pressemitteilungen sichtbar werden.
|
||||
- [ ] Trust Score fuer User/Firmen konzipieren und im Admin Backend justierbar machen.
|
||||
- [ ] Moderationslogik an Trust Score und Freigabeprozess anbinden.
|
||||
- [ ] Aufbewahrungsfristen fuer Magic Links, Token Requests, API Logs und Statuslogs definieren und technisch absichern.
|
||||
- [ ] Trust Score fuer User/Firmen konzipieren und im Admin Backend justierbar machen (KI-Plan Phase 6).
|
||||
- [ ] Moderationslogik an Trust Score anbinden (Klassifikations-Routing existiert bereits).
|
||||
- [ ] Stufen-Badges (Geprueft/Hochwertig) im oeffentlichen Web-Frontend ausgeben.
|
||||
- [ ] Aufbewahrungsfristen fuer Magic Links, Token Requests, API Logs, Statuslogs und `ki_audits`-Raw-Responses (DSGVO) definieren und technisch absichern.
|
||||
- [ ] Admin-editierbare Textvorlagen fuer neutrale Tombstone-/Entfernungs- und Systemtexte einbauen.
|
||||
- [ ] API-Nutzungs-Log im User Backend sichtbar machen.
|
||||
- [ ] Benachrichtigungen und Newsletter-Abos im Konto-Bereich ausbauen.
|
||||
- [ ] Zahlungsarten und firmenbezogene Zahlungsoptionen im User Backend aktivieren.
|
||||
- [ ] Credits, Tarife und Add-ons an ein echtes Preismodell anbinden.
|
||||
- [ ] Statistikbereich fuer Firmen und Pressemitteilungen umsetzen.
|
||||
- [ ] Medienbereich aus vorhandenen Pressemitteilungsbildern ableiten; spaeter echte Medienbibliothek pruefen.
|
||||
- [ ] Team-/Rollenverwaltung fuer Firmen im User Backend ergaenzen.
|
||||
- [ ] Anzeige-Lokalisierung von `published_at`, `created_at` und Status-Log-Zeitstempeln (aktuell UTC).
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Phase 1 ist funktional abgeschlossen; Phase 7 (PM-Form-Refactor) ebenfalls — siehe Plan-Doku oben.
|
||||
- Phase 8 fokussiert das User-Panel: Firmen-Liste auf Mockup-Niveau, PM-Titelbilder mit SVG-Platzhaltern und Veroeffentlichungs-Modal mit rechtlichen Hinweisen.
|
||||
- Die Admin-Oberflaeche bekommt in Phase 8 nur die Phase-7-Parallelitaeten (Show-Page-Felder, Listen-Indikatoren); groessere Admin-Aenderungen kommen erst mit Phase 2.
|
||||
- Phase 1, Phase 7 (PM-Form-Refactor), Phase 8 (User-Panel-Konsolidierung) und die KI-Pruef-Pipeline (Phasen 0–5) sind abgeschlossen — siehe Plan-Dokus oben.
|
||||
- Fuer Preise, Kontingente und den Veroeffentlichungs-Flow gilt ausschliesslich das Decision-Update vom 11.06.2026; aeltere Tarif-Tabellen in `Konzept-Update 1` und im Relaunch-Konzept sind ueberschrieben.
|
||||
- Der Quota-Stub (3 PM/Monat, zaehlt beim Einreichen) bleibt bis zum Tarif-Modul aktiv; die Umstellung auf Slot-Verbrauch bei Veroeffentlichung ist Teil des Launch-Blocks.
|
||||
- Die KI-Klassifikation laeuft asynchron — in Produktion wird ein Queue-Worker fuer die Queue `classification` benoetigt (Test-Drain: `php artisan classification:work`).
|
||||
- Anhaenge sind aktuell aus Sicherheitsgruenden deaktiviert, Tabelle und Komponente bleiben aber erhalten und werden in einem separaten Audit-Track reaktiviert.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,33 @@
|
|||
# User-Admin: Zusammenhänge und relevante Daten
|
||||
|
||||
Stand: 2026-05-21 (aktualisiert nach Phase 7)
|
||||
Stand: 2026-06-11 (aktualisiert nach Phase 8 + KI-Pipeline)
|
||||
|
||||
Diese Notiz beschreibt den User als fachlichen Mittelpunkt für die weitere Konzeption des Admin-User-Bereichs. Grundlage sind die aktuellen Models und Migrationen im Laravel-Projekt.
|
||||
|
||||
> **Was seit Phase 8 + KI-Pipeline dazugekommen ist (29.05.–11.06.2026)**:
|
||||
>
|
||||
> - `press_releases`: `placeholder_variant` (SVG-Titelbild-Platzhalter, 8G),
|
||||
> `classification`/`classified_at` (KI-Klassifikation Rot/Gelb/Grün),
|
||||
> `content_score`/`content_tier`/`scored_at` (Content-Score).
|
||||
> - `press_release_images`: Lizenz-/Rechtefelder `author`, `license_type`,
|
||||
> `license_detail`, `license_url`, `source_url`, `people_rights_status`,
|
||||
> `property_rights_status`, `rights_notes`, `persons_consent`,
|
||||
> `rights_confirmed_at` (8H + Erweiterung 10.06.).
|
||||
> - `users`: Quota-Stub `press_release_quota` +
|
||||
> `press_release_quota_used_this_month` (8J; wird vom Tarif-Modul abgelöst).
|
||||
> - Neue Tabelle `ki_audits` (Modell `KiAudit`, append-only Audit-Log jeder
|
||||
> KI-Entscheidung) mit Relation `PressRelease::kiAudits()`.
|
||||
> - Neue Enums: `PressReleasePlaceholder`, `ImageLicenseType`,
|
||||
> `PressReleaseClassification`, `PressReleaseContentTier`.
|
||||
> - Neue Services/Jobs: `PressReleaseCoverImage` (Cover-Resolver),
|
||||
> Treiber-Architektur unter `Services/PressRelease/Classification/` und
|
||||
> `…/ContentScore/`, Jobs `ClassifyPressRelease`/`ScorePressRelease`
|
||||
> (Queue `classification`), Konfiguration in `config/scoring.php`.
|
||||
> - Neue Commands: `press-releases:reset-monthly-quota` (Scheduler, 1. des
|
||||
> Monats), `classification:work` (Queue-Drain zum Testen).
|
||||
> - Zeitzonen-Konstante `PressRelease::DISPLAY_TIMEZONE` (Europe/Berlin) mit
|
||||
> `scheduledAtLocal()`/`embargoAtLocal()` für alle Termin-Anzeigen.
|
||||
|
||||
> **Was sich seit dem ursprünglichen Stand (2026-05-05) geändert hat**:
|
||||
>
|
||||
> - Pressemitteilungen haben zusätzliche Felder: `subtitle`, `scheduled_at`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue