Files
geograsim/v2-platform/tools/conformance-check/lib/check-manifest.php
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

104 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft manifest.json gegen Spec module-manifest.md.
*/
function check_manifest(array $m, Report $r): void {
// Pflichtfelder
$required = [
'specVersion', 'slug', 'displayName', 'displayNameEasy', 'version',
'shortDescription', 'shortDescriptionEasy',
'longDescription', 'longDescriptionEasy',
'estimatedDurationMin', 'difficultyLevels', 'supportedLanguages',
'entryHtml', 'cardImage',
'lehrplanAnker', 'glossarSchwerpunkte',
'telemetryMilestones', 'adminFieldsFile', 'maintainerInstance', 'lastUpdated',
];
$missing = [];
foreach ($required as $f) {
if (!array_key_exists($f, $m) || $m[$f] === null) $missing[] = $f;
}
if ($missing) {
$r->fail("Pflichtfelder fehlen", $missing);
} else {
$r->ok("Alle Pflichtfelder vorhanden");
}
// Slug
if (!empty($m['slug'])) {
if (preg_match('/^[a-z0-9-]+$/', $m['slug'])) {
$r->ok("Slug-Format ok ('{$m['slug']}')");
} else {
$r->fail("Slug muss nur Kleinbuchstaben, Ziffern und Bindestrich enthalten: '{$m['slug']}'");
}
}
// specVersion
if (!empty($m['specVersion']) && !preg_match('/^\d+\.\d+$/', $m['specVersion'])) {
$r->warn("specVersion sollte Major.Minor sein, z.B. '1.0': '{$m['specVersion']}'");
}
// Sprachen
if (!empty($m['supportedLanguages']) && is_array($m['supportedLanguages'])) {
if (!in_array('de-AT-standard', $m['supportedLanguages'], true)) {
$r->fail("supportedLanguages muss 'de-AT-standard' enthalten (Pflicht ab Spec 1.0)");
}
if (!in_array('de-AT-easy', $m['supportedLanguages'], true)) {
$r->fail("supportedLanguages muss 'de-AT-easy' enthalten (Easy-Sprache ist Pflicht)");
}
}
// Lehrplan-Anker mit Land-Prefix
if (!empty($m['lehrplanAnker']) && is_array($m['lehrplanAnker'])) {
foreach ($m['lehrplanAnker'] as $code) {
if (!preg_match('/^[A-Z]{2}-/', $code)) {
$r->fail("Lehrplan-Anker braucht Land-Prefix (z.B. AT-, DE-, CH-): '$code'");
}
}
if (count($m['lehrplanAnker']) > 0) {
$r->ok("Lehrplan-Anker: " . count($m['lehrplanAnker']) . " Eintrag/Einträge, alle mit Land-Prefix");
}
}
// Glossar-Schwerpunkte max 10
if (isset($m['glossarSchwerpunkte']) && is_array($m['glossarSchwerpunkte'])) {
$n = count($m['glossarSchwerpunkte']);
if ($n > 10) {
$r->fail("glossarSchwerpunkte hat $n Einträge, max. 10 erlaubt (alles weitere on-demand via /api/glossary/<slug>)");
} else {
$r->ok("glossarSchwerpunkte: $n von max 10 Einträgen");
}
}
// dbTables Prefix
if (!empty($m['dbTables']) && is_array($m['dbTables'])) {
$expectedPrefix = "m_{$m['slug']}_";
foreach ($m['dbTables'] as $table) {
if (!str_starts_with($table, $expectedPrefix)) {
$r->fail("DB-Tabelle '$table' muss Prefix '$expectedPrefix' haben");
}
}
}
// difficultyLevels: mind. 1
if (empty($m['difficultyLevels']) || !is_array($m['difficultyLevels']) || count($m['difficultyLevels']) < 1) {
$r->fail("difficultyLevels muss mindestens einen Eintrag haben");
} else {
foreach ($m['difficultyLevels'] as $i => $lvl) {
if (!isset($lvl['id'], $lvl['label'], $lvl['labelEasy'])) {
$r->fail("difficultyLevels[$i] braucht id, label, labelEasy");
}
}
}
// telemetryMilestones
if (!empty($m['telemetryMilestones']) && is_array($m['telemetryMilestones'])) {
foreach ($m['telemetryMilestones'] as $i => $ms) {
if (!isset($ms['id'], $ms['label'])) {
$r->fail("telemetryMilestones[$i] braucht id und label");
}
}
}
}