Files
AfiS-Aktensystem/web/lib/auth/permissions.ts
T
HarlekinandClaude Opus 5 e8c5efc214 Kein Löschen von Akten, Hochstufen bei eigener Stufe gedeckelt
Zwei Festlegungen, beide in docs/13-entscheidungen.md begründet.

case.delete ist gestrichen. Der Lebenszyklus kennt ARCHIVED und SEALED, und
eine Akte mit Verlaufseinträgen liesse sich ohnehin nicht hart löschen, weil
CaseEntry nach Regel 2 unlöschbar ist und der Fremdschlüssel das Kaskadieren
blockiert. Das ist die konsequente Fortsetzung von Regel 2 eine Ebene höher.

Niemand klassifiziert eine Akte höher als die eigene Freigabestufe. Sonst
entstehen Akten, die ihr Urheber nicht mehr sehen kann, und die Frage "wer
konnte das lesen" wird im Nachhinein schwer beantwortbar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 21:34:29 +02:00

63 lines
1.7 KiB
TypeScript

/**
* 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.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
/**
* Trägt der Nutzer eine Rolle, die zur Anmeldung berechtigt? Ergänzung
* gegenüber docs/03-auth-und-rechte.md: auf dem AfiS-Discord sind auch
* Gäste. Siehe docs/13-entscheidungen.md.
*/
hasMembership: boolean
}
export function can(p: EffectivePermissions, permission: Permission): boolean {
return p.isAdmin || p.permissions.has(permission)
}