@jmruthers/pace-core 0.5.68 → 0.5.70
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/dist/{DataTable-4IUY7BXB.js → DataTable-OSELOGMA.js} +6 -6
- package/dist/{PublicLoadingSpinner-DdKXTkCZ.d.ts → PublicLoadingSpinner-DLpF5bbs.d.ts} +78 -2
- package/dist/{chunk-OPCWH3A4.js → chunk-4YMVZ76F.js} +7 -6
- package/dist/chunk-4YMVZ76F.js.map +1 -0
- package/dist/{chunk-NN45OBIS.js → chunk-5G7JA3L5.js} +3 -5
- package/dist/{chunk-NN45OBIS.js.map → chunk-5G7JA3L5.js.map} +1 -1
- package/dist/{chunk-U6GPOF6J.js → chunk-5NV76BYF.js} +666 -110
- package/dist/chunk-5NV76BYF.js.map +1 -0
- package/dist/{chunk-D7ARGIA3.js → chunk-6RBH67W7.js} +23 -6
- package/dist/chunk-6RBH67W7.js.map +1 -0
- package/dist/{chunk-ZPG4XPV5.js → chunk-BHBMXMLT.js} +5 -7
- package/dist/chunk-BHBMXMLT.js.map +1 -0
- package/dist/{chunk-ZMS23NS5.js → chunk-FOT3WUV6.js} +3 -5
- package/dist/{chunk-ZMS23NS5.js.map → chunk-FOT3WUV6.js.map} +1 -1
- package/dist/{chunk-MOJXHWDE.js → chunk-GCUIIBLB.js} +382 -5
- package/dist/chunk-GCUIIBLB.js.map +1 -0
- package/dist/{chunk-PXWEDX7Y.js → chunk-KWQH4VO3.js} +3 -3
- package/dist/{chunk-ZPK5656W.js → chunk-O3NWNXDY.js} +4 -5
- package/dist/chunk-O3NWNXDY.js.map +1 -0
- package/dist/{chunk-KRCRNXPD.js → chunk-OTJUAYBG.js} +81 -18
- package/dist/chunk-OTJUAYBG.js.map +1 -0
- package/dist/chunk-SMJZMKYN.js +141 -0
- package/dist/chunk-SMJZMKYN.js.map +1 -0
- package/dist/{chunk-UYA6U6H7.js → chunk-V2TE7LOF.js} +4 -4
- package/dist/{chunk-L3RV2ALE.js → chunk-VKOCWWVY.js} +6 -1
- package/dist/{chunk-L3RV2ALE.js.map → chunk-VKOCWWVY.js.map} +1 -1
- package/dist/components.d.ts +4 -79
- package/dist/components.js +23 -581
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +9 -6
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +32 -19
- package/dist/index.js.map +1 -1
- package/dist/providers.js +6 -7
- package/dist/rbac/index.js +6 -6
- package/dist/styles/index.js +2 -2
- package/dist/theming/runtime.d.ts +4 -3
- package/dist/theming/runtime.js +3 -1
- package/dist/{usePublicRouteParams-CdoFxnJK.d.ts → usePublicRouteParams-Ua1Vz-HG.d.ts} +35 -1
- package/dist/utils.d.ts +4 -1
- package/dist/utils.js +3 -3
- package/docs/DOCUMENTATION_CHECKLIST.md +281 -0
- package/docs/README.md +22 -10
- 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/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +129 -0
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- 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/DataAccessRecord.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/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +7 -7
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +2 -2
- package/docs/api/interfaces/FileDisplayProps.md +107 -0
- package/docs/api/interfaces/FileMetadata.md +129 -0
- package/docs/api/interfaces/FileReference.md +118 -0
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +85 -0
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- 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/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 +1 -1
- 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 +1 -1
- 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/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +2 -2
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- 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/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/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- 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/UsePublicRouteParamsReturn.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 +228 -23
- package/docs/architecture/services.md +374 -0
- package/docs/best-practices/README.md +1 -1
- package/docs/best-practices/testing.md +1 -1
- package/docs/breaking-changes.md +182 -0
- package/docs/common-patterns.md +445 -0
- package/docs/core-concepts/authentication.md +26 -11
- package/docs/core-concepts/events.md +2 -0
- package/docs/core-concepts/organisations.md +2 -0
- package/docs/core-concepts/permissions.md +2 -0
- package/docs/{INDEX.md → documentation-index.md} +26 -38
- package/docs/faq.md +286 -0
- package/docs/{FILE_REFERENCE_SYSTEM.md → file-reference-system.md} +1 -1
- package/docs/getting-started/installation-guide.md +284 -0
- package/docs/getting-started/quick-start.md +8 -1
- package/docs/implementation-guides/app-layout.md +3 -1
- package/docs/implementation-guides/data-tables.md +2 -0
- package/docs/implementation-guides/dynamic-colors.md +47 -2
- package/docs/implementation-guides/event-theming-summary.md +220 -0
- package/docs/implementation-guides/forms.md +9 -7
- package/docs/implementation-guides/navigation.md +2 -0
- package/docs/migration/service-architecture.md +351 -0
- package/docs/rbac/README-rbac-rls-integration.md +2 -2
- package/docs/rbac/README.md +1 -1
- package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
- package/docs/rbac/quick-start.md +2 -0
- package/docs/rbac/rbac-rls-integration.md +2 -2
- package/docs/style-guide.md +136 -1
- package/docs/testing/README.md +1 -1
- package/docs/troubleshooting/authentication-issues.md +334 -0
- package/docs/troubleshooting/common-issues.md +2 -0
- package/docs/troubleshooting/styling-issues.md +199 -144
- package/docs/usage.md +23 -2
- package/package.json +3 -2
- package/src/__tests__/{TESTING_GUIDELINES.md → TEST_GUIDE_CURSOR.md} +20 -0
- package/src/__tests__/TEST_GUIDE_HUMAN.md +103 -0
- package/src/__tests__/fixtures/test-data.ts +90 -0
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +260 -0
- package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +224 -0
- package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +273 -0
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +98 -0
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +436 -0
- package/src/__tests__/helpers/__tests__/timer-utils.test.ts +371 -0
- package/src/__tests__/helpers/component-test-utils.tsx +14 -4
- package/src/__tests__/helpers/optimized-test-setup.ts +68 -0
- package/src/__tests__/helpers/test-providers.tsx +329 -0
- package/src/__tests__/helpers/test-utils.tsx +91 -45
- package/src/__tests__/helpers/timer-utils.ts +71 -0
- package/src/__tests__/hooks/usePermissions.test.ts +1 -5
- package/src/__tests__/integration/UserProfile.test.tsx +1 -5
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +42 -12
- package/src/__tests__/setup.ts +34 -28
- package/src/components/Alert/Alert.test.tsx +1 -5
- package/src/components/Avatar/Avatar.test.tsx +1 -5
- package/src/components/Button/Button.test.tsx +4 -20
- package/src/components/Card/Card.test.tsx +1 -5
- package/src/components/Checkbox/Checkbox.test.tsx +1 -5
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -5
- package/src/components/DataTable/__tests__/DataTable.test.tsx +45 -49
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +1 -5
- package/src/components/DataTable/__tests__/styles.test.ts +382 -0
- package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +409 -0
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +634 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +519 -0
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +714 -0
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +592 -0
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +354 -0
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +539 -0
- package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -5
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +1 -8
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +34 -38
- package/src/components/Footer/Footer.test.tsx +1 -5
- package/src/components/Form/Form.test.tsx +22 -35
- package/src/components/Header/Header.test.tsx +1 -9
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +1 -5
- package/src/components/Input/Input.test.tsx +2 -10
- package/src/components/LoginForm/LoginForm.test.tsx +1 -5
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +24 -24
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +1 -6
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -16
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +1 -4
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +1 -5
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +1 -7
- package/src/components/PasswordReset/PasswordChangeForm.test.tsx +1 -9
- package/src/components/PasswordReset/PasswordResetForm.test.tsx +1 -9
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +4 -5
- package/src/components/PublicLayout/PublicPageHeader.tsx +13 -9
- package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +666 -0
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +457 -0
- package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +393 -0
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +351 -0
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +374 -0
- package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +388 -0
- package/src/components/Select/Select.bug-test.tsx +69 -0
- package/src/components/Select/Select.refactored.tsx +497 -0
- package/src/components/Select/Select.test.tsx +42 -49
- package/src/components/Select/Select.tsx +5 -2
- package/src/components/Select/hooks.ts +254 -0
- package/src/components/Switch/Switch.test.tsx +1 -5
- package/src/components/Table/__tests__/Table.test.tsx +775 -0
- package/src/components/Toast/Toast.test.tsx +15 -8
- package/src/components/Tooltip/Tooltip.test.tsx +1 -5
- package/src/components/UserMenu/UserMenu.test.tsx +3 -15
- package/src/components/__tests__/FileDisplay.test.tsx +575 -0
- package/src/components/__tests__/FileUpload.test.tsx +446 -0
- package/src/components/__tests__/SuperAdminGuard.test.tsx +422 -354
- package/src/hooks/__tests__/ServiceHooks.test.tsx +613 -0
- package/src/hooks/__tests__/hooks.integration.test.tsx +1 -10
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +10 -14
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +307 -0
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +1 -6
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +1 -5
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +6 -9
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +321 -0
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
- package/src/hooks/__tests__/usePublicEventLogo.unit.test.ts +640 -0
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +435 -0
- package/src/hooks/__tests__/useRBAC.unit.test.ts +10 -10
- package/src/hooks/__tests__/useStorage.unit.test.ts +751 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/public/usePublicEvent.ts +30 -9
- package/src/hooks/public/usePublicRouteParams.ts +13 -3
- package/src/hooks/services/useAuth.ts +50 -0
- package/src/hooks/services/useAuthService.ts +30 -0
- package/src/hooks/services/useCurrentEvent.ts +36 -0
- package/src/hooks/services/useCurrentOrganisation.ts +52 -0
- package/src/hooks/services/useEventService.ts +30 -0
- package/src/hooks/services/useInactivityService.ts +30 -0
- package/src/hooks/services/useOrganisationService.ts +30 -0
- package/src/hooks/services/usePermissions.ts +70 -0
- package/src/hooks/services/useRBACService.ts +30 -0
- package/src/hooks/useCounter.test.ts +1 -5
- package/src/hooks/useEventTheme.ts +86 -0
- package/src/hooks/useOrganisationPermissions.test.ts +2 -5
- package/src/hooks/useOrganisationSecurity.test.ts +1 -5
- package/src/hooks/usePermissionCache.test.ts +1 -5
- package/src/hooks/usePermissionCheck.ts +150 -0
- package/src/hooks/useSecureDataAccess.test.ts +1 -5
- package/src/index.ts +7 -0
- package/src/providers/EventProvider.tsx +58 -2
- package/src/providers/OrganisationProvider.test.tsx +1 -5
- package/src/providers/OrganisationProvider.tsx +56 -4
- package/src/providers/UnifiedAuthProvider.test.tsx +1 -5
- package/src/providers/__tests__/AuthProvider.test.tsx +105 -439
- package/src/providers/__tests__/AuthProvider.test.tsx.backup +771 -0
- package/src/providers/__tests__/EventProvider.test.tsx +211 -110
- package/src/providers/__tests__/EventProvider.test.tsx.backup +824 -0
- package/src/providers/__tests__/InactivityProvider.test.tsx +1 -5
- package/src/providers/__tests__/OrganisationProvider.test.tsx +97 -261
- package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +820 -0
- package/src/providers/__tests__/ServiceProviders.test.tsx +477 -0
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +72 -504
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +911 -0
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +166 -0
- package/src/providers/services/AuthServiceProvider.tsx +65 -0
- package/src/providers/services/EventServiceProvider.tsx +83 -0
- package/src/providers/services/InactivityServiceProvider.tsx +83 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +77 -0
- package/src/providers/services/RBACServiceProvider.tsx +79 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +368 -0
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +210 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +269 -0
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +892 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +954 -0
- package/src/rbac/__tests__/integration.authflow.test.tsx +1 -5
- package/src/rbac/__tests__/integration.navigation.test.tsx +1 -4
- package/src/rbac/__tests__/rbac-core.test.tsx +2 -7
- package/src/rbac/__tests__/rbac-functions.test.ts +1 -9
- package/src/rbac/__tests__/rbac-integration.test.ts +1 -9
- package/src/rbac/api.test.ts +1 -9
- package/src/rbac/cache.test.ts +10 -8
- package/src/rbac/cli/__tests__/policy-manager.test.ts +339 -0
- package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -5
- package/src/rbac/components/NavigationProvider.test.tsx +1 -5
- package/src/rbac/components/PagePermissionProvider.test.tsx +1 -5
- package/src/rbac/components/SecureDataProvider.test.tsx +1 -5
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +25 -29
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +27 -30
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +23 -27
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +18 -22
- package/src/rbac/config.test.ts +1 -5
- package/src/rbac/hooks/useCan.test.ts +262 -9
- package/src/rbac/hooks/usePermissions.test.ts +246 -6
- package/src/rbac/hooks/useRBAC.simple.test.ts +1 -5
- package/src/rbac/hooks/useRBAC.test.ts +472 -198
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +1 -9
- package/src/services/AuthService.ts +416 -0
- package/src/services/EventService.ts +366 -0
- package/src/services/InactivityService.ts +388 -0
- package/src/services/OrganisationService.ts +592 -0
- package/src/services/RBACService.ts +522 -0
- package/src/services/__tests__/AuthService.test.ts +356 -0
- package/src/services/__tests__/BaseService.test.ts +314 -0
- package/src/services/__tests__/EventService.test.ts +489 -0
- package/src/services/__tests__/InactivityService.test.ts +403 -0
- package/src/services/__tests__/OrganisationService.test.ts +660 -0
- package/src/services/__tests__/RBACService.test.ts +492 -0
- package/src/services/base/BaseService.ts +87 -0
- package/src/services/interfaces/IAuthService.ts +39 -0
- package/src/services/interfaces/IEventService.ts +30 -0
- package/src/services/interfaces/IInactivityService.ts +31 -0
- package/src/services/interfaces/IOrganisationService.ts +41 -0
- package/src/services/interfaces/IRBACService.ts +62 -0
- package/src/theming/__tests__/runtime.test.ts +560 -0
- package/src/theming/runtime.ts +71 -28
- package/src/types/__tests__/file-reference.test.ts +447 -0
- package/src/types/__tests__/organisation.test.ts +1133 -0
- package/src/types/__tests__/theme.test.ts +830 -0
- package/src/types/__tests__/type-validation.test.ts +527 -0
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +1 -5
- package/src/utils/__tests__/debugLogger.test.ts +417 -0
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -6
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -5
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +35 -35
- package/src/utils/__tests__/organisationContext.unit.test.ts +1 -5
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +5 -11
- package/src/utils/__tests__/secureErrors.unit.test.ts +1 -6
- package/src/utils/__tests__/secureStorage.unit.test.ts +1 -5
- package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -5
- package/src/utils/__tests__/sessionTracking.unit.test.ts +1 -5
- package/src/utils/appIdResolver.test.ts +6 -10
- package/src/utils/appNameResolver.simple.test.ts +142 -0
- package/src/utils/appNameResolver.test.ts +31 -458
- package/src/utils/appNameResolver.test.ts.backup +494 -0
- package/src/utils/debugLogger.ts +26 -5
- package/src/utils/formatDate.test.ts +1 -5
- package/src/utils/organisationContext.test.ts +1 -5
- package/src/utils/performanceBudgets.ts +3 -4
- package/src/utils/secureDataAccess.test.ts +1 -5
- package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -5
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +1 -5
- package/dist/chunk-D7ARGIA3.js.map +0 -1
- package/dist/chunk-IPCH4YPT.js +0 -315
- package/dist/chunk-IPCH4YPT.js.map +0 -1
- package/dist/chunk-KRCRNXPD.js.map +0 -1
- package/dist/chunk-MOJXHWDE.js.map +0 -1
- package/dist/chunk-N2EUGZRW.js +0 -98
- package/dist/chunk-N2EUGZRW.js.map +0 -1
- package/dist/chunk-OPCWH3A4.js.map +0 -1
- package/dist/chunk-U6GPOF6J.js.map +0 -1
- package/dist/chunk-ZPG4XPV5.js.map +0 -1
- package/dist/chunk-ZPK5656W.js.map +0 -1
- package/docs/getting-started/installation.md +0 -269
- package/src/__tests__/REBUILD_PLAN.md +0 -223
- package/src/styles/base.css +0 -208
- package/src/styles/semantic.css +0 -24
- /package/dist/{DataTable-4IUY7BXB.js.map → DataTable-OSELOGMA.js.map} +0 -0
- /package/dist/{chunk-PXWEDX7Y.js.map → chunk-KWQH4VO3.js.map} +0 -0
- /package/dist/{chunk-UYA6U6H7.js.map → chunk-V2TE7LOF.js.map} +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Event Theming Implementation Summary
|
|
2
|
+
|
|
3
|
+
## What Exists in pace-core
|
|
4
|
+
|
|
5
|
+
### Database Schema
|
|
6
|
+
Events have an `event_colours` JSONB field that stores theme colors in OKLCH format:
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
interface Event {
|
|
10
|
+
event_colours?: Record<string, unknown> | null; // JSONB field for theme colors
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The expected format:
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"main": {
|
|
18
|
+
"50": {"L": 0.98, "C": 0.007, "H": 29.203},
|
|
19
|
+
"100": {"L": 0.96, "C": 0.018, "H": 29.203},
|
|
20
|
+
// ... all Tailwind shades 50-950
|
|
21
|
+
"raw": {"L": 0.587, "C": 0.24, "H": 29.203}
|
|
22
|
+
},
|
|
23
|
+
"sec": { /* secondary palette */ },
|
|
24
|
+
"acc": { /* accent palette */ }
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Runtime Theming System
|
|
29
|
+
Located in `packages/core/src/theming/runtime.ts`:
|
|
30
|
+
|
|
31
|
+
- **`applyPalette(palette)`** - Applies event colors dynamically
|
|
32
|
+
- **`clearPalette()`** - Clears dynamic theming, returns to app defaults
|
|
33
|
+
- **`generateSSRThemeCSS(palette)`** - SSR support
|
|
34
|
+
- **`isDynamicThemingActive()`** - Debug helper
|
|
35
|
+
|
|
36
|
+
### EventProvider
|
|
37
|
+
`packages/core/src/providers/EventProvider.tsx`:
|
|
38
|
+
- Fetches events from database via RPC `data_user_events_get`
|
|
39
|
+
- Stores `event_colours` in the event object
|
|
40
|
+
- Manages event selection state
|
|
41
|
+
- Auto-selects next upcoming event
|
|
42
|
+
|
|
43
|
+
## What Was Missing
|
|
44
|
+
|
|
45
|
+
### Automatic Event Theming Integration
|
|
46
|
+
There was **no automatic connection** between event selection and theming application. Consuming apps would need to manually:
|
|
47
|
+
1. Watch for selectedEvent changes
|
|
48
|
+
2. Extract event_colours
|
|
49
|
+
3. Call applyPalette()
|
|
50
|
+
4. Handle cleanup
|
|
51
|
+
|
|
52
|
+
## What I Added
|
|
53
|
+
|
|
54
|
+
### New Hook: `useEventTheme()`
|
|
55
|
+
|
|
56
|
+
**Location:** `packages/core/src/hooks/useEventTheme.ts`
|
|
57
|
+
|
|
58
|
+
**What it does:**
|
|
59
|
+
- Automatically watches selectedEvent from EventProvider
|
|
60
|
+
- Applies event colors when an event with `event_colours` is selected
|
|
61
|
+
- Clears theming when no event is selected
|
|
62
|
+
- Handles validation, errors, and cleanup
|
|
63
|
+
- Works consistently across all apps
|
|
64
|
+
|
|
65
|
+
**Usage:**
|
|
66
|
+
```tsx
|
|
67
|
+
import { useEventTheme } from '@jmruthers/pace-core';
|
|
68
|
+
|
|
69
|
+
function MyApp() {
|
|
70
|
+
useEventTheme(); // Just call it!
|
|
71
|
+
|
|
72
|
+
return <div>Your app</div>;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Exports:**
|
|
77
|
+
- Available from `@jmruthers/pace-core` (main export)
|
|
78
|
+
- Available from `@jmruthers/pace-core/hooks` (hooks export)
|
|
79
|
+
|
|
80
|
+
## Why This in pace-core?
|
|
81
|
+
|
|
82
|
+
This follows the pace-core principles:
|
|
83
|
+
|
|
84
|
+
### 1. **Consistency Across App Suite**
|
|
85
|
+
Every app (CAKE, TRACE, ADMIN, etc.) needs event theming. By having it in pace-core, all apps get the same behavior, UX, and error handling.
|
|
86
|
+
|
|
87
|
+
### 2. **Maximum Code Reuse**
|
|
88
|
+
Instead of every app implementing this logic, it's once in pace-core:
|
|
89
|
+
- No duplicated `useEffect` logic
|
|
90
|
+
- No duplicated event watching
|
|
91
|
+
- No duplicated error handling
|
|
92
|
+
- Centralized improvements benefit all apps
|
|
93
|
+
|
|
94
|
+
### 3. **Opt-in Design**
|
|
95
|
+
The hook is opt-in - apps call `useEventTheme()` if they want automatic theming. Apps can still use manual `applyPalette()` if they need custom logic.
|
|
96
|
+
|
|
97
|
+
## Architecture Decision
|
|
98
|
+
|
|
99
|
+
### What's in pace-core:
|
|
100
|
+
- ✅ Event theming infrastructure (runtime APIs)
|
|
101
|
+
- ✅ Automatic event theming hook (`useEventTheme`)
|
|
102
|
+
- ✅ Documentation and examples
|
|
103
|
+
- ✅ Type definitions
|
|
104
|
+
|
|
105
|
+
### What's in consuming apps:
|
|
106
|
+
- ✅ Calling `useEventTheme()` in the app component
|
|
107
|
+
- ✅ ADMIN app: Palette picker UI to set colors
|
|
108
|
+
- ✅ ADMIN app: Save colors to database via `event_colours` field
|
|
109
|
+
|
|
110
|
+
## How It Works
|
|
111
|
+
|
|
112
|
+
1. **ADMIN app** sets event colors via a palette picker and saves to `event.event_colours` in the database
|
|
113
|
+
2. **Consuming apps** (CAKE, TRACE) call `useEventTheme()` hook
|
|
114
|
+
3. When user selects an event via `EventSelector`, the hook detects the change
|
|
115
|
+
4. Hook extracts `event_colours` from selected event
|
|
116
|
+
5. Hook calls `applyPalette()` with the colors
|
|
117
|
+
6. CSS variables update dynamically → UI colors change
|
|
118
|
+
7. When event is deselected, hook calls `clearPalette()`
|
|
119
|
+
|
|
120
|
+
## Database Flow
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
ADMIN App
|
|
124
|
+
↓ (User sets colors in palette picker)
|
|
125
|
+
↓ (Save to database)
|
|
126
|
+
event.event_colours = {
|
|
127
|
+
main: { 50: {...}, 100: {...}, ... },
|
|
128
|
+
sec: { 50: {...}, 100: {...}, ... },
|
|
129
|
+
acc: { 50: {...}, 100: {...}, ... }
|
|
130
|
+
}
|
|
131
|
+
↓ (RPC fetches events)
|
|
132
|
+
EventProvider loads events
|
|
133
|
+
↓ (User selects event)
|
|
134
|
+
useEventTheme() detects change
|
|
135
|
+
↓ (Applies colors)
|
|
136
|
+
applyPalette() → CSS variables update
|
|
137
|
+
↓
|
|
138
|
+
UI colors change in CAKE/TRACE
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Usage Example
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
// In your consuming app (e.g., CAKE or TRACE)
|
|
145
|
+
|
|
146
|
+
import {
|
|
147
|
+
UnifiedAuthProvider,
|
|
148
|
+
EventProvider,
|
|
149
|
+
OrganisationProvider,
|
|
150
|
+
useEventTheme
|
|
151
|
+
} from '@jmruthers/pace-core';
|
|
152
|
+
|
|
153
|
+
function App() {
|
|
154
|
+
// Enable automatic event theming
|
|
155
|
+
useEventTheme();
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
<EventSelector />
|
|
160
|
+
{/* Rest of your app */}
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function RootLayout() {
|
|
166
|
+
return (
|
|
167
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName="CAKE">
|
|
168
|
+
<OrganisationProvider>
|
|
169
|
+
<EventProvider>
|
|
170
|
+
<App />
|
|
171
|
+
</EventProvider>
|
|
172
|
+
</OrganisationProvider>
|
|
173
|
+
</UnifiedAuthProvider>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Migration Guide
|
|
179
|
+
|
|
180
|
+
If you're already manually applying event colors in your consuming apps:
|
|
181
|
+
|
|
182
|
+
### Before:
|
|
183
|
+
```tsx
|
|
184
|
+
function App() {
|
|
185
|
+
const { selectedEvent } = useEvents();
|
|
186
|
+
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
if (selectedEvent?.event_colours) {
|
|
189
|
+
applyPalette(selectedEvent.event_colours);
|
|
190
|
+
} else {
|
|
191
|
+
clearPalette();
|
|
192
|
+
}
|
|
193
|
+
}, [selectedEvent]);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### After:
|
|
198
|
+
```tsx
|
|
199
|
+
function App() {
|
|
200
|
+
useEventTheme(); // Replaces the above useEffect
|
|
201
|
+
|
|
202
|
+
return <div>Your app</div>;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Benefits
|
|
207
|
+
|
|
208
|
+
- **Zero boilerplate** - One line to enable automatic theming
|
|
209
|
+
- **Consistent UX** - All apps behave the same way
|
|
210
|
+
- **Less code** - No duplication across apps
|
|
211
|
+
- **Type safe** - Full TypeScript support
|
|
212
|
+
- **Maintainable** - Centralized improvements
|
|
213
|
+
- **Flexible** - Can still use manual API if needed
|
|
214
|
+
|
|
215
|
+
## Documentation
|
|
216
|
+
|
|
217
|
+
Full documentation available at:
|
|
218
|
+
- **Implementation Guide:** `packages/core/docs/implementation-guides/dynamic-colors.md`
|
|
219
|
+
- **Usage Guide:** `packages/core/docs/usage.md`
|
|
220
|
+
- **API Reference:** Available in code docs and type definitions
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Forms
|
|
1
|
+
# Forms
|
|
2
|
+
|
|
3
|
+
> **📚 Implementation Guides** | [← Back to Documentation](../README.md) | [Data Tables](./data-tables.md) | [Validation](./forms.md) Implementation Guide
|
|
2
4
|
|
|
3
5
|
This guide covers how to implement forms using PACE Core's form components and validation system.
|
|
4
6
|
|
|
@@ -175,7 +177,7 @@ const conditionalSchema = z.object({
|
|
|
175
177
|
}
|
|
176
178
|
return true;
|
|
177
179
|
}, {
|
|
178
|
-
message: "
|
|
180
|
+
message: "Organisation details are required for organization accounts",
|
|
179
181
|
path: ["organizationName"]
|
|
180
182
|
});
|
|
181
183
|
|
|
@@ -191,7 +193,7 @@ function ConditionalForm() {
|
|
|
191
193
|
type="select"
|
|
192
194
|
options={[
|
|
193
195
|
{ value: 'individual', label: 'Individual' },
|
|
194
|
-
{ value: 'organization', label: '
|
|
196
|
+
{ value: 'organization', label: 'Organisation' }
|
|
195
197
|
]}
|
|
196
198
|
/>
|
|
197
199
|
|
|
@@ -200,11 +202,11 @@ function ConditionalForm() {
|
|
|
200
202
|
|
|
201
203
|
{userType === 'organization' && (
|
|
202
204
|
<Card className="p-4 space-y-4">
|
|
203
|
-
<h3 className="text-lg font-semibold">
|
|
204
|
-
<FormField name="organizationName" label="
|
|
205
|
+
<h3 className="text-lg font-semibold">Organisation Details</h3>
|
|
206
|
+
<FormField name="organizationName" label="Organisation Name" />
|
|
205
207
|
<FormField
|
|
206
208
|
name="organizationSize"
|
|
207
|
-
label="
|
|
209
|
+
label="Organisation Size"
|
|
208
210
|
type="select"
|
|
209
211
|
options={[
|
|
210
212
|
{ value: 'small', label: 'Small (1-50 employees)' },
|
|
@@ -361,7 +363,7 @@ function CustomFormField({ name, label, ...props }) {
|
|
|
361
363
|
|
|
362
364
|
## Best Practices
|
|
363
365
|
|
|
364
|
-
### 1. Schema
|
|
366
|
+
### 1. Schema Organisation
|
|
365
367
|
|
|
366
368
|
```typescript
|
|
367
369
|
// schemas/user.ts
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Navigation Implementation Guide
|
|
2
2
|
|
|
3
|
+
> **📚 Implementation Guides** | [← Back to Documentation](../README.md) | [App Layout](./app-layout.md) | [Permission Enforcement](./permission-enforcement.md)
|
|
4
|
+
|
|
3
5
|
This guide covers how to implement navigation systems using PACE Core's navigation components with permission-based filtering and RBAC integration.
|
|
4
6
|
|
|
5
7
|
## Overview
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Migration Guide: Service Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This guide helps you migrate from the old provider architecture to the new service-based architecture. The new architecture provides better testability, maintainability, and follows SOLID principles.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### 1. Update Provider Import
|
|
10
|
+
|
|
11
|
+
Replace the old provider with the new one:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
// Old way
|
|
15
|
+
import { UnifiedAuthProvider } from '@core/providers';
|
|
16
|
+
|
|
17
|
+
// New way
|
|
18
|
+
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Update Provider Usage
|
|
22
|
+
|
|
23
|
+
The new provider has the same API but requires additional configuration:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// Old way
|
|
27
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName="MY_APP">
|
|
28
|
+
<YourAppContent />
|
|
29
|
+
</UnifiedAuthProvider>
|
|
30
|
+
|
|
31
|
+
// New way
|
|
32
|
+
<NewUnifiedAuthProvider
|
|
33
|
+
supabaseClient={supabase}
|
|
34
|
+
appName="MY_APP"
|
|
35
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
36
|
+
warnBeforeMs={60 * 1000} // 60 seconds
|
|
37
|
+
onIdleLogout={() => {
|
|
38
|
+
// Handle idle logout - redirect to login
|
|
39
|
+
window.location.href = '/login';
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<YourAppContent />
|
|
43
|
+
</NewUnifiedAuthProvider>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. Update Hook Imports
|
|
47
|
+
|
|
48
|
+
Replace the old hook with the new one:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
// Old way
|
|
52
|
+
import { useUnifiedAuth } from '@core/providers';
|
|
53
|
+
|
|
54
|
+
// New way
|
|
55
|
+
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Detailed Migration Steps
|
|
59
|
+
|
|
60
|
+
### Step 1: Update Main App Setup
|
|
61
|
+
|
|
62
|
+
Update your main app file (usually `main.tsx` or `App.tsx`):
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// Before
|
|
66
|
+
import { UnifiedAuthProvider, OrganisationProvider, EventProvider } from '@core/providers';
|
|
67
|
+
|
|
68
|
+
function App() {
|
|
69
|
+
return (
|
|
70
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName="MY_APP">
|
|
71
|
+
<OrganisationProvider>
|
|
72
|
+
<EventProvider>
|
|
73
|
+
<YourAppContent />
|
|
74
|
+
</EventProvider>
|
|
75
|
+
</OrganisationProvider>
|
|
76
|
+
</UnifiedAuthProvider>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// After
|
|
81
|
+
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
82
|
+
|
|
83
|
+
function App() {
|
|
84
|
+
return (
|
|
85
|
+
<NewUnifiedAuthProvider
|
|
86
|
+
supabaseClient={supabase}
|
|
87
|
+
appName="MY_APP"
|
|
88
|
+
idleTimeoutMs={30 * 60 * 1000}
|
|
89
|
+
warnBeforeMs={60 * 1000}
|
|
90
|
+
onIdleLogout={() => window.location.href = '/login'}
|
|
91
|
+
>
|
|
92
|
+
<YourAppContent />
|
|
93
|
+
</NewUnifiedAuthProvider>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Step 2: Update Component Hooks
|
|
99
|
+
|
|
100
|
+
Update components that use the old hooks:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
// Before
|
|
104
|
+
import { useUnifiedAuth } from '@core/providers';
|
|
105
|
+
|
|
106
|
+
function MyComponent() {
|
|
107
|
+
const { user, isAuthenticated, signOut } = useUnifiedAuth();
|
|
108
|
+
// ... component logic
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// After
|
|
112
|
+
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
113
|
+
|
|
114
|
+
function MyComponent() {
|
|
115
|
+
const { user, isAuthenticated, signOut } = useNewUnifiedAuth();
|
|
116
|
+
// ... component logic (same API)
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 3: Update Individual Provider Usage
|
|
121
|
+
|
|
122
|
+
If you were using individual providers, you can now use individual service hooks:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
// Before
|
|
126
|
+
import { useAuth } from '@core/providers';
|
|
127
|
+
import { useOrganisations } from '@core/providers';
|
|
128
|
+
import { useEvents } from '@core/providers';
|
|
129
|
+
|
|
130
|
+
function MyComponent() {
|
|
131
|
+
const auth = useAuth();
|
|
132
|
+
const orgs = useOrganisations();
|
|
133
|
+
const events = useEvents();
|
|
134
|
+
// ... component logic
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// After - Option 1: Use unified hook (same API)
|
|
138
|
+
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
139
|
+
|
|
140
|
+
function MyComponent() {
|
|
141
|
+
const auth = useNewUnifiedAuth();
|
|
142
|
+
// ... component logic (same API)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// After - Option 2: Use individual service hooks (better performance)
|
|
146
|
+
import { useAuth } from '@core/hooks/services/useAuth';
|
|
147
|
+
import { useCurrentOrganisation } from '@core/hooks/services/useCurrentOrganisation';
|
|
148
|
+
import { useCurrentEvent } from '@core/hooks/services/useCurrentEvent';
|
|
149
|
+
|
|
150
|
+
function MyComponent() {
|
|
151
|
+
const auth = useAuth();
|
|
152
|
+
const orgs = useCurrentOrganisation();
|
|
153
|
+
const events = useCurrentEvent();
|
|
154
|
+
// ... component logic
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API Changes
|
|
159
|
+
|
|
160
|
+
### New Required Props
|
|
161
|
+
|
|
162
|
+
The new provider requires additional props for inactivity management:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
interface NewUnifiedAuthProviderProps {
|
|
166
|
+
// ... existing props
|
|
167
|
+
idleTimeoutMs: number; // REQUIRED: Inactivity timeout in milliseconds
|
|
168
|
+
warnBeforeMs: number; // REQUIRED: Warning time before logout in milliseconds
|
|
169
|
+
onIdleLogout: (reason: 'inactivity') => void; // REQUIRED: App handles redirect/navigation
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Backward Compatibility
|
|
174
|
+
|
|
175
|
+
The new provider maintains the same API as the old one, so existing components should work without changes:
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
// This still works exactly the same
|
|
179
|
+
const { user, isAuthenticated, signOut, hasRole, hasPermission } = useNewUnifiedAuth();
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Performance Optimizations
|
|
183
|
+
|
|
184
|
+
### Use Individual Service Hooks
|
|
185
|
+
|
|
186
|
+
For better performance, use individual service hooks instead of the unified hook:
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
// Less efficient - re-renders on any state change
|
|
190
|
+
const auth = useNewUnifiedAuth();
|
|
191
|
+
|
|
192
|
+
// More efficient - only re-renders when auth state changes
|
|
193
|
+
const auth = useAuth();
|
|
194
|
+
const permissions = usePermissions();
|
|
195
|
+
const organisation = useCurrentOrganisation();
|
|
196
|
+
const events = useCurrentEvent();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Service Subscription
|
|
200
|
+
|
|
201
|
+
Services use an observable pattern for efficient updates:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
// Services automatically notify subscribers of state changes
|
|
205
|
+
// No need to manually manage subscriptions
|
|
206
|
+
const auth = useAuth(); // Automatically subscribes to auth service changes
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Testing Updates
|
|
210
|
+
|
|
211
|
+
### Update Test Imports
|
|
212
|
+
|
|
213
|
+
Update your test files to use the new providers:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
// Before
|
|
217
|
+
import { UnifiedAuthProvider } from '@core/providers';
|
|
218
|
+
|
|
219
|
+
// After
|
|
220
|
+
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Update Test Setup
|
|
224
|
+
|
|
225
|
+
Update your test setup to use the new provider:
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
// Before
|
|
229
|
+
render(
|
|
230
|
+
<UnifiedAuthProvider supabaseClient={mockSupabase} appName="TEST_APP">
|
|
231
|
+
<TestComponent />
|
|
232
|
+
</UnifiedAuthProvider>
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// After
|
|
236
|
+
render(
|
|
237
|
+
<NewUnifiedAuthProvider
|
|
238
|
+
supabaseClient={mockSupabase}
|
|
239
|
+
appName="TEST_APP"
|
|
240
|
+
idleTimeoutMs={30000}
|
|
241
|
+
warnBeforeMs={5000}
|
|
242
|
+
onIdleLogout={() => {}}
|
|
243
|
+
>
|
|
244
|
+
<TestComponent />
|
|
245
|
+
</NewUnifiedAuthProvider>
|
|
246
|
+
);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Service Testing
|
|
250
|
+
|
|
251
|
+
You can now test services directly:
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
// Test services in isolation
|
|
255
|
+
describe('AuthService', () => {
|
|
256
|
+
let authService: AuthService;
|
|
257
|
+
|
|
258
|
+
beforeEach(() => {
|
|
259
|
+
authService = new AuthService(mockSupabase);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should sign in user', async () => {
|
|
263
|
+
const result = await authService.signIn('test@example.com', 'password');
|
|
264
|
+
expect(result.user).toBeDefined();
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Common Issues and Solutions
|
|
270
|
+
|
|
271
|
+
### Issue 1: Missing Required Props
|
|
272
|
+
|
|
273
|
+
**Error**: `Missing required prop: idleTimeoutMs`
|
|
274
|
+
|
|
275
|
+
**Solution**: Add the required inactivity management props:
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<NewUnifiedAuthProvider
|
|
279
|
+
supabaseClient={supabase}
|
|
280
|
+
appName="MY_APP"
|
|
281
|
+
idleTimeoutMs={30 * 60 * 1000} // Add this
|
|
282
|
+
warnBeforeMs={60 * 1000} // Add this
|
|
283
|
+
onIdleLogout={() => window.location.href = '/login'} // Add this
|
|
284
|
+
>
|
|
285
|
+
<YourAppContent />
|
|
286
|
+
</NewUnifiedAuthProvider>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Issue 2: Hook Not Found
|
|
290
|
+
|
|
291
|
+
**Error**: `useUnifiedAuth must be used within a UnifiedAuthProvider`
|
|
292
|
+
|
|
293
|
+
**Solution**: Update the hook import:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
// Change this
|
|
297
|
+
import { useUnifiedAuth } from '@core/providers';
|
|
298
|
+
|
|
299
|
+
// To this
|
|
300
|
+
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Issue 3: Provider Not Found
|
|
304
|
+
|
|
305
|
+
**Error**: `useNewUnifiedAuth must be used within a NewUnifiedAuthProvider`
|
|
306
|
+
|
|
307
|
+
**Solution**: Ensure the component is wrapped in the new provider:
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
// Make sure your app is wrapped in NewUnifiedAuthProvider
|
|
311
|
+
<NewUnifiedAuthProvider {...props}>
|
|
312
|
+
<YourAppContent />
|
|
313
|
+
</NewUnifiedAuthProvider>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Migration Checklist
|
|
317
|
+
|
|
318
|
+
- [ ] Update provider import from `UnifiedAuthProvider` to `NewUnifiedAuthProvider`
|
|
319
|
+
- [ ] Add required inactivity management props (`idleTimeoutMs`, `warnBeforeMs`, `onIdleLogout`)
|
|
320
|
+
- [ ] Update hook import from `useUnifiedAuth` to `useNewUnifiedAuth`
|
|
321
|
+
- [ ] Update test imports and setup
|
|
322
|
+
- [ ] Test the application to ensure everything works
|
|
323
|
+
- [ ] Consider using individual service hooks for better performance
|
|
324
|
+
- [ ] Remove old provider imports once migration is complete
|
|
325
|
+
|
|
326
|
+
## Rollback Plan
|
|
327
|
+
|
|
328
|
+
If you need to rollback:
|
|
329
|
+
|
|
330
|
+
1. **Revert imports**: Change back to old provider imports
|
|
331
|
+
2. **Revert provider usage**: Remove the new required props
|
|
332
|
+
3. **Revert hook usage**: Change back to old hook imports
|
|
333
|
+
4. **Test**: Ensure the application works with the old architecture
|
|
334
|
+
|
|
335
|
+
## Support
|
|
336
|
+
|
|
337
|
+
If you encounter issues during migration:
|
|
338
|
+
|
|
339
|
+
1. **Check the documentation**: Review the service architecture documentation
|
|
340
|
+
2. **Check the examples**: Look at the updated example app
|
|
341
|
+
3. **Check the tests**: Review the test files for usage examples
|
|
342
|
+
4. **Open an issue**: Report bugs or ask questions
|
|
343
|
+
|
|
344
|
+
## Next Steps
|
|
345
|
+
|
|
346
|
+
After migration:
|
|
347
|
+
|
|
348
|
+
1. **Explore individual services**: Consider using individual service hooks for better performance
|
|
349
|
+
2. **Write service tests**: Add unit tests for your custom services
|
|
350
|
+
3. **Optimize performance**: Use individual hooks instead of the unified hook where appropriate
|
|
351
|
+
4. **Contribute**: Help improve the service architecture
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
The RBAC-RLS integration provides dynamic permission enforcement that automatically respects RBAC configuration changes. This solves the critical issue where:
|
|
8
8
|
|
|
9
|
-
- **RBAC permissions are configurable** -
|
|
9
|
+
- **RBAC permissions are configurable** - Organisations can set which roles have which CRUD permissions for each page ✅
|
|
10
10
|
- **RLS policies were hardcoded** - Database-level security policies were static and didn't respect the dynamic RBAC configuration ❌
|
|
11
11
|
- **Result:** Users with valid RBAC permissions were blocked by RLS policies, breaking core functionality
|
|
12
12
|
|
|
@@ -346,7 +346,7 @@ When reporting issues, please include:
|
|
|
346
346
|
|
|
347
347
|
The RBAC-RLS integration provides a robust, scalable solution for dynamic permission enforcement. It solves the critical architectural issue where RBAC configuration and RLS policies were disconnected, ensuring that:
|
|
348
348
|
|
|
349
|
-
1. **
|
|
349
|
+
1. **Organisations have true control** over their permission systems
|
|
350
350
|
2. **Developers can rely on consistent behavior** across all operations
|
|
351
351
|
3. **Users get the functionality they expect** based on their assigned roles
|
|
352
352
|
4. **The system is maintainable and auditable** with clear change tracking
|
package/docs/rbac/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RBAC System
|
|
2
2
|
|
|
3
|
-
> **📚
|
|
3
|
+
> **📚 RBAC System** | [← Back to Documentation](../README.md) | [Quick Start](./quick-start.md) | [Permissions](../core-concepts/permissions.md)
|
|
4
4
|
|
|
5
5
|
The PACE Core RBAC (Role-Based Access Control) system provides comprehensive permission management with organisation context enforcement, caching, and audit logging.
|
|
6
6
|
|
|
@@ -6,7 +6,7 @@ This example demonstrates how to use the new RBAC-RLS integration system to solv
|
|
|
6
6
|
|
|
7
7
|
Before the RBAC-RLS integration, you had this situation:
|
|
8
8
|
|
|
9
|
-
1. **RBAC Configuration**:
|
|
9
|
+
1. **RBAC Configuration**: Organisation grants `planner` role `delete:page.meals` permission ✅
|
|
10
10
|
2. **RLS Policy**: Only allows `event_admin` role to delete meals ❌
|
|
11
11
|
3. **Result**: Delete operations fail silently, appearing to succeed but not actually deleting records
|
|
12
12
|
|
|
@@ -223,7 +223,7 @@ USING (
|
|
|
223
223
|
## Benefits
|
|
224
224
|
|
|
225
225
|
### 1. True Permission Control
|
|
226
|
-
-
|
|
226
|
+
- Organisations can configure permissions without code changes
|
|
227
227
|
- RBAC settings actually control what users can do
|
|
228
228
|
- No more disconnect between frontend and database permissions
|
|
229
229
|
|
|
@@ -322,7 +322,7 @@ CREATE TRIGGER permission_change_notification
|
|
|
322
322
|
|
|
323
323
|
The RBAC-RLS integration provides a robust, scalable solution for dynamic permission enforcement. It solves the critical architectural issue where RBAC configuration and RLS policies were disconnected, ensuring that:
|
|
324
324
|
|
|
325
|
-
1. **
|
|
325
|
+
1. **Organisations have true control** over their permission systems
|
|
326
326
|
2. **Developers can rely on consistent behavior** across all operations
|
|
327
327
|
3. **Users get the functionality they expect** based on their assigned roles
|
|
328
328
|
4. **The system is maintainable and auditable** with clear change tracking
|
package/docs/rbac/quick-start.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# RBAC Quick Start
|
|
2
2
|
|
|
3
|
+
> **📚 RBAC System** | [← Back to Documentation](../../README.md) | [RBAC Overview](./README.md) | [Examples](./examples.md)
|
|
4
|
+
|
|
3
5
|
> **⚠️ CRITICAL**: This guide is designed to be impossible to get wrong. Follow every step exactly as written, and your RBAC system will work perfectly.
|
|
4
6
|
|
|
5
7
|
Build your first RBAC-enabled application in under 10 minutes.
|