@jmruthers/pace-core 0.5.193 → 0.6.2

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 (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -91,7 +91,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
91
91
  });
92
92
 
93
93
  describe('PermissionGuard Component', () => {
94
- const defaultProps = {
94
+ const baseProps = {
95
95
  userId: 'user-123' as UUID,
96
96
  scope: { organisationId: 'org-123' as UUID },
97
97
  permission: 'read:users' as Permission,
@@ -106,7 +106,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
106
106
  error: null,
107
107
  });
108
108
 
109
- render(<PermissionGuard {...defaultProps} />);
109
+ render(<PermissionGuard {...baseProps} />);
110
110
 
111
111
  expect(screen.getByText('Protected Content')).toBeInTheDocument();
112
112
  });
@@ -119,7 +119,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
119
119
  });
120
120
 
121
121
  const fallback = <div>Access Denied</div>;
122
- render(<PermissionGuard {...defaultProps} fallback={fallback} />);
122
+ render(<PermissionGuard {...baseProps} fallback={fallback} />);
123
123
 
124
124
  expect(screen.getByText('Access Denied')).toBeInTheDocument();
125
125
  expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
@@ -133,7 +133,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
133
133
  });
134
134
 
135
135
  const loading = <div>Checking permissions...</div>;
136
- render(<PermissionGuard {...defaultProps} loading={loading} />);
136
+ render(<PermissionGuard {...baseProps} loading={loading} />);
137
137
 
138
138
  expect(screen.getByText('Checking permissions...')).toBeInTheDocument();
139
139
  expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
@@ -146,7 +146,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
146
146
  error: null,
147
147
  });
148
148
 
149
- render(<PermissionGuard {...defaultProps} />);
149
+ render(<PermissionGuard {...baseProps} />);
150
150
 
151
151
  expect(screen.getByRole('status')).toBeInTheDocument();
152
152
  expect(screen.getByText('Checking permissions...')).toBeInTheDocument();
@@ -160,7 +160,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
160
160
  });
161
161
 
162
162
  const fallback = <div>Error occurred</div>;
163
- render(<PermissionGuard {...defaultProps} fallback={fallback} />);
163
+ render(<PermissionGuard {...baseProps} fallback={fallback} />);
164
164
 
165
165
  expect(screen.getByText('Error occurred')).toBeInTheDocument();
166
166
  expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
@@ -180,7 +180,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
180
180
 
181
181
  render(
182
182
  <PermissionGuard
183
- {...defaultProps}
183
+ {...baseProps}
184
184
  userId={'' as any}
185
185
  fallback={<div>No Access</div>}
186
186
  />
@@ -202,13 +202,13 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
202
202
 
203
203
  render(
204
204
  <PermissionGuard
205
- {...defaultProps}
205
+ {...baseProps}
206
206
  userId={'' as any}
207
207
  fallback={<div>No Access</div>}
208
208
  />
209
209
  );
210
210
 
211
- expect(mockUseCan).toHaveBeenCalledWith('', expect.any(Object), expect.any(String), undefined);
211
+ expect(mockUseCan).toHaveBeenCalledWith('', expect.any(Object), expect.any(String), undefined, true, null, undefined);
212
212
  });
213
213
  });
214
214
 
@@ -221,7 +221,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
221
221
  error: null,
222
222
  });
223
223
 
224
- render(<PermissionGuard {...defaultProps} onDenied={onDenied} />);
224
+ render(<PermissionGuard {...baseProps} onDenied={onDenied} />);
225
225
 
226
226
  expect(onDenied).toHaveBeenCalledTimes(1);
227
227
  });
@@ -234,7 +234,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
234
234
  error: null,
235
235
  });
236
236
 
237
- render(<PermissionGuard {...defaultProps} onDenied={onDenied} />);
237
+ render(<PermissionGuard {...baseProps} onDenied={onDenied} />);
238
238
 
239
239
  expect(onDenied).not.toHaveBeenCalled();
240
240
  });
@@ -255,7 +255,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
255
255
  error: null,
256
256
  });
257
257
 
258
- render(<PermissionGuard {...defaultProps} auditLog={true} />);
258
+ render(<PermissionGuard {...baseProps} auditLog={true} />);
259
259
 
260
260
  // Note: Audit logging is currently commented out in PermissionGuard
