web: RSS-Feeds je Branche und je Portal (Roadmap 3.1); dev: Sichtung des Ordners, Protokoll-Teile umnummeriert

- /{edition}/feed und /{edition}/category/{slug}/feed (FeedController,
  RSS 2.0 mit atom:link self, dc:creator, category; jüngste 50 der Ausgabe,
  Branche inkl. aktiver Unterkategorien, nur visibleInArchive).
- Cache über WebPageCache (Key-Gruppe feed), Hub leitet per 301 aufs Portal
  (canonical.portal_only_content_routes).
- Autodiscovery über @yield('feed_links') auf Start-, Branchen- und
  Archivseiten, sichtbarer Link in der Archiv-Leiste, llms.txt nennt die
  Feed-Muster, Block „RSS-Feeds" im Panel „Auslieferung"
  (VisibilityStats::feedLinks).
- Übersetzungen unter web.rss (web.feed ist die Startseiten-Liste).
- Tests: FeedTest (7), VisibilityStatsTest erweitert.
- dev/2026-09-01: Sichtung 18.09. (Teil 11), zweite Teil-Serie des
  Protokolls jetzt 7–10 mit nachgezogenen Verweisen, Anhang 1 abgeglichen,
  E6 abgehakt, 2.6 extern, 1c.5/E8 wartet auf Daten, 3.1 abgehakt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-18 13:57:09 +00:00
parent e2ef4dee31
commit 9d5e5a0b54
20 changed files with 547 additions and 28 deletions

View file

