Files
tibi-docs/scripts/sync-server-docs.mjs
T
apairon 1928922e07 Audit + Umbau: Faktenfehler behoben, Server-/Admin-Lücken geschlossen, 49 Screenshots, Schema-Matrix generiert
- Audit: plans/doku-audit.md (Befunde, Phasen P1-P9, Ausführungsprotokoll) + plans/audit/ (8 Detailreports) + plans/offene-issues.md
- Werkzeuge: scripts/audit-docs.mjs (Links/Anker/Bilder/Tabellen), scripts/gen-schema-matrix.mjs (npm run gen:schemas)
- Neue Seiten: projekt/feld-rechte, reference/rest-system, reference/schema-properties, projekt/tests, 5 Anwender-Seiten
- Fehler behoben: EMBEDDING_BGE_M3_*-Env, allowSnapshots, MCP-Scopes (.read/.create/.update), meta.views, loadAll-Signatur, OpenAPI-Endpunkt, MongoDB 8, Befehlspalette
- Screenshots: 9 Admin + 10 Anwender aus Mock-Projekt corporate (t1 entfernt), 49 Bilder gesamt
- AGENTS.md: Sync-Behauptung richtiggestellt, Belegpflicht/UI-Namen/Screenshot-Regeln, Werkzeug-Abschnitt
- Build: 71 Seiten grün, 0 tote Links, 0 kaputte Tabellen
2026-10-17 01:49:35 +00:00

81 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
/**
* sync-server-docs.mjs — STILLGELEGT (2026-10-17).
*
* Grund: Der Sync kopierte die englischen Server-Docs nach src/content/docs/server/ und die
* Nova-Docs nach src/content/docs/admin/. Diese Ziele stehen nicht in der Sidebar, es entstanden
* verwaiste Seiten, die nie verlinkt wurden. Die deutschen Handseiten sind seither kanonisch.
*
* Nicht mehr aufrufen (kein npm-Script mehr). Datei bleibt nur als Nachweis/Referenz liegen.
*
* ALT: sync-server-docs.mjs — Single Source bleibt in den Quell-Repos,
* diese Doku rendert nur. Kopiert:
* - ../tibi-server/docs/*.md -> src/content/docs/server/ (ohne uebersicht.md zu überschreiben)
* - ../tibi-admin-nova/docs/*.md -> src/content/docs/admin/ (+ test-plans/)
* Fügt fehlendes Starlight-Frontmatter (title) aus Dateinamen/H1 hinzu.
*/
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const serverSrc = join(root, '..', 'tibi-server', 'docs');
const novaSrc = join(root, '..', 'tibi-admin-nova', 'docs');
const serverDst = join(root, 'src', 'content', 'docs', 'server');
const novaDst = join(root, 'src', 'content', 'docs', 'admin');
const titleFromName = (f) =>
f.replace(/\.md$/, '').replace(/^\d+-/, '').split('-')
.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
function ensureFrontmatter(file, fallbackTitle) {
let text = readFileSync(file, 'utf8');
if (text.startsWith('---')) return; // hat schon Frontmatter
const h1 = text.match(/^#\s+(.+)$/m)?.[1]?.trim() ?? fallbackTitle;
writeFileSync(file, `---\ntitle: '${h1.replace(/'/g, "''")}'\n---\n\n${text}`);
}
function syncTree(srcDir, dstDir, keep) {
let n = 0;
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;
const s = join(srcDir, entry.name);
const d = join(dstDir, entry.name);
if (entry.isDirectory()) {
mkdirSync(d, { recursive: true });
n += syncTree(s, d, []);
} else if (entry.name.endsWith('.md')) {
if (keep.includes(entry.name)) continue;
cpSync(s, d);
ensureFrontmatter(d, titleFromName(entry.name));
n++;
} else {
cpSync(s, d);
n++;
}
}
return n;
}
function syncDir(src, dst, { keep = [] } = {}) {
if (!existsSync(src)) {
console.warn(`[sync] Quelle fehlt, übersprungen: ${src}`);
return 0;
}
mkdirSync(dst, { recursive: true });
return syncTree(src, dst, keep);
}
// Alte Sync-Artefakte aufräumen (nur generierte, eigene uebersicht/konzept bleiben via keep)
const n1 = syncDir(serverSrc, serverDst, { keep: ['uebersicht.md'] });
const n2 = syncDir(novaSrc, novaDst, { keep: ['konzept.md'] });
console.log(`[sync] ${n1} Server-Dateien, ${n2} Nova-Dateien synchronisiert.`);
// Scaffold-Reste entfernen, falls vorhanden
for (const stale of [
join(root, 'src', 'content', 'docs', 'guides'),
join(root, 'src', 'content', 'docs', 'reference', 'example.md'),
]) {
if (existsSync(stale)) rmSync(stale, { recursive: true, force: true });
}