261
261
  // The component checks auditLog but doesn't actually log - this is expected behavior
@@ -278,7 +278,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
278
278
  error: null,
279
279
  });
280
280
 
281
- render(<PermissionGuard {...defaultProps} auditLog={true} />);
281
+ render(<PermissionGuard {...baseProps} auditLog={true} />);
282
282
 
283
283
  // Note: Audit logging is currently commented out in PermissionGuard
284
284
  // The component checks auditLog but doesn't actually log - this is expected behavior
@@ -301,7 +301,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
301
301
  error: null,
302
302
  });
303
303
 
304
- render(<PermissionGuard {...defaultProps} strictMode={true} />);
304
+ render(<PermissionGuard {...baseProps} strictMode={true} />);
305
305
 
306
306
  expect(mockLoggerInstance.error).toHaveBeenCalledWith(
307
307
  expect.stringContaining('STRICT MODE VIOLATION:'),
@@ -316,7 +316,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
316
316
  });
317
317
 
318
318
  describe('AccessLevelGuard Component', () => {
319
- const defaultProps = {
319
+ const baseProps = {
320
320
  userId: 'user-123' as UUID,
321
321
  scope: { organisationId: 'org-123' as UUID },
322
322
  minLevel: 'admin' as const,
@@ -331,7 +331,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
331
331
  error: null,
332
332
  });
333
333
 
334
- render(<AccessLevelGuard {...defaultProps} />);
334
+ render(<AccessLevelGuard {...baseProps} />);
335
335
 
336
336
  expect(screen.getByText('Admin Content')).toBeInTheDocument();
337
337
  });
@@ -344,7 +344,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
344
344
  });
345
345
 
346
346
  const fallback = <div>Insufficient Access</div>;
347
- render(<AccessLevelGuard {...defaultProps} fallback={fallback} />);
347
+ render(<AccessLevelGuard {...baseProps} fallback={fallback} />);
348
348
 
349
349
  expect(screen.getByText('Insufficient Access')).toBeInTheDocument();
350
350
  expect(screen.queryByText('Admin Content')).not.toBeInTheDocument();
@@ -358,7 +358,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
358
358
  });
359
359
 
360
360
  const loading = <div>Checking access level...</div>;
361
- render(<AccessLevelGuard {...defaultProps} loading={loading} />);
361
+ render(<AccessLevelGuard {...baseProps} loading={loading} />);
362
362
 
363
363
  expect(screen.getByText('Checking access level...')).toBeInTheDocument();
364
364
  expect(screen.queryByText('Admin Content')).not.toBeInTheDocument();
@@ -372,7 +372,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
372
372
  });
373
373
 
374
374
  const fallback = <div>Error occurred</div>;
375
- render(<AccessLevelGuard {...defaultProps} fallback={fallback} />);
375
+ render(<AccessLevelGuard {...baseProps} fallback={fallback} />);
376
376
 
377
377
  expect(screen.getByText('Error occurred')).toBeInTheDocument();
378
378
  expect(screen.queryByText('Admin Content')).not.toBeInTheDocument();
@@ -387,7 +387,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
387
387
  error: null,
388
388
  });
389
389
 
390
- render(<AccessLevelGuard {...defaultProps} minLevel="admin" />);
390
+ render(<AccessLevelGuard {...baseProps} minLevel="admin" />);
391
391
 
392
392
  expect(screen.getByText('Admin Content')).toBeInTheDocument();
393
393
  });
@@ -399,7 +399,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
399
399
  error: null,
400
400
  });
401
401
 
402
- render(<AccessLevelGuard {...defaultProps} minLevel="admin" />);
402
+ render(<AccessLevelGuard {...baseProps} minLevel="admin" />);
403
403
 
404
404
  expect(screen.getByText('Admin Content')).toBeInTheDocument();
405
405
  });
@@ -411,7 +411,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
411
411
  error: null,
412
412
  });
413
413
 
414
- render(<AccessLevelGuard {...defaultProps} minLevel="admin" />);
414
+ render(<AccessLevelGuard {...baseProps} minLevel="admin" />);
415
415
 
416
416
  expect(screen.queryByText('Admin Content')).not.toBeInTheDocument();
417
417
  });
@@ -423,7 +423,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
423
423
  error: null,
424
424
  });
425
425
 
