Commit graph

483 commits

Author SHA1 Message Date
fd8dd74d5f ops: Lokale Datenbank gegen fremde Testläufe absichern — DB_* nicht mehr als Container-Umgebung, Agenten-Regel, Testdatenbank-Pflicht im Baukasten
Am 07.10.2026 hat das RefreshDatabase eines frischen Demo-Projekts (Test der
Vorlagen aus dev/git-deploy-monitoring) die lokale Datenbank `pressekonto` auf
global-mysql vollständig geleert (Binärlog binlog.000009, Pos. 566161486).
Ursache: docker-compose.yml setzte DB_* als Container-Umgebungsvariablen, die
in Laravel Vorrang vor jeder .env haben; die phpunit.xml des Demo-Projekts
erzwang kein SQLite. Die eigene Suite war nicht beteiligt (force="true" und
Guard in tests/TestCase.php greifen; Gegenprobe mit MySQL-Variablen grün).

- docker-compose.yml: DB_* entfernt (Werte identisch in .env), wirksam nach
  Neuerstellen des Containers.
- Baukasten: „Testdatenbank absichern" (phpunit.xml mit force, Guard,
  Gegenprobe) als Pflicht vor RefreshDatabase.
- .ai/rules/general.md und CLAUDE.md: fremde/frische Laravel-Projekte nur mit
  SQLite :memory: testen; migrate hier erst nach migrate:status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:09:25 +00:00
32e1349517 dev: Baukasten Git-Deploy und Betriebsüberwachung für andere Laravel-Projekte (dev/git-deploy-monitoring) — Anleitungen, Checkliste, Vorlagen für Laravel, deploy.sh und Monitoring-Server
Vorlagen in einem frischen Laravel 12 eingebaut (30 Tests grün), deploy.sh
gegen ein simuliertes Repository durchgespielt (Deploy, Abbruch bei
Migrationen, Drift, Rollback, fehlender Worker). GlitchTip-Aufbewahrung heißt
seit Version 6 GLITCHTIP_RETENTION_DAYS — in der Projekt-Doku korrigiert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:45:16 +00:00
d083110b00 dev: Deploy v1.3.2 im Git-Deploy-Protokoll (Worker-Prüfung 4 s, Supervisor enabled)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:14:12 +00:00
3b4448ad4e dev: Worker-Ausfall 06.10. dokumentiert — Runbook ohne pauschales queue:retry all, Vorgehen bei stehendem Worker, externer Monitor erledigt (status.adametz.media)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:11:58 +00:00
c223daa563 deploy: Worker-Prüfung am Ende von deploy.sh — monitoring:queue-probe stellt einen Test-Job ein und wartet bis 60 s; ohne Worker Exit 3 mit Hinweis
Anlass 06.10.2026: Nach dem Deploy von v1.3.0 hat queue:restart den Worker
beendet, Supervisor lief nicht, über eine Stunde blieben KI-Prüfungen und
Mails liegen, ohne dass es auffiel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:11:58 +00:00
2c25eea045 dev: Monitoring-Plan — Nachtrag fehlgeschlagene Anmeldungen (Befund, Auswertung) und Einrichtung des externen Monitors (Uptime Kuma, ntfy, zweite Ebene)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:30:29 +00:00
05535aac37 auth: fehlgeschlagene Anmeldungen mit Einstieg (livewire/fortify/two-factor); unbekannte Adressen als Tageszähler statt Verlaufseintrag, Kachel im Systemstatus, Löschfrist 90 Tage
Auf Live kamen seit dem 05.10. rund 250 Versuche am Tag aus über 50 Quellen,
alle mit unbekannter Adresse — verteiltes Durchprobieren fremder
Zugangsdaten, das im Verlauf die relevanten Einträge verdeckte. Neue Tabelle
failed_login_tallies (Tag × Einstieg × IP-Hash), model:prune täglich 04:05.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:30:29 +00:00
9f806de1af dev: Git-Deploy — FPM-Reload ohne Passwort getestet, PK_FPM_RELOAD ungesetzt lassen; Nginx-Fehlerlog ausgewertet, process_control_timeout bewusst nicht gesetzt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:24:55 +00:00
6d03d8de39 billing: Rechnungsversand — PDF im Anhang der Zahlungsmail, optionale Rechnungs-E-Mail, Stripe-Rechnungs-PDF direkt aus dem Kundenbereich
Kundenwunsch 06.10.2026: Ein Kunde kam über die Stripe-Rechnungsseite nicht
an seine Rechnung und fragte nach Belegen und einer Rechnungs-E-Mail.

