@jmruthers/pace-core 0.6.1 → 0.6.3

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.
Files changed (549) hide show
  1. package/CHANGELOG.md +88 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +46 -87
  3. package/cursor-rules/01-standards-compliance.mdc +16 -47
  4. package/cursor-rules/02-project-structure.mdc +4 -4
  5. package/cursor-rules/03-solid-principles.mdc +45 -164
  6. package/cursor-rules/04-testing-standards.mdc +22 -69
  7. package/cursor-rules/05-bug-reports-and-features.mdc +2 -2
  8. package/cursor-rules/06-code-quality.mdc +42 -125
  9. package/cursor-rules/07-tech-stack-compliance.mdc +33 -128
  10. package/cursor-rules/08-markup-quality.mdc +452 -0
  11. package/cursor-rules/CHANGELOG.md +18 -0
  12. package/cursor-rules/README.md +2 -1
  13. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-Cb34EQs3.d.ts} +63 -1
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-THFPBKTP.js} +12 -10
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DEMpysFR.d.ts} +394 -171
  17. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +30 -8
  18. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
  19. package/dist/{api-N774RPUA.js → api-IAGWF3ZG.js} +10 -10
  20. package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
  21. package/dist/{chunk-JBKQ3SAO.js → chunk-2T2IG7T7.js} +107 -57
  22. package/dist/chunk-2T2IG7T7.js.map +1 -0
  23. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  24. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  25. package/dist/{chunk-3XTALGJF.js → chunk-6Z7LTB3D.js} +69 -240
  26. package/dist/chunk-6Z7LTB3D.js.map +1 -0
  27. package/dist/{chunk-4ZC4GX36.js → chunk-CNCQDFLN.js} +199 -46
  28. package/dist/chunk-CNCQDFLN.js.map +1 -0
  29. package/dist/chunk-DGUM43GV.js +11 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-DWUBLJJM.js} +361 -187
  31. package/dist/chunk-DWUBLJJM.js.map +1 -0
  32. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  33. package/dist/chunk-FFQEQTNW.js.map +1 -0
  34. package/dist/chunk-FMUCXFII.js +76 -0
  35. package/dist/chunk-FMUCXFII.js.map +1 -0
  36. package/dist/{chunk-4N5C5XZU.js → chunk-HFZBI76P.js} +4 -4
  37. package/dist/chunk-HFZBI76P.js.map +1 -0
  38. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  39. package/dist/chunk-L4OXEN46.js.map +1 -0
  40. package/dist/{chunk-R77UEZ4E.js → chunk-M43Y4SSO.js} +1 -1
  41. package/dist/chunk-M43Y4SSO.js.map +1 -0
  42. package/dist/{chunk-I7PSE6JW.js → chunk-M7MPQISP.js} +3 -76
  43. package/dist/chunk-M7MPQISP.js.map +1 -0
  44. package/dist/chunk-PQBSKX33.js +7793 -0
  45. package/dist/chunk-PQBSKX33.js.map +1 -0
  46. package/dist/chunk-QRPVRXYT.js +226 -0
  47. package/dist/chunk-QRPVRXYT.js.map +1 -0
  48. package/dist/{chunk-KNC55RTG.js → chunk-RWEBCB47.js} +194 -416
  49. package/dist/chunk-RWEBCB47.js.map +1 -0
  50. package/dist/{chunk-XM25TVIE.js → chunk-YDQHOZNA.js} +843 -388
  51. package/dist/chunk-YDQHOZNA.js.map +1 -0
  52. package/dist/{chunk-GLK6VM3F.js → chunk-ZNIWI3UC.js} +739 -737
  53. package/dist/chunk-ZNIWI3UC.js.map +1 -0
  54. package/dist/components.d.ts +5 -5
  55. package/dist/components.js +18 -16
  56. package/dist/components.js.map +1 -1
  57. package/dist/contextValidator-3JNZKUTX.js +9 -0
  58. package/dist/contextValidator-3JNZKUTX.js.map +1 -0
  59. package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
  60. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  61. package/dist/hooks.d.ts +55 -122
  62. package/dist/hooks.js +10 -13
  63. package/dist/hooks.js.map +1 -1
  64. package/dist/index.d.ts +60 -13
  65. package/dist/index.js +30 -25
  66. package/dist/index.js.map +1 -1
  67. package/dist/providers.d.ts +21 -3
  68. package/dist/providers.js +4 -3
  69. package/dist/rbac/index.d.ts +210 -139
  70. package/dist/rbac/index.js +17 -13
  71. package/dist/styles/index.js +1 -1
  72. package/dist/theming/runtime.d.ts +1 -13
  73. package/dist/theming/runtime.js +2 -2
  74. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  75. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  76. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  77. package/dist/types.d.ts +2 -2
  78. package/dist/types.js +1 -1
  79. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +38 -17
  80. package/dist/utils.d.ts +4 -5
  81. package/dist/utils.js +17 -19
  82. package/dist/utils.js.map +1 -1
  83. package/docs/api/README.md +21 -17
  84. package/docs/api/modules.md +4191 -2967
  85. package/docs/architecture/database-schema-requirements.md +161 -0
  86. package/docs/components/context-selector.md +126 -0
  87. package/docs/core-concepts/rbac-system.md +3 -3
  88. package/docs/documentation-index.md +2 -4
  89. package/docs/getting-started/cursor-rules.md +2 -1
  90. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  91. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  92. package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
  93. package/docs/migration/README.md +52 -6
  94. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  95. package/docs/migration/database-changes-december-2025.md +3 -3
  96. package/docs/pace-mint-fix-auto-selection.md +218 -0
  97. package/docs/pace-mint-rbac-setup.md +391 -0
  98. package/docs/rbac/event-based-apps.md +1 -1
  99. package/docs/rbac/getting-started.md +1 -1
  100. package/docs/rbac/quick-start.md +1 -1
  101. package/docs/rbac/secure-client-protection.md +330 -0
  102. package/docs/standards/README.md +1 -0
  103. package/package.json +4 -3
  104. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  105. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  106. package/scripts/audit/core/checks/bundle.cjs +142 -0
  107. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +784 -685
  108. package/scripts/audit/core/checks/config.cjs +54 -0
  109. package/scripts/audit/core/checks/coverage.cjs +84 -0
  110. package/scripts/audit/core/checks/dependencies.cjs +985 -0
  111. package/scripts/audit/core/checks/documentation.cjs +268 -0
  112. package/scripts/audit/core/checks/environment.cjs +116 -0
  113. package/scripts/audit/core/checks/error-handling.cjs +340 -0
  114. package/scripts/audit/core/checks/forms.cjs +172 -0
  115. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  116. package/scripts/audit/core/checks/hooks.cjs +334 -0
  117. package/scripts/audit/core/checks/imports.cjs +244 -0
  118. package/scripts/audit/core/checks/performance.cjs +325 -0
  119. package/scripts/audit/core/checks/routes.cjs +117 -0
  120. package/scripts/audit/core/checks/state.cjs +130 -0
  121. package/scripts/audit/core/checks/structure.cjs +65 -0
  122. package/scripts/audit/core/checks/style.cjs +584 -0
  123. package/scripts/audit/core/checks/testing.cjs +122 -0
  124. package/scripts/audit/core/checks/typescript.cjs +61 -0
  125. package/scripts/audit/core/scanner.cjs +199 -0
  126. package/scripts/audit/core/utils.cjs +137 -0
  127. package/scripts/audit/index.cjs +223 -0
  128. package/scripts/audit/reporters/console.cjs +151 -0
  129. package/scripts/audit/reporters/json.cjs +54 -0
  130. package/scripts/audit/reporters/markdown.cjs +124 -0
  131. package/scripts/audit-consuming-app.cjs +61 -936
  132. package/scripts/build-docs/build-decision.js +240 -0
  133. package/scripts/build-docs/cache-utils.js +105 -0
  134. package/scripts/build-docs/content-normalization.js +150 -0
  135. package/scripts/build-docs/file-utils.js +105 -0
  136. package/scripts/build-docs/git-utils.js +86 -0
  137. package/scripts/build-docs/hash-utils.js +116 -0
  138. package/scripts/build-docs/typedoc-runner.js +220 -0
  139. package/scripts/build-docs-incremental.js +77 -913
  140. package/scripts/utils/command-runner.js +16 -11
  141. package/scripts/validate-formats.js +61 -56
  142. package/scripts/validate-master.js +74 -69
  143. package/scripts/validate-pre-publish.js +70 -65
  144. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  145. package/src/components/Alert/Alert.test.tsx +12 -18
  146. package/src/components/Alert/Alert.tsx +5 -7
  147. package/src/components/Avatar/Avatar.test.tsx +4 -4
  148. package/src/components/Badge/Badge.tsx +14 -0
  149. package/src/components/Button/Button.tsx +22 -0
  150. package/src/components/Calendar/Calendar.tsx +8 -2
  151. package/src/components/Card/Card.tsx +4 -0
  152. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  153. package/src/components/Checkbox/Checkbox.tsx +2 -2
  154. package/src/components/ContextSelector/ContextSelector.tsx +384 -0
  155. package/src/components/ContextSelector/index.ts +3 -0
  156. package/src/components/DataTable/DataTable.tsx +38 -4
  157. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  158. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  159. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  160. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  161. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  162. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  163. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  164. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  165. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  166. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  167. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  168. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  169. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  170. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  171. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  172. package/src/components/DataTable/components/EditFields.tsx +307 -0
  173. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  174. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  175. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  176. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  177. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  178. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  179. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  180. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  181. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  182. package/src/components/DataTable/components/UnifiedTableBody.tsx +63 -851
  183. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  184. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  185. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  186. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  187. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  188. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  189. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  190. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  191. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  192. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  193. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  194. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  195. package/src/components/DataTable/hooks/useDataTablePermissions.ts +127 -33
  196. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  197. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  198. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  199. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  200. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  201. package/src/components/DataTable/styles.ts +6 -6
  202. package/src/components/DataTable/types.ts +6 -10
  203. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  204. package/src/components/DataTable/utils/debugTools.ts +18 -113
  205. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  206. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  207. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  208. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  209. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  210. package/src/components/Dialog/Dialog.tsx +31 -3
  211. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  212. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  213. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  214. package/src/components/ErrorBoundary/index.ts +27 -2
  215. package/src/components/FileDisplay/FileDisplay.tsx +74 -28
  216. package/src/components/FileUpload/FileUpload.tsx +22 -2
  217. package/src/components/Footer/Footer.test.tsx +16 -16
  218. package/src/components/Footer/Footer.tsx +14 -11
  219. package/src/components/Form/Form.tsx +1 -0
  220. package/src/components/Header/Header.test.tsx +43 -73
  221. package/src/components/Header/Header.tsx +59 -49
  222. package/src/components/Input/Input.test.tsx +2 -2
  223. package/src/components/Input/Input.tsx +8 -4
  224. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  225. package/src/components/LoginForm/LoginForm.tsx +4 -0
  226. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  227. package/src/components/NavigationMenu/types.ts +56 -0
  228. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  229. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
  230. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
  231. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
  232. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +13 -11
  233. package/src/components/PaceAppLayout/PaceAppLayout.tsx +167 -44
  234. package/src/components/PaceAppLayout/README.md +14 -17
  235. package/src/components/PaceAppLayout/test-setup.tsx +3 -4
  236. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  237. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  238. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  239. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  240. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  241. package/src/components/Select/Select.tsx +80 -434
  242. package/src/components/Select/context.ts +23 -0
  243. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  244. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  245. package/src/components/Select/hooks/useSelectState.ts +104 -0
  246. package/src/components/Select/index.ts +9 -1
  247. package/src/components/Select/types.ts +123 -0
  248. package/src/components/Select/utils/text.ts +26 -0
  249. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  250. package/src/components/Switch/Switch.tsx +4 -4
  251. package/src/components/Tabs/Tabs.tsx +1 -1
  252. package/src/components/Toast/Toast.tsx +4 -0
  253. package/src/components/Tooltip/Tooltip.tsx +2 -2
  254. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  255. package/src/components/UserMenu/UserMenu.tsx +21 -18
  256. package/src/components/index.ts +7 -7
  257. package/src/eslint-rules/pace-core-compliance.cjs +106 -0
  258. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  259. package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
  260. package/src/hooks/index.ts +1 -2
  261. package/src/hooks/public/usePublicEvent.ts +4 -0
  262. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  263. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  264. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  265. package/src/hooks/services/useAuth.ts +32 -0
  266. package/src/hooks/services/useCurrentEvent.ts +6 -0
  267. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  268. package/src/hooks/useAppConfig.ts +15 -30
  269. package/src/hooks/useDebounce.ts +9 -0
  270. package/src/hooks/useEventTheme.ts +6 -0
  271. package/src/hooks/useFileDisplay.ts +81 -50
  272. package/src/hooks/useFileReference.ts +25 -7
  273. package/src/hooks/useFileUrl.ts +11 -1
  274. package/src/hooks/useFocusManagement.ts +14 -0
  275. package/src/hooks/useFocusTrap.ts +3 -0
  276. package/src/hooks/useInactivityTracker.ts +3 -0
  277. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  278. package/src/hooks/useOrganisationPermissions.ts +4 -0
  279. package/src/hooks/useOrganisationSecurity.ts +4 -0
  280. package/src/hooks/usePerformanceMonitor.ts +4 -0
  281. package/src/hooks/usePermissionCache.ts +7 -0
  282. package/src/hooks/useQueryCache.ts +12 -1
  283. package/src/hooks/useSessionRestoration.ts +4 -0
  284. package/src/hooks/useStorage.ts +4 -0
  285. package/src/hooks/useToast.ts +1 -1
  286. package/src/index.ts +6 -6
  287. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  288. package/src/providers/services/AuthServiceProvider.tsx +35 -7
  289. package/src/providers/services/EventServiceProvider.tsx +51 -5
  290. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  291. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +126 -134
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  294. package/src/rbac/README.md +1 -1
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
  296. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  297. package/src/rbac/adapters.tsx +12 -3
  298. package/src/rbac/api.test.ts +59 -51
  299. package/src/rbac/api.ts +246 -167
  300. package/src/rbac/components/NavigationProvider.tsx +4 -1
  301. package/src/rbac/components/PagePermissionGuard.tsx +185 -17
  302. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  303. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  304. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  305. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  306. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  307. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  308. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  309. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  310. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  311. package/src/rbac/engine.ts +38 -14
  312. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
  313. package/src/rbac/hooks/permissions/index.ts +7 -0
  314. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  315. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  316. package/src/rbac/hooks/permissions/useCan.ts +377 -0
  317. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  318. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  319. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  320. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  321. package/src/rbac/hooks/useCan.test.ts +64 -66
  322. package/src/rbac/hooks/usePermissions.ts +14 -995
  323. package/src/rbac/hooks/useRBAC.test.ts +1 -5
  324. package/src/rbac/hooks/useRBAC.ts +36 -37
  325. package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
  326. package/src/rbac/hooks/useResolvedScope.ts +35 -40
  327. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  328. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  329. package/src/rbac/hooks/useSecureSupabase.ts +27 -7
  330. package/src/rbac/index.ts +7 -0
  331. package/src/rbac/permissions.ts +0 -30
  332. package/src/rbac/secureClient.test.ts +22 -18
  333. package/src/rbac/secureClient.ts +294 -68
  334. package/src/rbac/security.ts +0 -17
  335. package/src/rbac/types.ts +9 -0
  336. package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
  337. package/src/rbac/utils/clientSecurity.ts +93 -0
  338. package/src/rbac/utils/contextValidator.ts +77 -168
  339. package/src/services/AuthService.ts +39 -7
  340. package/src/services/EventService.ts +186 -54
  341. package/src/services/OrganisationService.ts +81 -14
  342. package/src/services/__tests__/EventService.test.ts +1 -2
  343. package/src/services/base/BaseService.ts +3 -0
  344. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  345. package/src/theming/parseEventColours.ts +5 -19
  346. package/src/types/vitest-globals.d.ts +51 -26
  347. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  348. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  349. package/src/utils/__tests__/index.unit.test.ts +2 -2
  350. package/src/utils/audit/audit.ts +0 -3
  351. package/src/utils/core/cn.ts +1 -1
  352. package/src/utils/dynamic/dynamicUtils.ts +7 -4
  353. package/src/utils/file-reference/index.ts +53 -1
  354. package/src/utils/formatting/formatting.ts +8 -18
  355. package/src/utils/index.ts +0 -1
  356. package/dist/chunk-3QRJFVBR.js.map +0 -1
  357. package/dist/chunk-3XTALGJF.js.map +0 -1
  358. package/dist/chunk-4N5C5XZU.js.map +0 -1
  359. package/dist/chunk-4ZC4GX36.js.map +0 -1
  360. package/dist/chunk-7D4SUZUM.js +0 -38
  361. package/dist/chunk-BYFSK72L.js.map +0 -1
  362. package/dist/chunk-EXUD6RNJ.js +0 -451
  363. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  364. package/dist/chunk-GLK6VM3F.js.map +0 -1
  365. package/dist/chunk-I7PSE6JW.js.map +0 -1
  366. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  367. package/dist/chunk-KNC55RTG.js.map +0 -1
  368. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  369. package/dist/chunk-R77UEZ4E.js.map +0 -1
  370. package/dist/chunk-SQGMNID3.js.map +0 -1
  371. package/dist/chunk-T33XF5ZC.js +0 -12922
  372. package/dist/chunk-T33XF5ZC.js.map +0 -1
  373. package/dist/chunk-XM25TVIE.js.map +0 -1
  374. package/docs/api/classes/ColumnFactory.md +0 -243
  375. package/docs/api/classes/ErrorBoundary.md +0 -144
  376. package/docs/api/classes/InvalidScopeError.md +0 -73
  377. package/docs/api/classes/Logger.md +0 -178
  378. package/docs/api/classes/MissingUserContextError.md +0 -66
  379. package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
  380. package/docs/api/classes/PermissionDeniedError.md +0 -73
  381. package/docs/api/classes/RBACAuditManager.md +0 -297
  382. package/docs/api/classes/RBACCache.md +0 -322
  383. package/docs/api/classes/RBACEngine.md +0 -171
  384. package/docs/api/classes/RBACError.md +0 -76
  385. package/docs/api/classes/RBACNotInitializedError.md +0 -66
  386. package/docs/api/classes/SecureSupabaseClient.md +0 -160
  387. package/docs/api/classes/StorageUtils.md +0 -328
  388. package/docs/api/enums/FileCategory.md +0 -184
  389. package/docs/api/enums/LogLevel.md +0 -54
  390. package/docs/api/enums/RBACErrorCode.md +0 -228
  391. package/docs/api/enums/RPCFunction.md +0 -118
  392. package/docs/api/interfaces/AddressFieldProps.md +0 -241
  393. package/docs/api/interfaces/AddressFieldRef.md +0 -94
  394. package/docs/api/interfaces/AggregateConfig.md +0 -43
  395. package/docs/api/interfaces/AutocompleteOptions.md +0 -75
  396. package/docs/api/interfaces/AvatarProps.md +0 -128
  397. package/docs/api/interfaces/BadgeProps.md +0 -27
  398. package/docs/api/interfaces/ButtonProps.md +0 -53
  399. package/docs/api/interfaces/CalendarProps.md +0 -70
  400. package/docs/api/interfaces/CardProps.md +0 -66
  401. package/docs/api/interfaces/ColorPalette.md +0 -7
  402. package/docs/api/interfaces/ColorShade.md +0 -66
  403. package/docs/api/interfaces/ComplianceResult.md +0 -30
  404. package/docs/api/interfaces/DataAccessRecord.md +0 -96
  405. package/docs/api/interfaces/DataRecord.md +0 -11
  406. package/docs/api/interfaces/DataTableAction.md +0 -249
  407. package/docs/api/interfaces/DataTableColumn.md +0 -504
  408. package/docs/api/interfaces/DataTableProps.md +0 -625
  409. package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
  410. package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
  411. package/docs/api/interfaces/DatabaseIssue.md +0 -41
  412. package/docs/api/interfaces/EmptyStateConfig.md +0 -61
  413. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
  414. package/docs/api/interfaces/EventAppRoleData.md +0 -71
  415. package/docs/api/interfaces/ExportColumn.md +0 -90
  416. package/docs/api/interfaces/ExportOptions.md +0 -126
  417. package/docs/api/interfaces/FileDisplayProps.md +0 -249
  418. package/docs/api/interfaces/FileMetadata.md +0 -129
  419. package/docs/api/interfaces/FileReference.md +0 -118
  420. package/docs/api/interfaces/FileSizeLimits.md +0 -7
  421. package/docs/api/interfaces/FileUploadOptions.md +0 -139
  422. package/docs/api/interfaces/FileUploadProps.md +0 -293
  423. package/docs/api/interfaces/FooterProps.md +0 -105
  424. package/docs/api/interfaces/FormFieldProps.md +0 -166
  425. package/docs/api/interfaces/FormProps.md +0 -113
  426. package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
  427. package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
  428. package/docs/api/interfaces/InputProps.md +0 -53
  429. package/docs/api/interfaces/LabelProps.md +0 -107
  430. package/docs/api/interfaces/LoggerConfig.md +0 -62
  431. package/docs/api/interfaces/LoginFormProps.md +0 -184
  432. package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
  433. package/docs/api/interfaces/NavigationContextType.md +0 -164
  434. package/docs/api/interfaces/NavigationGuardProps.md +0 -139
  435. package/docs/api/interfaces/NavigationItem.md +0 -120
  436. package/docs/api/interfaces/NavigationMenuProps.md +0 -221
  437. package/docs/api/interfaces/NavigationProviderProps.md +0 -117
  438. package/docs/api/interfaces/Organisation.md +0 -140
  439. package/docs/api/interfaces/OrganisationContextType.md +0 -388
  440. package/docs/api/interfaces/OrganisationMembership.md +0 -140
  441. package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
  442. package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
  443. package/docs/api/interfaces/PaceAppLayoutProps.md +0 -406
  444. package/docs/api/interfaces/PaceLoginPageProps.md +0 -47
  445. package/docs/api/interfaces/PageAccessRecord.md +0 -85
  446. package/docs/api/interfaces/PagePermissionContextType.md +0 -140
  447. package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
  448. package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
  449. package/docs/api/interfaces/PaletteData.md +0 -41
  450. package/docs/api/interfaces/ParsedAddress.md +0 -120
  451. package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
  452. package/docs/api/interfaces/ProgressProps.md +0 -42
  453. package/docs/api/interfaces/ProtectedRouteProps.md +0 -97
  454. package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
  455. package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
  456. package/docs/api/interfaces/PublicPageLayoutProps.md +0 -198
  457. package/docs/api/interfaces/QuickFix.md +0 -52
  458. package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
  459. package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
  460. package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
  461. package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
  462. package/docs/api/interfaces/RBACConfig.md +0 -133
  463. package/docs/api/interfaces/RBACContext.md +0 -52
  464. package/docs/api/interfaces/RBACLogger.md +0 -112
  465. package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
  466. package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
  467. package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
  468. package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
  469. package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
  470. package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
  471. package/docs/api/interfaces/RBACResult.md +0 -58
  472. package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
  473. package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
  474. package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
  475. package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
  476. package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
  477. package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
  478. package/docs/api/interfaces/RBACRolesListParams.md +0 -52
  479. package/docs/api/interfaces/RBACRolesListResult.md +0 -74
  480. package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
  481. package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
  482. package/docs/api/interfaces/ResourcePermissions.md +0 -155
  483. package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
  484. package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
  485. package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
  486. package/docs/api/interfaces/RoleManagementResult.md +0 -52
  487. package/docs/api/interfaces/RouteAccessRecord.md +0 -107
  488. package/docs/api/interfaces/RouteConfig.md +0 -134
  489. package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
  490. package/docs/api/interfaces/SecureDataContextType.md +0 -168
  491. package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
  492. package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
  493. package/docs/api/interfaces/SetupIssue.md +0 -41
  494. package/docs/api/interfaces/StorageConfig.md +0 -41
  495. package/docs/api/interfaces/StorageFileInfo.md +0 -74
  496. package/docs/api/interfaces/StorageFileMetadata.md +0 -151
  497. package/docs/api/interfaces/StorageListOptions.md +0 -99
  498. package/docs/api/interfaces/StorageListResult.md +0 -41
  499. package/docs/api/interfaces/StorageUploadOptions.md +0 -101
  500. package/docs/api/interfaces/StorageUploadResult.md +0 -63
  501. package/docs/api/interfaces/StorageUrlOptions.md +0 -60
  502. package/docs/api/interfaces/StyleImport.md +0 -19
  503. package/docs/api/interfaces/SwitchProps.md +0 -34
  504. package/docs/api/interfaces/TabsContentProps.md +0 -9
  505. package/docs/api/interfaces/TabsListProps.md +0 -9
  506. package/docs/api/interfaces/TabsProps.md +0 -9
  507. package/docs/api/interfaces/TabsTriggerProps.md +0 -50
  508. package/docs/api/interfaces/TextareaProps.md +0 -53
  509. package/docs/api/interfaces/ToastActionElement.md +0 -9
  510. package/docs/api/interfaces/ToastProps.md +0 -9
  511. package/docs/api/interfaces/UnifiedAuthContextType.md +0 -820
  512. package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -171
  513. package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
  514. package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
  515. package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -136
  516. package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
  517. package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
  518. package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
  519. package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
  520. package/docs/api/interfaces/UsePublicEventReturn.md +0 -68
  521. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
  522. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -120
  523. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -94
  524. package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
  525. package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
  526. package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
  527. package/docs/api/interfaces/UserEventAccess.md +0 -118
  528. package/docs/api/interfaces/UserMenuProps.md +0 -86
  529. package/docs/api/interfaces/UserProfile.md +0 -63
  530. package/docs/migration/quick-migration-guide.md +0 -356
  531. package/docs/migration/service-architecture.md +0 -281
  532. package/src/components/EventSelector/EventSelector.test.tsx +0 -720
  533. package/src/components/EventSelector/EventSelector.tsx +0 -420
  534. package/src/components/EventSelector/index.ts +0 -3
  535. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
  536. package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -324
  537. package/src/components/OrganisationSelector/index.ts +0 -9
  538. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  539. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  540. package/src/hooks/useSecureDataAccess.ts +0 -681
  541. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-THFPBKTP.js.map} +0 -0
  542. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
  543. /package/dist/{api-N774RPUA.js.map → api-IAGWF3ZG.js.map} +0 -0
  544. /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
  545. /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
  546. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  547. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  548. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  549. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