426
- render(<AccessLevelGuard {...defaultProps} minLevel="planner" />);
426
+ render(<AccessLevelGuard {...baseProps} minLevel="planner" />);
427
427
 
428
428
  expect(screen.getByText('Admin Content')).toBeInTheDocument();
429
429
  });
@@ -439,7 +439,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
439
439
 
440
440
  render(
441
441
  <AccessLevelGuard
442
- {...defaultProps}
442
+ {...baseProps}
443
443
  userId={'' as any}
444
444
  minLevel="admin"
445
445
  fallback={<div>No Access</div>}
@@ -462,7 +462,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
462
462
 
463
463
  render(
464
464
  <AccessLevelGuard
465
- {...defaultProps}
465
+ {...baseProps}
466
466
  userId={'' as any}
467
467
  minLevel="admin"
468
468
  fallback={<div>No Access</div>}
@@ -499,7 +499,7 @@ describe('RBAC Adapters - Comprehensive Tests', () => {
499
499
  scope: { organisationId: 'org-123', eventId: 'event-123', appId: 'app-123' },
500
500
  permission: 'read:users',
501
501
  pageId: undefined,
502
- });
502
+ }, null, undefined, null);
503
503
  expect(handler).toHaveBeenCalledWith(req);
504
504
  expect(result).toEqual({ success: true });
505
505
  });
@@ -85,7 +85,7 @@ vi.mock('../hooks/useRBAC', () => ({
85
85
  }));
86
86
  import { useRBAC } from '../hooks/useRBAC';
87
87
  import { useOrganisationSecurity } from '../../hooks/useOrganisationSecurity';
88
- import { useSecureDataAccess } from '../../hooks/useSecureDataAccess';
88
+ // useSecureDataAccess has been removed - use useSecureSupabase from @jmruthers/pace-core/rbac instead
89
89
  import { usePermissions } from '../hooks';
90
90
  import { useCan, useAccessLevel, useHasAnyPermission, useHasAllPermissions } from '../hooks';
91
91
  import { useCachedPermissions } from '../hooks';
@@ -104,9 +104,7 @@ vi.mock('../hooks', () => ({
104
104
  useHasAllPermissions: () => ({ hasAllPermissions: () => true, isLoading: false, error: null }),
105
105
  useCachedPermissions: () => ({ cachedPermissions: [], isLoading: false, error: null }),
106
106
  }));
