Commit graph

482 commits

Author SHA1 Message Date
2215826f37 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
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
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
c385ad9037 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
dfc7ed1001 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
ce6e8b48e0 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
06e37c9992 dev: Monitoring-Plan — Nachtrag fehlgeschlagene Anmeldungen (Befund, Auswertung) und Einrichtung des externen Monitors (Uptime Kuma, ntfy, zweite Ebene)
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:30:29 +00:00
0aaee12eb5 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
bc5e151823 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
a5bf33109e billing: Rechnungsversand — PDF im Anhang der Zahlungsmail, optionale Rechnungs-E-Mail, Stripe-Rechnungs-PDF direkt aus dem Kundenbereich
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
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
debf094cae 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
31da9ea8b6 livewire: Volt entfernt — Komponenten als Livewire-4-Single-File-Components, Route::livewire(), Livewire::test(); livewire/volt deinstalliert
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
- 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
79bb6cf1d0 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
92709d8862 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
eb2bf0b092 build: Assets für v1.1.2
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:18:49 +00:00
072fd6235e 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
88b4feb352 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
16af3740bc 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
a90f24a43f 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
2f02acceaf 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
e316734e35 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
73da704607 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
4ca099f6c1 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
f288ab6d82 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
cd18832aab 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
b1cec167d6 chore: docs/ aus dem Repository — lebt im Obsidian-Vault (Devcontainer-Mount), Q-05 entschieden; entpackte Deploy-Pakete ignoriert
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
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
8a64bd7147 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
33dc9918cc 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
df7ebdca10 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
22b62dfc1f 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
8769a71100 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
f2ed268b51 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
2701588ac1 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
aa47e113fe 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
5ec252da12 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
7cd84b2be3 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
f0eeef0144 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
c2e0b85242 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
1d417f87f7 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
dfb0513e73 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
98c465b691 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
21e88710b6 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
97cd8f9e90 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
b80cce6c37 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
48129e99a0 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
4e34c3d0d1 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
d99f55e555 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
6d558cd26a 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
0e5cd20626 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
3b613fadf4 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
62723b551a 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
0240c143c8 archive: Beweisarchiv — verschlüsselte Einträge, Legal Hold, Purge mit Tombstone, Restore-Abgleich, Auslöser und Admin-Seite (Bildkennzeichnung Block F)
- archive_entries (append-only) + archive_access_log; Disk archive außerhalb des Web-Roots; eigener ARCHIVE_KEY (archive:key), AES-256-CBC, SHA-256 am Eintrag
- EvidenceArchive: record/open/manifest/export (signiertes ZIP), setLegalHold/releaseLegalHold (Frist läuft neu), purgeDue, exportTombstones, reconcileAfterRestore
- PressReleaseArchiver: image_removed (Original, Snapshot, Bestätigungen), pm_depublished (letzter veröffentlichter Stand), gdpr_change (Anonymisierung, Korrekturen), label_corrected
- Hooks in Remover, depublish/archive/changeStatusFromAdmin/deleteFromAdmin, AnonymizationService, CorrectionService, ImageCorrectionService
- Scheduler archive:purge 03:20 und archive:export-tombstones 03:30; archive:reconcile-after-restore im Runbook
- Admin ▸ Management ▸ Beweisarchiv (Liste, Legal Hold mit Pflichtvermerk, Öffnen/Export nur mit Zweck)
- Scope-Wächter: neue Befehle nutzen withoutGlobalScope(PortalScope::class)

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