presseportale/app/Models/PressReleaseIndexCheck.php
Kevin Adametz 6c4618afed admin: Indexierungsstatus aus der Search Console, Kundenansicht vorbereitet und zu (Anhang 1: 1c.4, E8)
press-releases:check-index-status fragt täglich je Portal ein Kontingent
veröffentlichter Meldungen über die URL Inspection API ab, nach Alter
gestaffelt, nie geprüfte zuerst. Jede Antwort wird als Momentaufnahme in
press_release_index_checks gespeichert; der reduzierte Befund (IndexState)
trennt „noch nicht gecrawlt" von „gecrawlt, nicht indexiert".

Client authentifiziert sich als Service-Konto über ein selbst signiertes
JWT — kein Google-SDK. Admin ▸ Reports ▸ Indexierung zeigt die Verteilung
je Portal getrennt nach Direkteinreichung und Syndikation (Status-Log
source=api; Altbestand ohne Log zählt als direkt).

Das Kundenpanel heißt jetzt „Auslieferung", zeigt Sitemap-Datum und die
Abrufe durch Such- und KI-Dienste mit dem Satz „Ein Abruf ist kein Zitat";
der Google-Index-Block hängt an GSC_CUSTOMER_VISIBLE (false).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:21:51 +00:00

62 lines
1.5 KiB
PHP

<?php
namespace App\Models;
use App\Enums\IndexState;
use App\Enums\Portal;
use Database\Factories\PressReleaseIndexCheckFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* Eine Momentaufnahme des Indexierungsstatus einer Meldung auf einem Portal
* (Roadmap 1c.4). Append-only — jeder Prüflauf schreibt eine neue Zeile.
*/
class PressReleaseIndexCheck extends Model
{
/** @use HasFactory<PressReleaseIndexCheckFactory> */
use HasFactory;
public const ?string CREATED_AT = null;
public const ?string UPDATED_AT = null;
protected $fillable = [
'press_release_id',
'portal',
'url',
'state',
'verdict',
'coverage_state',
'indexing_state',
'robots_txt_state',
'page_fetch_state',
'last_crawl_time',
'google_canonical',
'raw',
'checked_at',
];
/**
* @return array<string, string>
*/
protected function casts(): array
{
return [
'portal' => Portal::class,
'state' => IndexState::class,
'last_crawl_time' => 'datetime',
'checked_at' => 'datetime',
'raw' => 'array',
];
}
/**
* @return BelongsTo<PressRelease, $this>
*/
public function pressRelease(): BelongsTo
{
return $this->belongsTo(PressRelease::class);
}
}