fix: persist custom roles immediately, show them in user modal

- createRole() now calls api.rolePermissions.save() on creation so the
  role survives a page refresh (was only in local state before)
- UserModal now renders custom roles from savedPermissions context
  alongside the system role buttons
- mapRole() passes custom_* role keys through unchanged
- handleSave falls back to u.role for custom roles (no backendRoleMap entry)
- Table badge handles missing ROLE_META entry for custom roles
- DB migration 082: removes users.role CHECK constraint so custom role
  keys can be stored in the users table
- Backend POST/PATCH: allow custom_* roles through role allowlist checks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 19:57:59 +03:00
parent a701366216
commit 9e1eff30a6
3 changed files with 82 additions and 35 deletions

View File

@@ -59,12 +59,13 @@ const users: FastifyPluginAsync = async (fastify) => {
const { email, password, name, role = 'housekeeper', phone, position } = request.body
// Role creation permissions
const isCustomRole = (r: string) => r.startsWith('custom_')
const hotelAdminAllowedRoles = ['manager', 'housekeeper', 'receptionist', 'accountant', 'security', 'technician']
const managerAllowedRoles = ['housekeeper', 'receptionist', 'accountant', 'security', 'technician']
if (request.user.role === 'hotel_admin' && !hotelAdminAllowedRoles.includes(role)) {
if (request.user.role === 'hotel_admin' && !hotelAdminAllowedRoles.includes(role) && !isCustomRole(role)) {
return reply.code(403).send({ error: 'Недостаточно прав для создания этой роли' })
}
if (request.user.role === 'manager' && !managerAllowedRoles.includes(role)) {
if (request.user.role === 'manager' && !managerAllowedRoles.includes(role) && !isCustomRole(role)) {
return reply.code(403).send({ error: 'Недостаточно прав для создания этой роли' })
}
@@ -131,10 +132,11 @@ const users: FastifyPluginAsync = async (fastify) => {
return reply.code(403).send({ error: 'Нельзя назначить роль системного администратора' })
}
// Managers can change role but not to manager/super_admin
const isCustomRole = (r: string) => r.startsWith('custom_')
const managerAllowedRoles = ['housekeeper', 'receptionist', 'accountant', 'security', 'technician']
if (request.user.role === 'super_admin' ||
(request.user.role === 'hotel_admin' && managerAllowedRoles.concat(['manager']).includes(request.body.role)) ||
(request.user.role === 'manager' && managerAllowedRoles.includes(request.body.role))) {
(request.user.role === 'hotel_admin' && (managerAllowedRoles.concat(['manager']).includes(request.body.role) || isCustomRole(request.body.role))) ||
(request.user.role === 'manager' && (managerAllowedRoles.includes(request.body.role) || isCustomRole(request.body.role)))) {
updates.push(`role = $${idx}`); values.push(request.body.role); idx++
}
}