feat: Chemikalien-Recherche über lokale RiSU-Stoffliste (kein KI-Aufruf mehr)

Ersetzt den ursprünglichen KI-Websuche-Ansatz (GESTIS scheiterte sowohl über
Websuche als auch über direkten API-Zugriff an fehlenden schulspezifischen
Tätigkeitsbeschränkungen) durch einen reinen lokalen Datenbank-Lookup gegen die
offizielle RiSU-Stoffliste (1764 Stoffe inkl. Tätigkeitsbeschränkungs-Codes,
Legende zur Abfragezeit übersetzt statt in die Datenbank gebacken). Keine
KI-Kosten, keine Drittanbieter-Abhängigkeit mehr für diese Funktion.

HazardSubstance.AgeRestriction zu ActivityRestriction umbenannt, da die
Tätigkeitsbeschränkung mehr abdeckt als reine Altersgrenzen. Details und
verworfene Zwischenstände in TODO.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 23:43:56 +02:00
co-authored by Claude Sonnet 5
parent 038337997f
commit 7b883555bf
14 changed files with 647 additions and 37 deletions
+37
View File
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/stoffliste.php';
header('Content-Type: application/json');
$config = require __DIR__ . '/config.php';
$pdo = ai_backend_db($config);
ai_backend_authenticate($pdo); // nur eingeloggte Nutzer der App dürfen abfragen
$body = json_decode(file_get_contents('php://input'), true);
if (!is_array($body) || !isset($body['name']) || trim((string) $body['name']) === '') {
ai_backend_fail(400, 'Ungültige Anfrage: "name" fehlt.');
}
$name = trim((string) $body['name']);
// Reiner Datenbank-Lookup (siehe stoffliste.php) — kein KI-Aufruf, keine Kosten, keine
// Netzwerkabhängigkeit von Drittanbietern. Findet die App den Stoff nicht, trägt die Lehrkraft
// die Angaben von Hand ein (kein Rateversuch über eine externe Quelle mehr, siehe TODO.md).
$entry = stoffliste_lookup($name);
if ($entry === null) {
ai_backend_fail(404, 'Stoff nicht in der RiSU-Stoffliste gefunden. Bitte Schreibweise/CAS-Nummer prüfen oder Angaben manuell eintragen.');
}
echo json_encode([
'name' => $entry['name'],
'cas' => $entry['cas'],
'ghsPictograms' => $entry['ghsPictograms'],
'signalWord' => $entry['signalWord'],
'hStatements' => implode(', ', $entry['hStatements']),
'pStatements' => implode(', ', $entry['pStatements']),
'activityRestriction' => implode('; ', stoffliste_restriction_texts($entry['activityRestrictionCodes'])),
'source' => 'RiSU-Stoffliste (Sicheres Experimentieren im Unterricht)'
. ($entry['zvg'] !== '' && $entry['zvg'] !== '-' ? ', ZVG ' . $entry['zvg'] : ''),
]);