import { Grant, GrantEffect, GrantRole, GrantScopeType, GrantSubjectType } from '@dorfteich/shared'; import { GrantEffect as PrismaEffect, GrantRole as PrismaRole, GrantScopeType as PrismaScopeType, GrantSubjectType as PrismaSubjectType, RoleGrant, } from '@prisma/client'; /** * Maps between the database's uppercase grant enums and the shared model's * lowercase strings (issue #51), so the resolution algorithm in * `@dorfteich/shared` sees one canonical shape regardless of storage. */ const SUBJECT_TO_DB: Record = { user: 'USER', authenticated: 'AUTHENTICATED', public: 'PUBLIC', }; const ROLE_TO_DB: Record = { pond_admin: 'POND_ADMIN', editor: 'EDITOR', reader: 'READER', }; const SCOPE_TO_DB: Record = { pond: 'POND', label: 'LABEL', page: 'PAGE', }; const EFFECT_TO_DB: Record = { allow: 'ALLOW', deny: 'DENY' }; const SUBJECT_FROM_DB: Record = { USER: 'user', AUTHENTICATED: 'authenticated', PUBLIC: 'public', }; const ROLE_FROM_DB: Record = { POND_ADMIN: 'pond_admin', EDITOR: 'editor', READER: 'reader', }; const SCOPE_FROM_DB: Record = { POND: 'pond', LABEL: 'label', PAGE: 'page', }; const EFFECT_FROM_DB: Record = { ALLOW: 'allow', DENY: 'deny' }; /** A stored grant row → the shared model shape. */ export function toGrant(row: RoleGrant): Grant { return { subjectType: SUBJECT_FROM_DB[row.subjectType], subjectId: row.subjectId, role: ROLE_FROM_DB[row.role], scopeType: SCOPE_FROM_DB[row.scopeType], scopeId: row.scopeId, effect: EFFECT_FROM_DB[row.effect], }; } /** The shared grant shape → the Prisma enum columns (for writes). */ export function toGrantColumns(grant: Grant): { subjectType: PrismaSubjectType; subjectId: string | null; role: PrismaRole; scopeType: PrismaScopeType; scopeId: string | null; effect: PrismaEffect; } { return { subjectType: SUBJECT_TO_DB[grant.subjectType], subjectId: grant.subjectId, role: ROLE_TO_DB[grant.role], scopeType: SCOPE_TO_DB[grant.scopeType], scopeId: grant.scopeId, effect: EFFECT_TO_DB[grant.effect], }; }