// Permission predicates the dashboard uses to shadow create / edit / // delete affordances. Mirrors the canonical role → capability rules in // crates/manager-core/src/authz.rs: // // owner / admin instance role → implicit app_admin on every app // app_admin → settings, domain claims, delete app, delete scripts // editor → CRUD on scripts, routes, sandbox config (no script delete) // viewer → read scripts + execution logs // member with no membership → no access // // These helpers are read-only and have no Svelte runes — callers pass // the current `MeDto` and (when relevant) the per-app `my_role` they // already hold. Hiding here never authorizes anything; the backend's // `require(Capability::…)` is always the ground truth. import type { AppRole, MeDto } from './api'; /** Owner + admin only. Members never see "New app". */ export function canCreateApp(me: MeDto | null): boolean { if (!me) return false; return me.instance_role === 'owner' || me.instance_role === 'admin'; } /** Owner + admin only — the "Users" admin page is also gated this way. */ export function canManageUsers(me: MeDto | null): boolean { if (!me) return false; return me.instance_role === 'owner' || me.instance_role === 'admin'; } /** Can mutate scripts and routes (Save, +Add route, remove route). */ export function canWriteApp(me: MeDto | null, appMyRole: AppRole | null): boolean { if (!me) return false; if (me.instance_role === 'owner' || me.instance_role === 'admin') return true; return appMyRole === 'app_admin' || appMyRole === 'editor'; } /** Can take app-admin actions: app settings, domain claims, delete * app, delete scripts, manage members. */ export function canAdminApp(me: MeDto | null, appMyRole: AppRole | null): boolean { if (!me) return false; if (me.instance_role === 'owner' || me.instance_role === 'admin') return true; return appMyRole === 'app_admin'; }