@ -1540,7 +1540,7 @@ Test: `RetireLinkSpamCompaniesTest`.
---
## Teil 5 — Block 2: Organische Sichtbarkeit (ab 17.09.2026)
# Teil 7 — Block 2: Organische Sichtbarkeit (ab 17.09.2026)
Block 1 ist komplett und live (17.09.2026). Block 2 beginnt mit dem
technischen Teil (2.1, 2.2, 2.7); die Inhalts- und Marketing-Pakete (2.3,
@ -1739,11 +1739,11 @@ neue Tabellen-Styles), `view:cache`/`route:cache` wie üblich, dann
eine Meldung im Rich-Results-Test (search.google.com/test/rich-results)
prüfen.
## Teil 6 — Anhang 1 zur Roadmap (17.09.2026)
# Teil 8 — Anhang 1 zur Roadmap (17.09.2026)
Grundlage: `roadmap-anhang1-2026.md`. 2.6 (Zuschriften an Betreiber)
bewusst ausgelassen — übernimmt der Betreiber an anderer Stelle. 2.7 war
mit Teil 5 bereits gebaut; die Formulierungsgrenze (Abruf belegbar,
mit Teil 7 bereits gebaut; die Formulierungsgrenze (Abruf belegbar,
Nennung nicht) gilt in allen neuen Texten.
### 1c.0 Crawler-Abruf-Protokoll
@ -1891,7 +1891,7 @@ Inhalte trägt das Hilfe-Center. Dafür steht **Hilfe** jetzt in der
Topleiste der Portale neben FAQ (Desktop) und im Burger-Menü unter den
Service-Links (Mobile); der Hub hatte den Link bereits.
## Teil 7 — Anhang 2: Doppelveröffentlichung und Quellenauskunft (17.09.2026)
# Teil 9 — Anhang 2: Doppelveröffentlichung und Quellenauskunft (17.09.2026)
Grundlage: `roadmap-anhang2-2026.md`. Commits siehe unten. **Der
Mechanismus ist gebaut und getestet, aber ausgeschaltet**
@ -1999,7 +1999,7 @@ Hintergrund), dann `press-releases:duplicates-report`. Erst nach E9:
`CANONICAL_ASSIGNMENT_ENABLED=true`, `press-releases:assign-canonicals
--dry-run`, dann ohne Flag, `view:cache`, Sitemaps prüfen.
## Teil 8 — E9 und E10 entschieden, Hub-Erreichbarkeit geprüft (18.09.2026)
# Teil 10 — E9 und E10 entschieden, Hub-Erreichbarkeit geprüft (18.09.2026)
### E9 — kanonische Zuordnung aktiv
@ -2122,3 +2122,80 @@ Pfade werden jetzt ab `base_path()` aufgelöst.
Dev-Verteilung presseecho (Bestand): direkt 8.845 Erstquellen / 2.126
Kopien, API 1.308 / 308.
# Teil 11 — Abschluss Block 0–2, Block 3.1 RSS-Feeds (18.09.2026)
## Sichtung des Ordners (18.09.2026)
Alle Dokumente in `dev/2026-09-01/` gegen Code und Git-Stand abgeglichen.
Befunde und was daraus wurde:
| Befund | Erledigt |
|---|---|
| `GSC_PROPERTY_BUSINESSPORTAL24` hatte als Vorgabe `sc-domain:businessportal24.de`, die Property ist `.com` | Vorgabe in `config/search_console.php` und `.env.example` korrigiert (live ist der Wert explizit gesetzt) |
| Anhang 1: Tippfehler in der Übersicht, 1c.2/1c.3/2.7 nicht abgehakt | angeglichen |
| Protokoll: „Teil 5" und „Teil 6" doppelt vergeben | zweite Serie ist jetzt Teil 7–10, Verweise in Roadmap und Anhang 2 nachgezogen |
| Log-Aufteilung je Thema lag uncommittet auf dem Branch | Commit 2ec6169 (billing, ki, monitoring, market als Tagesdateien; Suite loggt nur nach `testing-*.log`) |
| `docs/weiteres`: Decision-Update Duplicate-Content gelöscht, Verlinkung & Backlinks wieder da | Duplicate-Content ist durch Anhang 2 überholt (entfernt, README-Index nachgezogen); Verlinkung bleibt als Referenz für die Link-Policy |
| E6 stand offen, ist aber in 1d.1/1d.2 umgesetzt | als entschieden geführt |
| 2.6 Zuschriften | extern, in Arbeit beim Betreiber — nicht Teil der Umsetzung |
| 1c.5/E8 | Indexierungsprüfung läuft täglich; Entscheidung, sobald die Verteilung belastbar ist |
**Bleibt offen, bewusst nicht aus dem Code heraus erledigt:**
- 0.7: Absatz zur Ereignistabelle (Zweck, Umfang, 395 Tage, Rechtsgrundlage)
in der Datenschutzerklärung — Rechtstext, Betreiber.
- 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`.
- 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
Console.
## 3.1 — RSS-Feeds je Branche
**Stand vorher:** keine Feeds (siehe 1c.1: „keine Feeds vorhanden, daher
kein Feed-Eintrag").
**Umsetzung** (`FeedController`, `web.feed`-View):
- `/{edition}/feed` — alle Meldungen der Ausgabe (Portal × Sprache);
`/{edition}/category/{slug}/feed` — Branche inklusive aktiver
Unterkategorien, wie die Branchenseite. Jeweils die jüngsten 50, neueste
zuerst, nur `visibleInArchive` (kein Termin in der Zukunft, kein 410).
- RSS 2.0 mit `atom:link rel="self"`, `dc:creator` = Firmenname,
`category` = lokalisierter Branchenname, `guid` = Permalink, Teaser 300
Zeichen ohne Markup. Kanaltitel „Pressemitteilungen {Branche} – {Portal}",
Beschreibung aus der Kategoriebeschreibung (2.3), sonst Tagline.
- Bei Doppelveröffentlichung führt jedes Portal seine eigene Fassung — Leser
und Feeds sehen beide (Anhang 2, Abschnitt 1); nur die Suchmaschine
bekommt die Erstquelle. Kein Canonical-Filter im Feed.
- Cache wie die Seitendaten (`WebPageCache`, 5 min frisch, bis 1 h stale
mit Neuaufbau nach der Antwort); `WebCaches::forgetPublicPages()` leert
ihn mit. Eine Korrektur (nur `forgetSitemaps()`) erscheint im Feed nach
spätestens fünf Minuten — hingenommen.
- Hub: `feed` und `kategorie.feed` in `canonical.portal_only_content_routes`
→ 301 auf presseecho, wie Kategorie und Archiv.
- Autodiscovery: `@yield('feed_links')` im Web-Layout; Startseiten nennen
den Portal-Feed, Branchenseite Branchen- und Portal-Feed, Jahresarchiv
den Branchen-Feed — Adressen aus der Portal-Basis, nicht aus `url()`
(das liefert wegen `forceRootUrl` den Hub). Sichtbarer Link „RSS-Feed"
in der Archiv-Leiste der Branchenseite; `llms.txt` nennt beide Muster.
- Absenderansicht: Block „RSS-Feeds" im Panel „Auslieferung" mit Branchen-
und Portal-Feed je Portal der Meldung, plus dem Satz, dass Abonnenten uns
nicht bekannt sind (`VisibilityStats::feedLinks()`).
- Übersetzungen unter `web.rss` — `web.feed` war schon die Meldungsliste der
Startseite.
Nicht gebaut: Feeds je Newsroom (kein Arbeitspaket), Bild-Enclosures
(zusätzliche Queries je Item, kein Bedarf benannt), Feed-Einträge in der
Sitemap (Feeds gehören nicht hinein).
Tests: `FeedTest` (7 — Branche mit Kindern und Fremdportal, Portal-Feed,
404, englische Ausgabe, Autodiscovery + llms.txt, Hub-301, Cache),
`VisibilityStatsTest` (+Feed-Links im Summary und im Panel). Pint, Larastan
ohne Befund.
**Deploy:** `view:cache`/`route:cache` neu; kein `migrate`, kein
`cache:clear` (neue Cache-Keys).