Serverseitige KI-Auswertung des Marken-Klarheits-Checks (Dual-Provider:
Anthropic/OpenAI, umschaltbar via KLARHEITS_CHECK_KI), mit kuratiertem
Prompt, belegtem Grad aus dem Wortlaut, deterministischem Fallback und
Datenschutz-Abschnitt zur KI-Verarbeitung im Privacy-Modus.
Neu in diesem Stand:
- Test-Protokoll (KlarheitsCheckProtokoll): schreibt je KI-Lauf Eingabe +
Ausgabe mit Datum und Session-ID als JSONL. Token-geschützte Ansicht unter
/klarheits-check/protokoll/{token} plus Komfort-Übersicht (nur außerhalb
der Produktion). Per KLARHEITS_CHECK_LOG abschaltbar.
- Missbrauchsschutz der KI-Anfragen: pro IP/Minute, pro IP/Tag und globaler
Tagesdeckel (konfigurierbar). Bei Überschreitung statisches Ergebnis mit
Hinweis statt KI; greift nur bei Freitext.
- Deutlicher Lade-Hinweis ("Bitte warten … bis zu 30 Sekunden") mit größerem
Spinner während der KI-Anfrage.
Abgedeckt durch Feature-Tests (Auswerten, Protokoll, Probe-Command).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
1.8 KiB
PHP
54 lines
1.8 KiB
PHP
<?php
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
use function Pest\Laravel\artisan;
|
|
|
|
test('das probe-command schickt jedes szenario an den anbieter und gibt das json aus', function () {
|
|
config([
|
|
'services.openai.api_key' => 'sk-openai-test',
|
|
'services.openai.url' => 'https://api.openai.com/v1/chat/completions',
|
|
'services.openai.model' => 'gpt-5.4-mini',
|
|
]);
|
|
|
|
Http::fake([
|
|
'api.openai.com/*' => Http::response([
|
|
'choices' => [['message' => ['content' => json_encode([
|
|
'gesamt' => 'Testeinordnung.',
|
|
'spiegel' => [['nr' => 1, 'grad' => 'scharf', 'text' => 'Beleg.']],
|
|
'luecken' => [],
|
|
'stimmigkeit' => [],
|
|
'schluss' => 'Brücke zum Audit.',
|
|
])]]],
|
|
]),
|
|
]);
|
|
|
|
artisan('klarheits-check:probe', ['--provider' => 'openai'])
|
|
->expectsOutputToContain('Szenario: Off-topic & Injection (Relevanz-/Missbrauchs-Schutz)')
|
|
->assertSuccessful();
|
|
|
|
// Vier Szenarien → vier KI-Anfragen.
|
|
Http::assertSentCount(4);
|
|
});
|
|
|
|
test('ein einzelnes szenario lässt sich gezielt ausführen', function () {
|
|
config(['services.openai.api_key' => 'sk-openai-test']);
|
|
|
|
Http::fake([
|
|
'api.openai.com/*' => Http::response([
|
|
'choices' => [['message' => ['content' => json_encode([
|
|
'gesamt' => 'x', 'spiegel' => [], 'luecken' => [], 'stimmigkeit' => [], 'schluss' => 'y',
|
|
])]]],
|
|
]),
|
|
]);
|
|
|
|
artisan('klarheits-check:probe', ['--provider' => 'openai', '--only' => 'scharf'])
|
|
->assertSuccessful();
|
|
|
|
Http::assertSentCount(1);
|
|
});
|
|
|
|
test('ein unbekanntes szenario schlägt fehl', function () {
|
|
artisan('klarheits-check:probe', ['--only' => 'gibtsnicht'])
|
|
->assertExitCode(1);
|
|
});
|