fix(#P7-P8): Statische Route-Permissions auf Backend-/Manifest-Wahrheit gestellt — /communication comm:read (Phantom communication:read entfernt), /mail/settings mail:config (Backend verlangt config), /import-export import_export:read (Core-Modul, kein Plugin — Kritik-Aussage korrigiert), /activity audit:read (Phantom activity:read entfernt, Seite nutzt Audit-API), /wiki wiki:read (vorher ungeschützt); Regressionstest routePermissions.test.ts 6/6; Gates: tsc 0, Production-Build exit 0

This commit is contained in:
Agent Zero
2026-08-27 20:04:18 +02:00
parent 88d96d4a49
commit f27f0474ef
2 changed files with 61 additions and 5 deletions
@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
/**
* Welle 3 (Kritikpunkt 7/8): Statische Route-Permissions müssen die
* Backend-/Manifest-Wahrheit spiegeln. Beweist per Source-Inspektion:
* - /communication → comm:read (Backend verlangt comm:read; communication:read
* war eine Phantom-Permission, die nirgends registriert war)
* - /mail/settings → mail:config (Backend mail-settings verlangt mail:config)
* - /import-export → import_export:read (Backend verlangt import_export:read;
* vorher fälschlich contacts:read)
* - /activity → audit:read (Seite nutzt Audit-API; activity:read war Phantom)
* - /wiki → wiki:read (Backend verlangt wiki:read; vorher ungeschützt)
*/
const routerSource = readFileSync(
join(__dirname, '..', '..', 'routes', 'index.tsx'),
'utf-8',
);
function routePermission(path: string): string | null {
const marker = `path: '${path}'`;
const idx = routerSource.indexOf(marker);
if (idx === -1) return null;
const lineEnd = routerSource.indexOf('\n', idx);
const line = routerSource.slice(idx, lineEnd);
const match = line.match(/permission="([^"]+)"/);
return match ? match[1] : null;
}
describe('static route permissions match backend/manifest truth', () => {
it('communication uses comm:read (registered permission)', () => {
expect(routePermission('/communication')).toBe('comm:read');
});
it('mail/settings uses mail:config (backend requires mail:config)', () => {
expect(routePermission('/mail/settings')).toBe('mail:config');
});
it('import-export uses import_export:read (backend requires it)', () => {
expect(routePermission('/import-export')).toBe('import_export:read');
});
it('activity uses audit:read (page calls audit API)', () => {
expect(routePermission('/activity')).toBe('audit:read');
});
it('wiki is protected with wiki:read (backend requires wiki:read)', () => {
expect(routePermission('/wiki')).toBe('wiki:read');
});
it('phantom permissions are gone from the router', () => {
expect(routerSource).not.toContain('communication:read');
expect(routerSource).not.toContain('activity:read');
});
});