import express from 'express' import { existsSync } from 'node:fs' import './database' import { getAllRows } from './db/crud' import { rpcModules } from './rpcModules' import { STARTER_FILE, readStarterPackage, importStarterPackage, summarizeStarter, } from './db/starterPackage' const app = express() app.use(express.json({ limit: '50mb' })) // Backup-Import kann alle Tabellen als ein JSON-Body enthalten app.post('/api/rpc', (req, res) => { const { module, fn, args } = req.body as { module?: string; fn?: string; args?: unknown[] } const mod = module ? rpcModules[module] : undefined const handler = fn ? mod?.[fn] : undefined if (!mod || typeof handler !== 'function') { res.json({ ok: false, error: `Unbekannte RPC-Zielfunktion: ${module}.${fn}` }) return } try { const result = handler(...(args ?? [])) res.json({ ok: true, result: result ?? null }) } catch (err) { res.json({ ok: false, error: err instanceof Error ? err.message : 'Unbekannter Server-Fehler' }) } }) /** V2-Default 4001 — Produktiv bleibt auf 4000. */ const port = process.env.API_PORT ? Number(process.env.API_PORT) : 4001 if (!Number.isFinite(port) || port === 4000) { throw new Error( `[server] SAFETY: API_PORT=${process.env.API_PORT ?? '(unset)'} ist ungültig oder kollidiert mit Produktiv-Port 4000. ` + `V2 erwartet z.B. 4001 (siehe .env).`, ) } /** Team-ZIP: leere DB automatisch mit Struktur befüllen (keine Meetings/Personen). */ function seedStarterIfEmpty(): void { const dims = getAllRows('feedbackDimensions') if (dims.length > 0) return if (!existsSync(STARTER_FILE)) { console.warn('[server] DB ohne Feedback-Struktur und ohne Starter-Paket — Config bleibt leer.') return } try { const pkg = readStarterPackage() const { structureRows } = importStarterPackage(pkg) const counts = summarizeStarter(pkg) console.log(`[server] Starter-Struktur automatisch geladen (${structureRows} Zeilen).`) console.log( `[server] Dimensionen=${counts.feedbackDimensions} Kategorien=${counts.feedbackCategories} ` + `Kriterien=${counts.feedbackCriterionItems} Typen=${counts.assignmentTypes}`, ) } catch (err) { console.warn('[server] Auto-Seed fehlgeschlagen:', err instanceof Error ? err.message : err) } } seedStarterIfEmpty() app.listen(port, () => { console.log(`[server] DEV-RPC-API (AssignmentMonitorV2) auf http://localhost:${port}/api/rpc`) console.log(`[server] Produktiv (AssigmentMonitor) nutzt Port 4000 — diese Instanz ist davon getrennt.`) })