{ "doc": "docs/anleitung-entwicklung.md", "range": "541-1004", "claims_checked": 120, "wrong": [ { "line": "635-640", "claim": "Das Dockerfile setzt als CMD: prisma migrate deploy --schema apps/api/prisma/schema.prisma && node apps/api/dist/main.js", "actual": "Der CMD ist `sh apps/api/scripts/migrate-and-start.sh`. Das Skript trennt Migrations- und Laufzeitverbindung (TESSERA_MIGRATE_DATABASE_URL, Vorgabe DATABASE_URL), Rollentrennung gemäß docs/mandantentrennung-datenbankrolle.md.", "evidence": "apps/api/Dockerfile:59; apps/api/scripts/migrate-and-start.sh:1-40", "fix": "CMD-Block ersetzen durch `CMD [\"sh\", \"apps/api/scripts/migrate-and-start.sh\"]` und ergänzen: Das Skript führt `prisma migrate deploy` (mit TESSERA_MIGRATE_DATABASE_URL, falls gesetzt, sonst DATABASE_URL) aus und startet danach die API mit DATABASE_URL." } ], "outdated": [ { "line": "549-550", "claim": "forTenant() führt vor jeder Query SELECT set_config('app.current_tenant', $1, true) aus", "actual": "Die Anweisung setzt drei Werte in einem Aufruf: app.current_tenant, app.current_user (leer, wenn kein userId) und app.system_context (leer).", "evidence": "apps/api/src/prisma/prisma-tenant.extension.ts:201", "fix": "Ergänzen: 'setzt zugleich app.current_user (optionaler dritter Parameter) und löscht app.system_context'." } ], "missing": [ { "line": "558-566", "claim": "RLS-Abschnitt", "actual": "Es gibt zusätzlich eine Systemkontext-Variante (app.system_context='true', Zeile 228 der Extension) und Wächter-Specs rls-coverage/rls-access-inventory/rls-app-role/rls-preflight in apps/api/src/prisma/, die nicht erwähnt werden.", "evidence": "apps/api/src/prisma/prisma-tenant.extension.ts:228; apps/api/src/prisma/*.spec.ts", "fix": "Kurz die RLS-Wächter-Specs und den Systemkontext-Weg (für Hintergrunddienste) erwähnen." } ], "ok_count": 119, "notes": "Geprüft und korrekt: TenantGuard/APP_GUARD-Reihenfolge, x-tenant-id, req.tenantId; RLS-Zählung 23 = 4+3+16; zehn persönliche Tabellen in Migration 20260911120000; plattformweite Modelle ohne tenantId; Role-Enum; RolesGuard global; module-grants Routen und Rollen (matrix vor users/:userId); postinstall-Skript; Vitest-Konfigurationen (node/jsdom, setup.ts, passWithNoTests); Testbefehle; Desktop-Spec mit NestFactory; CI-Job desktop mit cargo check/clippy; Tenders-Routenreihenfolge (alle genannten statischen Routen vor @Get(':id')); CHANGELOG-Mechanik (next.config, Dockerfile, .dockerignore, publish-release.sh exit 1, filterChangelogForChannel); Release-Fenster (Endpunkte, getRunningRelease, parse/compareReleaseVersions, selectReleaseNotice, User.lastSeenReleaseVersion); Dashboard-Hintergrund (Spalte, Endpunkt, getMe, shared-Parser); i18n-Wächter-Specs; @custom-variant dark in globals.css:22; Nextcloud-Teilen (nextcloud-shares.ts, Grenzen 8 MiB/64 KiB/1 MiB, Routen, checkShareCreate 10 und checkShareAttempt 40 je 10 min, mapShareFailure, e2e-shares.sh mit Argumenten und policy_wait); Zertifikatsmanager (3 POST-Routen, Limits 30/5/20 MiB, 200/50/50, KDF 1.000.000/6.000.000, ZIP-Grenzen, PEM_BLOCKS 1000, 512 KiB certBuildJsonBody, http-setup, createGuardedLookup, AIA 8 s/256 KiB, public-url-guard Exporte, Fixtures, e2e-cert.sh)." }