- Profil ▸ Rechnungsadresse ▸ Rechnungsversand: Schalter „Rechnungs-PDF an
  die Konto-E-Mail" (Standard an), optionale „E-Mail für Rechnungen" mit
  Schalter „Rechnungen als PDF an diese Adresse senden" (Standard an).
  Neue Spalten an billing_addresses (klein, ohne FULLTEXT).
- InvoiceDelivery entscheidet Empfänger und Anhang; gleiche Adresse wie das
  Konto ergibt eine Mail mit PDF.
- Zahlungsbestätigung (STR) und Bestandskunden-Rechnung/-Erinnerung (MAN)
  folgen der Einstellung; die Fassung an die Rechnungs-E-Mail nennt das
  Konto, ohne Blindkopie und ohne Login-Button.
- StripeInvoicePdf holt das Stripe-PDF einmal und legt es lokal ab
  (storage/app/private/invoices/stripe); Mailversand wiederholt bei
  Stripe-Ausfall (5 Versuche).
- Rechnungsseite: „PDF öffnen" aus pressekonto, „Beleg bei Stripe" für den
  Zahlungsbeleg auf der Stripe-Seite.

Suite 2.340 grün, einer übersprungen; Larastan und Pint ohne Meldung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:47:49 +00:00
da9411bdab dev: Deploy v1.2.0 (Volt entfernt) im Git-Deploy-Protokoll
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:47:49 +00:00
2cde7284a1 livewire: Volt entfernt — Komponenten als Livewire-4-Single-File-Components, Route::livewire(), Livewire::test(); livewire/volt deinstalliert
- 83 Komponenten: Livewire\Volt\Component → Livewire\Component
- 73 Routen (admin, auth, customer): Volt::route() → Route::livewire()
- 88 Testdateien: Volt::test/actingAs → Livewire::test/actingAs
- VoltServiceProvider gelöscht; composer remove livewire/volt
- config/livewire.php auf v4-Schlüssel (component_layout, component_placeholder,
  component_locations, make_command: SFC ohne ⚡). Der alte Schlüssel layout war
  wirkungslos; alle gerouteten Komponenten setzen ihr Layout selbst.
- CLAUDE.md, AGENTS.md, boost.json, .cursorrules, Skill volt-development
- Roadmap: erledigt; Larastan erfasst SFCs weiterhin nicht (Blade-Dateien)

