Child of PAR-182. Expands RBAC from a fixed enum to a configurable model (product direction).
Requirement
Model (proposed)
role (tenant-scoped: id, name, is_system, is_owner) and role_permission (role_id → permission key). Permission keys: e.g. issue.read/create/update/delete, member.manage, settings.manage, team.manage, role.manage, release.manage, integration.manage.tenant_member.role (enum text) → tenant_member.role_id FK; backfill owner→owner role, member→contributor, viewer→viewer.WorkspaceAdminService seed path, alongside seedStates).Enforcement is split out into sibling issues (API/MCP/UI). This issue is the model + defaults + migration only.
Depends on / pairs with the enforcement children. Replaces the hard-coded unions in tesks-ui/lib/roles.ts.
Verified LIVE. V19 creates role+role_permission, seeds owner/admin/contributor/viewer for all existing workspaces + grants, adds & backfills tenant_member.role_id. Owner immutability + last-owner guard in WorkspaceAdminService.setMemberRole/removeMember (via PermissionService.actorIsOwner); custom role CRUD gated on role.manage. Acceptance met.
Done on develop (commit
25680a9). MigrationV19__rbac_roles.sqladdsrole+role_permission(tenant-scoped) androle_idontenant_memberandapi_key. Seeds four system roles per workspace — owner/admin/contributor/viewer — with fine-grained grants; backfills existing members (owner→owner, member→contributor, viewer→viewer) and existing API keys → admin. New workspaces seed the same set viaWorkspaceAdminService.seedRoles(creator → owner). Owner role isis_owner(immutable, only role withissue.destroy+workspace.manage). Verified by the RBAC test suite (100 tests green).