@jmruthers/pace-core 0.5.184 → 0.5.186
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +60 -1
- package/core-usage-manifest.json +312 -0
- package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
- package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
- package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-DIzEzwKl.d.ts} +23 -10
- package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
- package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
- package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
- package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
- package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
- package/dist/{chunk-W22JP75J.js → chunk-DAGICKHT.js} +9 -7
- package/dist/chunk-DAGICKHT.js.map +1 -0
- package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
- package/dist/chunk-FXFJRTKI.js.map +1 -0
- package/dist/{chunk-CSOFYHAG.js → chunk-GRIQLQ52.js} +374 -60
- package/dist/chunk-GRIQLQ52.js.map +1 -0
- package/dist/{chunk-NQPMQGS2.js → chunk-HDCUMOOI.js} +497 -399
- package/dist/chunk-HDCUMOOI.js.map +1 -0
- package/dist/chunk-HESYZWZW.js +388 -0
- package/dist/chunk-HESYZWZW.js.map +1 -0
- package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
- package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
- package/dist/{chunk-PWAHJW4G.js → chunk-OALXJH4Y.js} +86 -33
- package/dist/chunk-OALXJH4Y.js.map +1 -0
- package/dist/{chunk-MI7HBHN3.js → chunk-TC7D3CR3.js} +89 -9
- package/dist/chunk-TC7D3CR3.js.map +1 -0
- package/dist/chunk-THRPYOFK.js +215 -0
- package/dist/chunk-THRPYOFK.js.map +1 -0
- package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
- package/dist/chunk-U6WNSFX5.js.map +1 -0
- package/dist/{chunk-UHNYIBXL.js → chunk-UQWSHFVX.js} +1 -1
- package/dist/chunk-UQWSHFVX.js.map +1 -0
- package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
- package/dist/components.d.ts +182 -6
- package/dist/components.js +157 -11
- package/dist/components.js.map +1 -1
- package/dist/{database.generated-CBmg2950.d.ts → database.generated-DI89OQeI.d.ts} +63 -9
- package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
- package/dist/{file-reference-D06mEEWW.d.ts → file-reference-PRTSLxKx.d.ts} +10 -1
- package/dist/hooks.d.ts +52 -15
- package/dist/hooks.js +12 -22
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.js +82 -18
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +3 -1
- package/dist/rbac/index.d.ts +206 -15
- package/dist/rbac/index.js +28 -6
- package/dist/timezone-_pgH8qrY.d.ts +530 -0
- package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-D71QLlg4.d.ts} +114 -3
- package/dist/utils.d.ts +110 -152
- package/dist/utils.js +128 -138
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +60 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +178 -0
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +5 -5
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +54 -0
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +18 -2
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +30 -0
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
- package/docs/api/interfaces/DatabaseIssue.md +41 -0
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +6 -6
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +48 -8
- package/docs/api/interfaces/FileUploadProps.md +46 -13
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +62 -0
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +52 -0
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +4 -4
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +5 -5
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +41 -0
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
- package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +746 -50
- package/docs/api-reference/components.md +26 -12
- package/docs/api-reference/hooks.md +111 -0
- package/docs/api-reference/rpc-functions.md +1 -1
- package/docs/api-reference/utilities.md +184 -0
- package/docs/getting-started/installation-guide.md +75 -16
- package/docs/getting-started/quick-start.md +61 -11
- package/docs/implementation-guides/authentication.md +88 -12
- package/docs/implementation-guides/file-reference-system.md +26 -3
- package/docs/implementation-guides/file-upload-storage.md +30 -1
- package/docs/rbac/README.md +1 -0
- package/docs/rbac/compliance/compliance-guide.md +544 -0
- package/docs/rbac/getting-started.md +158 -33
- package/docs/standards/pace-core-compliance.md +432 -0
- package/eslint-config-pace-core.cjs +93 -0
- package/package.json +15 -3
- package/scripts/analyze-bundle.js +232 -0
- package/scripts/build-css.js +56 -0
- package/scripts/build-docs-incremental.js +1015 -0
- package/scripts/check-pace-core-compliance.cjs +2353 -0
- package/scripts/check-pace-core-compliance.js +512 -0
- package/scripts/generate-docs.js +157 -0
- package/scripts/setup-build-cache.js +73 -0
- package/scripts/utils/command-runner.js +131 -0
- package/scripts/utils/env.js +33 -0
- package/scripts/utils/index.js +10 -0
- package/scripts/utils/logger.js +88 -0
- package/scripts/utils/path-helpers.js +37 -0
- package/scripts/validate-formats.js +133 -0
- package/scripts/validate-master.js +155 -0
- package/scripts/validate-pre-publish.js +140 -0
- package/scripts/validate-theme.js +142 -0
- package/src/components/Calendar/Calendar.tsx +8 -1
- package/src/components/Card/Card.tsx +47 -8
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
- package/src/components/DatePickerWithTimezone/README.md +135 -0
- package/src/components/DatePickerWithTimezone/index.ts +10 -0
- package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
- package/src/components/DateTimeField/DateTimeField.tsx +232 -0
- package/src/components/DateTimeField/README.md +148 -0
- package/src/components/DateTimeField/index.ts +10 -0
- package/src/components/FileUpload/FileUpload.test.tsx +2 -0
- package/src/components/FileUpload/FileUpload.tsx +10 -1
- package/src/components/Header/Header.test.tsx +47 -18
- package/src/components/Header/Header.tsx +22 -7
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
- package/src/components/PaceAppLayout/README.md +9 -0
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +146 -5
- package/src/components/index.ts +8 -0
- package/src/eslint-rules/pace-core-compliance.cjs +406 -0
- package/src/eslint-rules/pace-core-compliance.js +640 -0
- package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useFileReference.test.ts +2 -0
- package/src/hooks/useFormDialog.ts +147 -0
- package/src/hooks/usePreventTabReload.ts +106 -0
- package/src/hooks/useSecureDataAccess.ts +2 -2
- package/src/index.ts +27 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
- package/src/rbac/__tests__/rbac-role-isolation.test.ts +456 -0
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
- package/src/rbac/compliance/database-validator.ts +165 -0
- package/src/rbac/compliance/index.ts +38 -0
- package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
- package/src/rbac/compliance/runtime-compliance.ts +77 -0
- package/src/rbac/compliance/setup-validator.ts +131 -0
- package/src/rbac/components/PagePermissionGuard.tsx +8 -64
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
- package/src/rbac/docs/event-based-apps.md +285 -0
- package/src/rbac/errors.ts +11 -0
- package/src/rbac/hooks/useRoleManagement.ts +292 -12
- package/src/rbac/index.ts +30 -0
- package/src/services/OrganisationService.ts +4 -0
- package/src/styles/core.css +5 -5
- package/src/types/database.generated.ts +63 -9
- package/src/types/file-reference.ts +9 -0
- package/src/utils/__tests__/timezone.test.ts +345 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +60 -4
- package/src/utils/file-reference/index.ts +13 -2
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
- package/src/utils/formatting/formatting.ts +179 -0
- package/src/utils/index.ts +27 -1
- package/src/utils/location/index.ts +16 -0
- package/src/utils/location/location.test.ts +286 -0
- package/src/utils/location/location.ts +175 -0
- package/src/utils/security/secureDataAccess.ts +1 -1
- package/src/utils/storage/helpers.ts +68 -0
- package/src/utils/timezone/index.ts +17 -0
- package/src/utils/timezone/timezone.test.ts +349 -0
- package/src/utils/timezone/timezone.ts +281 -0
- package/dist/chunk-CSOFYHAG.js.map +0 -1
- package/dist/chunk-FUEYYMX5.js.map +0 -1
- package/dist/chunk-HKIT6O7W.js +0 -198
- package/dist/chunk-HKIT6O7W.js.map +0 -1
- package/dist/chunk-KUEN3HFB.js +0 -94
- package/dist/chunk-KUEN3HFB.js.map +0 -1
- package/dist/chunk-M7W4CP3M.js.map +0 -1
- package/dist/chunk-MI7HBHN3.js.map +0 -1
- package/dist/chunk-NQPMQGS2.js.map +0 -1
- package/dist/chunk-PWAHJW4G.js.map +0 -1
- package/dist/chunk-UHNYIBXL.js.map +0 -1
- package/dist/chunk-W22JP75J.js.map +0 -1
- package/dist/formatting-5wETwiGF.d.ts +0 -162
- /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
- /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
- /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
# RBAC/Auth Compliance Guide
|
|
2
|
+
|
|
3
|
+
> **📚 RBAC Compliance** | [← Back to RBAC Documentation](../README.md) | [Troubleshooting](./troubleshooting-compliance.md) | [Migrating Custom Auth](./migrating-custom-auth.md)
|
|
4
|
+
|
|
5
|
+
This guide explains how to achieve RBAC/auth compliance in your pace app to ensure proper security and consistent usage of pace-core.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The RBAC/auth compliance system ensures that:
|
|
10
|
+
- All auth/rbac/permission functionality uses pace-core exclusively
|
|
11
|
+
- RBAC system is properly initialized
|
|
12
|
+
- All pages are protected with PagePermissionGuard
|
|
13
|
+
- Supabase configuration is centralized
|
|
14
|
+
- No custom auth/rbac code exists
|
|
15
|
+
|
|
16
|
+
## Compliance Checks
|
|
17
|
+
|
|
18
|
+
The compliance system checks for:
|
|
19
|
+
|
|
20
|
+
### 1. Custom Auth/RBAC Code
|
|
21
|
+
|
|
22
|
+
**What it checks:**
|
|
23
|
+
- Custom auth hooks (useAuth, useLogin, useLogout, etc.)
|
|
24
|
+
- Custom RBAC components (PermissionGuard, AuthGuard, etc.)
|
|
25
|
+
- Custom permission utilities (checkPermission, hasAccess, etc.)
|
|
26
|
+
|
|
27
|
+
**How to fix:**
|
|
28
|
+
- Remove custom implementations
|
|
29
|
+
- Import equivalent from `@jmruthers/pace-core` or `@jmruthers/pace-core/rbac`
|
|
30
|
+
- Update all usages
|
|
31
|
+
|
|
32
|
+
See [Migrating Custom Auth](./migrating-custom-auth.md) for detailed migration steps.
|
|
33
|
+
|
|
34
|
+
### 2. Duplicate Supabase Configuration
|
|
35
|
+
|
|
36
|
+
**What it checks:**
|
|
37
|
+
- Multiple `createClient` calls
|
|
38
|
+
- Supabase environment variables in multiple files
|
|
39
|
+
|
|
40
|
+
**How to fix:**
|
|
41
|
+
- Create a single `supabase.ts` file
|
|
42
|
+
- Export the client instance
|
|
43
|
+
- Import from the shared location everywhere
|
|
44
|
+
|
|
45
|
+
### 3. Unprotected Pages
|
|
46
|
+
|
|
47
|
+
**What it checks:**
|
|
48
|
+
- Routes without PagePermissionGuard
|
|
49
|
+
- Pages without permission checks
|
|
50
|
+
|
|
51
|
+
**How to fix:**
|
|
52
|
+
- Wrap all routes with PagePermissionGuard
|
|
53
|
+
- Set `pageName` and `operation` props
|
|
54
|
+
- Ensure pages exist in `rbac_app_pages` table
|
|
55
|
+
|
|
56
|
+
### 4. Direct Supabase Auth Usage
|
|
57
|
+
|
|
58
|
+
**What it checks:**
|
|
59
|
+
- Direct calls to `supabase.auth.signIn`, `supabase.auth.signUp`, etc.
|
|
60
|
+
|
|
61
|
+
**How to fix:**
|
|
62
|
+
- Use `useUnifiedAuth` hook from pace-core
|
|
63
|
+
- Use `UnifiedAuthProvider` to wrap your app
|
|
64
|
+
- Replace all direct auth calls with pace-core methods
|
|
65
|
+
|
|
66
|
+
### 5. Provider Setup Issues
|
|
67
|
+
|
|
68
|
+
**What it checks:**
|
|
69
|
+
- Missing `UnifiedAuthProvider` or `OrganisationProvider`
|
|
70
|
+
- Incorrect provider nesting order
|
|
71
|
+
- Providers placed in wrong locations
|
|
72
|
+
|
|
73
|
+
**How to fix:**
|
|
74
|
+
- Ensure correct nesting: `QueryClientProvider` → `BrowserRouter` → `UnifiedAuthProvider` → `OrganisationProvider` → `App`
|
|
75
|
+
- Place providers in `main.tsx` or `App.tsx` entry file
|
|
76
|
+
- See [Provider Setup](#provider-setup) section below
|
|
77
|
+
|
|
78
|
+
### 6. Vite Configuration Issues
|
|
79
|
+
|
|
80
|
+
**What it checks:**
|
|
81
|
+
- `@jmruthers/pace-core` in `optimizeDeps.include` (should be excluded)
|
|
82
|
+
- Missing `@jmruthers/pace-core` in `optimizeDeps.exclude`
|
|
83
|
+
- Missing `react-router-dom` in `resolve.dedupe`
|
|
84
|
+
|
|
85
|
+
**How to fix:**
|
|
86
|
+
- Add `@jmruthers/pace-core` to `optimizeDeps.exclude`
|
|
87
|
+
- Remove `@jmruthers/pace-core` from `optimizeDeps.include`
|
|
88
|
+
- Add `react-router-dom` to `resolve.dedupe`
|
|
89
|
+
- See [Vite Configuration](#vite-configuration) section below
|
|
90
|
+
|
|
91
|
+
### 7. Router Setup Issues
|
|
92
|
+
|
|
93
|
+
**What it checks:**
|
|
94
|
+
- Missing `BrowserRouter`
|
|
95
|
+
- `BrowserRouter` placed incorrectly (inside `UnifiedAuthProvider` instead of wrapping it)
|
|
96
|
+
- `Routes` used without `BrowserRouter`
|
|
97
|
+
|
|
98
|
+
**How to fix:**
|
|
99
|
+
- Wrap app with `BrowserRouter` from `react-router-dom`
|
|
100
|
+
- Ensure `BrowserRouter` wraps `UnifiedAuthProvider` (not the other way around)
|
|
101
|
+
- See [Router Setup](#router-setup) section below
|
|
102
|
+
|
|
103
|
+
## Running Compliance Checks
|
|
104
|
+
|
|
105
|
+
### Static Analysis
|
|
106
|
+
|
|
107
|
+
Run the compliance check script:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run check:pace-core
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This will scan your codebase and report:
|
|
114
|
+
- Custom auth/rbac code
|
|
115
|
+
- Duplicate configurations
|
|
116
|
+
- Unprotected pages
|
|
117
|
+
- Direct Supabase auth usage
|
|
118
|
+
- Provider setup issues
|
|
119
|
+
- Vite configuration problems
|
|
120
|
+
- Router setup issues
|
|
121
|
+
|
|
122
|
+
### ESLint Rules
|
|
123
|
+
|
|
124
|
+
The compliance system includes ESLint rules that run during development:
|
|
125
|
+
|
|
126
|
+
- `no-custom-auth-code` - Disallows custom auth/rbac implementations
|
|
127
|
+
- `no-duplicate-supabase-config` - Disallows multiple Supabase configurations
|
|
128
|
+
- `require-page-permission-guard` - Requires PagePermissionGuard on routes
|
|
129
|
+
- `no-direct-supabase-auth` - Disallows direct Supabase auth usage
|
|
130
|
+
|
|
131
|
+
### Runtime Validation
|
|
132
|
+
|
|
133
|
+
Check runtime compliance programmatically:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { checkRuntimeCompliance } from '@jmruthers/pace-core/rbac';
|
|
137
|
+
|
|
138
|
+
const result = checkRuntimeCompliance();
|
|
139
|
+
if (!result.setup.isCompliant) {
|
|
140
|
+
console.warn('RBAC setup issues:', result.setup.issues);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Achieving Compliance
|
|
145
|
+
|
|
146
|
+
### Step 1: Initialize RBAC
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// main.tsx or App.tsx
|
|
150
|
+
import { setupRBAC } from '@jmruthers/pace-core/rbac';
|
|
151
|
+
import { createClient } from '@supabase/supabase-js';
|
|
152
|
+
|
|
153
|
+
const supabase = createClient(
|
|
154
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
155
|
+
import.meta.env.VITE_SUPABASE_ANON_KEY
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// ⚠️ REQUIRED: Call setupRBAC before rendering
|
|
159
|
+
setupRBAC(supabase);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 2: Set Up Providers
|
|
163
|
+
|
|
164
|
+
**⚠️ CRITICAL: Provider nesting order matters!**
|
|
165
|
+
|
|
166
|
+
The correct nesting order is:
|
|
167
|
+
1. `QueryClientProvider` (outermost)
|
|
168
|
+
2. `BrowserRouter`
|
|
169
|
+
3. `UnifiedAuthProvider`
|
|
170
|
+
4. `OrganisationProvider`
|
|
171
|
+
5. `App` (innermost)
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
// main.tsx - Correct setup
|
|
175
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
176
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
177
|
+
import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
|
|
178
|
+
|
|
179
|
+
const queryClient = new QueryClient();
|
|
180
|
+
|
|
181
|
+
createRoot(document.getElementById("root")!).render(
|
|
182
|
+
<QueryClientProvider client={queryClient}>
|
|
183
|
+
<BrowserRouter>
|
|
184
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName={APP_NAME}>
|
|
185
|
+
<OrganisationProvider>
|
|
186
|
+
<App />
|
|
187
|
+
</OrganisationProvider>
|
|
188
|
+
</UnifiedAuthProvider>
|
|
189
|
+
</BrowserRouter>
|
|
190
|
+
</QueryClientProvider>
|
|
191
|
+
);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Common mistakes to avoid:**
|
|
195
|
+
- ❌ `BrowserRouter` inside `UnifiedAuthProvider` (causes Router context errors)
|
|
196
|
+
- ❌ `UnifiedAuthProvider` wrapping `BrowserRouter` (causes context errors)
|
|
197
|
+
- ❌ Missing `BrowserRouter` (causes `useNavigate` errors)
|
|
198
|
+
|
|
199
|
+
### Step 3: Protect All Pages
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
// pages/Dashboard.tsx
|
|
203
|
+
import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
|
|
204
|
+
|
|
205
|
+
function Dashboard() {
|
|
206
|
+
return (
|
|
207
|
+
<PagePermissionGuard pageName="dashboard" operation="read">
|
|
208
|
+
<DashboardContent />
|
|
209
|
+
</PagePermissionGuard>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Step 4: Use pace-core Auth
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
// components/Login.tsx
|
|
218
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
219
|
+
|
|
220
|
+
function Login() {
|
|
221
|
+
const { signIn } = useUnifiedAuth();
|
|
222
|
+
|
|
223
|
+
const handleLogin = async () => {
|
|
224
|
+
await signIn({ email, password });
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return <button onClick={handleLogin}>Login</button>;
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Step 5: Configure Vite
|
|
232
|
+
|
|
233
|
+
**⚠️ CRITICAL: Vite configuration prevents React context mismatches!**
|
|
234
|
+
|
|
235
|
+
Add to your `vite.config.ts`:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { defineConfig } from 'vite';
|
|
239
|
+
|
|
240
|
+
export default defineConfig({
|
|
241
|
+
resolve: {
|
|
242
|
+
dedupe: ['react', 'react-dom', 'react-router-dom']
|
|
243
|
+
},
|
|
244
|
+
optimizeDeps: {
|
|
245
|
+
include: [
|
|
246
|
+
'react',
|
|
247
|
+
'react-dom',
|
|
248
|
+
'react/jsx-runtime'
|
|
249
|
+
],
|
|
250
|
+
// CRITICAL: Exclude pace-core to prevent React context mismatches
|
|
251
|
+
exclude: ['@jmruthers/pace-core', 'react-router-dom']
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Why this matters:**
|
|
257
|
+
- Pre-bundling `@jmruthers/pace-core` creates separate React instances
|
|
258
|
+
- This causes "useUnifiedAuth must be used within a UnifiedAuthProvider" errors
|
|
259
|
+
- Excluding it ensures pace-core uses the same React instance as your app
|
|
260
|
+
|
|
261
|
+
### Step 6: Centralize Supabase Config
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// src/lib/supabase.ts
|
|
265
|
+
import { createClient } from '@supabase/supabase-js';
|
|
266
|
+
|
|
267
|
+
export const supabase = createClient(
|
|
268
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
269
|
+
import.meta.env.VITE_SUPABASE_ANON_KEY
|
|
270
|
+
);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Database Configuration
|
|
274
|
+
|
|
275
|
+
Ensure your database is properly configured:
|
|
276
|
+
|
|
277
|
+
1. **App Registration**: App must exist in `rbac_apps` table
|
|
278
|
+
2. **Pages**: All pages must be registered in `rbac_app_pages` table
|
|
279
|
+
3. **Permissions**: Permissions must be configured in `rbac_page_permissions` table
|
|
280
|
+
4. **User Roles**: Users must have roles in `rbac_organisation_roles` table
|
|
281
|
+
|
|
282
|
+
See [RBAC Quick Start](../quick-start.md) for database setup instructions.
|
|
283
|
+
|
|
284
|
+
## Quick Fixes
|
|
285
|
+
|
|
286
|
+
The compliance system provides quick fix suggestions:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { getQuickFixes } from '@jmruthers/pace-core/rbac';
|
|
290
|
+
|
|
291
|
+
const fixes = getQuickFixes('custom-auth-code', { name: 'useAuth', type: 'hook' });
|
|
292
|
+
fixes.forEach(fix => {
|
|
293
|
+
console.log(fix.suggestion);
|
|
294
|
+
console.log(fix.codeExample);
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## CI/CD Integration
|
|
299
|
+
|
|
300
|
+
Add compliance checks to your CI/CD pipeline:
|
|
301
|
+
|
|
302
|
+
```yaml
|
|
303
|
+
# .github/workflows/compliance.yml
|
|
304
|
+
- name: Check pace-core compliance
|
|
305
|
+
run: npm run check:pace-core
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The script exits with code 1 if compliance issues are found, causing the build to fail.
|
|
309
|
+
|
|
310
|
+
## Troubleshooting Common Issues
|
|
311
|
+
|
|
312
|
+
### Provider Setup Issues
|
|
313
|
+
|
|
314
|
+
**Issue:** "useUnifiedAuth must be used within a UnifiedAuthProvider" error
|
|
315
|
+
|
|
316
|
+
**Possible causes:**
|
|
317
|
+
1. `UnifiedAuthProvider` is missing or not wrapping your app
|
|
318
|
+
2. `BrowserRouter` is inside `UnifiedAuthProvider` (wrong nesting)
|
|
319
|
+
3. Vite is pre-bundling `@jmruthers/pace-core` (React context mismatch)
|
|
320
|
+
|
|
321
|
+
**Solution:**
|
|
322
|
+
1. **Check provider nesting** in `main.tsx`:
|
|
323
|
+
```tsx
|
|
324
|
+
// ✅ CORRECT
|
|
325
|
+
<QueryClientProvider>
|
|
326
|
+
<BrowserRouter>
|
|
327
|
+
<UnifiedAuthProvider>
|
|
328
|
+
<OrganisationProvider>
|
|
329
|
+
<App />
|
|
330
|
+
</OrganisationProvider>
|
|
331
|
+
</UnifiedAuthProvider>
|
|
332
|
+
</BrowserRouter>
|
|
333
|
+
</QueryClientProvider>
|
|
334
|
+
|
|
335
|
+
// ❌ WRONG - BrowserRouter inside UnifiedAuthProvider
|
|
336
|
+
<UnifiedAuthProvider>
|
|
337
|
+
<BrowserRouter>
|
|
338
|
+
<App />
|
|
339
|
+
</BrowserRouter>
|
|
340
|
+
</UnifiedAuthProvider>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
2. **Check Vite config** - ensure `@jmruthers/pace-core` is in `optimizeDeps.exclude`:
|
|
344
|
+
```typescript
|
|
345
|
+
optimizeDeps: {
|
|
346
|
+
exclude: ['@jmruthers/pace-core', 'react-router-dom']
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
3. **Clear Vite cache** and restart dev server:
|
|
351
|
+
```bash
|
|
352
|
+
rm -rf node_modules/.vite
|
|
353
|
+
npm run dev
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Router Context Issues
|
|
357
|
+
|
|
358
|
+
**Issue:** "useNavigate() may be used only in the context of a <Router> component" error
|
|
359
|
+
|
|
360
|
+
**Possible causes:**
|
|
361
|
+
1. Missing `BrowserRouter`
|
|
362
|
+
2. `BrowserRouter` placed incorrectly
|
|
363
|
+
3. `react-router-dom` being pre-bundled by Vite
|
|
364
|
+
|
|
365
|
+
**Solution:**
|
|
366
|
+
1. **Add BrowserRouter** wrapping your app:
|
|
367
|
+
```tsx
|
|
368
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
369
|
+
|
|
370
|
+
<BrowserRouter>
|
|
371
|
+
<UnifiedAuthProvider>
|
|
372
|
+
<App />
|
|
373
|
+
</UnifiedAuthProvider>
|
|
374
|
+
</BrowserRouter>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
2. **Update Vite config**:
|
|
378
|
+
```typescript
|
|
379
|
+
resolve: {
|
|
380
|
+
dedupe: ['react', 'react-dom', 'react-router-dom']
|
|
381
|
+
},
|
|
382
|
+
optimizeDeps: {
|
|
383
|
+
exclude: ['react-router-dom']
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
3. **Clear Vite cache** and restart
|
|
388
|
+
|
|
389
|
+
### Vite Configuration Issues
|
|
390
|
+
|
|
391
|
+
**Issue:** React context mismatch errors, components can't find providers
|
|
392
|
+
|
|
393
|
+
**Possible causes:**
|
|
394
|
+
1. `@jmruthers/pace-core` is being pre-bundled by Vite
|
|
395
|
+
2. Multiple React instances in the bundle
|
|
396
|
+
|
|
397
|
+
**Solution:**
|
|
398
|
+
1. **Exclude pace-core from pre-bundling**:
|
|
399
|
+
```typescript
|
|
400
|
+
optimizeDeps: {
|
|
401
|
+
exclude: ['@jmruthers/pace-core']
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
2. **Dedupe React dependencies**:
|
|
406
|
+
```typescript
|
|
407
|
+
resolve: {
|
|
408
|
+
dedupe: ['react', 'react-dom', 'react-router-dom']
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
3. **Clear Vite cache**:
|
|
413
|
+
```bash
|
|
414
|
+
rm -rf node_modules/.vite
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Custom Auth/RBAC Code Detected
|
|
418
|
+
|
|
419
|
+
**Issue:** Custom `useAuth` hook or `PermissionGuard` component found
|
|
420
|
+
|
|
421
|
+
**Solution:**
|
|
422
|
+
1. Remove your custom implementation
|
|
423
|
+
2. Import from pace-core:
|
|
424
|
+
```typescript
|
|
425
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
426
|
+
import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
|
|
427
|
+
```
|
|
428
|
+
3. Update all usages - see [Migration Examples](#migrating-from-custom-code) below
|
|
429
|
+
|
|
430
|
+
### Duplicate Supabase Configuration
|
|
431
|
+
|
|
432
|
+
**Issue:** Multiple `createClient` calls found
|
|
433
|
+
|
|
434
|
+
**Solution:**
|
|
435
|
+
1. Create a single `supabase.ts` file:
|
|
436
|
+
```typescript
|
|
437
|
+
// src/lib/supabase.ts
|
|
438
|
+
export const supabase = createClient(url, key);
|
|
439
|
+
```
|
|
440
|
+
2. Remove all other `createClient` calls
|
|
441
|
+
3. Import from the shared location everywhere
|
|
442
|
+
|
|
443
|
+
### Unprotected Pages
|
|
444
|
+
|
|
445
|
+
**Issue:** Route without PagePermissionGuard
|
|
446
|
+
|
|
447
|
+
**Solution:**
|
|
448
|
+
1. Wrap all routes with PagePermissionGuard:
|
|
449
|
+
```tsx
|
|
450
|
+
<PagePermissionGuard pageName="dashboard" operation="read">
|
|
451
|
+
<Dashboard />
|
|
452
|
+
</PagePermissionGuard>
|
|
453
|
+
```
|
|
454
|
+
2. Ensure pages exist in `rbac_app_pages` table
|
|
455
|
+
|
|
456
|
+
### Direct Supabase Auth Usage
|
|
457
|
+
|
|
458
|
+
**Issue:** Direct `supabase.auth` calls detected
|
|
459
|
+
|
|
460
|
+
**Solution:**
|
|
461
|
+
1. Use `useUnifiedAuth` hook instead:
|
|
462
|
+
```typescript
|
|
463
|
+
const { signIn } = useUnifiedAuth();
|
|
464
|
+
await signIn({ email, password });
|
|
465
|
+
```
|
|
466
|
+
2. Ensure `UnifiedAuthProvider` wraps your app
|
|
467
|
+
|
|
468
|
+
### RBAC Not Initialized
|
|
469
|
+
|
|
470
|
+
**Issue:** `setupRBAC()` not called
|
|
471
|
+
|
|
472
|
+
**Solution:**
|
|
473
|
+
```typescript
|
|
474
|
+
// main.tsx - Must be called before rendering
|
|
475
|
+
import { setupRBAC } from '@jmruthers/pace-core/rbac';
|
|
476
|
+
setupRBAC(supabase);
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Migrating from Custom Code
|
|
480
|
+
|
|
481
|
+
### Migrating `useAuth` Hook
|
|
482
|
+
|
|
483
|
+
**Before:**
|
|
484
|
+
```typescript
|
|
485
|
+
// src/hooks/useAuth.ts
|
|
486
|
+
export function useAuth() {
|
|
487
|
+
const [user, setUser] = useState(null);
|
|
488
|
+
// ... custom logic
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**After:**
|
|
493
|
+
```typescript
|
|
494
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
495
|
+
const { user } = useUnifiedAuth();
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Migrating `PermissionGuard` Component
|
|
499
|
+
|
|
500
|
+
**Before:**
|
|
501
|
+
```tsx
|
|
502
|
+
<PermissionGuard permission="read:users">
|
|
503
|
+
<UsersPage />
|
|
504
|
+
</PermissionGuard>
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**After:**
|
|
508
|
+
```tsx
|
|
509
|
+
<PagePermissionGuard pageName="users" operation="read">
|
|
510
|
+
<UsersPage />
|
|
511
|
+
</PagePermissionGuard>
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Migrating `checkPermission` Utility
|
|
515
|
+
|
|
516
|
+
**Before:**
|
|
517
|
+
```typescript
|
|
518
|
+
const hasAccess = checkPermission(user, 'read:users');
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**After:**
|
|
522
|
+
```typescript
|
|
523
|
+
import { isPermitted } from '@jmruthers/pace-core/rbac';
|
|
524
|
+
const hasAccess = await isPermitted({
|
|
525
|
+
userId: user.id,
|
|
526
|
+
scope: { organisationId: org.id },
|
|
527
|
+
permission: 'read:page.users'
|
|
528
|
+
});
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Step-by-Step Migration Process
|
|
532
|
+
|
|
533
|
+
1. **Audit:** Run `npm run check:pace-core` to find all custom code
|
|
534
|
+
2. **Setup:** Ensure `setupRBAC()` is called and providers are configured
|
|
535
|
+
3. **Migrate:** Replace custom code with pace-core equivalents one component at a time
|
|
536
|
+
4. **Test:** Verify all auth flows and permission checks work
|
|
537
|
+
5. **Clean:** Remove custom files and update all imports
|
|
538
|
+
|
|
539
|
+
## Next Steps
|
|
540
|
+
|
|
541
|
+
- [RBAC Troubleshooting](../troubleshooting.md) - General RBAC issues
|
|
542
|
+
- [RBAC Quick Start](../quick-start.md) - Getting started with RBAC
|
|
543
|
+
- [RBAC API Reference](../api-reference.md) - Complete API documentation
|
|
544
|
+
|