107
- vi.mock('../../hooks/useSecureDataAccess', () => ({
108
- useSecureDataAccess: () => ({ secureDataAccess: { secureQuery: vi.fn().mockResolvedValue([]) } })
109
- }));
107
+ // useSecureDataAccess has been removed - no longer needed
110
108
  vi.mock('../../hooks/usePermissionCache', () => ({
111
109
  usePermissionCache: () => ({
112
110
  permissionCache: new Map([
@@ -197,7 +195,8 @@ const TestComponent = () => {
197
195
  const { cachedPermissions } = useCachedPermissions();
198
196
  const { permissionCache } = usePermissionCache();
199
197
  const { organisationPermissions } = useOrganisationPermissions();
200
- const { secureDataAccess: secureData } = useSecureDataAccess();
198
+ // useSecureDataAccess has been removed - use useSecureSupabase from @jmruthers/pace-core/rbac instead
199
+ const secureData = { secureQuery: vi.fn().mockResolvedValue([]) };
201
200
 
202
201
  if (isLoading) return <div>Loading...</div>;
203
202
  if (!isAuthenticated) return <div>Not authenticated</div>;
@@ -90,7 +90,16 @@ export function PermissionGuard({
90
90
  const effectiveUserId = userId ?? authContext?.user?.id ?? null;
91
91
 
92
92
  // Always call useCan hook, but handle the case where userId might be undefined
93
- const { can, isLoading, error } = useCan(effectiveUserId || '', scope, permission, pageId);
93
+ // Pass null for super admin status (not checked yet - hook will check if needed)
94
+ const { can, isLoading, error } = useCan(
95
+ effectiveUserId || '',
96
+ scope,
97
+ permission,
98
+ pageId,
99
+ true, // useCache
100
+ null, // precomputedSuperAdmin - not checked yet
101
+ undefined // appName
102
+ );
94
103
 
95
104
  // If still no userId, show helpful error
96
105
  if (!effectiveUserId) {
@@ -294,7 +303,7 @@ export function withPermissionGuard<T extends any[]>(
294
303
  scope: { organisationId, eventId, appId },
295
304
  permission: config.permission,
296
305
  pageId: config.pageId,
297
- });
306
+ }, null, undefined, null);
298
307
 
299
308
  if (!hasPermission) {
300
309
  throw new Error(`Permission denied: ${config.permission}`);
@@ -516,7 +525,7 @@ export function createRBACMiddleware(config: {
516
525
  pageId?: UUID;
517
526
  }>;
518
527
  fallbackUrl?: string;
519
- }) {
528
+ }): (req: { nextUrl: { pathname: string }; user?: { id: string }; organisationId?: string }, res: { redirect: (url: string) => void }, next: () => void) => Promise<void> {
520
529
  return async (req: { nextUrl: { pathname: string }; user?: { id: string }; organisationId?: string }, res: { redirect: (url: string) => void }, next: () => void) => {
521
530
  const { pathname } = req.nextUrl;
522
531
  const userId = req.user?.id;
@@ -539,7 +548,7 @@ export function createRBACMiddleware(config: {
539
548
  scope: { organisationId },
540
549
  permission: protectedRoute.permission,
541
550
  pageId: protectedRoute.pageId,
542
- });
551
+ }, null, undefined, null);
543
552
 
544
553
  if (!hasPermission) {
545
554
  return res.redirect(config.fallbackUrl || '/access-denied');
@@ -579,7 +588,7 @@ export function createRBACMiddleware(config: {
579
588
  export function createRBACExpressMiddleware(config: {
580
589
  permission: Permission;
581
590
  pageId?: UUID;
582
- }) {
591
+ }): (req: { user?: { id: string }; organisationId?: string; eventId?: string; appId?: string }, res: { status: (code: number) => { json: (data: object) => void } }, next: () => void) => Promise<void> {
583
592
  return async (req: { user?: { id: string }; organisationId?: string; eventId?: string; appId?: string }, res: { status: (code: number) => { json: (data: object) => void } }, next: () => void) => {
584
593
  const userId = req.user?.id;
585
594
  const organisationId = req.organisationId;
package/src/rbac/api.ts CHANGED
@@ -129,39 +129,44 @@ export async function getAccessLevel(
129
129
  appConfig?: AppConfig | null,
130
130
  appName?: string
131
131
  ): Promise<AccessLevel> {
132
- const engine = getEngine();
133
-
134
- // Check super admin status first - super admins bypass context requirements
135
- const isSuperAdminUser = await engine['checkSuperAdmin'](input.userId);
136
- if (isSuperAdminUser) {
137
- return 'super';
138
- }
139
-
140
- // Fetch app config if not provided
141
- let resolvedAppConfig: AppConfig | null = appConfig ?? null;
142
- let resolvedAppName = appName;
143
-
144
- if (!resolvedAppConfig && input.scope.appId) {
145
- resolvedAppConfig = await getAppConfig(input.scope.appId);
146
- }
147
-
148
- // Validate context using ContextValidator
149
- const validation = await ContextValidator.resolveRequiredContext(
150
- input.scope,
151
- resolvedAppConfig,
152
- resolvedAppName,
153
- engine['supabase']
154
- );
155
-
156
- if (!validation.isValid || !validation.resolvedScope) {
157
- throw validation.error || new OrganisationContextRequiredError();
132
+ try {
133
+ const engine = getEngine();
134
+
135
+ // Check super admin status first - super admins bypass context requirements
136
+ const isSuperAdminUser = await engine['checkSuperAdmin'](input.userId);
137
+ if (isSuperAdminUser) {
138
+ return 'super';
139
+ }
140
+
141
+ // Fetch app config if not provided
142
+ let resolvedAppConfig: AppConfig | null = appConfig ?? null;
143
+ let resolvedAppName = appName;
144
+
145
+ if (!resolvedAppConfig && input.scope.appId) {
146
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
147
+ }
148
+
149
+ // Validate context using ContextValidator
150
+ const validation = await ContextValidator.resolveRequiredContext(
151
+ input.scope,
152
+ resolvedAppConfig,
153
+ resolvedAppName,
154
+ engine['supabase']
155
+ );
156
+
157
+ if (!validation.isValid || !validation.resolvedScope) {
158
+ throw validation.error || new OrganisationContextRequiredError();
159
+ }
160
+
161
+ // Use resolved scope
162
+ return engine.getAccessLevel({
163
+ ...input,
164
+ scope: validation.resolvedScope
165
+ });
166
+ } catch (error) {
167
+ // Re-throw the error - this is an API function that should propagate errors
168
+ throw error;
158
169
  }
159
-
160
- // Use resolved scope
161
- return engine.getAccessLevel({
162
- ...input,
163
- scope: validation.resolvedScope
164
- });
165
170
  }
166
171
 
167
172
  /**
@@ -192,41 +197,51 @@ export async function getPermissionMap(
192
197
  appConfig?: AppConfig | null,
193
198
  appName?: string
194
199
  ): Promise<PermissionMap> {
195
- const engine = getEngine();
196
-
197
- // Fetch app config if not provided
198
- let resolvedAppConfig: AppConfig | null = appConfig ?? null;
199
- let resolvedAppName = appName;
200
-
201
- if (!resolvedAppConfig && input.scope.appId) {
202
- resolvedAppConfig = await getAppConfig(input.scope.appId);
203
- }
204
-
205
- // Validate context using ContextValidator
206
- const validation = await ContextValidator.resolveRequiredContext(
207
- input.scope,
208
- resolvedAppConfig,
209
- resolvedAppName,
210
- engine['supabase']
211
- );
212
-
213
- if (!validation.isValid || !validation.resolvedScope) {
214
- throw validation.error || new OrganisationContextRequiredError();
200
+ try {
201
+ const engine = getEngine();
202
+
203
+ // Fetch app config if not provided
204
+ let resolvedAppConfig: AppConfig | null = appConfig ?? null;
205
+ let resolvedAppName = appName;
206
+
207
+ if (!resolvedAppConfig && input.scope.appId) {
208
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
209
+ }
210
+
211
+ // Validate context using ContextValidator
212
+ const validation = await ContextValidator.resolveRequiredContext(
213
+ input.scope,
214
+ resolvedAppConfig,
215
+ resolvedAppName,
216
+ engine['supabase']
217
+ );
218
+
219
+ if (!validation.isValid || !validation.resolvedScope) {
220
+ throw validation.error || new OrganisationContextRequiredError();
221
+ }
222
+
223
+ // Use resolved scope
224
+ return engine.getPermissionMap({
225
+ ...input,
226
+ scope: validation.resolvedScope
227
+ });
228
+ } catch (error) {
229
+ // Re-throw the error - this is an API function that should propagate errors
230
+ throw error;
215
231
  }
216
-
217
- // Use resolved scope
218
- return engine.getPermissionMap({
219
- ...input,
220
- scope: validation.resolvedScope
221
- });
222
232
  }
223
233
 
224
234
  export async function resolveAppContext(input: {
225
235
  userId: UUID;
226
236
  appName: string;
227
237
  }): Promise<RBACAppContext | null> {
228
- const engine = getEngine();
229
- return engine.resolveAppContext(input);
238
+ try {
239
+ const engine = getEngine();
240
+ return await engine.resolveAppContext(input);
241
+ } catch (error) {
242
+ // Re-throw the error - this is an API function that should propagate errors
243
+ throw error;
244
+ }
230
245
  }
231
246
 
232
247
  export async function getRoleContext(
@@ -287,17 +302,33 @@ export async function getRoleContext(
287
302
  export async function isPermitted(
288
303
  input: PermissionCheck,
289
304
  appConfig?: AppConfig | null,
290
- appName?: string
305
+ appName?: string,
306
+ /**
307
+ * Pre-computed super admin status to avoid duplicate checks.
308
+ * Pass null if not checked yet (will check), true if already checked and is super admin,
309
+ * or false if already checked and is not super admin.
310
+ * @default null
311
+ */
312
+ precomputedSuperAdmin: boolean | null = null
291
313
  ): Promise<boolean> {
292
314
  const engine = getEngine();
293
315
 
294
316
  // Check super admin status first - super admins bypass context requirements
295
317
  // Super admins have access to all permissions regardless of organisation context
296
- const isSuperAdminUser = await engine['checkSuperAdmin'](input.userId);
297
- if (isSuperAdminUser) {
318
+ // PERFORMANCE: Use precomputed value if provided to avoid duplicate checks
319
+ if (precomputedSuperAdmin === true) {
298
320
  return true;
299
321
  }
300
322
 
323
+ // If null, check super admin status
324
+ if (precomputedSuperAdmin === null) {
325
+ const isSuperAdminUser = await engine['checkSuperAdmin'](input.userId);
326
+ if (isSuperAdminUser) {
327
+ return true;
328
+ }
329
+ }
330
+ // If precomputedSuperAdmin === false, skip check and proceed with permission check
331
+
301
332
  // Fetch app config if not provided and we have appId
302
333
  let resolvedAppConfig: AppConfig | null = appConfig ?? null;
303
334
  let resolvedAppName = appName;
@@ -391,7 +422,9 @@ export async function isPermittedCached(
391
422
  // Use request deduplication - if same request is in-flight, share the promise
392
423
  return getOrCreateRequest(input, async (checkInput) => {
393
424
  // Check permission with context validation
394
- const result = await isPermitted(checkInput, appConfig, appName);
425
+ // Note: We can't pass precomputedSuperAdmin here because getOrCreateRequest doesn't support it
426
+ // The super admin check in isPermitted will be cached, so it's not a huge performance hit
427
+ const result = await isPermitted(checkInput, appConfig, appName, null);
395
428
 
396
429
  // Determine if this is a page-level check (has pageId or permission contains 'page.')
397
430
  const isPageLevelCheck = !!pageId || permission.includes('page.');
@@ -410,7 +443,7 @@ export async function isPermittedCached(
410
443
  * @returns Promise<boolean> - True if user has permission
411
444
  */
412
445
  export async function hasPermission(input: PermissionCheck): Promise<boolean> {
413
- return isPermitted(input);
446
+ return isPermitted(input, null, undefined, null);
414
447
  }
415
448
 
416
449
  /**
@@ -431,7 +464,7 @@ export async function hasAnyPermission(input: {
431
464
  const hasPermission = await isPermitted({
432
465
  ...baseInput,
433
466
  permission,
434
- });
467
+ }, null, undefined, null);
435
468
 
436
469
  if (hasPermission) {
437
470
  return true;
@@ -459,7 +492,7 @@ export async function hasAllPermissions(input: {
459
492
  const hasPermission = await isPermitted({
460
493
  ...baseInput,
461
494
  permission,
462
- });
495
+ }, null, undefined, null);
463
496
 
464
497
  if (!hasPermission) {
465
498
  return false;
@@ -49,7 +49,7 @@
49
49
  * - Efficient filtering
50
50
  *
51
51
  * @dependencies
52
- * - React 18+ - Component framework
52
+ * - React 19+ - Component framework
53
53
  * - NavigationProvider - Navigation permission context
54
54
  * - NavigationGuard - Individual navigation item protection
55
55
  * - RBAC types - Type definitions
@@ -58,7 +58,7 @@
58
58
  * - Efficient error handling
59
59
  *
60
60
  * @dependencies
61
- * - React 18+ - Component framework
61
+ * - React 19+ - Component framework
62
62
  * - useCan hook - Permission checking
63
63
  * - useUnifiedAuth - Authentication context
64
64
  * - RBAC types - Type definitions
@@ -49,7 +49,7 @@
49
49
  * - Cached permission checks
50
50
  *
51
51
  * @dependencies
52
- * - React 18+ - Context and hooks
52
+ * - React 19+ - Context and hooks
53
53
  * - useUnifiedAuth - Authentication context
54
54
  * - RBAC types - Type definitions
55
55
  */
@@ -211,12 +211,15 @@ export function NavigationProvider({
211
211
  const permission = item.permissions[0];
212
212
 
213
213
  // Call useCan hook for actual permission checking
214
+ // Pass null for super admin status (not checked yet - hook will check if needed)
214
215
  const { can, error } = useCan(
215
216
  user.id,
216
217
  currentScope,
217
218
  permission,
218
219
  item.pageId,
219
- true // useCache
220
+ true, // useCache
221
+ null, // precomputedSuperAdmin - not checked yet
222
+ undefined // appName
220
223
  );
221
224
 
222
225
  // Handle errors gracefully - allow access when there are permission check errors (graceful degradation)