Web-Anwendung: Design-Tokens, Texte, Gesundheitsendpunkt
Design-Tokens aus docs/10-design-system.md als CSS-Variablen: Grundpalette, die sechs Klassifizierungsfarben, Eckenradius durchgehend 2 px, keine Schatten ausser dem Fokusring. Der Schwärzungsbalken mit dem einmaligen Durchwischen respektiert prefers-reduced-motion. Vier Tests halten die Tokens gegen das Dokument. IBM Plex selbst gehostet als woff2, latin und latin-ext getrennt über unicode-range, font-display: swap, immutable-Cache. Alle Oberflächentexte in lib/i18n/de.ts. Ein Test durchsucht app/ und components/ nach Umlauten im JSX und schlägt fehl, wenn dort deutscher Text steht. Er hat beim ersten Lauf gleich einen Verstoss gefunden. /api/health prüft Datenbank, Discord-Gateway und ClamAV. Die Gesamtbewertung fällt nur auf "down", wenn die Datenbank weg ist: die anderen Dienste haben eigene Healthchecks im Stack, und ein ausgefallener Virenscanner soll nicht den Web-Container als tot markieren. Strikte CSP mit Nonce, kein unsafe-inline für Skripte. Die erste Route liegt bei 100 kB JavaScript nach Kompression, Budget sind 120 kB.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Rechte-Enum aus docs/03-auth-und-rechte.md. RoleMapping.permissions ist in der
|
||||
* Datenbank ein String[], diese Liste ist die verbindliche Menge gültiger Werte
|
||||
* und die Grundlage der Kästchen im Adminbereich.
|
||||
*/
|
||||
export const PERMISSIONS = [
|
||||
'case.read',
|
||||
'case.create',
|
||||
'case.edit',
|
||||
'case.close',
|
||||
'case.reopen',
|
||||
'case.delete',
|
||||
'case.edit_closed',
|
||||
'entry.create',
|
||||
'entry.correct',
|
||||
'entry.edit_own',
|
||||
'entry.edit_any',
|
||||
'entry.retract',
|
||||
'personnel.read',
|
||||
'personnel.edit',
|
||||
'template.manage',
|
||||
'roles.manage',
|
||||
'audit.read',
|
||||
'export.approve',
|
||||
'admin',
|
||||
] as const
|
||||
|
||||
export type Permission = (typeof PERMISSIONS)[number]
|
||||
|
||||
/**
|
||||
* Diese drei sind im Auslieferungszustand keiner Rolle zugeordnet. Der Leiter
|
||||
* schaltet sie bewusst frei. Der Adminbereich weist beim Zuweisen darauf hin.
|
||||
*/
|
||||
export const OPT_IN_PERMISSIONS: readonly Permission[] = [
|
||||
'entry.edit_own',
|
||||
'entry.edit_any',
|
||||
'entry.retract',
|
||||
]
|
||||
|
||||
export function isPermission(value: string): value is Permission {
|
||||
return (PERMISSIONS as readonly string[]).includes(value)
|
||||
}
|
||||
|
||||
/** Aufgelöste Rechte eines Nutzers für genau einen Request. */
|
||||
export type EffectivePermissions = {
|
||||
userId: string
|
||||
/** Höchste Stufe aller Rollen. */
|
||||
clearanceLevel: number
|
||||
/** Vereinigung aller Rollen. */
|
||||
permissions: Set<Permission>
|
||||
/** Aus BOOTSTRAP_ADMIN_IDS oder Recht 'admin'. */
|
||||
isAdmin: boolean
|
||||
}
|
||||
|
||||
export function can(p: EffectivePermissions, permission: Permission): boolean {
|
||||
return p.isAdmin || p.permissions.has(permission)
|
||||
}
|
||||
Reference in New Issue
Block a user