box_admin)box_admin.User (prisma/mysql/schema/user.prisma)Role (prisma/mysql/schema/role.prisma)UserRole (prisma/mysql/schema/user-role.prisma)Menu (prisma/mysql/schema/menu.prisma)RoleMenu (prisma/mysql/schema/role-menu.prisma)ApiPermission (prisma/mysql/schema/api-permission.prisma)RoleApiPermission (prisma/mysql/schema/role-api-permission.prisma)LoginLog (prisma/mysql/schema/login-log.prisma)OperationLog (prisma/mysql/schema/operation-log.prisma)QuotaLog (prisma/mysql/schema/quota-log.prisma)CacheSyncAction (prisma/mysql/schema/cache-sync-action.prisma)ImageConfig (no references in apps/box-mgnt-api/src)ProviderVideoSync (defined in MySQL schema, but mgnt provider sync code writes to Mongo)| Model | Primary Key | Unique Constraints | Relations |
|---|---|---|---|
| User | id (auto-increment int) |
username |
UserRole.userId -> User.id |
| Role | id |
name |
UserRole.roleId -> Role.id, RoleMenu.roleId -> Role.id, RoleApiPermission.roleId -> Role.id |
| UserRole | id |
(userId, roleId) |
userId -> User, roleId -> Role |
| Menu | id |
frontendAuth |
self relation (parentId -> Menu.id), RoleMenu.menuId -> Menu.id, ApiPermission.menuId -> Menu.id |
| RoleMenu | id |
(roleId, menuId) |
roleId -> Role, menuId -> Menu |
| ApiPermission | id |
(menuId, path, method) |
menuId -> Menu, RoleApiPermission.apiPermissionId -> ApiPermission.id |
| RoleApiPermission | id |
(roleId, apiPermissionId) |
roleId -> Role, apiPermissionId -> ApiPermission |
| LoginLog | id |
none | none |
| OperationLog | id |
none | menuId is nullable but not enforced by FK in schema |
| QuotaLog | id |
none | none |
| CacheSyncAction | id (BigInt) |
none | none; indexed by status,nextAttemptAt and entityType,entityId |
MenuType (DIRECTORY, MENU, SUBMENU, BUTTON)LoginType / LoginStatusOperationTypeUser.twoFARecoveryCodes, User.allowIpsMenu.metaOperationLog.body, OperationLog.responseCacheSyncAction.payloadMenu.frontendAuth queried by findUnique in apps/box-mgnt-api/src/mgnt-backend/core/menu/menu.service.tsbox_admin)sys_user
id (int), username, password, status, nick, photo, remark, twoFA, twoFALastUsedStep, twoFARecoveryCodes, allowIps, jwtToken, oAuthJwtToken, lastLoginTime, create_time, update_timeusername, index on status (optional for listing)sys_role
id (int), name, status, remark, create_time, update_timenamesys_user_role
id (int), user_id, role_id, create_time, update_time(user_id, role_id); index on user_id, role_idsys_menu
id (int), parent_id, title, status, type, order, frontend_auth, path, name, icon, redirect, component_key, meta, canView, canCreate, canUpdate, canDelete, create_time, update_timefrontend_auth, index on parent_id, index on typesys_role_menu
id (int), role_id, menu_id, canView, canCreate, canUpdate, canDelete, create_time, update_time(role_id, menu_id); index on role_id, menu_idsys_api_permission
id (int), menu_id, path, method, create_time, update_time(menu_id, path, method); index on menu_idsys_role_api_permission
id (int), role_id, api_permission_id, create_time, update_time(role_id, api_permission_id); index on role_id, api_permission_idsys_login_log
id (int), type, status, username, ip_address, user_agent, create_time, update_timeusername, create_timesys_operation_log
id (int), username, menu_id, description, type, status, method, path, body, response, ip_address, call_method, create_time, update_timeusername, menu_id, create_timesys_quota_log
id (int), username, op_username, amount, is_inc, quota, remark, create_time, update_timeusername, create_timecache_sync_action
id (long), entityType, entityId, operation, status, attempts, nextAttemptAt, lastError, payload, createdAt, updatedAt(status, nextAttemptAt), (entityType, entityId)User.id, Role.id, Menu.id).UserRole (list, get, update)
apps/box-mgnt-api/src/mgnt-backend/core/user/user.service.tsinclude on userRoles.role and where clauses with userRoles.someRoleMenu (get permissions)
apps/box-mgnt-api/src/mgnt-backend/core/role/role.service.tsApiPermission + RoleApiPermission
apps/box-mgnt-api/src/mgnt-backend/core/menu/menu.service.tsapps/box-mgnt-api/src/mgnt-backend/core/menu/menu.service.tsRoleService.create and RoleService.update use $transaction to insert role + roleMenu or replace roleMenuUserService.create, UserService.update, UserService.delete use $transaction to change user and userRole togetherMenuService.updatePermission deletes roleApiPermission + apiPermission, then recreates in a $transactionMenuService.delete deletes roleMenu + menu in a $transactionUserService.list and RoleService.list use $transaction to fetch list + countsys_user_role, sys_role_menu, sys_role_api_permission) and perform multi-step queries in services.roleIds on sys_user and menuIds on sys_role) to reduce query count.include and some relational filters with:
$lookup aggregation pipelines (only if performance is acceptable)counters with { _id: "sys_user", seq: 123 }).prisma/mysql/schema/user.prismaprisma/mysql/schema/role.prismaprisma/mysql/schema/user-role.prismaprisma/mysql/schema/menu.prismaprisma/mysql/schema/role-menu.prismaprisma/mysql/schema/api-permission.prismaprisma/mysql/schema/role-api-permission.prismaprisma/mysql/schema/login-log.prismaprisma/mysql/schema/operation-log.prismaprisma/mysql/schema/quota-log.prismaprisma/mysql/schema/cache-sync-action.prisma