@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
|
@@ -69,17 +69,64 @@ if (!supabaseUrl || !supabaseAnonKey) {
|
|
|
69
69
|
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
### 4.
|
|
72
|
+
### 4. Configure Vite (CRITICAL)
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
**⚠️ CRITICAL**: This configuration prevents React context and Router context errors.
|
|
75
|
+
|
|
76
|
+
Add to your `vite.config.ts`:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { defineConfig } from 'vite';
|
|
80
|
+
import react from '@vitejs/plugin-react';
|
|
81
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
82
|
+
import path from 'path';
|
|
83
|
+
|
|
84
|
+
export default defineConfig({
|
|
85
|
+
plugins: [
|
|
86
|
+
react(),
|
|
87
|
+
tailwindcss({
|
|
88
|
+
content: [
|
|
89
|
+
'./src/**/*.{js,ts,jsx,tsx}',
|
|
90
|
+
'./node_modules/@jmruthers/pace-core/src/**/*.{js,ts,jsx,tsx}'
|
|
91
|
+
]
|
|
92
|
+
})
|
|
93
|
+
],
|
|
94
|
+
resolve: {
|
|
95
|
+
alias: {
|
|
96
|
+
"@": path.resolve(__dirname, "./src"),
|
|
97
|
+
},
|
|
98
|
+
// CRITICAL: Dedupe React and React Router to ensure single instances
|
|
99
|
+
dedupe: ['react', 'react-dom', 'react-router-dom']
|
|
100
|
+
},
|
|
101
|
+
// CRITICAL: Exclude pace-core from pre-bundling to prevent React context mismatches
|
|
102
|
+
optimizeDeps: {
|
|
103
|
+
include: [
|
|
104
|
+
'react',
|
|
105
|
+
'react-dom',
|
|
106
|
+
'react/jsx-runtime'
|
|
107
|
+
],
|
|
108
|
+
exclude: ['@jmruthers/pace-core', 'react-router-dom']
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 5. App Setup with Authentication
|
|
114
|
+
|
|
115
|
+
**⚠️ CRITICAL**:
|
|
116
|
+
1. Provider nesting order matters - follow the exact structure below
|
|
117
|
+
2. UnifiedAuthProvider requires inactivity timeout configuration
|
|
118
|
+
3. setupRBAC() must be called before rendering
|
|
75
119
|
|
|
76
120
|
```tsx
|
|
77
121
|
// src/main.tsx
|
|
78
122
|
import React from 'react'
|
|
79
123
|
import ReactDOM from 'react-dom/client'
|
|
80
124
|
import { BrowserRouter } from 'react-router-dom'
|
|
125
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
81
126
|
import {
|
|
82
|
-
UnifiedAuthProvider
|
|
127
|
+
UnifiedAuthProvider,
|
|
128
|
+
OrganisationProvider,
|
|
129
|
+
setupRBAC
|
|
83
130
|
} from '@jmruthers/pace-core'
|
|
84
131
|
import { supabase } from './lib/supabase'
|
|
85
132
|
import App from './App.tsx'
|
|
@@ -87,17 +134,46 @@ import App from './App.tsx'
|
|
|
87
134
|
// CRITICAL: Import the CSS system - includes everything you need
|
|
88
135
|
import '@jmruthers/pace-core/src/styles/core.css'
|
|
89
136
|
|
|
137
|
+
// ⚠️ REQUIRED: Setup RBAC before rendering
|
|
138
|
+
setupRBAC(supabase);
|
|
139
|
+
|
|
140
|
+
const queryClient = new QueryClient();
|
|
141
|
+
|
|
90
142
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
91
143
|
<React.StrictMode>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
144
|
+
{/* CRITICAL: Correct nesting order */}
|
|
145
|
+
<QueryClientProvider client={queryClient}>
|
|
146
|
+
<BrowserRouter>
|
|
147
|
+
<UnifiedAuthProvider
|
|
148
|
+
supabaseClient={supabase}
|
|
149
|
+
appName="my-app"
|
|
150
|
+
requireOrganisationContext={true}
|
|
151
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes - REQUIRED
|
|
152
|
+
warnBeforeMs={60 * 1000} // 60 seconds - REQUIRED
|
|
153
|
+
onIdleLogout={() => window.location.href = '/login'} // REQUIRED
|
|
154
|
+
>
|
|
155
|
+
<OrganisationProvider>
|
|
156
|
+
<App />
|
|
157
|
+
</OrganisationProvider>
|
|
158
|
+
</UnifiedAuthProvider>
|
|
159
|
+
</BrowserRouter>
|
|
160
|
+
</QueryClientProvider>
|
|
161
|
+
</React.StrictMode>
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Provider Nesting Order (CRITICAL):**
|
|
166
|
+
1. `React.StrictMode` (outermost)
|
|
167
|
+
2. `QueryClientProvider`
|
|
168
|
+
3. `BrowserRouter`
|
|
169
|
+
4. `UnifiedAuthProvider`
|
|
170
|
+
5. `OrganisationProvider`
|
|
171
|
+
6. `App` (innermost)
|
|
172
|
+
|
|
173
|
+
**Why this order matters:**
|
|
174
|
+
- `BrowserRouter` must wrap `UnifiedAuthProvider` to provide Router context
|
|
175
|
+
- `UnifiedAuthProvider` must be inside `BrowserRouter` to use Router hooks
|
|
176
|
+
- Wrong nesting causes "useNavigate() may be used only in the context of a <Router>" errors
|
|
101
177
|
<App />
|
|
102
178
|
</UnifiedAuthProvider>
|
|
103
179
|
</BrowserRouter>
|
|
@@ -45,14 +45,16 @@ CREATE TABLE file_references (
|
|
|
45
45
|
|
|
46
46
|
**Organisation-First Structure:**
|
|
47
47
|
```
|
|
48
|
-
{bucket}/{orgId}/{
|
|
48
|
+
{bucket}/{orgId}/{folder}/{timestamp-uuid-filename}
|
|
49
49
|
|
|
50
50
|
Examples:
|
|
51
51
|
- files/org-123/profile_photos/timestamp-uuid-photo.jpg (private)
|
|
52
|
-
- files/org-123/
|
|
52
|
+
- files/org-123/documents/timestamp-uuid-passport.pdf (private)
|
|
53
53
|
- public-files/org-123/event_logos/timestamp-uuid-logo.png (public)
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
**Note:** The `folder` prop determines the storage path, while `category` is stored in the `file_metadata` JSONB field for filtering and metadata purposes. You can use the same value for both (e.g., `category={FileCategory.PROFILE_PHOTOS}` and `folder="profile_photos"`), or use different values if needed.
|
|
57
|
+
|
|
56
58
|
### Bucket Selection
|
|
57
59
|
|
|
58
60
|
The system uses two Supabase storage buckets:
|
|
@@ -77,7 +79,10 @@ await service.createFileReference({
|
|
|
77
79
|
table_name: 'pace_person',
|
|
78
80
|
record_id: personId,
|
|
79
81
|
organisation_id: orgId,
|
|
82
|
+
app_id: 'your-app-id',
|
|
80
83
|
category: FileCategory.PROFILE_PHOTOS,
|
|
84
|
+
folder: 'profile_photos',
|
|
85
|
+
pageContext: 'configuration',
|
|
81
86
|
is_public: false // Uses 'files' bucket
|
|
82
87
|
}, file);
|
|
83
88
|
|
|
@@ -86,7 +91,10 @@ await service.createFileReference({
|
|
|
86
91
|
table_name: 'event',
|
|
87
92
|
record_id: eventId,
|
|
88
93
|
organisation_id: orgId,
|
|
94
|
+
app_id: 'your-app-id',
|
|
89
95
|
category: FileCategory.EVENT_LOGOS,
|
|
96
|
+
folder: 'event_logos',
|
|
97
|
+
pageContext: 'configuration',
|
|
90
98
|
is_public: true // Uses 'public-files' bucket
|
|
91
99
|
}, file);
|
|
92
100
|
```
|
|
@@ -136,6 +144,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
|
|
|
136
144
|
organisation_id={orgId}
|
|
137
145
|
app_id="your-app-id" // Optional - auto-resolved from app name if not provided
|
|
138
146
|
category={FileCategory.PROFILE_PHOTOS}
|
|
147
|
+
folder="profile_photos"
|
|
148
|
+
pageContext="configuration"
|
|
139
149
|
accept="image/*"
|
|
140
150
|
maxSize={5 * 1024 * 1024}
|
|
141
151
|
onUploadSuccess={(result) => {
|
|
@@ -157,6 +167,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
|
|
|
157
167
|
organisation_id={orgId}
|
|
158
168
|
// app_id omitted - will be auto-resolved from app name
|
|
159
169
|
category={FileCategory.PROFILE_PHOTOS}
|
|
170
|
+
folder="profile_photos"
|
|
171
|
+
pageContext="configuration"
|
|
160
172
|
accept="image/*"
|
|
161
173
|
maxSize={5 * 1024 * 1024}
|
|
162
174
|
showProgress={true}
|
|
@@ -191,6 +203,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
|
|
|
191
203
|
organisation_id={orgId}
|
|
192
204
|
app_id="your-app-id"
|
|
193
205
|
category={FileCategory.EVENT_LOGOS}
|
|
206
|
+
folder="event_logos"
|
|
207
|
+
pageContext="configuration"
|
|
194
208
|
accept="image/*"
|
|
195
209
|
isPublic={true} // Uploads to public-files bucket
|
|
196
210
|
showPreview={true}
|
|
@@ -210,6 +224,8 @@ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
|
|
|
210
224
|
organisation_id={orgId}
|
|
211
225
|
app_id="your-app-id"
|
|
212
226
|
category={FileCategory.PROFILE_PHOTOS}
|
|
227
|
+
folder="profile_photos"
|
|
228
|
+
pageContext="configuration"
|
|
213
229
|
>
|
|
214
230
|
<div className="custom-upload-ui">
|
|
215
231
|
<p>Click to upload profile photo</p>
|
|
@@ -237,6 +253,8 @@ import { FileDisplay, FileCategory } from '@jmruthers/pace-core';
|
|
|
237
253
|
organisation_id={orgId}
|
|
238
254
|
app_id="your-app-id"
|
|
239
255
|
category={FileCategory.PROFILE_PHOTOS}
|
|
256
|
+
folder="profile_photos"
|
|
257
|
+
pageContext="configuration"
|
|
240
258
|
/>
|
|
241
259
|
</FileDisplay>
|
|
242
260
|
```
|
|
@@ -331,6 +349,8 @@ const result = await uploadFile({
|
|
|
331
349
|
organisation_id: orgId,
|
|
332
350
|
app_id: 'your-app-id',
|
|
333
351
|
category: FileCategory.PROFILE_PHOTOS,
|
|
352
|
+
folder: 'profile_photos',
|
|
353
|
+
pageContext: 'configuration',
|
|
334
354
|
is_public: false // Uses 'files' bucket
|
|
335
355
|
}, file);
|
|
336
356
|
|
|
@@ -341,6 +361,8 @@ const publicResult = await uploadFile({
|
|
|
341
361
|
organisation_id: orgId,
|
|
342
362
|
app_id: 'your-app-id',
|
|
343
363
|
category: FileCategory.EVENT_LOGOS,
|
|
364
|
+
folder: 'event_logos',
|
|
365
|
+
pageContext: 'configuration',
|
|
344
366
|
is_public: true // Uses 'public-files' bucket
|
|
345
367
|
}, logoFile);
|
|
346
368
|
|
|
@@ -475,14 +497,15 @@ const files = await service.listFileReferences('pace_person', personId, orgId);
|
|
|
475
497
|
|
|
476
498
|
```sql
|
|
477
499
|
-- Create file reference (replaces insert_file_reference)
|
|
500
|
+
-- Requires page context for context-aware permission checks
|
|
478
501
|
SELECT data_file_reference_create(
|
|
479
502
|
p_table_name := 'pace_person',
|
|
480
503
|
p_record_id := 'person-uuid',
|
|
481
504
|
p_file_path := 'org-123/profile_photos/file.jpg',
|
|
482
505
|
p_organisation_id := 'org-uuid',
|
|
483
506
|
p_app_id := 'app-uuid',
|
|
507
|
+
p_page_context := 'configuration',
|
|
484
508
|
p_file_metadata := '{"fileName": "photo.jpg"}'::jsonb,
|
|
485
|
-
p_category := 'profile_photos',
|
|
486
509
|
p_is_public := false
|
|
487
510
|
);
|
|
488
511
|
|
|
@@ -48,6 +48,8 @@ function MyFileUpload() {
|
|
|
48
48
|
organisation_id="org-123"
|
|
49
49
|
// app_id auto-resolved from app name
|
|
50
50
|
category={FileCategory.GENERAL_DOCUMENTS}
|
|
51
|
+
folder="documents"
|
|
52
|
+
pageContext="configuration"
|
|
51
53
|
accept=".pdf,.doc,.docx"
|
|
52
54
|
maxSize={5 * 1024 * 1024} // 5MB
|
|
53
55
|
showProgress={true}
|
|
@@ -102,6 +104,8 @@ function UserProfile({ userId }: { userId: string }) {
|
|
|
102
104
|
record_id={userId}
|
|
103
105
|
organisation_id="org-123"
|
|
104
106
|
category={FileCategory.GENERAL_DOCUMENTS}
|
|
107
|
+
folder="documents"
|
|
108
|
+
pageContext="configuration"
|
|
105
109
|
accept=".pdf,.doc,.docx"
|
|
106
110
|
maxSize={10 * 1024 * 1024}
|
|
107
111
|
/>
|
|
@@ -126,7 +130,9 @@ interface FileUploadProps {
|
|
|
126
130
|
record_id: string;
|
|
127
131
|
organisation_id: string;
|
|
128
132
|
app_id?: string; // Optional - will be resolved from app name if not provided
|
|
129
|
-
category: FileCategory;
|
|
133
|
+
category: FileCategory; // File category for metadata (stored in file_metadata JSONB field)
|
|
134
|
+
folder: string; // Folder name in storage bucket (e.g., 'profile_photos', 'documents')
|
|
135
|
+
pageContext: string; // The page context where the file upload occurs (e.g., 'configuration', 'forms', 'applications')
|
|
130
136
|
accept?: string;
|
|
131
137
|
maxSize?: number;
|
|
132
138
|
multiple?: boolean;
|
|
@@ -142,6 +148,8 @@ interface FileUploadProps {
|
|
|
142
148
|
}
|
|
143
149
|
```
|
|
144
150
|
|
|
151
|
+
**Note:** The `category` prop is used for metadata purposes (stored in the `file_metadata` JSONB field), while the `folder` prop determines the actual storage path: `{orgId}/{folder}/{timestamp-uuid-filename}`. You can use the same value for both (e.g., `category={FileCategory.PROFILE_PHOTOS}` and `folder="profile_photos"`), or use different values if needed.
|
|
152
|
+
|
|
145
153
|
#### Usage Examples
|
|
146
154
|
|
|
147
155
|
**Basic Upload:**
|
|
@@ -152,6 +160,8 @@ interface FileUploadProps {
|
|
|
152
160
|
record_id="person-123"
|
|
153
161
|
organisation_id={organisationId}
|
|
154
162
|
category={FileCategory.PROFILE_PHOTOS}
|
|
163
|
+
folder="profile_photos"
|
|
164
|
+
pageContext="configuration"
|
|
155
165
|
accept="image/*"
|
|
156
166
|
maxSize={2 * 1024 * 1024} // 2MB
|
|
157
167
|
onUploadSuccess={(result) => console.log('Uploaded:', result.file_reference)}
|
|
@@ -168,6 +178,8 @@ interface FileUploadProps {
|
|
|
168
178
|
record_id="person-123"
|
|
169
179
|
organisation_id={organisationId}
|
|
170
180
|
category={FileCategory.GENERAL_DOCUMENTS}
|
|
181
|
+
folder="documents"
|
|
182
|
+
pageContext="forms"
|
|
171
183
|
multiple={true}
|
|
172
184
|
accept=".pdf,.doc,.docx"
|
|
173
185
|
showProgress={true}
|
|
@@ -197,6 +209,23 @@ interface FileUploadProps {
|
|
|
197
209
|
</FileUpload>
|
|
198
210
|
```
|
|
199
211
|
|
|
212
|
+
#### Page Context and Permissions
|
|
213
|
+
|
|
214
|
+
The `pageContext` parameter enables context-aware permission checks for file uploads. Instead of requiring a generic `'create:files'` permission on a `'files'` page, the system checks permissions based on the actual page where the upload occurs.
|
|
215
|
+
|
|
216
|
+
**Permission Check Behavior:**
|
|
217
|
+
- The system checks for `'create:page.{pageContext}'` permission first
|
|
218
|
+
- If that permission doesn't exist, it checks for `'update:page.{pageContext}'` permission
|
|
219
|
+
- The user needs at least one of these permissions to upload files
|
|
220
|
+
- This ensures file uploads are controlled by the same permissions as the page where they occur
|
|
221
|
+
|
|
222
|
+
**Example Use Cases:**
|
|
223
|
+
- Event logo uploads on the `'configuration'` page require `'create:page.configuration'` or `'update:page.configuration'` permission
|
|
224
|
+
- Form document uploads on the `'forms'` page require `'create:page.forms'` or `'update:page.forms'` permission
|
|
225
|
+
- Application file uploads on the `'applications'` page require `'create:page.applications'` or `'update:page.applications'` permission
|
|
226
|
+
|
|
227
|
+
**Important:** The `pageContext` must match a page defined in your RBAC system (`rbac_app_pages` table) for the permission checks to work correctly.
|
|
228
|
+
|
|
200
229
|
### FileDisplay
|
|
201
230
|
|
|
202
231
|
A component for displaying and managing files associated with database records.
|
package/docs/rbac/README.md
CHANGED
|
@@ -66,6 +66,7 @@ function MyComponent() {
|
|
|
66
66
|
- **[Event-Based Apps](./event-based-apps.md)** - Get up and running in 10 minutes (foolproof guide for event-based apps)
|
|
67
67
|
- **[API Reference](./api-reference.md)** - Complete API documentation
|
|
68
68
|
- **[Troubleshooting](./troubleshooting.md)** - Common issues and solutions
|
|
69
|
+
- **[Compliance Guide](./compliance/compliance-guide.md)** - Ensuring proper RBAC/auth setup and usage
|
|
69
70
|
- **[Examples](./examples.md)** - Practical usage examples
|
|
70
71
|
- **[Advanced Patterns](./advanced-patterns.md)** - Complex scenarios and optimizations
|
|
71
72
|
|