Suite 2.325 grün, einer übersprungen; Larastan und Pint ohne Meldung;
route:cache und view:cache laufen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:59:36 +00:00
5782297dca dev: Git-Deploy live seit v1.1.3 (06.10.2026) — Protokoll, Befunde der Umwandlung, Runbook §10 und GlitchTip-Doku angepasst
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:43:01 +00:00
2a61122b11 fix: eigene Flux-Icons ins Repository — macOS-Muster "Icon" in der .gitignore traf bei core.ignorecase auch resources/views/flux/icon/
Die vier Icons (u. a. chevrons-up-down in der Sidebar) lagen nur lokal und
auf Live; ein frischer Checkout hätte sie nicht. Das Muster trifft jetzt nur
noch die macOS-Datei Icon\r. Beim Umstellen von Live auf Git-Deploy
aufgefallen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:35:44 +00:00
88f343d3a0 build: Assets für v1.1.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:18:49 +00:00
3a6cb6a57e dev: GlitchTip-Doku auf Git-Deploy umgestellt (Release-Datei schreibt deploy.sh)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:17:19 +00:00
9e35c73d23 dev: GlitchTip-Dokumentation (dev/glitch-tip) — Überblick, Meldewege, API-Abruf, Ablauf zur Fehlerbehebung, Regeln, Protokoll der Einträge; Verweis in CLAUDE.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:12:41 +00:00
3fd3ac002f fix: Registrierung — Platzhalter serverseitig übersetzt statt als Alpine-Ausdruck (GlitchTip browser-pressekonto 15), Wächtertest; Promise-Ablehnungen mit Typ und Inhalt (10); vertippte artisan-Befehle nicht melden (server-pressekonto 9)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:12:29 +00:00
df557e419b search-console: vorübergehende Google-Fehler einmal wiederholt und nur als Warnung protokolliert, Portal-Abbruch nach fünf Fehlern in Folge, Zeitbudget 40 Minuten (GlitchTip server-pressekonto 11–14)
Am 06.10.2026 hing die URL Inspection API zeitweise: 28 Zeitüberschreitungen
und 4 × 500, jede einzeln als Fehler gemeldet, der Lauf zog sich über 1¾
Stunden. Neu: SearchConsoleUnavailable für Timeout/5xx/429 (Warnung, Meldung
bleibt fällig), echte Fehler (401/403/400) weiter über report(); FAILURE —
und damit ein Betriebs-Alert — nur bei Abbruch oder ≥ 50 % Fehlern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:12:29 +00:00
17dceec4f7 tests: Testsuite meldet nicht mehr an GlitchTip — Sentry-DSNs in phpunit.xml geleert, Wächtertest; Produktions-Logs unter dev/ ignoriert
Seit der lokalen DSN landeten absichtlich provozierte Fehler aus den Tests
(„Queue weg“, „Datenbank nicht erreichbar“, SQLite „no such table“,
fehlende Rolle `customer`, Wasserstandsmarke) als Issues in GlitchTip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:00:50 +00:00
168a1cd3de build: Assets für v1.1.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:12:09 +00:00
129de4fc76 deploy: Git-Deploy per Tag — dev/betrieb/deploy.sh, Ablauf und einmalige Umstellung in git-deploy.md, Runbook §10; public/build wird versioniert
- deploy.sh: bricht ohne Änderung ab bei Abweichung im Checkout oder neuen
  Migrationen ohne --migrations; down, Checkout, RELEASE, Composer, Caches,
  queue:restart, FPM, up; Rollback = derselbe Aufruf mit dem vorherigen Tag
- git-deploy.md: Forgejo-Zugang, Umwandlung von ~/pressekonto.com in einen
  Checkout von v1.1.0 ohne Dateiänderung, Release lokal, Prüfungen, Rollback
- Assets werden lokal gebaut und committet, auf dem Server kein Node

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:12:09 +00:00
dd688e5a7a dev: KAS-Passwort erledigt — SSH-Zugang des Altsystems geändert und deaktiviert, KAS-Hosting bleibt für die Postfächer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:12:09 +00:00
1d7ce9e942 dev: Roadmap — Volt entfernen und auf Livewire-4-Single-File-Components umstellen (Umfang, Schritte)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:40:29 +00:00
01d68c2637 dev: Deploy v1.1.0 am 05.10.2026 live — Protokoll in Deploy-Checkliste, Entwicklungsplan (Blöcke 9/10) und Monitoring-Plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:36:44 +00:00
984d001380 chore: docs/ aus dem Repository — lebt im Obsidian-Vault (Devcontainer-Mount), Q-05 entschieden; entpackte Deploy-Pakete ignoriert
Die Dateien bleiben in der Historie und im Vault; git rm --cached, nichts
auf der Platte gelöscht.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:30:33 +00:00
2dda9ecc44 dev: Deploy-Checkliste — Server braucht kein Git
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:59:27 +00:00
c837ef954e dev: Deploy-Checkliste v1.1.0 — Paket gebaut, Entwicklerdateien aus der Paketliste ausgenommen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:55:49 +00:00
9a05cb9e4d mcp: Context7-API-Schlüssel aus .mcp.json und .codex/config.toml entfernt — kommt jetzt aus CONTEXT7_API_KEY
Der Schlüssel stand seit Mai im Repository und auf origin; er bleibt in der
Historie und muss bei Context7 rotiert werden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:53:06 +00:00
8690165625 dev: Monitoring-Plan (Phasen 1–3, Entscheidungen M1–M9, Protokoll), Deploy-Checkliste v1.1.0, Runbook um Versionsdatei und Composer-Schritt ergänzt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:53:06 +00:00
d884eb7482 monitoring: Betriebsüberwachung Phase 1 — GlitchTip (Server- und Browserfehler), Fehlersignale ohne Exception, /health mit Scheduler-Herzschlag, ntfy-Alarme, fehlgeschlagene Anmeldungen im Verlauf, Umami im Kundenbereich, Versionsnummer
- GlitchTip über die Sentry-SDKs; Datenschutzfilter (nur User-ID, keine
  Request-Bodys, Tokens aus URL/Query/Referer, E-Mails aus Meldungen).
  Browser-SDK erst beim ersten Fehler nachgeladen.
