Legacy-API-Paritaet S1+S2: connektar-Flow verhaltensgleich + KI-Schalter
Eigene Compat-Controller (Api/Legacy) fuer die 5 real genutzten
/service-Endpoints (Prod-Log-Beleg): Company-/Kontakt-Create (liefen
410!), PM-Create, Bild-Upload, published-only-GET — verschachtelte
Alt-Params, 201+Location+{}, Alt-Fehlerformat, Hit-Zaehlung,
Legacy-Land-Mapping.
- Anlegen = Einreichen (Alt-Verhalten); Sofort-Publish via neuer
Permission api:immediate-publication (WS-7: connektar zuweisen)
- Admin-Schalter 'KI-Pruefung Legacy-API' (app_settings-Tabelle,
Toggle auf /admin/press-releases): an = review + KI-Routing
- Admin-PM-Liste: KI-Spalte (Ampel-Badge) + manueller Pruef-Button
ohne Routing fuer ungepruefte PMs
- Mails bei API-Einlieferern an Pressekontakt, sonst Firmen-Mail,
Fallback Einlieferer (User-Entscheidung 10.07.)
- Tests: LegacyServiceParityTest (connektar-Flow end-to-end);
Suite 1182 gruen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fef45733df
commit
a3fd361ece
15 changed files with 906 additions and 24 deletions
|
|
@ -1,6 +1,10 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Portal;
|
||||
use App\Http\Controllers\Api\Legacy\LegacyPressReleaseController;
|
||||
use App\Jobs\ClassifyPressRelease;
|
||||
use App\Jobs\ScorePressRelease;
|
||||
use App\Models\AppSetting;
|
||||
use App\Enums\PressReleaseStatus;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
|
|
@ -137,6 +141,43 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
$this->resetPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin-Schalter (Entscheidung 10.07.2026): KI-Prüfung für Legacy-API-
|
||||
* Einlieferungen. Aus = Alt-Verhalten Sofort-Publish (connektar).
|
||||
*/
|
||||
public bool $legacyApiAiReview = false;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->legacyApiAiReview = AppSetting::getBool(LegacyPressReleaseController::SETTING_AI_REVIEW);
|
||||
}
|
||||
|
||||
public function updatedLegacyApiAiReview(bool $value): void
|
||||
{
|
||||
AppSetting::setValue(LegacyPressReleaseController::SETTING_AI_REVIEW, $value);
|
||||
|
||||
Flux::toast(
|
||||
$value
|
||||
? __('KI-Prüfung für Legacy-API-Einlieferungen aktiviert.')
|
||||
: __('Legacy-API veröffentlicht wieder sofort (Alt-Verhalten).'),
|
||||
variant: 'success',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manuelle KI-Prüfung aus der Liste — bewusst ohne Routing: bewertet
|
||||
* und protokolliert, ändert aber nie den Status (Admin entscheidet).
|
||||
*/
|
||||
public function runAiCheck(int $id): void
|
||||
{
|
||||
$pr = $this->findAdminPR($id);
|
||||
|
||||
ClassifyPressRelease::dispatch($pr->id, route: false)->onQueue('classification');
|
||||
ScorePressRelease::dispatch($pr->id)->onQueue('classification');
|
||||
|
||||
Flux::toast(__('KI-Prüfung angestoßen — Ergebnis erscheint nach dem nächsten Queue-Lauf.'), variant: 'success');
|
||||
}
|
||||
|
||||
public function resetFilters(): void
|
||||
{
|
||||
$this->search = '';
|
||||
|
|
@ -468,6 +509,13 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
@endforeach
|
||||
</flux:select>
|
||||
|
||||
{{-- Entscheidung 10.07.2026: KI-Prüfung für Legacy-API-Einlieferungen;
|
||||
aus = Alt-Verhalten (Sofort-Publish für berechtigte Bestandskunden). --}}
|
||||
<flux:field variant="inline" class="whitespace-nowrap">
|
||||
<flux:switch wire:model.live="legacyApiAiReview" />
|
||||
<flux:label>{{ __('KI-Prüfung Legacy-API') }}</flux:label>
|
||||
</flux:field>
|
||||
|
||||
<flux:select wire:model.live="portalFilter" class="w-full">
|
||||
<option value="all">{{ __('Alle Portale') }}</option>
|
||||
@foreach ($portalOptions as $p)
|
||||
|
|
@ -809,6 +857,7 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
:direction="$sortDir" wire:click="sort('created_at')">{{ __('Datum') }}</flux:table.column>
|
||||
<flux:table.column class="w-[80px]" sortable :sorted="$sortBy === 'hits'" :direction="$sortDir"
|
||||
wire:click="sort('hits')">{{ __('Hits') }}</flux:table.column>
|
||||
<flux:table.column class="w-[120px]">{{ __('KI-Prüfung') }}</flux:table.column>
|
||||
<flux:table.column class="w-[90px]">{{ __('Aktionen') }}</flux:table.column>
|
||||
</flux:table.columns>
|
||||
|
||||
|
|
@ -945,6 +994,24 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
class="font-mono text-[12px] text-[color:var(--color-ink-2)] tabular-nums">{{ number_format($pr->hits) }}</span>
|
||||
</flux:table.cell>
|
||||
|
||||
<flux:table.cell>
|
||||
@if ($pr->classification)
|
||||
@php
|
||||
$kiBadgeClass = match ($pr->classification) {
|
||||
\App\Enums\PressReleaseClassification::Green => 'published',
|
||||
\App\Enums\PressReleaseClassification::Yellow => 'review',
|
||||
\App\Enums\PressReleaseClassification::Red => 'rejected',
|
||||
};
|
||||
@endphp
|
||||
<span @class(['badge', $kiBadgeClass])>{{ $pr->classification->label() }}</span>
|
||||
@else
|
||||
<flux:button size="sm" variant="filled" icon="sparkles" wire:click="runAiCheck({{ $pr->id }})"
|
||||
wire:loading.attr="disabled" title="{{ __('KI-Prüfung starten (ohne Statusänderung)') }}">
|
||||
{{ __('Prüfen') }}
|
||||
</flux:button>
|
||||
@endif
|
||||
</flux:table.cell>
|
||||
|
||||
<flux:table.cell>
|
||||
<div class="flex items-center gap-1">
|
||||
<flux:button size="sm" variant="filled" icon="eye"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue