fix: replace dead camelCase permission keys with OrgPermission enum in role seed (ISSUE-162)#164
Closed
GitAddRemote wants to merge 1 commit into
Closed
fix: replace dead camelCase permission keys with OrgPermission enum in role seed (ISSUE-162)#164GitAddRemote wants to merge 1 commit into
GitAddRemote wants to merge 1 commit into
Conversation
…n role seed (ISSUE-162) - Replace all camelCase permission keys in roles.seed.ts with correct OrgPermission enum values (can_view_org_inventory, etc.) - Import OrgPermission from permissions.constants.ts as single source of truth - Make seedRoles() upsert permissions on existing roles so re-running the seeder heals a broken database rather than silently skipping - Owner and Admin get full inventory access; Member gets view+shared; Viewer gets view-only
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes ISSUE-162 where default roles were seeded with invented camelCase permission keys that the backend never enforced, leaving Owner/Admin/Member/Viewer users with effectively zero valid permissions. The seed now uses the real OrgPermission enum values, and seedRoles() heals existing roles by upserting their permissions instead of skipping them.
Changes:
- Replace camelCase permission keys in
defaultRoleswithOrgPermissionenum values across Owner/Admin/Member/Viewer. - Make
seedRoles()update permissions on already-existing roles instead of leaving them untouched.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| backend/src/database/seeds/roles.seed.ts | Imports OrgPermission and rewrites every role's permissions object using enum-keyed booleans. |
| backend/src/database/seeds/database-seeder.service.ts | Changes the "role already exists" branch to overwrite permissions from the seed and log an update. |
Comments suppressed due to low confidence (1)
backend/src/database/seeds/roles.seed.ts:38
- Role
descriptionfields still reference organization/user/role/settings management (e.g., "Can delete organization and manage all settings", "Can manage users and settings"), but the actual permissions now only cover inventory-related capabilities. These descriptions are misleading to anyone reading them in the DB or UI; consider updating them to accurately reflect the inventory-focused permissions that are actually granted.
description:
'Full access to organization. Can delete organization and manage all settings.',
permissions: {
[OrgPermission.CAN_VIEW_ORG_INVENTORY]: true,
[OrgPermission.CAN_EDIT_ORG_INVENTORY]: true,
[OrgPermission.CAN_ADMIN_ORG_INVENTORY]: true,
[OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true,
},
},
{
name: 'Admin',
description: 'Administrative access. Can manage users and settings.',
permissions: {
[OrgPermission.CAN_VIEW_ORG_INVENTORY]: true,
[OrgPermission.CAN_EDIT_ORG_INVENTORY]: true,
[OrgPermission.CAN_ADMIN_ORG_INVENTORY]: true,
[OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true,
},
},
{
name: 'Member',
description: 'Standard member access. Can view and participate.',
permissions: {
[OrgPermission.CAN_VIEW_ORG_INVENTORY]: true,
[OrgPermission.CAN_EDIT_ORG_INVENTORY]: false,
[OrgPermission.CAN_ADMIN_ORG_INVENTORY]: false,
[OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true,
},
},
{
name: 'Viewer',
description: 'Read-only access. Can only view information.',
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
4
to
46
| export const defaultRoles: Partial<Role>[] = [ | ||
| { | ||
| name: 'Owner', | ||
| description: | ||
| 'Full access to organization. Can delete organization and manage all settings.', | ||
| permissions: { | ||
| // Organization management | ||
| canDeleteOrganization: true, | ||
| canEditOrganization: true, | ||
| canViewOrganization: true, | ||
|
|
||
| // User management | ||
| canInviteUsers: true, | ||
| canRemoveUsers: true, | ||
| canEditUserRoles: true, | ||
| canViewUsers: true, | ||
|
|
||
| // Role management | ||
| canCreateRoles: true, | ||
| canEditRoles: true, | ||
| canDeleteRoles: true, | ||
| canViewRoles: true, | ||
|
|
||
| // Settings | ||
| canManageSettings: true, | ||
| canViewSettings: true, | ||
| [OrgPermission.CAN_VIEW_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_EDIT_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_ADMIN_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true, | ||
| }, | ||
| }, | ||
| { | ||
| name: 'Admin', | ||
| description: 'Administrative access. Can manage users and settings.', | ||
| permissions: { | ||
| // Organization management | ||
| canEditOrganization: true, | ||
| canViewOrganization: true, | ||
|
|
||
| // User management | ||
| canInviteUsers: true, | ||
| canRemoveUsers: true, | ||
| canEditUserRoles: true, | ||
| canViewUsers: true, | ||
|
|
||
| // Role management | ||
| canViewRoles: true, | ||
|
|
||
| // Settings | ||
| canManageSettings: true, | ||
| canViewSettings: true, | ||
| [OrgPermission.CAN_VIEW_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_EDIT_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_ADMIN_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true, | ||
| }, | ||
| }, | ||
| { | ||
| name: 'Member', | ||
| description: 'Standard member access. Can view and participate.', | ||
| permissions: { | ||
| // Organization management | ||
| canViewOrganization: true, | ||
|
|
||
| // User management | ||
| canViewUsers: true, | ||
|
|
||
| // Role management | ||
| canViewRoles: true, | ||
|
|
||
| // Settings | ||
| canViewSettings: true, | ||
| [OrgPermission.CAN_VIEW_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_EDIT_ORG_INVENTORY]: false, | ||
| [OrgPermission.CAN_ADMIN_ORG_INVENTORY]: false, | ||
| [OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: true, | ||
| }, | ||
| }, | ||
| { | ||
| name: 'Viewer', | ||
| description: 'Read-only access. Can only view information.', | ||
| permissions: { | ||
| // Organization management | ||
| canViewOrganization: true, | ||
|
|
||
| // User management | ||
| canViewUsers: true, | ||
|
|
||
| // Settings | ||
| canViewSettings: true, | ||
| [OrgPermission.CAN_VIEW_ORG_INVENTORY]: true, | ||
| [OrgPermission.CAN_EDIT_ORG_INVENTORY]: false, | ||
| [OrgPermission.CAN_ADMIN_ORG_INVENTORY]: false, | ||
| [OrgPermission.CAN_VIEW_MEMBER_SHARED_ITEMS]: false, | ||
| }, | ||
| }, | ||
| ]; |
Comment on lines
+96
to
+98
| existingRole.permissions = roleData.permissions ?? {}; | ||
| await this.rolesRepository.save(existingRole); | ||
| this.logger.info(` ✓ Updated permissions for role: ${roleData.name}`); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
roles.seed.ts(e.g.canViewOrganization,canInviteUsers) with correctOrgPermissionenum values (can_view_org_inventory, etc.) — the keys the backend actually enforcesseedRoles()upsert permissions on existing roles rather than skipping them, so re-runningpnpm seedheals a broken database without data lossRoot Cause
Two disconnected permission systems were never reconciled.
roles.seed.tsused camelCase keys invented outside theOrgPermissionenum; the backend only checks snake_caseOrgPermissionkeys. Every user assignedOwner,Admin,Member, orViewerhad zero valid permissions, causing 403s on all inventory endpoints.Permission Matrix (post-fix)
Test plan
pnpm seedagainst an existing database — all four roles should log✓ Updated permissions for roleSELECT name, permissions FROM role ORDER BY name— all roles showOrgPermissionsnake_case keysdemouser (Owner role) and switch to org view — inventory loads without 403pnpm seeda second time — idempotent, no errors🤖 Generated with Claude Code