@jmruthers/pace-core 0.6.8 → 0.6.10
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 +3 -0
- package/audit-tool/audits/02-project-structure.cjs +97 -32
- package/audit-tool/audits/03-architecture.cjs +145 -19
- package/audit-tool/audits/04-code-quality.cjs +86 -1
- package/audit-tool/audits/06-security-rbac.cjs +109 -11
- package/cursor-rules/02-project-structure.mdc +2 -26
- package/cursor-rules/05-styling.mdc +84 -6
- package/cursor-rules/06-security-rbac.mdc +124 -1
- package/dist/{DataTable-6RMSCQJ6.js → DataTable-SAXFG4XI.js} +11 -13
- package/dist/{AuthService-DmfO5rGS.d.ts → InactivityServiceProvider-DHryoh6K.d.ts} +24 -249
- package/dist/UnifiedAuthProvider-BBD2PS3Q.js +7 -0
- package/dist/{UnifiedAuthProvider-CKvHP1MK.d.ts → UnifiedAuthProvider-CiBAl9-s.d.ts} +34 -22
- package/dist/{api-7P7DI652.js → api-F47QJ7FX.js} +3 -3
- package/dist/assets/app-icons/admin_favicon.svg +462 -0
- package/dist/assets/app-icons/base_favicon.svg +85 -0
- package/dist/assets/app-icons/cake_favicon.svg +68 -0
- package/dist/assets/app-icons/core_favicon.svg +256 -0
- package/dist/assets/app-icons/gear_favicon.svg +91 -0
- package/dist/assets/app-icons/medi_favicon.svg +92 -0
- package/dist/assets/app-icons/mint_favicon.svg +83 -0
- package/dist/assets/app-icons/pace_favicon.svg +49 -0
- package/dist/assets/app-icons/pump_favicon.svg +68 -0
- package/dist/assets/app-icons/seed_favicon.svg +91 -0
- package/dist/assets/app-icons/team_favicon.svg +67 -0
- package/dist/assets/app-icons/trac_favicon.svg +112 -0
- package/dist/assets/app-icons/trip_favicon.svg +102 -0
- package/dist/audit-Z6ZZBWLU.js +3 -0
- package/dist/chunk-3GWSPISD.js +61 -0
- package/dist/{chunk-4DDCYDQ3.js → chunk-66R6RLUZ.js} +12 -27
- package/dist/{chunk-FYHN4DD5.js → chunk-7YDC7LMU.js} +80 -8
- package/dist/{chunk-S7DKJPLT.js → chunk-BCTXBU6U.js} +22 -17
- package/dist/{chunk-TTRFSOKR.js → chunk-BTHN5MKC.js} +4 -4
- package/dist/{chunk-A3W6LW53.js → chunk-DDMPHZ3D.js} +6 -18
- package/dist/{chunk-MPBLMWVR.js → chunk-FBZ7U3ID.js} +140 -92
- package/dist/chunk-FN52B75D.js +246 -0
- package/dist/{chunk-5W2A3DRC.js → chunk-JJEYZ3DX.js} +5 -4
- package/dist/chunk-KPYQWGFQ.js +183 -0
- package/dist/{chunk-IUBRCBSY.js → chunk-KSNLMI7N.js} +14 -8
- package/dist/chunk-KYURMOQM.js +977 -0
- package/dist/{chunk-LX6U42O3.js → chunk-LNHFAF4X.js} +160 -58
- package/dist/{chunk-NKHKXPI4.js → chunk-MPY44PWB.js} +683 -627
- package/dist/{chunk-AHU7G2R5.js → chunk-NIU6DPQV.js} +10 -6
- package/dist/{chunk-HF6O3O37.js → chunk-RMLY6KB5.js} +1 -1
- package/dist/{chunk-6GLLNA6U.js → chunk-SACF5YSM.js} +1 -1
- package/dist/{chunk-EURB7QFZ.js → chunk-TFIPNIPE.js} +867 -534
- package/dist/{chunk-OJ4SKRSV.js → chunk-UZNAFKGW.js} +25 -5
- package/dist/chunk-W46INAVW.js +1216 -0
- package/dist/chunk-X5EAU5G7.js +793 -0
- package/dist/{chunk-T5CVK4R3.js → chunk-Y4PF6HIM.js} +110 -64
- package/dist/components.d.ts +8 -86
- package/dist/components.js +21 -55
- package/dist/{database.generated-CcnC_DRc.d.ts → database.generated-DT8JTZiP.d.ts} +12 -12
- package/dist/eslint-rules/rules/05-styling.cjs +507 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +10 -0
- package/dist/{event-CW5YB_2p.d.ts → event-WTAQuGcq.d.ts} +1 -1
- package/dist/{functions-lBy5L2ry.d.ts → functions-DH45k8ec.d.ts} +1 -1
- package/dist/hooks.d.ts +12 -11
- package/dist/hooks.js +69 -44
- package/dist/index.d.ts +380 -32
- package/dist/index.js +46 -32
- package/dist/papaparseLoader-WG2UXQ22.js +7 -0
- package/dist/providers.d.ts +28 -14
- package/dist/providers.js +5 -5
- package/dist/rbac/eslint-rules.js +2 -2
- package/dist/rbac/index.d.ts +58 -214
- package/dist/rbac/index.js +11 -11
- package/dist/theming/runtime.d.ts +9 -3
- package/dist/theming/runtime.js +2 -2
- package/dist/{timezone-BZe_eUxx.d.ts → timezone-K-ptz3HO.d.ts} +22 -23
- package/dist/{types-t9H8qKRw.d.ts → types-BE2sEHKd.d.ts} +1 -1
- package/dist/{types-BeoeWV5I.d.ts → types-CvOPXWWZ.d.ts} +6 -5
- package/dist/{types-DXstZpNI.d.ts → types-D05dCGma.d.ts} +56 -149
- package/dist/types-Dr8sNhER.d.ts +50 -0
- package/dist/types.d.ts +5 -5
- package/dist/{PublicPageProvider-CIGSujI2.d.ts → usePublicPageContext-vxBlEHO9.d.ts} +294 -151
- package/dist/{usePublicRouteParams-MamNgwqe.d.ts → usePublicRouteParams-G3Ks53mk.d.ts} +8 -7
- package/dist/utils.d.ts +301 -137
- package/dist/utils.js +42 -41
- package/dist/{validation-643vUDZW.d.ts → validation-g5n0hDkh.d.ts} +2 -2
- package/docs/api/modules.md +542 -549
- package/docs/api-reference/components.md +5 -5
- package/docs/api-reference/rpc-functions.md +3 -3
- package/docs/implementation-guides/data-tables.md +256 -8
- package/docs/rbac/RBAC_CONTRACT.md +0 -12
- package/docs/standards/2-project-structure-standards.md +12 -74
- package/docs/standards/6-security-rbac-standards.md +222 -7
- package/docs/standards/7-api-tech-stack-standards.md +91 -3
- package/docs/testing/README.md +10 -0
- package/docs/testing/test-setup-for-consumers.md +914 -0
- package/eslint-config-pace-core.cjs +4 -0
- package/package.json +1 -1
- package/scripts/eslint-audit.cjs +110 -11
- package/src/__mocks__/lucide-react.ts +0 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +0 -2
- package/src/__tests__/index.test.ts +532 -0
- package/src/__tests__/integration/UserProfile.test.tsx +1 -1
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -8
- package/src/__tests__/rls-policies.test.ts +3 -2
- package/src/assets/app-icons/admin_favicon.svg +462 -0
- package/src/assets/app-icons/base_favicon.svg +85 -0
- package/src/assets/app-icons/cake_favicon.svg +68 -0
- package/src/assets/app-icons/core_favicon.svg +256 -0
- package/src/assets/app-icons/gear_favicon.svg +91 -0
- package/src/assets/app-icons/index.ts +83 -0
- package/src/assets/app-icons/medi_favicon.svg +92 -0
- package/src/assets/app-icons/mint_favicon.svg +83 -0
- package/src/assets/app-icons/pace_favicon.svg +49 -0
- package/src/assets/app-icons/pump_favicon.svg +68 -0
- package/src/assets/app-icons/seed_favicon.svg +91 -0
- package/src/assets/app-icons/team_favicon.svg +67 -0
- package/src/assets/app-icons/trac_favicon.svg +112 -0
- package/src/assets/app-icons/trip_favicon.svg +102 -0
- package/src/components/AddressField/AddressField.test.tsx +378 -3
- package/src/components/AddressField/AddressField.tsx +2 -2
- package/src/components/AddressField/types.ts +2 -2
- package/src/components/Alert/Alert.test.tsx +35 -25
- package/src/components/Alert/Alert.tsx +8 -8
- package/src/components/AppSwitcher/AppSwitcher.test.tsx +1250 -0
- package/src/components/AppSwitcher/AppSwitcher.tsx +315 -0
- package/src/components/Avatar/Avatar.test.tsx +11 -1
- package/src/components/Avatar/Avatar.tsx +3 -2
- package/src/components/Badge/Badge.test.tsx +11 -1
- package/src/components/Button/Button.test.tsx +13 -3
- package/src/components/Calendar/Calendar.test.tsx +523 -131
- package/src/components/Calendar/Calendar.tsx +107 -488
- package/src/components/Card/Card.test.tsx +220 -249
- package/src/components/Checkbox/Checkbox.test.tsx +58 -174
- package/src/components/ContextSelector/ContextSelector.tsx +3 -3
- package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +360 -0
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.export.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.select-label-display.test.tsx +485 -0
- package/src/components/DataTable/__tests__/DataTable.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +1 -1
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +76 -580
- package/src/components/DataTable/__tests__/README.md +1 -1
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +1 -1
- package/src/components/DataTable/__tests__/keyboard.test.tsx +1 -1
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +1 -3
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +0 -6
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +14 -6
- package/src/components/DataTable/components/ActionButtons.tsx +9 -4
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +3 -3
- package/src/components/DataTable/components/ColumnFilter.tsx +2 -7
- package/src/components/DataTable/components/DataTableCore.tsx +44 -52
- package/src/components/DataTable/components/DataTableLayout.tsx +37 -26
- package/src/components/DataTable/components/DataTableModals.tsx +118 -30
- package/src/components/DataTable/components/DataTableToolbar.tsx +2 -2
- package/src/components/DataTable/components/EditFields.tsx +6 -47
- package/src/components/DataTable/components/EditableRow.tsx +8 -8
- package/src/components/DataTable/components/EmptyState.tsx +6 -3
- package/src/components/DataTable/components/FilterRow.tsx +18 -11
- package/src/components/DataTable/components/GroupingDropdown.tsx +0 -1
- package/src/components/DataTable/components/ImportModal.tsx +305 -133
- package/src/components/DataTable/components/LoadingState.tsx +2 -2
- package/src/components/DataTable/components/PaginationControls.tsx +0 -4
- package/src/components/DataTable/components/RowComponent.tsx +42 -22
- package/src/components/DataTable/components/UnifiedTableBody.tsx +52 -12
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +51 -463
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +122 -116
- package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +40 -68
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +9 -137
- package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +57 -17
- package/src/components/DataTable/components/__tests__/DataTableCore.test.tsx +792 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +24 -65
- package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +467 -0
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +8 -125
- package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +528 -56
- package/src/components/DataTable/components/__tests__/EditFields.test.tsx +526 -0
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +1 -68
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +8 -25
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +3 -62
- package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +9 -14
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +50 -186
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +39 -97
- package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +13 -103
- package/src/components/DataTable/components/__tests__/RowComponent.test.tsx +629 -0
- package/src/components/DataTable/components/__tests__/SortIndicator.test.tsx +135 -0
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +31 -171
- package/src/components/DataTable/components/__tests__/cellValueUtils.test.ts +453 -0
- package/src/components/DataTable/components/hooks/useImportModalFocus.test.ts +184 -0
- package/src/components/DataTable/components/hooks/usePermissionTracking.test.ts +381 -0
- package/src/components/DataTable/context/DataTableContext.tsx +9 -10
- package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +12 -26
- package/src/components/DataTable/core/ColumnFactory.ts +3 -3
- package/src/components/DataTable/core/ColumnManager.ts +0 -1
- package/src/components/DataTable/core/DataManager.ts +4 -2
- package/src/components/DataTable/core/LocalDataAdapter.ts +1 -1
- package/src/components/DataTable/core/PluginRegistry.ts +2 -2
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +114 -2
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +103 -5
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +57 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +63 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +42 -9
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +29 -7
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +58 -4
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +16 -21
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +93 -4
- package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +227 -54
- package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +215 -62
- package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +217 -39
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +101 -6
- package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +157 -27
- package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +80 -0
- package/src/components/DataTable/hooks/__tests__/useKeyboardNavigation.test.ts +787 -0
- package/src/components/DataTable/hooks/__tests__/useServerSideDataEffect.test.ts +258 -0
- package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +298 -23
- package/src/components/DataTable/hooks/__tests__/useTableHandlers.test.ts +440 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +11 -22
- package/src/components/DataTable/hooks/useDataTableState.ts +20 -24
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +5 -5
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +13 -1
- package/src/components/DataTable/hooks/useTableColumns.ts +36 -38
- package/src/components/DataTable/hooks/useTableHandlers.ts +8 -20
- package/src/components/DataTable/index.ts +24 -2
- package/src/components/DataTable/types.ts +6 -3
- package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +3 -67
- package/src/components/DataTable/utils/__tests__/aggregationUtils.test.ts +288 -0
- package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +3 -60
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +1 -1
- package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +9 -21
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +102 -86
- package/src/components/DataTable/utils/__tests__/paginationUtils.test.ts +593 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +33 -49
- package/src/components/DataTable/utils/__tests__/selectFieldUtils.test.ts +208 -0
- package/src/components/DataTable/utils/a11yUtils.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +5 -5
- package/src/components/DataTable/utils/errorHandling.ts +3 -1
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +2 -2
- package/src/components/DataTable/utils/hierarchicalSorting.ts +3 -3
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/DataTable/utils/performanceUtils.ts +1 -1
- package/src/components/DataTable/utils/selectFieldUtils.ts +127 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +17 -24
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +1 -1
- package/src/components/DateTimeField/DateTimeField.test.tsx +2 -15
- package/src/components/DateTimeField/DateTimeField.tsx +1 -1
- package/src/components/Dialog/Dialog.test.tsx +2007 -407
- package/src/components/Dialog/Dialog.tsx +97 -192
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +2 -62
- package/src/components/ErrorBoundary/ErrorBoundaryContext.context.ts +17 -0
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +2 -45
- package/src/components/ErrorBoundary/ErrorBoundaryContext.types.ts +41 -0
- package/src/components/ErrorBoundary/index.ts +3 -4
- package/src/components/ErrorBoundary/useErrorBoundaryContext.ts +20 -0
- package/src/components/FileDisplay/FileDisplay.test.tsx +454 -222
- package/src/components/FileDisplay/FileDisplay.tsx +14 -12
- package/src/components/FileDisplay/index.tsx +1 -1
- package/src/components/FileUpload/FileUpload.test.tsx +54 -18
- package/src/components/FileUpload/FileUpload.tsx +10 -7
- package/src/components/FileUpload/index.tsx +1 -1
- package/src/components/Footer/Footer.test.tsx +33 -114
- package/src/components/Form/Form.test.tsx +388 -68
- package/src/components/Form/Form.tsx +57 -42
- package/src/components/Header/Header.test.tsx +645 -154
- package/src/components/Header/Header.tsx +52 -43
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +35 -76
- package/src/components/Input/Input.test.tsx +34 -120
- package/src/components/Label/Label.test.tsx +47 -46
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +9 -12
- package/src/components/LoginForm/LoginForm.test.tsx +0 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +1399 -82
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
- package/src/components/NavigationMenu/__tests__/useNavigationFiltering.test.ts +1934 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +5 -15
- package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +1307 -0
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +47 -46
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +81 -38
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +87 -66
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +245 -39
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -20
- package/src/components/PaceAppLayout/README.md +0 -9
- package/src/components/PaceAppLayout/test-setup.tsx +15 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +759 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +2 -3
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +1 -1
- package/src/components/Progress/Progress.test.tsx +127 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +1196 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +24 -6
- package/src/components/PublicLayout/PublicLayout.test.tsx +1435 -14
- package/src/components/PublicLayout/PublicPageContext.ts +28 -0
- package/src/components/PublicLayout/PublicPageLayout.tsx +6 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +2 -41
- package/src/components/PublicLayout/usePublicPageContext.ts +36 -0
- package/src/components/Select/Select.test.tsx +46 -9
- package/src/components/Select/Select.tsx +31 -24
- package/src/components/Select/__tests__/context.test.tsx +56 -0
- package/src/components/Select/hooks/__tests__/useSelectEvents.test.ts +279 -0
- package/src/components/Select/hooks/__tests__/useSelectSearch.test.tsx +295 -0
- package/src/components/Select/hooks/__tests__/useSelectState.test.ts +254 -0
- package/src/components/Select/hooks/useSelectState.ts +16 -16
- package/src/components/Select/types.ts +3 -0
- package/src/components/Select/utils/__tests__/text.test.tsx +104 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +28 -112
- package/src/components/Switch/Switch.test.tsx +57 -153
- package/src/components/Table/Table.test.tsx +47 -317
- package/src/components/Tabs/Tabs.tsx +3 -3
- package/src/components/Textarea/Textarea.test.tsx +11 -38
- package/src/components/Toast/Toast.test.tsx +78 -569
- package/src/components/Tooltip/Tooltip.test.tsx +4 -21
- package/src/components/UserMenu/UserMenu.test.tsx +1 -21
- package/src/components/UserMenu/UserMenu.tsx +3 -6
- package/src/components/__tests__/index.test.ts +346 -0
- package/src/components/index.ts +12 -1
- package/src/constants/__tests__/performance.test.ts +91 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +239 -129
- package/src/hooks/__tests__/hooks.integration.test.tsx +4 -3
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +88 -29
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +282 -98
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +53 -109
- package/src/hooks/__tests__/useDataTableState.test.ts +143 -49
- package/src/hooks/__tests__/useDebounce.unit.test.ts +94 -19
- package/src/hooks/__tests__/useEvents.unit.test.ts +100 -125
- package/src/hooks/__tests__/useFileDisplay.test.ts +540 -0
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1 -4
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +27 -247
- package/src/hooks/__tests__/useFileUrlCache.test.ts +246 -56
- package/src/hooks/__tests__/useFocusManagement.unit.test.ts +442 -68
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +345 -560
- package/src/hooks/__tests__/useFormDialog.test.ts +51 -222
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +1 -1
- package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +1 -4
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -1
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +1 -1
- package/src/hooks/__tests__/usePermissionCache.test.ts +506 -0
- package/src/hooks/__tests__/usePreventTabReload.test.ts +255 -36
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +17 -8
- package/src/hooks/__tests__/usePublicEvent.test.ts +16 -24
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +12 -4
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +3 -6
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +1 -2
- package/src/hooks/__tests__/useQueryCache.test.ts +313 -66
- package/src/hooks/__tests__/useSessionDraft.test.ts +496 -103
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +2 -2
- package/src/hooks/__tests__/useStorage.unit.test.ts +72 -102
- package/src/hooks/__tests__/useToast.test.ts +413 -0
- package/src/hooks/__tests__/useToast.unit.test.tsx +1 -1
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +175 -21
- package/src/hooks/index.ts +13 -1
- package/src/hooks/public/usePublicEvent.test.ts +304 -0
- package/src/hooks/public/usePublicEvent.ts +11 -11
- package/src/hooks/public/usePublicEventLogo.test.ts +655 -120
- package/src/hooks/public/usePublicEventLogo.ts +2 -2
- package/src/hooks/public/usePublicFileDisplay.test.ts +723 -0
- package/src/hooks/public/usePublicFileDisplay.ts +79 -49
- package/src/hooks/public/usePublicRouteParams.test.ts +595 -0
- package/src/hooks/public/usePublicRouteParams.ts +2 -2
- package/src/hooks/services/useAuthService.ts +1 -1
- package/src/hooks/services/useEventService.ts +1 -1
- package/src/hooks/useAccessibleApps.test.ts +400 -0
- package/src/hooks/useAccessibleApps.ts +264 -0
- package/src/hooks/useAddressAutocomplete.test.ts +165 -42
- package/src/hooks/useAddressAutocomplete.ts +41 -28
- package/src/hooks/useAppConfig.ts +13 -3
- package/src/hooks/useDataTablePerformance.ts +13 -12
- package/src/hooks/useDataTableState.ts +5 -5
- package/src/hooks/useEventTheme.test.ts +66 -17
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +8 -1
- package/src/hooks/useFileDisplay.ts +66 -33
- package/src/hooks/useFileReference.test.ts +365 -87
- package/src/hooks/useFileReference.ts +2 -6
- package/src/hooks/useFileUrlCache.ts +4 -1
- package/src/hooks/useFormDialog.ts +2 -2
- package/src/hooks/useInactivityTracker.ts +3 -3
- package/src/hooks/useOrganisationPermissions.test.ts +1 -2
- package/src/hooks/useOrganisationPermissions.ts +1 -4
- package/src/hooks/useOrganisationSecurity.test.ts +1 -30
- package/src/hooks/useOrganisationSecurity.ts +3 -3
- package/src/hooks/useOrganisations.ts +1 -1
- package/src/hooks/usePerformanceMonitor.ts +1 -1
- package/src/hooks/usePermissionCache.ts +2 -6
- package/src/hooks/useQueryCache.ts +7 -7
- package/src/hooks/useSessionDraft.ts +14 -11
- package/src/hooks/useSessionRestoration.ts +1 -1
- package/src/hooks/useStorage.ts +75 -40
- package/src/hooks/useToast.ts +2 -2
- package/src/hooks/useZodForm.ts +3 -3
- package/src/icons/__tests__/index.test.ts +133 -0
- package/src/icons/index.ts +1 -1
- package/src/index.ts +43 -4
- package/src/providers/OrganisationProvider.test.tsx +40 -0
- package/src/providers/OrganisationProvider.tsx +5 -5
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +7 -12
- package/src/providers/__tests__/AuthProvider.test.tsx +22 -91
- package/src/providers/__tests__/EventProvider.test.tsx +16 -80
- package/src/providers/__tests__/InactivityProvider.test.tsx +29 -173
- package/src/providers/__tests__/OrganisationProvider.test.tsx +4 -5
- package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +591 -0
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +80 -196
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +40 -133
- package/src/providers/__tests__/index.test.ts +138 -0
- package/src/providers/services/AuthServiceContext.ts +27 -0
- package/src/providers/services/AuthServiceProvider.tsx +81 -20
- package/src/providers/services/EventServiceContext.ts +25 -0
- package/src/providers/services/EventServiceProvider.tsx +11 -20
- package/src/providers/services/InactivityServiceContext.ts +25 -0
- package/src/providers/services/InactivityServiceProvider.tsx +7 -17
- package/src/providers/services/OrganisationServiceContext.ts +25 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +7 -17
- package/src/providers/services/UnifiedAuthContext.ts +99 -0
- package/src/providers/services/UnifiedAuthProvider.test.tsx +212 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +38 -143
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +61 -95
- package/src/providers/services/__tests__/AuthServiceProvider.test.tsx +638 -0
- package/src/providers/services/__tests__/EventServiceProvider.test.tsx +839 -0
- package/src/providers/services/__tests__/InactivityServiceProvider.test.tsx +662 -0
- package/src/providers/services/__tests__/OrganisationServiceProvider.test.tsx +440 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.advanced.test.tsx +435 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.appId.test.tsx +408 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +55 -48
- package/src/providers/services/__tests__/contexts.test.tsx +281 -0
- package/src/providers/services/__tests__/useUnifiedAuth.test.tsx +251 -0
- package/src/providers/services/useUnifiedAuth.ts +29 -0
- package/src/rbac/README.md +5 -5
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +9 -14
- package/src/rbac/__tests__/audit-batched.test.ts +550 -0
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +1 -14
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +43 -12
- package/src/rbac/__tests__/cache-invalidation.test.ts +8 -14
- package/src/rbac/__tests__/engine.comprehensive.test.ts +2 -7
- package/src/rbac/__tests__/index.test.ts +107 -0
- package/src/rbac/__tests__/performance.test.ts +451 -0
- package/src/rbac/__tests__/rbac-core.test.tsx +2 -2
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +0 -5
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +1 -7
- package/src/rbac/__tests__/rbac-functions.test.ts +0 -1
- package/src/rbac/__tests__/rbac-integration.test.ts +0 -1
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +21 -32
- package/src/rbac/adapters.test.tsx +654 -0
- package/src/rbac/adapters.tsx +24 -9
- package/src/rbac/api.test.ts +13 -217
- package/src/rbac/api.ts +85 -16
- package/src/rbac/audit-batched.ts +5 -4
- package/src/rbac/audit.test.ts +225 -28
- package/src/rbac/audit.ts +22 -17
- package/src/rbac/cache-invalidation.ts +18 -15
- package/src/rbac/cache.test.ts +123 -63
- package/src/rbac/cache.ts +3 -4
- package/src/rbac/components/AccessDenied.tsx +20 -18
- package/src/rbac/components/NavigationGuard.tsx +10 -8
- package/src/rbac/components/PagePermissionGuard.tsx +27 -25
- package/src/rbac/components/__tests__/AccessDenied.test.tsx +324 -0
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +242 -71
- package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +20 -37
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +18 -17
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +452 -129
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -13
- package/src/rbac/config.test.ts +131 -48
- package/src/rbac/config.ts +11 -8
- package/src/rbac/docs/event-based-apps.md +26 -13
- package/src/rbac/engine.test.ts +496 -146
- package/src/rbac/engine.ts +53 -13
- package/src/rbac/errors.test.ts +99 -87
- package/src/rbac/eslint-rules.js +2 -2
- package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +0 -5
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +601 -1
- package/src/rbac/hooks/permissions/__tests__/useAccessLevel.test.ts +622 -0
- package/src/rbac/hooks/permissions/__tests__/useCan.test.ts +798 -0
- package/src/rbac/hooks/permissions/__tests__/useMultiplePermissions.test.ts +843 -0
- package/src/rbac/hooks/permissions/__tests__/usePermissions.test.ts +545 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +7 -8
- package/src/rbac/hooks/permissions/useCan.ts +12 -10
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +57 -8
- package/src/rbac/hooks/permissions/usePermissions.ts +15 -14
- package/src/rbac/hooks/useCan.test.ts +319 -3
- package/src/rbac/hooks/usePermissions.test.ts +426 -0
- package/src/rbac/hooks/usePermissions.ts +5 -7
- package/src/rbac/hooks/useRBAC.test.ts +1669 -2
- package/src/rbac/hooks/useRBAC.ts +7 -11
- package/src/rbac/hooks/useResolvedScope.test.ts +442 -5
- package/src/rbac/hooks/useResolvedScope.ts +4 -1
- package/src/rbac/hooks/useResourcePermissions.test.ts +538 -1
- package/src/rbac/hooks/useResourcePermissions.ts +9 -7
- package/src/rbac/hooks/useRoleManagement.test.ts +659 -1
- package/src/rbac/hooks/useRoleManagement.ts +16 -12
- package/src/rbac/hooks/useSecureSupabase.ts +11 -12
- package/src/rbac/index.ts +32 -32
- package/src/rbac/permissions.test.ts +149 -68
- package/src/rbac/permissions.ts +0 -3
- package/src/rbac/request-deduplication.test.ts +347 -0
- package/src/rbac/secureClient.test.ts +112 -159
- package/src/rbac/secureClient.ts +46 -26
- package/src/rbac/security.test.ts +125 -44
- package/src/rbac/security.ts +7 -6
- package/src/rbac/types.test.ts +236 -0
- package/src/rbac/types.ts +7 -5
- package/src/rbac/utils/__tests__/clientSecurity.test.ts +192 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +1 -3
- package/src/rbac/utils/__tests__/deep-equal.test.ts +23 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +10 -57
- package/src/rbac/utils/clientSecurity.ts +6 -4
- package/src/rbac/utils/contextValidator.ts +1 -2
- package/src/rbac/utils/eventContext.ts +2 -2
- package/src/services/AuthService.ts +13 -11
- package/src/services/EventService.ts +4 -5
- package/src/services/OrganisationService.ts +13 -30
- package/src/services/__tests__/AuthService.edge-cases.test.ts +746 -0
- package/src/services/__tests__/AuthService.restoreSession.test.ts +23 -3
- package/src/services/__tests__/AuthService.test.ts +4 -8
- package/src/services/__tests__/BaseService.edge-cases.test.ts +506 -0
- package/src/services/__tests__/BaseService.test.ts +49 -0
- package/src/services/__tests__/EventService.edge-cases.test.ts +633 -0
- package/src/services/__tests__/EventService.eventColours.test.ts +0 -12
- package/src/services/__tests__/EventService.test.ts +0 -7
- package/src/services/__tests__/InactivityService.edge-cases.test.ts +492 -0
- package/src/services/__tests__/InactivityService.lifecycle.test.ts +0 -5
- package/src/services/__tests__/OrganisationService.edge-cases.test.ts +633 -0
- package/src/services/base/BaseService.test.ts +214 -0
- package/src/services/interfaces/IOrganisationService.ts +0 -1
- package/src/services/interfaces/__tests__/IAuthService.test.ts +190 -0
- package/src/services/interfaces/__tests__/IEventService.test.ts +176 -0
- package/src/services/interfaces/__tests__/IInactivityService.test.ts +183 -0
- package/src/services/interfaces/__tests__/IOrganisationService.test.ts +207 -0
- package/src/styles/core.css +1 -0
- package/src/theming/__tests__/runtime.test.ts +29 -94
- package/src/theming/parseEventColours.ts +18 -9
- package/src/theming/runtime.ts +1 -5
- package/src/types/__tests__/core.test.ts +397 -0
- package/src/types/__tests__/database-generated.test.ts +78 -0
- package/src/types/__tests__/file-reference.test.ts +270 -366
- package/src/types/__tests__/guards.test.ts +26 -26
- package/src/types/__tests__/index.test.ts +265 -0
- package/src/types/__tests__/type-validation.test.ts +3 -3
- package/src/types/__tests__/validation.test.ts +0 -2
- package/src/types/auth.ts +0 -1
- package/src/types/database.generated.ts +9 -9
- package/src/types/event.ts +1 -1
- package/src/types/rpc-responses.ts +33 -0
- package/src/types/supabase.ts +1 -2
- package/src/types/vitest-globals.d.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +64 -77
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +13 -0
- package/src/utils/__tests__/formatDate.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -2
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +48 -13
- package/src/utils/__tests__/request-deduplication.test.ts +349 -0
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -1
- package/src/utils/__tests__/timezone.test.ts +1 -1
- package/src/utils/__tests__/validation.unit.test.ts +1 -2
- package/src/utils/__tests__/validationUtils.unit.test.ts +1 -1
- package/src/utils/app/appConfig.test.ts +235 -0
- package/src/utils/app/appIdResolver.test.ts +188 -20
- package/src/utils/app/appNameResolver.test.ts +18 -10
- package/src/utils/app/appNameResolver.ts +11 -9
- package/src/utils/app/appPortMap.test.ts +125 -0
- package/src/utils/app/appPortMap.ts +51 -0
- package/src/utils/app/buildAppUrl.test.ts +273 -0
- package/src/utils/app/buildAppUrl.ts +114 -0
- package/src/utils/audit/audit.test.ts +354 -39
- package/src/utils/context/organisationContext.test.ts +10 -4
- package/src/utils/context/organisationContext.ts +5 -5
- package/src/utils/context/sessionTracking.test.ts +354 -0
- package/src/utils/core/__tests__/cn.test.ts +66 -0
- package/src/utils/core/__tests__/debugLogger.test.ts +113 -0
- package/src/utils/core/__tests__/logger.test.ts +217 -0
- package/src/utils/core/debugLogger.ts +15 -8
- package/src/utils/core/logger.ts +20 -16
- package/src/utils/device/deviceFingerprint.test.ts +8 -5
- package/src/utils/device/deviceFingerprint.ts +3 -3
- package/src/utils/dynamic/__tests__/dynamicUtils.test.ts +185 -0
- package/src/utils/dynamic/__tests__/lazyLoad.test.tsx +156 -0
- package/src/utils/dynamic/createLazyComponent.tsx +38 -0
- package/src/utils/dynamic/dynamicUtils.ts +6 -6
- package/src/utils/dynamic/lazyLoad.tsx +8 -36
- package/src/utils/dynamic/papaparseLoader.ts +7 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +583 -145
- package/src/utils/file-reference/index.ts +0 -1
- package/src/utils/formatting/formatDate.test.ts +22 -148
- package/src/utils/formatting/formatDateTime.test.ts +41 -119
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +40 -84
- package/src/utils/formatting/formatNumber.test.ts +259 -0
- package/src/utils/formatting/formatTime.test.ts +36 -128
- package/src/utils/formatting/formatting.ts +1 -1
- package/src/utils/google-places/googlePlacesUtils.test.ts +72 -3
- package/src/utils/google-places/googlePlacesUtils.ts +15 -2
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +58 -1
- package/src/utils/google-places/loadGoogleMapsScript.ts +2 -1
- package/src/utils/index.ts +52 -11
- package/src/utils/location/location.test.ts +18 -115
- package/src/utils/performance/__tests__/bundleAnalysis.test.ts +148 -0
- package/src/utils/performance/__tests__/performanceBenchmark.test.ts +251 -0
- package/src/utils/performance/__tests__/performanceBudgets.test.ts +241 -0
- package/src/utils/performance/bundleAnalysis.ts +16 -22
- package/src/utils/performance/performanceBenchmark.ts +12 -4
- package/src/utils/performance/performanceBudgets.ts +9 -6
- package/src/utils/permissions/__tests__/permissionTypes.test.ts +149 -0
- package/src/utils/permissions/permissionUtils.test.ts +20 -42
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +180 -9
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +164 -16
- package/src/utils/persistence/sensitiveFieldDetection.ts +2 -2
- package/src/utils/request-deduplication.ts +6 -4
- package/src/utils/security/auth-utils.ts +7 -7
- package/src/utils/security/secureDataAccess.test.ts +22 -191
- package/src/utils/security/secureErrors.test.ts +163 -0
- package/src/utils/security/secureStorage.test.ts +156 -0
- package/src/utils/security/secureStorage.ts +1 -1
- package/src/utils/security/security.test.ts +204 -0
- package/src/utils/security/securityMonitor.test.ts +90 -0
- package/src/utils/security/securityMonitor.ts +1 -1
- package/src/utils/storage/__tests__/config.unit.test.ts +239 -0
- package/src/utils/storage/__tests__/index.unit.test.ts +64 -12
- package/src/utils/storage/helpers.test.ts +757 -430
- package/src/utils/storage/helpers.ts +1 -2
- package/src/utils/storage/{index.ts → storageUtils.ts} +1 -36
- package/src/utils/storage/types.ts +2 -2
- package/src/utils/supabase/createBaseClient.test.ts +201 -0
- package/src/utils/supabase/createBaseClient.ts +27 -8
- package/src/utils/timezone/timezone.test.ts +25 -43
- package/src/utils/validation/__tests__/common.test.ts +115 -0
- package/src/utils/validation/__tests__/csrf.test.ts +65 -0
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +27 -7
- package/src/utils/validation/__tests__/passwordSchema.test.ts +164 -0
- package/src/utils/validation/__tests__/schema.test.ts +127 -0
- package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +76 -3
- package/src/utils/validation/__tests__/user.test.ts +173 -0
- package/src/utils/validation/__tests__/validation.test.ts +197 -0
- package/src/utils/validation/__tests__/validationUtils.test.ts +265 -43
- package/src/utils/validation/htmlSanitization.ts +27 -31
- package/src/utils/validation/schema.ts +6 -3
- package/src/utils/validation/sqlInjectionProtection.ts +2 -2
- package/src/vite-env.d.ts +6 -0
- package/dist/DataTable-DRUIgtUH.d.ts +0 -166
- package/dist/UnifiedAuthProvider-7SNDOWYD.js +0 -7
- package/dist/audit-MYQXYZFU.js +0 -3
- package/dist/chunk-7ILTDCL2.js +0 -80
- package/dist/chunk-EF2UGZWY.js +0 -611
- package/dist/chunk-FEJLJNWA.js +0 -181
- package/dist/chunk-GS5672WG.js +0 -2003
- package/dist/chunk-S6ZQKDY6.js +0 -62
- package/dist/chunk-Z2FNRKF3.js +0 -994
- package/dist/useToast-AyaT-x7p.d.ts +0 -68
- package/src/components/DataTable/components/index.ts +0 -16
- package/src/components/DataTable/core/index.ts +0 -1
- package/src/components/DataTable/hooks/index.ts +0 -13
- package/src/components/DataTable/utils/index.ts +0 -9
- package/src/components/PublicLayout/index.ts +0 -32
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
- package/src/hooks/public/index.ts +0 -36
- package/src/hooks/usePermissionCache.test.ts +0 -536
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +0 -82
- package/src/rbac/audit-enhanced.ts +0 -384
- package/src/rbac/compliance/database-validator.ts +0 -165
- package/src/rbac/compliance/index.ts +0 -48
- package/src/rbac/compliance/pattern-detector.ts +0 -553
- package/src/rbac/compliance/quick-fix-suggestions.ts +0 -209
- package/src/rbac/compliance/runtime-compliance.ts +0 -99
- package/src/rbac/compliance/setup-validator.ts +0 -131
- package/src/rbac/components/index.ts +0 -26
- package/src/rbac/hooks/index.ts +0 -34
- package/src/rbac/hooks/permissions/index.ts +0 -4
- package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -490
- package/src/utils/app/appNameResolver.simple.test.ts +0 -212
- package/src/utils/google-places/index.ts +0 -26
- package/src/utils/location/index.ts +0 -16
- package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -332
- package/src/utils/timezone/index.ts +0 -17
- package/src/utils/validation/index.ts +0 -73
|
@@ -24,8 +24,8 @@ All helper functions used in RLS policies **MUST** have these attributes:
|
|
|
24
24
|
| Requirement | Why | Example |
|
|
25
25
|
|------------|-----|---------|
|
|
26
26
|
| `STABLE` | Prevents re-evaluation for each row | `STABLE` |
|
|
27
|
-
| `SECURITY DEFINER` | Bypass RLS to avoid
|
|
28
|
-
| `SET search_path TO 'public'` |
|
|
27
|
+
| `SECURITY DEFINER` | Bypass RLS to avoid circular dependencies when querying RLS-protected tables | `SECURITY DEFINER` |
|
|
28
|
+
| `SET search_path TO 'public'` | **MANDATORY** - Prevents search path hijacking attacks | `SET search_path TO public` |
|
|
29
29
|
| No inline `auth.uid()` | Causes InitPlan nodes, severe performance degradation | Use helper function instead |
|
|
30
30
|
|
|
31
31
|
### Helper Function Template
|
|
@@ -34,19 +34,31 @@ All helper functions used in RLS policies **MUST** have these attributes:
|
|
|
34
34
|
CREATE OR REPLACE FUNCTION function_name(parameters)
|
|
35
35
|
RETURNS return_type
|
|
36
36
|
LANGUAGE plpgsql
|
|
37
|
-
STABLE -- ✅ Required
|
|
38
|
-
SECURITY DEFINER -- ✅ Required
|
|
39
|
-
SET search_path TO public -- ✅
|
|
37
|
+
STABLE -- ✅ Required for performance
|
|
38
|
+
SECURITY DEFINER -- ✅ Required if querying RLS-protected tables
|
|
39
|
+
SET search_path TO public -- ✅ MANDATORY - Prevents search path hijacking
|
|
40
40
|
AS $$
|
|
41
41
|
DECLARE
|
|
42
42
|
-- Declarations
|
|
43
43
|
BEGIN
|
|
44
44
|
-- Function body
|
|
45
|
+
-- Always schema-qualify table/function references (e.g., public.table_name)
|
|
45
46
|
RETURN result;
|
|
46
47
|
END;
|
|
47
48
|
$$;
|
|
49
|
+
|
|
50
|
+
-- ✅ Document why SECURITY DEFINER is needed
|
|
51
|
+
COMMENT ON FUNCTION function_name(parameters) IS
|
|
52
|
+
'Purpose description. SECURITY DEFINER required because this function queries rbac_organisation_roles which has RLS policies. STABLE for RLS policy performance.';
|
|
48
53
|
```
|
|
49
54
|
|
|
55
|
+
**Security Checklist:**
|
|
56
|
+
- [ ] `SET search_path TO public` is present (MANDATORY)
|
|
57
|
+
- [ ] All table/function references are schema-qualified (e.g., `public.table_name`)
|
|
58
|
+
- [ ] Function is marked `STABLE` or `IMMUTABLE` when possible
|
|
59
|
+
- [ ] Function ownership uses least-privilege role (not superuser unless necessary)
|
|
60
|
+
- [ ] COMMENT documents why SECURITY DEFINER is needed
|
|
61
|
+
|
|
50
62
|
### Forbidden Patterns
|
|
51
63
|
|
|
52
64
|
**❌ NEVER use these patterns in RLS policies:**
|
|
@@ -99,6 +111,206 @@ FOR SELECT USING (
|
|
|
99
111
|
);
|
|
100
112
|
```
|
|
101
113
|
|
|
114
|
+
## SECURITY DEFINER Requirements & Security
|
|
115
|
+
|
|
116
|
+
### When SECURITY DEFINER is Necessary
|
|
117
|
+
|
|
118
|
+
**SECURITY DEFINER is REQUIRED when:**
|
|
119
|
+
- Helper function queries tables with RLS policies (e.g., `rbac_organisation_roles`, `rbac_global_roles`)
|
|
120
|
+
- Function needs to bypass RLS to avoid circular dependencies
|
|
121
|
+
- Function performs administrative operations requiring elevated privileges
|
|
122
|
+
|
|
123
|
+
**Why it's needed:**
|
|
124
|
+
When an RLS policy calls a helper function that queries RLS-protected tables, without SECURITY DEFINER:
|
|
125
|
+
1. RLS policy calls helper function
|
|
126
|
+
2. Helper function queries RLS-protected table (e.g., `rbac_organisation_roles`)
|
|
127
|
+
3. That query triggers RLS again → infinite recursion or circular dependency
|
|
128
|
+
|
|
129
|
+
**Example:**
|
|
130
|
+
```sql
|
|
131
|
+
-- ✅ CORRECT: SECURITY DEFINER required because function queries rbac_organisation_roles
|
|
132
|
+
CREATE OR REPLACE FUNCTION check_user_organisation_access(p_organisation_id UUID)
|
|
133
|
+
RETURNS boolean
|
|
134
|
+
LANGUAGE plpgsql
|
|
135
|
+
STABLE
|
|
136
|
+
SECURITY DEFINER -- ✅ Required: queries rbac_organisation_roles (has RLS)
|
|
137
|
+
SET search_path TO public -- ✅ MANDATORY: prevents search path hijacking
|
|
138
|
+
AS $$
|
|
139
|
+
BEGIN
|
|
140
|
+
-- This queries rbac_organisation_roles which has RLS policies
|
|
141
|
+
-- Without SECURITY DEFINER, this would trigger RLS again → circular dependency
|
|
142
|
+
RETURN EXISTS (
|
|
143
|
+
SELECT 1 FROM public.rbac_organisation_roles -- ✅ Schema-qualified
|
|
144
|
+
WHERE user_id = auth.uid()
|
|
145
|
+
AND organisation_id = p_organisation_id
|
|
146
|
+
);
|
|
147
|
+
END;
|
|
148
|
+
$$;
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**SECURITY DEFINER is NOT necessary when:**
|
|
152
|
+
- Function only performs pure computation (no table queries)
|
|
153
|
+
- Function only queries tables without RLS policies
|
|
154
|
+
- Function doesn't need to bypass RLS
|
|
155
|
+
|
|
156
|
+
**Example:**
|
|
157
|
+
```sql
|
|
158
|
+
-- ✅ CORRECT: No SECURITY DEFINER needed (pure computation, no RLS-protected queries)
|
|
159
|
+
CREATE OR REPLACE FUNCTION calculate_total(p_amount NUMERIC, p_tax_rate NUMERIC)
|
|
160
|
+
RETURNS NUMERIC
|
|
161
|
+
LANGUAGE plpgsql
|
|
162
|
+
STABLE -- ✅ STABLE for performance, but no SECURITY DEFINER needed
|
|
163
|
+
AS $$
|
|
164
|
+
BEGIN
|
|
165
|
+
RETURN p_amount * (1 + p_tax_rate);
|
|
166
|
+
END;
|
|
167
|
+
$$;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Security Risks & Mitigations
|
|
171
|
+
|
|
172
|
+
**Security Risks:**
|
|
173
|
+
1. **Search path hijacking** - If `search_path` includes untrusted schemas, malicious objects could be called
|
|
174
|
+
2. **Privilege escalation** - Functions run with owner's privileges, not caller's
|
|
175
|
+
3. **Unqualified object references** - Could resolve to objects in wrong schemas
|
|
176
|
+
4. **Performance implications** - Can affect query optimization
|
|
177
|
+
|
|
178
|
+
**Required Mitigations (MANDATORY):**
|
|
179
|
+
|
|
180
|
+
| Mitigation | Requirement | Why |
|
|
181
|
+
|------------|-------------|-----|
|
|
182
|
+
| `SET search_path TO public` | **MANDATORY** | Prevents search path hijacking attacks |
|
|
183
|
+
| Schema-qualify references | **MANDATORY** | Ensures objects resolve to correct schemas |
|
|
184
|
+
| `STABLE` or `IMMUTABLE` | **REQUIRED** | Helps with query optimization and performance |
|
|
185
|
+
| Least-privilege ownership | **RECOMMENDED** | Functions should be owned by appropriate roles (not superuser unless necessary) |
|
|
186
|
+
| Document rationale | **REQUIRED** | COMMENT must explain why SECURITY DEFINER is needed |
|
|
187
|
+
|
|
188
|
+
**Example with all mitigations:**
|
|
189
|
+
```sql
|
|
190
|
+
-- ✅ CORRECT: All security mitigations in place
|
|
191
|
+
CREATE OR REPLACE FUNCTION check_user_organisation_access(p_organisation_id UUID)
|
|
192
|
+
RETURNS boolean
|
|
193
|
+
LANGUAGE plpgsql
|
|
194
|
+
STABLE -- ✅ Performance optimization
|
|
195
|
+
SECURITY DEFINER -- ✅ Required: queries RLS-protected tables
|
|
196
|
+
SET search_path TO public -- ✅ MANDATORY: prevents search path hijacking
|
|
197
|
+
AS $$
|
|
198
|
+
BEGIN
|
|
199
|
+
-- ✅ Schema-qualified references
|
|
200
|
+
RETURN EXISTS (
|
|
201
|
+
SELECT 1 FROM public.rbac_organisation_roles
|
|
202
|
+
WHERE user_id = auth.uid()
|
|
203
|
+
AND organisation_id = p_organisation_id
|
|
204
|
+
);
|
|
205
|
+
END;
|
|
206
|
+
$$;
|
|
207
|
+
|
|
208
|
+
-- ✅ Document why SECURITY DEFINER is needed
|
|
209
|
+
COMMENT ON FUNCTION check_user_organisation_access(UUID) IS
|
|
210
|
+
'Checks if current user has access to organisation. SECURITY DEFINER required because function queries public.rbac_organisation_roles which has RLS policies. Without SECURITY DEFINER, this would create circular RLS dependency. STABLE for RLS policy performance. SET search_path TO public prevents search path hijacking.';
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Decision Tree: When to Use SECURITY DEFINER
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
1. Does this helper function query tables with RLS policies?
|
|
217
|
+
├─ YES → SECURITY DEFINER required (to avoid circular RLS)
|
|
218
|
+
│ └─ Continue to step 3
|
|
219
|
+
└─ NO → Continue to step 2
|
|
220
|
+
|
|
221
|
+
2. Does this function need elevated privileges for administrative operations?
|
|
222
|
+
├─ YES → SECURITY DEFINER may be appropriate (document why)
|
|
223
|
+
│ └─ Continue to step 3
|
|
224
|
+
└─ NO → SECURITY DEFINER not needed
|
|
225
|
+
└─ Use STABLE or IMMUTABLE only
|
|
226
|
+
|
|
227
|
+
3. If using SECURITY DEFINER, verify all security requirements:
|
|
228
|
+
├─ SET search_path TO public (or specific schema list) ✅ MANDATORY
|
|
229
|
+
├─ Schema-qualify all table/function references ✅ MANDATORY
|
|
230
|
+
├─ Use STABLE/IMMUTABLE when possible ✅ REQUIRED
|
|
231
|
+
├─ Owned by appropriate role (not superuser unless needed) ✅ RECOMMENDED
|
|
232
|
+
└─ Document why SECURITY DEFINER is needed in COMMENT ✅ REQUIRED
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Security Anti-Patterns
|
|
236
|
+
|
|
237
|
+
**❌ NEVER use these patterns:**
|
|
238
|
+
|
|
239
|
+
```sql
|
|
240
|
+
-- ❌ BAD: Missing SET search_path (security risk)
|
|
241
|
+
CREATE OR REPLACE FUNCTION bad_function()
|
|
242
|
+
RETURNS boolean
|
|
243
|
+
LANGUAGE plpgsql
|
|
244
|
+
STABLE
|
|
245
|
+
SECURITY DEFINER -- Missing SET search_path TO public!
|
|
246
|
+
AS $$
|
|
247
|
+
BEGIN
|
|
248
|
+
RETURN EXISTS (SELECT 1 FROM rbac_organisation_roles); -- Unqualified reference
|
|
249
|
+
END;
|
|
250
|
+
$$;
|
|
251
|
+
|
|
252
|
+
-- ❌ BAD: Unqualified table reference (security risk)
|
|
253
|
+
CREATE OR REPLACE FUNCTION bad_function()
|
|
254
|
+
RETURNS boolean
|
|
255
|
+
LANGUAGE plpgsql
|
|
256
|
+
STABLE
|
|
257
|
+
SECURITY DEFINER
|
|
258
|
+
SET search_path TO public
|
|
259
|
+
AS $$
|
|
260
|
+
BEGIN
|
|
261
|
+
RETURN EXISTS (SELECT 1 FROM rbac_organisation_roles); -- Should be public.rbac_organisation_roles
|
|
262
|
+
END;
|
|
263
|
+
$$;
|
|
264
|
+
|
|
265
|
+
-- ❌ BAD: SECURITY DEFINER without justification
|
|
266
|
+
CREATE OR REPLACE FUNCTION pure_computation(x NUMERIC)
|
|
267
|
+
RETURNS NUMERIC
|
|
268
|
+
LANGUAGE plpgsql
|
|
269
|
+
STABLE
|
|
270
|
+
SECURITY DEFINER -- Not needed! Function doesn't query RLS-protected tables
|
|
271
|
+
AS $$
|
|
272
|
+
BEGIN
|
|
273
|
+
RETURN x * 2; -- Pure computation, no table queries
|
|
274
|
+
END;
|
|
275
|
+
$$;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**✅ CORRECT patterns:**
|
|
279
|
+
|
|
280
|
+
```sql
|
|
281
|
+
-- ✅ GOOD: All security requirements met
|
|
282
|
+
CREATE OR REPLACE FUNCTION check_user_organisation_access(p_organisation_id UUID)
|
|
283
|
+
RETURNS boolean
|
|
284
|
+
LANGUAGE plpgsql
|
|
285
|
+
STABLE
|
|
286
|
+
SECURITY DEFINER -- ✅ Required: queries RLS-protected tables
|
|
287
|
+
SET search_path TO public -- ✅ MANDATORY: prevents search path hijacking
|
|
288
|
+
AS $$
|
|
289
|
+
BEGIN
|
|
290
|
+
-- ✅ Schema-qualified reference
|
|
291
|
+
RETURN EXISTS (
|
|
292
|
+
SELECT 1 FROM public.rbac_organisation_roles
|
|
293
|
+
WHERE user_id = auth.uid()
|
|
294
|
+
AND organisation_id = p_organisation_id
|
|
295
|
+
);
|
|
296
|
+
END;
|
|
297
|
+
$$;
|
|
298
|
+
|
|
299
|
+
COMMENT ON FUNCTION check_user_organisation_access(UUID) IS
|
|
300
|
+
'SECURITY DEFINER required: queries public.rbac_organisation_roles (has RLS). Without it, circular RLS dependency would occur.';
|
|
301
|
+
|
|
302
|
+
-- ✅ GOOD: No SECURITY DEFINER needed (pure computation)
|
|
303
|
+
CREATE OR REPLACE FUNCTION calculate_total(p_amount NUMERIC, p_tax_rate NUMERIC)
|
|
304
|
+
RETURNS NUMERIC
|
|
305
|
+
LANGUAGE plpgsql
|
|
306
|
+
STABLE -- ✅ STABLE for performance, but no SECURITY DEFINER needed
|
|
307
|
+
AS $$
|
|
308
|
+
BEGIN
|
|
309
|
+
RETURN p_amount * (1 + p_tax_rate); -- No table queries
|
|
310
|
+
END;
|
|
311
|
+
$$;
|
|
312
|
+
```
|
|
313
|
+
|
|
102
314
|
## Helper Selection Quick Guide
|
|
103
315
|
|
|
104
316
|
| Scenario | Helper(s) to use | Notes |
|
|
@@ -112,10 +324,11 @@ FOR SELECT USING (
|
|
|
112
324
|
|
|
113
325
|
## RLS Helper Requirements (enforced)
|
|
114
326
|
|
|
115
|
-
- Helper functions **must** be `STABLE`, `SECURITY DEFINER
|
|
327
|
+
- Helper functions **must** be `STABLE`, `SECURITY DEFINER` (when querying RLS-protected tables), and `SET search_path TO public` (MANDATORY for SECURITY DEFINER functions).
|
|
116
328
|
- **Never** inline `auth.uid()`, `auth.role()`, or `current_setting()` inside policies.
|
|
117
329
|
- Use `get_app_id()` for app UUIDs (do not hardcode UUIDs or call legacy getters).
|
|
118
330
|
- Avoid subqueries inside policies; move lookups into helpers.
|
|
331
|
+
- **Security**: All SECURITY DEFINER functions must schema-qualify table/function references and document why SECURITY DEFINER is needed.
|
|
119
332
|
|
|
120
333
|
## Standard Helper Functions
|
|
121
334
|
|
|
@@ -818,6 +1031,7 @@ export async function checkPermission(userId: string, permission: string) {
|
|
|
818
1031
|
- Use safe, user-friendly error messaging.
|
|
819
1032
|
- Prefer pace-core security helpers and secure clients (`useSecureSupabase`, RBAC helpers) over custom implementations.
|
|
820
1033
|
- Monitor RLS performance (avoid subqueries/InitPlan); keep helpers `STABLE SECURITY DEFINER` with `SET search_path TO public`.
|
|
1034
|
+
- **SECURITY DEFINER functions**: Must schema-qualify all references, use `SET search_path TO public`, and document why SECURITY DEFINER is needed.
|
|
821
1035
|
- **Edge Functions MUST use pace-core `isPermitted()` API - no exceptions allowed.**
|
|
822
1036
|
|
|
823
1037
|
### Common Pitfalls to Avoid
|
|
@@ -902,7 +1116,8 @@ Tables are assigned to specific apps for RBAC permission checking:
|
|
|
902
1116
|
- [ ] Policy coverage: All tables (except mint_*) have RLS enabled and policies
|
|
903
1117
|
- [ ] Performance: Queries complete in < 1 second
|
|
904
1118
|
- [ ] Security: Cross-organisation access is blocked
|
|
905
|
-
- [ ] Helper functions: All are STABLE SECURITY DEFINER
|
|
1119
|
+
- [ ] Helper functions: All are STABLE, SECURITY DEFINER (when needed), with `SET search_path TO public`
|
|
1120
|
+
- [ ] Security: All SECURITY DEFINER functions schema-qualify references and document rationale
|
|
906
1121
|
|
|
907
1122
|
## Maintenance
|
|
908
1123
|
|
|
@@ -322,8 +322,8 @@ CREATE OR REPLACE FUNCTION data_events_list(p_organisation_id UUID)
|
|
|
322
322
|
RETURNS TABLE (...)
|
|
323
323
|
LANGUAGE plpgsql
|
|
324
324
|
STABLE
|
|
325
|
-
SECURITY DEFINER
|
|
326
|
-
SET search_path TO public
|
|
325
|
+
SECURITY DEFINER -- ✅ Required: queries RLS-protected tables or needs elevated privileges
|
|
326
|
+
SET search_path TO public -- ✅ MANDATORY: prevents search path hijacking
|
|
327
327
|
AS $$
|
|
328
328
|
BEGIN
|
|
329
329
|
-- Check organisation access
|
|
@@ -331,11 +331,99 @@ BEGIN
|
|
|
331
331
|
RAISE EXCEPTION 'Access denied';
|
|
332
332
|
END IF;
|
|
333
333
|
|
|
334
|
+
-- ✅ Schema-qualified reference
|
|
334
335
|
RETURN QUERY
|
|
335
|
-
SELECT * FROM events
|
|
336
|
+
SELECT * FROM public.events
|
|
336
337
|
WHERE organisation_id = p_organisation_id;
|
|
337
338
|
END;
|
|
338
339
|
$$;
|
|
340
|
+
|
|
341
|
+
-- ✅ Document why SECURITY DEFINER is needed
|
|
342
|
+
COMMENT ON FUNCTION data_events_list(UUID) IS
|
|
343
|
+
'Lists events for an organisation. SECURITY DEFINER required because function queries RLS-protected tables via check_user_organisation_access(). STABLE for read operation performance. SET search_path TO public prevents search path hijacking.';
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### SECURITY DEFINER Security Requirements for RPC Functions
|
|
347
|
+
|
|
348
|
+
**RPC functions that use SECURITY DEFINER MUST follow these security requirements:**
|
|
349
|
+
|
|
350
|
+
| Requirement | Why | Example |
|
|
351
|
+
|------------|-----|---------|
|
|
352
|
+
| `SET search_path TO public` | **MANDATORY** - Prevents search path hijacking attacks | `SET search_path TO public` |
|
|
353
|
+
| Schema-qualify references | **MANDATORY** - Ensures objects resolve to correct schemas | `public.events` not `events` |
|
|
354
|
+
| `STABLE` for read operations | **REQUIRED** - Helps with query optimization | `STABLE` |
|
|
355
|
+
| Document rationale | **REQUIRED** - COMMENT must explain why SECURITY DEFINER is needed | See COMMENT example above |
|
|
356
|
+
| Least-privilege ownership | **RECOMMENDED** - Functions should be owned by appropriate roles | Not superuser unless necessary |
|
|
357
|
+
|
|
358
|
+
**When SECURITY DEFINER is needed for RPC functions:**
|
|
359
|
+
- Function queries RLS-protected tables (e.g., `rbac_organisation_roles`, `rbac_global_roles`)
|
|
360
|
+
- Function needs to bypass RLS to avoid circular dependencies
|
|
361
|
+
- Function performs administrative operations requiring elevated privileges
|
|
362
|
+
|
|
363
|
+
**Security Checklist for RPC Functions with SECURITY DEFINER:**
|
|
364
|
+
- [ ] `SET search_path TO public` is present (MANDATORY)
|
|
365
|
+
- [ ] All table/function references are schema-qualified (e.g., `public.table_name`)
|
|
366
|
+
- [ ] Function is marked `STABLE` for read operations
|
|
367
|
+
- [ ] Function ownership uses least-privilege role (not superuser unless necessary)
|
|
368
|
+
- [ ] COMMENT documents why SECURITY DEFINER is needed
|
|
369
|
+
|
|
370
|
+
**Example with all security requirements:**
|
|
371
|
+
|
|
372
|
+
```sql
|
|
373
|
+
-- ✅ CORRECT: All security requirements met
|
|
374
|
+
CREATE OR REPLACE FUNCTION data_events_list(p_organisation_id UUID)
|
|
375
|
+
RETURNS TABLE (id UUID, name TEXT, date TIMESTAMPTZ)
|
|
376
|
+
LANGUAGE plpgsql
|
|
377
|
+
STABLE -- ✅ Performance optimization
|
|
378
|
+
SECURITY DEFINER -- ✅ Required: queries RLS-protected tables
|
|
379
|
+
SET search_path TO public -- ✅ MANDATORY: prevents search path hijacking
|
|
380
|
+
AS $$
|
|
381
|
+
BEGIN
|
|
382
|
+
-- ✅ Schema-qualified reference
|
|
383
|
+
IF NOT public.check_user_organisation_access(p_organisation_id) THEN
|
|
384
|
+
RAISE EXCEPTION 'Access denied';
|
|
385
|
+
END IF;
|
|
386
|
+
|
|
387
|
+
-- ✅ Schema-qualified reference
|
|
388
|
+
RETURN QUERY
|
|
389
|
+
SELECT e.id, e.name, e.date
|
|
390
|
+
FROM public.events e
|
|
391
|
+
WHERE e.organisation_id = p_organisation_id;
|
|
392
|
+
END;
|
|
393
|
+
$$;
|
|
394
|
+
|
|
395
|
+
-- ✅ Document why SECURITY DEFINER is needed
|
|
396
|
+
COMMENT ON FUNCTION data_events_list(UUID) IS
|
|
397
|
+
'Lists events for an organisation. SECURITY DEFINER required because function queries public.rbac_organisation_roles (via check_user_organisation_access) which has RLS policies. Without SECURITY DEFINER, this would create circular RLS dependency. STABLE for read operation performance. SET search_path TO public prevents search path hijacking.';
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Security Anti-Patterns:**
|
|
401
|
+
|
|
402
|
+
```sql
|
|
403
|
+
-- ❌ BAD: Missing SET search_path (security risk)
|
|
404
|
+
CREATE OR REPLACE FUNCTION bad_rpc()
|
|
405
|
+
RETURNS TABLE (...)
|
|
406
|
+
LANGUAGE plpgsql
|
|
407
|
+
STABLE
|
|
408
|
+
SECURITY DEFINER -- Missing SET search_path TO public!
|
|
409
|
+
AS $$
|
|
410
|
+
BEGIN
|
|
411
|
+
RETURN QUERY SELECT * FROM events;
|
|
412
|
+
END;
|
|
413
|
+
$$;
|
|
414
|
+
|
|
415
|
+
-- ❌ BAD: Unqualified reference (security risk)
|
|
416
|
+
CREATE OR REPLACE FUNCTION bad_rpc()
|
|
417
|
+
RETURNS TABLE (...)
|
|
418
|
+
LANGUAGE plpgsql
|
|
419
|
+
STABLE
|
|
420
|
+
SECURITY DEFINER
|
|
421
|
+
SET search_path TO public
|
|
422
|
+
AS $$
|
|
423
|
+
BEGIN
|
|
424
|
+
RETURN QUERY SELECT * FROM events; -- Should be public.events
|
|
425
|
+
END;
|
|
426
|
+
$$;
|
|
339
427
|
```
|
|
340
428
|
|
|
341
429
|
**Real-World Example: Complex RPC with Multiple Security Checks**
|
package/docs/testing/README.md
CHANGED
|
@@ -10,6 +10,14 @@ This guide covers testing strategies, patterns, and best practices for applicati
|
|
|
10
10
|
|
|
11
11
|
> 📖 **For comprehensive testing standards and patterns**, see the [Testing Standard](../standards/testing-standard.md) - the authoritative guide for writing world-class tests in pace-core.
|
|
12
12
|
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
**New to testing with pace-core?** Start here:
|
|
16
|
+
|
|
17
|
+
1. **[Test Infrastructure Setup Guide](./test-infrastructure-setup.md)** - Complete guide to set up Vitest, coverage reporting, and test configuration in your consuming app. After following this guide, you'll be able to run `npm run test:coverage` and receive comprehensive coverage reports matching pace-core's setup.
|
|
18
|
+
|
|
19
|
+
2. **This guide** - Learn testing patterns, strategies, and best practices for writing tests.
|
|
20
|
+
|
|
13
21
|
## Overview
|
|
14
22
|
|
|
15
23
|
PACE Core provides comprehensive testing support with:
|
|
@@ -23,6 +31,8 @@ PACE Core provides comprehensive testing support with:
|
|
|
23
31
|
|
|
24
32
|
## Testing Setup
|
|
25
33
|
|
|
34
|
+
> 💡 **First time setting up tests?** See the [Test Infrastructure Setup Guide](./test-infrastructure-setup.md) for complete configuration instructions.
|
|
35
|
+
|
|
26
36
|
### 1. Basic Testing Configuration
|
|
27
37
|
|
|
28
38
|
```tsx
|