- ReportErrorSignals: tote interne Links (404 mit eigenem Referrer), 403/429
  für Angemeldete, 419 als gedrosselte Warnung.
- /health (Bearer-Token): DB, Cache, Queue-Rückstau, Scheduler-Herzschlag,
  Plattenplatz → 200/503; Scheduler und Plattenplatz auch im Systemstatus.
- OperationalAlert zusätzlich per ntfy (JSON-POST), unabhängig von der Mail.
- Verlauf: login_failed (Grund unbekannt/kein Passwort/falsch),
  login_lockout, two_factor_failed; IP nur als gekürzter HMAC.
- Umami: Kundenbereich mit eigenem Schalter und identify('user-<id>'),
  nie im Admin/bei Impersonation; Query-Filter auch auf den Webseiten
  (signierte Links gingen bisher an Umami).
- queue:prune-failed nach 30 Tagen.
- Versionsnummer: config('app.version') aus APP_VERSION oder Datei RELEASE
  (git describe --tags), in GlitchTip, /health, Systemstatus, artisan about.

Plan: dev/betrieb/monitoring-plan.md (Entscheidungen M1–M9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:53:00 +00:00
2079dfdaa8 deps: Composer-Update (Laravel 12.69.3, Livewire 4.4.7, Flux 2.20.1, Fortify 1.40.0), league/commonmark 2.10.3 behebt zwei Advisories; Sentry-SDKs für GlitchTip (sentry/sentry-laravel, @sentry/browser)
Livewire 4.4.7 rendert ModelNotFoundException im Testhelfer als 404 statt
sie zu werfen — zwei Tests auf assertNotFound() umgestellt, Laufzeitverhalten
unverändert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:52:48 +00:00
448643b4d8 dev: Commit-Hashes der Blöcke 9 und 10 im Protokoll nachgetragen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:13 +00:00
4a7e496d1b dev: Umsetzungsaudits 29.09. und 02.10., Entwicklungsplan Blöcke 9 und 10 mit bestätigten Entscheidungen E19–E34 und Deploy-Plan, Runbook ergänzt
- UMSETZUNGSAUDIT-2026-09-29.md (Bestandsaufnahme) und -2026-10-02.md
- ENTWICKLUNGSPLAN.md: Block 9 und 10, Entscheidungen E19–E34 vom Betreiber
  am 02.10.2026 bestätigt (E25 revidiert), Deploy-Plan A–E, Protokoll
- deploy-runbook.md: vollständige Scheduler-Tabelle, Restore-Schritte mit
  --accept-unsigned/--without-export, Zugangsdaten aus Abschnitt 7 entfernt
  (stehen weiter in der Historie — Passwort wird rotiert)
- Bildplan-Protokoll mit Korrektur zu „Altbestand geschützt" (A-05)
- dev/README.md und dev/roadmap.md verweisen auf den aktuellen Stand
- .env.example: neue Schlüssel aus Block 9/10

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:01 +00:00
f1c0e2766b images: nur freigegebene Bilder in Feed und PDF, versionierte Veröffentlichungssnapshots, Bestätigung an das gezeigte Bild gebunden, getrennte Rückhaltegründe (Umsetzungsaudit 29.09.: B-01 bis B-14, N09, OPT-3 bis OPT-5; 02.10.: O03)
- B-01/B-02: Startseiten-Feed, Card-Helfer und Nachweis-PDF nur mit
  isPubliclyDeliverable()
- B-03: Livewire-Temp-Upload 16 MiB
- N09: Snapshot je Bytes- und Metadaten-Hash inkl. OG-Variante, put()
  geprüft, alle Fassungen ins Archiv
- O03: published_ever_at in der Freigabetransaktion
  (markPublishedIfNowPublic) — Kundenbestätigung, Vorab-Sichtung, Korrektur
- B-04/B-14: Bestätigung an Bild-ID und SHA gebunden, unter Sperre
- B-05/B-06: Entfernen unter Sperre mit frischem Stand und Archivauftrag;
  Korrektur archiviert über den Auftrag, Nacharbeiten abgesichert
- B-07: precheck_withheld_at getrennt von withheld_at (Migration + Übernahme)
- B-08, B-09, B-11, B-12: published_ever_at nur bei Status published,
  Admin-Eigentümer mit Kundenregel, Sweep verwaister Originale,
  Verarbeitungsfehler als Formularmeldung
- K-02-Teil: nach Kundenbestätigung erneut routen
- OPT-3 bis OPT-5: pingImage für JPEG, Hash durchgereicht, erstes Frame

Admin-PM-Detailseite enthält zusätzlich K-06 (Autorisierung) und A-08
(Nachweis per POST), weil die Datei ungeteilt committet ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:01 +00:00
60650baeb8 archive: Auftragstabelle statt Marker, exklusiver Abschluss, Quarantäne, Restore über Payload-Identität und signierte Exporte, Schlüsselrotation (Umsetzungsaudit 29.09.: A-01 bis A-15, OPT-6, 5.1 d; 02.10.: O04, O05, O07, O08)
- A-01/A-02/A-04: archive_pending_jobs je Vorgang (ArchivePendingQueue),
  Depublikationsstand am Auftrag festgehalten, Nachholer ohne Schlüssel
  FAILURE; archive_pending_at nur noch Sammelmarker
- O07: Direktweg und Nachholer beanspruchen den Auftrag unter Zeilensperre
- O08: fehlende Snapshot-Datei → Verweis auf den image_removed-Eintrag oder
  offener Auftrag, nie ein still unvollständiger Nachweis
- A-03/A-06: Sweep verschiebt in die Quarantäne, Pause beim Restore,
  archive:reregister; Restore-Abgleich löscht Anwendungskopien erneut
- O04/O05: Restore ordnet über den Payload-Pfad zu; unsignierte Exporte nur
  mit --accept-unsigned, reregister bricht bei ungültigem/fehlendem Export ab
- A-05, A-07 bis A-15: Altbestand als möglicherweise veröffentlicht, Hold-
  Historie, Zweck per POST, Nachweise gelöschter Bilder nur mit
  compliance:manage, Anhänge auf ihrer Disk, Schlüssel-ID und
  ARCHIVE_PREVIOUS_KEYS, HMAC per HKDF, archive:verify-export
- 5.1 d: Depublikation im Meldeverfahren trägt legal_request_id

PressReleaseService.php enthält zusätzlich K-01 (Prüfung im Publish-Lock),
N19 (archive() gibt Kopien frei) und N09 (markImagesPublished nur für
auslieferbare Bilder), weil die Datei ungeteilt committet ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:01 +00:00
c82f279fef press-releases/jobs: Scheduler respektiert manuelle Prüfung und kommt an Blockaden vorbei, Newsletter-Versand per Schalter gesperrt, kurze Scheduler-Sperren (Umsetzungsaudit 29.09.: K-01, K-02, K-05, K-06, K-09, E9, OPT-8, OPT-9; 02.10.: O06)
- K-01: publish-scheduled filtert manual_review_required_at; publish() prüft
  für ki/scheduler unter der Sperre (ManualReviewRequiredException)
- K-02: Kontingent- und Bildsperre sind fachliche Ausgänge (Exit 0, einmaliger
  Verlaufseintrag); KI-Job ohne Retry bei Bildsperre
- O06: Kandidaten per Cursor (scheduled_at, id), Limit zählt bearbeitete
  Meldungen, Blockaden nur ein Scan-Budget
- K-05: KI-Job lädt vor dem Routing neu, überholter Status ohne Retry; backoff
- K-06: Admin-Aktionen mit Permission-Prüfung und Fehlermeldung statt 500
- K-09: withoutOverlapping() mit kurzer Sperrdauer, purge-events 03:50,
  neuer Wochenlauf press-release-images:sweep-orphan-originals (So 04:45)
- E9: NEWSLETTER_SENDING_ENABLED (Standard aus) sperrt Start, Resume und Job
- OPT-9: ExpireGrandfathering prüft die Queue-Voraussetzung aus E18

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:00 +00:00
d6e49c11c3 web/seo: Änderungsdatum unabhängig von Aufrufen, EN-URLs in Sitemap und Legacy-API, signierte Bounce-Referenz, Merge/Canonical konsistent (Umsetzungsaudit 29.09.: R-02 bis R-11, N17, N18, OPT-1, OPT-2; 02.10.: O01)
- R-02/K-03: Aufrufaggregation und Merge ändern updated_at nicht mehr; neue
  Spalte press_releases.content_changed_at (INSTANT), contentModifiedAt()
  für Sitemap-lastmod, dateModified und article:modified_time
- R-03: Sitemap und Legacy-view_url mit /en/ für englische Meldungen
- R-04/O01: X-Pk-Ref je Empfänger per HMAC signiert; auf eine Sperre zählt —
  hart wie weich — nur ein gültig signierter Rückläufer, unsignierte
  standardmäßig nur zur Sichtung (BOUNCE_UNSIGNED_KIND=policy)
- R-05/R-06: Unmerge setzt nur unveränderte Füllwerte zurück
  (company_merge_moves.merged_value), Canonical-Neubewertung nach Merge und
  Unmerge, assignAll setzt veraltete Verweise zurück
- R-07 bis R-11: Crawler zählen nicht als Aufruf, Mail-Klick gedrosselt und
  verzögert geschrieben, Claim-Zähler erst nach Versand, email_bounces nach
  395 Tagen gelöscht, Canonical-Portal über Kategorie-ID, llms-Cache geleert,
  Feed-Teaser ohne Doppel-Escaping, Merge-Ketten aufgelöst
- N17/N18: kein falsches „gelistet seit", Rollen im Indexbericht wie Sitemap
- OPT-1/OPT-2: topFeeds in SQL, purge-events löscht nach Grenz-ID

Enthält aus PressRelease.php auch die Card-Bild-Helfer (B-01) und
wasEverPublished()/neverPublished() (A-05), weil die Datei ungeteilt
committet ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:00 +00:00
1ccb4a8479 auth/security: API-Firmenzuordnung nur für Mitglieder oder Allowlist, Google-Vorabübernahme geschlossen, gemeinsamer Login-Abschluss (Umsetzungsaudit 29.09.: R-01, K-04, K-07, K-08, B-10)
- R-01: ApiNewsroomAssignment hängt an eine bestehende Firma nur noch Owner,
  Mitglieder oder Nutzer aus NEWSROOM_API_ASSIGNMENT_USER_IDS; Pivot mit
  granted_via = api; Befehl company-memberships:api-assignments (Liste,
  --remove mit Vorschau)
- K-04: OAuth-Verifikation eines offenen Kontos verwirft Passwort,
  remember_token und Sanctum-Tokens; SessionRevocation + Middleware
  EnsureSessionIsNotRevoked widerruft alte Sessions (Redis-tauglich)
- K-08: LoginCompletion für Passwort, Magic Link und Google — last_login_at
  und Anmeldemethode auch nach 2FA, Landeziel über die Challenge, Google
  ohne erzwungenes remember, magic-login ohne guest für eigene Links
- B-10: eigener Magic-Link-Zweck image_confirmation (Migration)
- K-07: legalAcceptanceVersions #[Locked], Versionswechsel beim Absenden
  wird abgelehnt, Gate-Abfragen je Request zwischengespeichert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:00 +00:00
3dbc3fa673 tests: gemeinsamer Testhelfer, DB_URL-Guard vor RefreshDatabase, Larastan voller Scope ohne Meldung (Umsetzungsaudit 29.09.: Q-01, Q-02; 02.10.: O02)
- makeCustomerForShowPhase8a() nach tests/Pest.php — die Suite läuft damit
  auch parallel (--parallel) und dateiweise grün
- phpunit.xml leert DB_URL, der Guard in TestCase::setUpTraits() bricht bei
  gesetzter url ab, bevor RefreshDatabase eine Verbindung öffnet
- HasUniqueSlug ohne widersprüchliche @var-Annotation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:09:00 +00:00
80536ab998 dev: Bildkennzeichnung — Deploy 1b live (Formular v2 an, Testkonto geprüft), Precheck und Gate bleiben aus
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-28 13:08:15 +00:00
05cd604a1e dev: Bildkennzeichnung — Deploy 1, 2 und 2b am 28.09.2026 live, Protokoll
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-28 13:04:26 +00:00
c6543eb680 dev: Entscheidungen E10–E18 vom Betreiber bestätigt (25.09.2026)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 15:24:10 +00:00
c38bcebf12 dev: Entwicklungsplan Block 8 — Abgleich Umsetzungsaudit 25.09., Entscheidungen E10–E18, Live-Schritte, Protokoll
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 14:27:12 +00:00
2a2215b3c3 audit: Nacharbeit Umsetzungsaudit 25.09.2026 — Bildfreigabe, Beweisarchiv, KI-Atomarität, Berichte (Block 8, N01–N05, N07, N08, N10–N21, 5.1, 5.2)
Bilder (N01, N05, N07, N08): gemeinsamer Freigabezustand
PressReleaseImage::isPubliclyDeliverable() für Seiten, OG und Medienroute
(Bestand bleibt sichtbar, v2 nur mit Bestätigung, Admin-Upload bis zum
Kundenklick nicht öffentlich); eigene Ability confirmImageRights nur für den
Kontoinhaber, ohne Super-Admin-Kurzschluss, Identität und ausstehende
Bestätigung auch im Service; Status-Regel unter der PM-Sperre; Cache-Flush
nach dem Commit außerhalb der Dateibereinigung; Snapshot nach Bestätigung an
veröffentlichter PM; Bestätigungstexte an die gezeigte Kennung gebunden.

Beweisarchiv (N02, N10, N11, N12, N13, 5.1): Tombstone unter Zeilensperre mit
erneuter Hold-/Fristprüfung; Dateioperationen ausgewertet, Commands mit
FAILURE; record() über .tmp + move; Marker archive_pending_at mit
archive:retry-pending und archive:sweep-orphans; Anonymisierung entfernt Bilder
über den Remover mit Antragsbezug; Draft-Purge räumt Medien nie
veröffentlichter abgelehnter Einreichungen; App-Kopien fallen mit dem
Archiv-Tombstone; label_corrected nur für veröffentlichte Bilder;
archive_entries.legal_request_id; FileDeletion-Helfer; Systemstatus-Checks.

KI und Hintergrund (N03, N04, N14, N20, N21): Ergebnis-UPDATE und Audit in
einer Transaktion; erwarteter Hash bis in reject()/holdForManualReview();
Ablaufmail per beanspruchtem Marker in einer Transaktion; strikte
Schemaprüfung der Vision-Antwort; Fortschrittsmarke ungecacht.

Berichte und Canonical (N15–N19, 5.2): lückenlose Alterskohorten;
Feed-Identität mit Portal und Sprache; Sitemap-Rolle in der Kundenansicht;
Indexverteilung auf einer Grundgesamtheit; Kopien nach Wegfall der
Erstquelle neu bewertet; Kategorie-Admin leert Seiten-Caches; Dry-Run
zählt alle Tabellen.

Gesamtsuite: 2.122 Tests grün, einer übersprungen; Larastan und Pint sauber.
Zwei Migrationen (nullable Spalten, INSTANT). N09 offen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 14:26:49 +00:00
34fa342c7f tests/legal: Testdatenbank-Guard vor den DB-Traits, Flags in phpunit.xml gepinnt, Zustimmung an gezeigte Fassung gebunden (Umsetzungsaudit 25.09.: N22, N06, 5.3)
- Tests\TestCase prüft die Standardverbindung in setUpTraits(), also vor
  RefreshDatabase — bisher erst nach dem Refresh (N22). Eigener Test.
- phpunit.xml pinnt IMAGE_RIGHTS_V2, IMAGE_PRECHECK(_STAGE) und
  LEGAL_ACCEPTANCE_GATE auf die Vorgaben aus .env.example; die Suite hing
  sonst an der lokalen .env (Audit Abschnitt 6).
- Zustimmungsgate: die Livewire-Komponenten tragen die beim Rendern gezeigten
  Fassungen (Trait-Hook rendering); weicht die aktuelle Fassung beim Absenden
  ab, wird die Annahme abgelehnt und der neue Wortlaut gezeigt. Ein fehlendes
  Pflichtdokument ist bei aktivem Gate ein Konfigurationsfehler (N06).
- Audit vom 25.09., Decision-Update vom 22.09. und Plan Fassung 2 versioniert;
  die Antwortkopie „…-211.md" entfernt; U10-Formulierung im Plan präzisiert.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 13:35:14 +00:00
aaeee24412 admin: Management ▸ Bilder — Liste aller Titelbilder mit PM-Link, Nachweis, Kennzeichnung, Bestätigungsstand und KI-Vorab-Check, Filter nach Sichtung/Zustand/Ausgang (Bildkennzeichnung)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 12:46:33 +00:00
bcd02f2e8f web: KI-Badge am Artikelbild nach rechts unten, damit es das Nachweis-Zeichen links nicht überlappt (Bildkennzeichnung D.2)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 12:34:41 +00:00
8bb7049bdc images: KI-Vorab-Check für Titelbilder — Vision-Sichtung mit definiertem Ausgang je Befund, Admin-Queue, Protokoll und Archiv-Snapshot (Bildkennzeichnung Block K)
Decision-Update Abschnitt 12 (E15, S24): Sichtung auf offensichtliche
Probleme, keine Rechteprüfung, öffentlich weiterhin „automatisierte Prüfung".

- ImagePrecheckManager mit openai- und deterministic-Treiber (Muster der
  Text-Prüfstrecke), Bild auf 1024 px, Metadaten gestrippt, JPEG als Data-URI,
  Antwortschema 12.4; Fehler → Ausgang `error`, durchlassen mit Vermerk.
- Auswertung 12.3: reject (Stock-Wasserzeichen, Nacktheit/Gewalt, Dokument
  ab 0,85), queue (Screenshot, fremdes Logo, Kennzeichen ab 0,6 sowie
  Ablehnungskategorien 0,6–0,85), hint (Personen, „wirkt KI" nur bei „ohne
  KI", technischer Mangel). Stufe 1 wertet nur das Wasserzeichen; die KI setzt
  nie die Kennzeichnung (E9). Herabstufung per Config (12.8).
- Uploader: Check vor jedem Schreiben, Ablehnung speichert nichts und
  landet als ki_audits `image_precheck` an der PM; Hash-Bindung zwischen
  Vorprüfung im Formular und Speichern; Spalten precheck*, Snapshot
  `precheck_snapshot` im Bestätigungsprotokoll, Archiv-Payload erweitert.
- Queue: Bild zurückgehalten (withheld_at), Meldung läuft weiter; Admin
  entscheidet mit Vermerk (Freigabe/Ablehnung → ki_audits
  `image_precheck_review`); Ansicht „Bild-Sichtung" in der PM-Liste,
  Sichtungsblock auf der PM-Seite, Systemstatus-Zähler.
- Formular v2: Ablehnungsgrund unter dem Dateifeld, Hinweise nach der
  Dateiauswahl, „wird kurz gesichtet" an der Karte; API 422 mit Grund,
  Warnung `image_under_review`.
- Config images.precheck (IMAGE_PRECHECK aus, STAGE 1); 17 Tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 13:27:31 +00:00
70e15d5df5 images: press-release-images:regenerate-variants --only=og für den Bestand, Testhelfer eindeutig benannt (Bildkennzeichnung H.1)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:13:49 +00:00
075d0d931f legal/web: Zustimmungsgate je Dokumentversion (aus bis AGB 0.7), OG-Variante mit eingebranntem Bildnachweis, Nachweis in Teasern (Bildkennzeichnung Blöcke G und H)
- legal_document_acceptances (insert-only), LegalAcceptanceGate, Pflicht-Schalter im Einreichungs-Modal über den gemeinsamen Trait; API: GET/POST /api/v1/legal/acceptances, submit antwortet 428 mit den geforderten Fassungen; LEGAL_ACCEPTANCE_GATE
- ImageService: og-Variante (1200×630) mit halbtransparentem Balken und Inter SemiBold, regenerateOgVariant() für Korrekturen und Bestand; Fokuspunkt/Letterbox getestet
- Uploader brennt den Nachweis beim Upload ein, ImageCorrectionService baut die OG-Variante nach einer Korrektur neu; Artikelseite nutzt og für og:image
- Teaser: Nachweis in alt/title (Feed, Hero, Kategorie, Newsroom), Unterschrift am Hero-Bild; PressRelease::cardImageCredit()

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:12:17 +00:00