@@ -11,13 +11,18 @@ import { renderHook, waitFor } from '@testing-library/react';
11
11
  import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
12
12
  import { useCan } from './usePermissions';
13
13
 
14
- // Mock the RBAC API
15
- vi.mock('../api', () => ({
16
- isPermitted: vi.fn(),
17
- isPermittedCached: vi.fn()
18
- }));
14
+ // Mock the RBAC API - use async factory to support dynamic imports
15
+ vi.mock('../api', async () => {
16
+ const actual = await vi.importActual('../api');
17
+ return {
18
+ ...actual,
19
+ isPermitted: vi.fn(),
20
+ isPermittedCached: vi.fn(),
21
+ isSuperAdmin: vi.fn()
22
+ };
23
+ });
19
24
 
20
- import { isPermitted, isPermittedCached } from '../api';
25
+ import { isPermitted, isPermittedCached, isSuperAdmin } from '../api';
21
26
 
22
27
  // Mock data
23
28
  const mockUserId = 'user-123';
@@ -32,12 +37,15 @@ const mockPageId = 'dashboard';
32
37
  describe('useCan Hook', () => {
33
38
  const mockIsPermitted = vi.mocked(isPermitted);
34
39
  const mockIsPermittedCached = vi.mocked(isPermittedCached);
40
+ const mockIsSuperAdmin = vi.mocked(isSuperAdmin);
35
41
 
36
42
  beforeEach(() => {
37
43
  vi.clearAllMocks();
38
44
  // Reset mocks to return resolved promises by default
39
45
  mockIsPermitted.mockResolvedValue(true);
40
46
  mockIsPermittedCached.mockResolvedValue(true);
47
+ // Default to not super admin for most tests
48
+ mockIsSuperAdmin.mockResolvedValue(false);
41
49
  });
42
50
 
43
51
  describe('Permission Checking', () => {
@@ -45,7 +53,7 @@ describe('useCan Hook', () => {
45
53
  mockIsPermitted.mockResolvedValue(true);
46
54
 
47
55
  const { result } = renderHook(() =>
48
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
56
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
49
57
  );
50
58
 
51
59
  expect(result.current.isLoading).toBe(true);
@@ -62,7 +70,7 @@ describe('useCan Hook', () => {
62
70
  mockIsPermitted.mockResolvedValue(false);
63
71
 
64
72
  const { result } = renderHook(() =>
65
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
73
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
66
74
  );
67
75
 
68
76
  await waitFor(() => {
@@ -76,7 +84,7 @@ describe('useCan Hook', () => {
76
84
  mockIsPermitted.mockImplementation(() => new Promise(() => {})); // Never resolves
77
85
 
78
86
  const { result } = renderHook(() =>
79
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
87
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
80
88
  );
81
89
 
82
90
  expect(result.current.isLoading).toBe(true);
@@ -89,7 +97,7 @@ describe('useCan Hook', () => {
89
97
  mockIsPermitted.mockRejectedValue(error);
90
98
 
91
99
  const { result } = renderHook(() =>
92
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
100
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
93
101
  );
94
102
 
95
103
  await waitFor(() => {
@@ -105,7 +113,7 @@ describe('useCan Hook', () => {
105
113
  mockIsPermittedCached.mockResolvedValue(true);
106
114
 
107
115
  const { result } = renderHook(() =>
108
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
116
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
109
117
  );
110
118
 
111
119
  await waitFor(() => {
@@ -118,7 +126,6 @@ describe('useCan Hook', () => {
118
126
  permission: mockPermission,
119
127
  pageId: mockPageId
120
128
  },
121
- undefined,
122
129
  undefined
123
130
  );
124
131
  expect(mockIsPermitted).not.toHaveBeenCalled();
@@ -129,7 +136,7 @@ describe('useCan Hook', () => {
129
136
  mockIsPermitted.mockResolvedValue(true);
130
137
 
131
138
  const { result } = renderHook(() =>
132
- useCan(mockUserId, mockScope, mockPermission, mockPageId, false)
139
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, false, false)
133
140
  );
134
141
 
135
142
  await waitFor(() => {
@@ -143,7 +150,7 @@ describe('useCan Hook', () => {
143
150
  pageId: mockPageId
144
151
  },
145
152
  undefined,
146
- undefined
153
+ false
147
154
  );
148
155
  expect(mockIsPermittedCached).not.toHaveBeenCalled();
149
156
  });
@@ -153,7 +160,7 @@ describe('useCan Hook', () => {
153
160
  mockIsPermitted.mockResolvedValue(true);
154
161
 
155
162
  const { result } = renderHook(() =>
156
- useCan(mockUserId, mockScope, mockPermission, mockPageId, false)
163
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, false, false)
157
164
  );
158
165
 
159
166
  await waitFor(() => {
@@ -169,7 +176,7 @@ describe('useCan Hook', () => {
169
176
  mockIsPermitted.mockResolvedValue(true);
170
177
 
171
178
  const { result } = renderHook(() =>
172
- useCan(mockUserId, mockScope, mockPermission, 'custom-page', false)
179
+ useCan(mockUserId, mockScope, mockPermission, 'custom-page', false, false)
173
180
  );
174
181
 
175
182
  await waitFor(() => {
@@ -182,7 +189,7 @@ describe('useCan Hook', () => {
182
189
  pageId: 'custom-page'
183
190
  },
184
191
  undefined,
185
- undefined
192
+ false
186
193
  );
187
194
  });
188
195
  });
@@ -191,7 +198,7 @@ describe('useCan Hook', () => {
191
198
  mockIsPermitted.mockResolvedValue(true);
192
199
 
193
200
  const { result } = renderHook(() =>
194
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
201
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
195
202
  );
196
203
 
197
204
  await waitFor(() => {
@@ -204,7 +211,7 @@ describe('useCan Hook', () => {
204
211
  pageId: undefined
205
212
  },
206
213
  undefined,
207
- undefined
214
+ false
208
215
  );
209
216
  });
210
217
  });
@@ -215,7 +222,7 @@ describe('useCan Hook', () => {
215
222
  mockIsPermitted.mockResolvedValue(true);
216
223
 
217
224
  const { result, rerender } = renderHook(
218
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
225
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
219
226
  {
220
227
  initialProps: {
221
228
  userId: mockUserId,
@@ -246,7 +253,7 @@ describe('useCan Hook', () => {
246
253
  pageId: undefined
247
254
  },
248
255
  undefined,
249
- undefined
256
+ false
250
257
  );
251
258
  });
252
259
  });
@@ -255,7 +262,7 @@ describe('useCan Hook', () => {
255
262
  mockIsPermitted.mockResolvedValue(true);
256
263
 
257
264
  const { result, rerender } = renderHook(
258
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
265
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
259
266
  {
260
267
  initialProps: {
261
268
  userId: mockUserId,
@@ -287,7 +294,7 @@ describe('useCan Hook', () => {
287
294
  pageId: undefined
288
295
  },
289
296
  undefined,
290
- undefined
297
+ false
291
298
  );
292
299
  });
293
300
  });
@@ -296,7 +303,7 @@ describe('useCan Hook', () => {
296
303
  mockIsPermitted.mockResolvedValue(true);
297
304
 
298
305
  const { result, rerender } = renderHook(
299
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
306
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
300
307
  {
301
308
  initialProps: {
302
309
  userId: mockUserId,
@@ -327,7 +334,7 @@ describe('useCan Hook', () => {
327
334
  pageId: undefined
328
335
  },
329
336
  undefined,
330
- undefined
337
+ false
331
338
  );
332
339
  });
333
340
  });
@@ -338,7 +345,7 @@ describe('useCan Hook', () => {
338
345
  mockIsPermitted.mockRejectedValue('String error');
339
346
 
340
347
  const { result } = renderHook(() =>
341
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
348
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
342
349
  );
343
350
 
344
351
  await waitFor(() => {
@@ -353,7 +360,7 @@ describe('useCan Hook', () => {
353
360
  .mockResolvedValueOnce(true);
354
361
 
355
362
  const { result, rerender } = renderHook(
356
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
363
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
357
364
  {
358
365
  initialProps: {
359
366
  userId: mockUserId,
@@ -383,10 +390,10 @@ describe('useCan Hook', () => {
383
390
 
384
391
  describe('Role-Based Permission Scenarios', () => {
385
392
  it('allows super admin permissions', async () => {
386
- mockIsPermitted.mockResolvedValue(true);
387
-
393
+ // When precomputedSuperAdmin is true, the hook bypasses permission checks
394
+ // Super admins get immediate access without calling isPermitted
388
395
  const { result } = renderHook(() =>
389
- useCan(mockUserId, mockScope, 'update:organisations', undefined, false)
396
+ useCan(mockUserId, mockScope, 'update:organisations', undefined, false, true)
390
397
  );
391
398
 
392
399
  await waitFor(() => {
@@ -395,23 +402,15 @@ describe('useCan Hook', () => {
395
402
  expect(result.current.error).toBeNull();
396
403
  });
397
404
 
398
- expect(mockIsPermitted).toHaveBeenCalledWith(
399
- {
400
- userId: mockUserId,
401
- scope: mockScope,
402
- permission: 'update:organisations',
403
- pageId: undefined
404
- },
405
- undefined,
406
- undefined
407
- );
405
+ // Super admins bypass permission checks - isPermitted should not be called
406
+ expect(mockIsPermitted).not.toHaveBeenCalled();
408
407
  });
409
408
 
410
409
  it('denies super admin permissions for regular users', async () => {
411
410
  mockIsPermitted.mockResolvedValue(false);
412
411
 
413
412
  const { result } = renderHook(() =>
414
- useCan(mockUserId, mockScope, 'super_admin', undefined, false)
413
+ useCan(mockUserId, mockScope, 'super_admin', undefined, false, false)
415
414
  );
416
415
 
417
416
  await waitFor(() => {
@@ -425,7 +424,7 @@ describe('useCan Hook', () => {
425
424
  mockIsPermitted.mockResolvedValue(true);
426
425
 
427
426
  const { result } = renderHook(() =>
428
- useCan(mockUserId, mockScope, 'org_admin', undefined, false)
427
+ useCan(mockUserId, mockScope, 'org_admin', undefined, false, false)
429
428
  );
430
429
 
431
430
  await waitFor(() => {
@@ -439,7 +438,7 @@ describe('useCan Hook', () => {
439
438
  mockIsPermitted.mockResolvedValue(false);
440
439
 
441
440
  const { result } = renderHook(() =>
442
- useCan(mockUserId, mockScope, 'org_admin', undefined, false)
441
+ useCan(mockUserId, mockScope, 'org_admin', undefined, false, false)
443
442
  );
444
443
 
445
444
  await waitFor(() => {
@@ -453,7 +452,7 @@ describe('useCan Hook', () => {
453
452
  mockIsPermitted.mockResolvedValue(true);
454
453
 
455
454
  const { result } = renderHook(() =>
456
- useCan(mockUserId, mockScope, 'event_admin', undefined, false)
455
+ useCan(mockUserId, mockScope, 'event_admin', undefined, false, false)
457
456
  );
458
457
 
459
458
  await waitFor(() => {
@@ -467,7 +466,7 @@ describe('useCan Hook', () => {
467
466
  mockIsPermitted.mockResolvedValue(false);
468
467
 
469
468
  const { result } = renderHook(() =>
470
- useCan(mockUserId, mockScope, 'event_admin', undefined, false)
469
+ useCan(mockUserId, mockScope, 'event_admin', undefined, false, false)
471
470
  );
472
471
 
473
472
  await waitFor(() => {
@@ -481,7 +480,7 @@ describe('useCan Hook', () => {
481
480
  mockIsPermitted.mockResolvedValue(true);
482
481
 
483
482
  const { result } = renderHook(() =>
484
- useCan(mockUserId, mockScope, 'read:users', undefined, false)
483
+ useCan(mockUserId, mockScope, 'read:users', undefined, false, false)
485
484
  );
486
485
 
487
486
  await waitFor(() => {
@@ -495,7 +494,7 @@ describe('useCan Hook', () => {
495
494
  mockIsPermitted.mockResolvedValue(false);
496
495
 
497
496
  const { result } = renderHook(() =>
498
- useCan(mockUserId, mockScope, 'read:users', undefined, false)
497
+ useCan(mockUserId, mockScope, 'read:users', undefined, false, false)
499
498
  );
500
499
 
501
500
  await waitFor(() => {
@@ -509,7 +508,7 @@ describe('useCan Hook', () => {
509
508
  mockIsPermitted.mockResolvedValue(true);
510
509
 
511
510
  const { result } = renderHook(() =>
512
- useCan(mockUserId, mockScope, 'participant', undefined, false)
511
+ useCan(mockUserId, mockScope, 'participant', undefined, false, false)
513
512
  );
514
513
 
515
514
  await waitFor(() => {
@@ -526,7 +525,7 @@ describe('useCan Hook', () => {
526
525
  mockIsPermittedCached.mockResolvedValue(true);
527
526
 
528
527
  const { result } = renderHook(() =>
529
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
528
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
530
529
  );
531
530
 
532
531
  await waitFor(() => {
@@ -542,7 +541,6 @@ describe('useCan Hook', () => {
542
541
  permission: mockPermission,
543
542
  pageId: mockPageId
544
543
  },
545
- undefined,
546
544
  undefined
547
545
  );
548
546
  });
@@ -552,7 +550,7 @@ describe('useCan Hook', () => {
552
550
  mockIsPermittedCached.mockResolvedValue(false);
553
551
 
554
552
  const { result } = renderHook(() =>
555
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
553
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
556
554
  );
557
555
 
558
556
  await waitFor(() => {
@@ -569,7 +567,7 @@ describe('useCan Hook', () => {
569
567
  );
570
568
 
571
569
  const { result } = renderHook(() =>
572
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
570
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
573
571
  );
574
572
 
575
573
  // Should show loading initially
@@ -587,7 +585,7 @@ describe('useCan Hook', () => {
587
585
  mockIsPermitted.mockRejectedValue(networkError);
588
586
 
589
587
  const { result } = renderHook(() =>
590
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
588
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
591
589
  );
592
590
 
593
591
  await waitFor(() => {
@@ -603,7 +601,7 @@ describe('useCan Hook', () => {
603
601
  mockIsPermitted.mockResolvedValue(false);
604
602
 
605
603
  const { result } = renderHook(() =>
606
- useCan('', mockScope, mockPermission, undefined, false)
604
+ useCan('', mockScope, mockPermission, undefined, false, false)
607
605
  );
608
606
 
609
607
  await waitFor(() => {
@@ -617,7 +615,7 @@ describe('useCan Hook', () => {
617
615
  mockIsPermitted.mockResolvedValue(false);
618
616
 
619
617
  const { result } = renderHook(() =>
620
- useCan(mockUserId, mockScope, '', undefined, false)
618
+ useCan(mockUserId, mockScope, '', undefined, false, false)
621
619
  );
622
620
 
623
621
  await waitFor(() => {
@@ -631,14 +629,14 @@ describe('useCan Hook', () => {
631
629
  pageId: undefined
632
630
  },
633
631
  undefined,
634
- undefined
632
+ false
635
633
  );
636
634
  });
637
635
  });
638
636
 
639
637
  it('handles empty scope', async () => {
640
638
  const { result } = renderHook(() =>
641
- useCan(mockUserId, {} as any, mockPermission, undefined, false)
639
+ useCan(mockUserId, {} as any, mockPermission, undefined, false, false)
642
640
  );
643
641
 
644
642
  await waitFor(() => {
@@ -654,7 +652,7 @@ describe('useCan Hook', () => {
654
652
 
655
653
  const emptyScope = {} as any;
656
654
  const { result } = renderHook(() =>
657
- useCan(mockUserId, emptyScope, mockPermission, undefined, false)
655
+ useCan(mockUserId, emptyScope, mockPermission, undefined, false, false)
658
656
  );
659
657
 
660
658
  // Initially loading
@@ -678,7 +676,7 @@ describe('useCan Hook', () => {
678
676
 
679
677
  it('handles null userId', async () => {
680
678
  const { result } = renderHook(() =>
681
- useCan(null as any, mockScope, mockPermission, undefined, false)
679
+ useCan(null as any, mockScope, mockPermission, undefined, false, false)
682
680
  );
683
681
 
684
682
  await waitFor(() => {
@@ -690,7 +688,7 @@ describe('useCan Hook', () => {
690
688
 
691
689
  it('handles undefined userId', async () => {
692
690
  const { result } = renderHook(() =>
693
- useCan(undefined as any, mockScope, mockPermission, undefined, false)
691
+ useCan(undefined as any, mockScope, mockPermission, undefined, false, false)
694
692
  );
695
693
 
696
694
  await waitFor(() => {
@@ -704,7 +702,7 @@ describe('useCan Hook', () => {
704
702
  const invalidScope = { organisationId: '', eventId: 'event-123' };
705
703
 
706
704
  const { result } = renderHook(() =>
707
- useCan(mockUserId, invalidScope, mockPermission, undefined, false)
705
+ useCan(mockUserId, invalidScope, mockPermission, undefined, false, false)
708
706
  );
709
707
 
710
708
  await waitFor(() => {
@@ -718,7 +716,7 @@ describe('useCan Hook', () => {
718
716
  const invalidScope = { organisationId: ' ', eventId: 'event-123' };
719
717
 
720
718
  const { result } = renderHook(() =>
721
- useCan(mockUserId, invalidScope, mockPermission, undefined, false)
719
+ useCan(mockUserId, invalidScope, mockPermission, undefined, false, false)
722
720
  );
723
721
 
724
722
  await waitFor(() => {
@@ -730,7 +728,7 @@ describe('useCan Hook', () => {
730
728
 
731
729
  it('handles undefined scope gracefully', async () => {
732
730
  const { result } = renderHook(() =>
733
- useCan(mockUserId, undefined as any, mockPermission, undefined, false)
731
+ useCan(mockUserId, undefined as any, mockPermission, undefined, false, false)
734
732
  );
735
733
 
736
734
  await waitFor(() => {
@@ -742,7 +740,7 @@ describe('useCan Hook', () => {
742
740
 
743
741
  it('handles null scope gracefully', async () => {
744
742
  const { result } = renderHook(() =>
745
- useCan(mockUserId, null as any, mockPermission, undefined, false)
743
+ useCan(mockUserId, null as any, mockPermission, undefined, false, false)
746
744
  );
747
745
 
748
746
  await waitFor(() => {
@@ -758,7 +756,7 @@ describe('useCan Hook', () => {
758
756
  mockIsPermitted.mockResolvedValue(true);
759
757
 
760
758
  const { result, rerender } = renderHook(() =>
761
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
759
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
762
760
  );
763
761
 
764
762
  await waitFor(() => {
@@ -778,7 +776,7 @@ describe('useCan Hook', () => {
778
776
  mockIsPermitted.mockResolvedValue(true);
779
777
 
780
778
  const { result, rerender } = renderHook(
781
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
779
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
782
780
  {
783
781
  initialProps: {
784
782
  userId: mockUserId,