press-releases: assign-canonicals leert Seiten- und Sitemap-Caches; dev: Live-Lauf 21.09.2026 protokolliert (9.221 Paare)

Der Nachlauf über den Bestand änderte rel=canonical und die Sitemap-Auswahl,
ließ aber gecachte Meldungsseiten (1 h stale) und Sitemap-Caches (1 h)
stehen. Nach einem Lauf mit Änderungen wird WebCaches::forgetPublicPages()
aufgerufen; der Test prüft das über den vorher gecachten Sitemap-Stand.

Protokoll Teil 11: Nachtrag Live-Deploy (hash-content 179.619,
duplicates-report 9.221 Paare / 1.468 seit 07/2026, assign-canonicals
9.223/9.221, basiswert-0.1.json auf dem Server), Anhang 2 1c.7/1c.8 mit
Live-Zahlen, Basiswerte 0.1 mit Hinweis auf die noch zu holende Datei.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-21 13:05:43 +00:00
parent 2b042d6aa7
commit eb658020e5
5 changed files with 91 additions and 6 deletions

View file

@ -3,6 +3,7 @@
namespace App\Console\Commands;
use App\Services\PressRelease\CanonicalAssigner;
use App\Support\WebCaches;
use Illuminate\Console\Command;
/**
@ -44,6 +45,14 @@ class AssignCanonicalPressReleases extends Command
$dryRun ? 'würden geändert' : 'geändert',
));
// rel=canonical steckt in den gecachten Meldungsseiten, die Sitemaps
// (1 h) nennen nur die Erstquelle — nach einer Zuordnung über den
// Bestand sollen beide sofort den neuen Stand zeigen.
if (! $dryRun && $result['changed'] > 0) {
WebCaches::forgetPublicPages();
$this->line('Seiten- und Sitemap-Caches geleert.');
}
return self::SUCCESS;
}
}

View file

@ -68,6 +68,11 @@ erheben.
> nachgerüstet, aber die Zahlen oben stammen aus dem Lauf davor. Vor dem
> Livegang von Block 1 einmal nachziehen:
> `php artisan press-releases:view-distribution --json > basiswert-0.1.json`
>
> **21.09.2026:** Lauf mit `--from=2026-06-01 --to=2026-09-01 --json` auf
> dem Live-Server erfolgt, Datei liegt dort unter
> `dev/2026-09-01/basiswert-0.1.json`. Sobald sie im Repo ist, wird die
> Zeile „28–55 Tage" je Portal hier eingetragen.
---

View file

@ -40,8 +40,8 @@ Schneller als über die API geht es zunächst über eine Bestandsabfrage nach id
| Nr. | Arbeitspaket | Aufwand | Abhängigkeit |
|---|---|---|---|
| ~~1c.7~~ | Doppelveröffentlichung erheben — **gebaut 17.09.2026**: `content_hash`, `press-releases:hash-content`, `press-releases:duplicates-report`. Befund: 9.092 Paare = 53 % des Archivs (Protokoll Teil 9) | S | keine |
| ~~1c.8~~ | Kanonische Zuordnung — **gebaut 17.09.2026, ausgeschaltet bis E9**: `CanonicalAssigner`, `canonical_press_release_id`, Zuordnung bei Veröffentlichung + `press-releases:assign-canonicals`; rel=canonical, mainEntityOfPage, Sitemaps nur Erstquelle. Schalter `CANONICAL_ASSIGNMENT_ENABLED` | M | 1c.7 |
| ~~1c.7~~ | Doppelveröffentlichung erheben — **gebaut 17.09.2026**: `content_hash`, `press-releases:hash-content`, `press-releases:duplicates-report`. Befund Dev: 9.092 Paare = 53 % des Archivs (Protokoll Teil 9); **Live 21.09.2026: 9.221 Paare = 18.442 URLs, 1.468 davon seit 07/2026** | S | keine |
| ~~1c.8~~ | Kanonische Zuordnung — **gebaut 17.09.2026, seit E9 aktiv, Bestand live zugeordnet 21.09.2026 (9.221 Paare; Protokoll Teil 11, Nachtrag Live-Deploy)**: `CanonicalAssigner`, `canonical_press_release_id`, Zuordnung bei Veröffentlichung + `press-releases:assign-canonicals`; rel=canonical, mainEntityOfPage, Sitemaps nur Erstquelle. Schalter `CANONICAL_ASSIGNMENT_ENABLED` | M | 1c.7 |
| ~~1c.9~~ | Quellenauskunft — **gebaut 17.09.2026, hinter `GSC_CUSTOMER_VISIBLE`**: `user_canonical` gespeichert, `sourceVerdict()` (eigene / andere eigene Fassung / fremdes Portal), Text im Block „Google-Index" | S | 1c.4, 1c.8 |
### Zur Auswahl in 1c.8

View file

@ -2149,7 +2149,11 @@ Befunde und was daraus wurde:
Konversionsschritte; keine IP, lit. f) plus Frist 395 Tage in Abschnitt 13,
auf Hub und beiden Portalen (eine Datei). Text vom Betreiber abgenommen.
- 0.1: Kohortenwerte „28–55 Tage" vom Live-System (Fenster 01.06.–01.09.)
einmal erheben und ablegen: `php artisan press-releases:view-distribution --from=2026-06-01 --to=2026-09-01 --json > dev/2026-09-01/basiswert-0.1.json`.
einmal erheben und ablegen: `php artisan press-releases:view-distribution --from=2026-06-01 --to=2026-09-01 --json > dev/2026-09-01/basiswert-0.1.json`
— **am 21.09.2026 auf dem Live-Server erzeugt**, liegt dort unter
`~/pressekonto.com/dev/2026-09-01/basiswert-0.1.json`; ins Repo
übernehmen und in `basiswerte-block0.md` eintragen (siehe Nachtrag
Live-Deploy unten).
- Abbruchbedingungen der Blöcke 1–3 tragen weiter Platzhalter für Zeitraum
und Schwellwert; Block 1 läuft seit 17.09. ohne festen Vergleichspunkt.
- 2.2 Publisher Center (Betreiber), Ergebnis nach 4–6 Wochen in der Search
@ -2284,3 +2288,60 @@ Cache-Treffer, Report je Reader/Feed, Panel, Bereinigung),
`config:cache`. 0.7 (Datenschutzerklärung) ist seit dem 21.09.2026 erledigt,
siehe oben.
### Nachtrag 21.09.2026 — Live-Deploy des Branches, Zuordnung über den Bestand
Der Branch `technik/betriebsfixes-2026-09` (Block 1c/1d-Reste, Block 2,
Anhang 1, Anhang 2, E9/E10, 3.1 mit Newsroom-Feeds, RSS-Seite und
Abruf-Protokoll, 0.7, Audit-Blöcke 1–7) ist am 21.09.2026 auf dem
Live-Server. Läufe nach der Migration, in dieser Reihenfolge:
| Schritt | Ergebnis |
|---|---|
| `press-releases:hash-content` | 179.619 Meldungen geprüft, 179.619 Prüfsummen ergänzt (ganzer Bestand inkl. Altbestand offline) |
| `press-releases:duplicates-report` (13:19) | sichtbar: presseecho 12.753, businessportal24 22.181, both 0; **9.221 Paare = 18.442 URLs**, davon 1.468 Paare seit 07/2026; Zuordnung vorher 0; keine Meldung ohne Prüfsumme |
| `press-releases:assign-canonicals --dry-run` | 9.221 Paare, 9.221 würden geändert |
| `press-releases:assign-canonicals` | **9.223 Paare, 9.221 geändert** |
| `press-releases:view-distribution --from=2026-06-01 --to=2026-09-01 --json` | `basiswert-0.1.json` auf dem Server geschrieben (0.1, siehe oben) |
Lesart der Zahlen:
- Live liegen 129 Paare mehr als auf der Dev-Kopie vom 17.09. (9.092) —
die Kopie war älter, seither sind neue Doppelveröffentlichungen
dazugekommen. 1.468 Paare seit Juli bei rund 2.900 Meldungen im
Quartal heißt: **etwa jede zweite neue Meldung erscheint auf beiden
Portalen.** Das ist der Befund aus Anhang 2, jetzt am Bestand belegt.
- Zwischen Dry-Run und scharfem Lauf kamen zwei Paare dazu (9.221 → 9.223),
die der Lauf **nicht** mehr ändern musste: die Zuordnung bei
Veröffentlichung (`CanonicalAssigner::assignFor`) hatte sie bereits
gesetzt. Damit ist der laufende Mechanismus live nachgewiesen, nicht nur
der Nachlauf über den Bestand.
- Erstquelle je Hauptkategorie wie in E9 konfiguriert: sonstiges (3.126
Paare), politik, haus, reisen, kultur, sport, mode, medizin → presseecho;
it (1.214), handel, motor-verkehr, finanzen, wissenschaft-forschung,
recht → businessportal24. Größter Einzelposten ist `sonstiges` — ein
Drittel aller Paare hat keine fachliche Zuordnung; das ist eher ein
Klassifikations- als ein Kanonisierungsthema.
- Die Sitemaps beider Portale tragen ab jetzt je Paar nur noch die
Erstquelle, die Kopie verweist per rel=canonical dorthin. In der Search
Console zeigt sich das über die nächsten Wochen als Rückgang bei
„Duplikat — Google hat eine andere Seite als kanonisch gewählt" bzw.
„Duplikat — vom Nutzer als kanonisch festgelegt" (1c.5/E8 lesen das aus
`press-releases:check-index-status` ab).
**Befund aus der Prüfung des Laufs, behoben:** `assign-canonicals` hat die
gecachten Meldungsseiten (rel=canonical, 5 min frisch / 1 h stale) und die
Sitemap-Caches (1 h) nicht geleert — nach dem Nachlauf über den Bestand
zeigten beide bis zu einer Stunde den alten Stand. Der Befehl ruft jetzt
nach einem Lauf mit Änderungen `WebCaches::forgetPublicPages()` auf und
meldet „Seiten- und Sitemap-Caches geleert." (`CanonicalAssignmentTest`
prüft das über den vorher gecachten Sitemap-Stand). Für den Live-Lauf vom
21.09. ist das inzwischen durch die TTL erledigt.
**Noch zu prüfen auf dem Server** (nicht Teil der Ausgabe oben):
`FEED_FETCHES_RECORDED_SINCE=2026-09-21` und
`CRAWLER_HITS_RECORDED_SINCE=2026-09-21` in der `.env` + `config:cache`;
`categories:seed-descriptions` (2.3); `livewire:publish --assets`;
`queue:restart` und FPM-Neustart; Audit-Plan „Live-Schritte nach dem
Deploy" (`company-memberships:audit`, `--classify --before=<Deploy-Zeitpunkt>`,
`schedule:list` auf `billing:expire-grandfathering`); Rechnungs-Paket
`legacy:settle-unpaid --dry-run` → scharf.

View file

@ -84,18 +84,28 @@ test('assigning the backlog links the duplicate to the source and the sitemaps l
[$pe, $b24] = duplicatePair('it');
// Vor der Zuordnung nennt jedes Portal seine eigene Fassung — und cached die Sitemap eine Stunde.
$this->get('https://presseecho.test/sitemap.xml')->assertSuccessful()
->assertSee('https://presseecho.test/de/press-release/doppel-standort', false);
$this->artisan(AssignCanonicalPressReleases::class, ['--dry-run' => true])
->expectsOutputToContain('[Dry-Run] 1 Paare, 1 würden geändert.')
->assertSuccessful();
expect($b24->fresh()->canonical_press_release_id)->toBeNull();
$this->artisan(AssignCanonicalPressReleases::class)->expectsOutputToContain('1 Paare, 1 geändert.')->assertSuccessful();
$this->artisan(AssignCanonicalPressReleases::class)
->expectsOutputToContain('1 Paare, 1 geändert.')
->expectsOutputToContain('Seiten- und Sitemap-Caches geleert.')
->assertSuccessful();
expect($pe->fresh()->canonical_press_release_id)->toBe($b24->id)
->and($b24->fresh()->canonical_press_release_id)->toBeNull();
// Zweiter Lauf ändert nichts mehr.
$this->artisan(AssignCanonicalPressReleases::class)->expectsOutputToContain('1 Paare, 0 geändert.')->assertSuccessful();
$this->artisan(AssignCanonicalPressReleases::class)
->expectsOutputToContain('1 Paare, 0 geändert.')
->doesntExpectOutputToContain('Caches geleert')
->assertSuccessful();
// Detailseite: die Kopie zeigt per rel=canonical auf die Erstquelle, die Erstquelle auf sich selbst.
$this->get('https://presseecho.test/de/press-release/doppel-standort')->assertSuccessful()
@ -104,7 +114,7 @@ test('assigning the backlog links the duplicate to the source and the sitemaps l
$this->get('https://businessportal24.test/de/press-release/doppel-standort')->assertSuccessful()
->assertSee('<link rel="canonical" href="https://businessportal24.test/de/press-release/doppel-standort">', false);
// Sitemaps: nur die Erstquelle.
// Sitemaps: nur die Erstquelle — der Lauf hat den 1-h-Cache von oben geleert.
$this->get('https://presseecho.test/sitemap.xml')->assertSuccessful()
->assertDontSee('https://presseecho.test/de/press-release/doppel-standort', false);
$this->get('https://businessportal24.test/sitemap.xml')->assertSuccessful()