@jmruthers/pace-core 0.6.10 → 0.6.11

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 (726) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/audit-tool/00-dependencies.cjs +46 -13
  3. package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
  4. package/audit-tool/audits/02-project-structure.cjs +13 -3
  5. package/audit-tool/audits/03-architecture.cjs +78 -4
  6. package/audit-tool/audits/04-code-quality.cjs +9 -2
  7. package/audit-tool/audits/05-styling.cjs +19 -7
  8. package/audit-tool/audits/06-security-rbac.cjs +105 -14
  9. package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
  10. package/audit-tool/audits/08-testing-documentation.cjs +11 -3
  11. package/audit-tool/audits/09-operations.cjs +19 -7
  12. package/audit-tool/index.cjs +22 -11
  13. package/audit-tool/utils/report-utils.cjs +4 -0
  14. package/cursor-rules/01-pace-core-compliance.mdc +1 -0
  15. package/cursor-rules/02-project-structure.mdc +1 -0
  16. package/cursor-rules/03-architecture.mdc +3 -1
  17. package/cursor-rules/04-code-quality.mdc +1 -0
  18. package/cursor-rules/05-styling.mdc +41 -7
  19. package/cursor-rules/06-security-rbac.mdc +2 -1
  20. package/cursor-rules/07-api-tech-stack.mdc +1 -0
  21. package/cursor-rules/08-testing-documentation.mdc +1 -0
  22. package/cursor-rules/09-operations.mdc +1 -0
  23. package/dist/{DataTable-SAXFG4XI.js → DataTable-EFYP2QLE.js} +10 -7
  24. package/dist/{InactivityServiceProvider-DHryoh6K.d.ts → InactivityServiceProvider-BbxwwDz1.d.ts} +10 -1
  25. package/dist/{UnifiedAuthProvider-CiBAl9-s.d.ts → UnifiedAuthProvider-Bkt_tzdS.d.ts} +56 -24
  26. package/dist/{api-F47QJ7FX.js → api-BZR2CYXL.js} +3 -2
  27. package/dist/api-result-USV1Czr-.d.ts +51 -0
  28. package/dist/{audit-Z6ZZBWLU.js → audit-HI2DHUVU.js} +2 -1
  29. package/dist/{auth-BZOJqrdd.d.ts → auth-JvdRVaud.d.ts} +1 -1
  30. package/dist/{chunk-KSNLMI7N.js → chunk-2DL2WSOE.js} +1 -155
  31. package/dist/{chunk-MPY44PWB.js → chunk-2OEVOGGR.js} +4648 -3560
  32. package/dist/chunk-44CNXN4P.js +15 -0
  33. package/dist/{chunk-Y4PF6HIM.js → chunk-4R3T5ENU.js} +867 -786
  34. package/dist/{chunk-LNHFAF4X.js → chunk-7A6IMHH2.js} +289 -247
  35. package/dist/chunk-CU2BU2MQ.js +2 -0
  36. package/dist/{chunk-JJEYZ3DX.js → chunk-D6BMFMQZ.js} +37 -2
  37. package/dist/{chunk-BCTXBU6U.js → chunk-ENLXB7GP.js} +88 -71
  38. package/dist/{chunk-FBZ7U3ID.js → chunk-J2KQK6DG.js} +937 -987
  39. package/dist/{chunk-TFIPNIPE.js → chunk-KJXRL3XE.js} +3300 -2245
  40. package/dist/{chunk-3GWSPISD.js → chunk-L5LFKKLJ.js} +1 -1
  41. package/dist/{chunk-X5EAU5G7.js → chunk-PCSHBLPB.js} +132 -114
  42. package/dist/{chunk-NIU6DPQV.js → chunk-QRYSEPHB.js} +2 -0
  43. package/dist/{chunk-KYURMOQM.js → chunk-V7FTM2LU.js} +423 -320
  44. package/dist/chunk-WY6Y7KC3.js +264 -0
  45. package/dist/{chunk-FN52B75D.js → chunk-XOJME5T7.js} +176 -15
  46. package/dist/{chunk-7YDC7LMU.js → chunk-XPFVT3GN.js} +71 -66
  47. package/dist/{chunk-66R6RLUZ.js → chunk-YFTFFJIV.js} +3 -3
  48. package/dist/{chunk-W46INAVW.js → chunk-YYTWKVHO.js} +688 -570
  49. package/dist/components.d.ts +8 -7
  50. package/dist/components.js +17 -15
  51. package/dist/{database.generated-DT8JTZiP.d.ts → database.generated-qkdoiVrJ.d.ts} +45 -10
  52. package/dist/eslint-rules/index.cjs +3 -0
  53. package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
  54. package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
  55. package/dist/{event-WTAQuGcq.d.ts → event-BfCox3N2.d.ts} +36 -10
  56. package/dist/{file-reference-BavO2eQj.d.ts → file-reference-DU1hcawx.d.ts} +29 -13
  57. package/dist/hooks.d.ts +22 -9
  58. package/dist/hooks.js +34 -25
  59. package/dist/icons/index.d.ts +1 -0
  60. package/dist/icons/index.js +1 -0
  61. package/dist/index.d.ts +66 -177
  62. package/dist/index.js +316 -340
  63. package/dist/pagination-BW1mqywp.d.ts +201 -0
  64. package/dist/providers.d.ts +6 -5
  65. package/dist/providers.js +5 -3
  66. package/dist/rbac/index.d.ts +123 -138
  67. package/dist/rbac/index.js +10 -8
  68. package/dist/theming/runtime.d.ts +19 -2
  69. package/dist/theming/runtime.js +1 -1
  70. package/dist/{timezone-K-ptz3HO.d.ts → timezone-BTWWXKVY.d.ts} +1 -1
  71. package/dist/types.d.ts +17 -10
  72. package/dist/types.js +1 -0
  73. package/dist/{usePublicPageContext-vxBlEHO9.d.ts → usePublicPageContext-B91dGYW1.d.ts} +433 -356
  74. package/dist/{usePublicRouteParams-G3Ks53mk.d.ts → usePublicRouteParams-BgV6VhMi.d.ts} +73 -4
  75. package/dist/utils.d.ts +163 -145
  76. package/dist/utils.js +42 -25
  77. package/docs/api/modules.md +782 -643
  78. package/docs/api-reference/rpc-functions.md +12 -3
  79. package/docs/core-concepts/rbac-system.md +8 -0
  80. package/docs/getting-started/cursor-rules.md +17 -20
  81. package/docs/getting-started/dependencies.md +1 -1
  82. package/docs/getting-started/setup.md +235 -0
  83. package/docs/implementation-guides/authentication.md +27 -0
  84. package/docs/implementation-guides/data-tables.md +176 -3
  85. package/docs/migration/ApiResult-migration.md +25 -0
  86. package/docs/rbac/api-reference.md +33 -31
  87. package/docs/standards/0-standards-overview.md +50 -15
  88. package/docs/standards/1-pace-core-compliance-standards.md +62 -57
  89. package/docs/standards/2-project-structure-standards.md +33 -16
  90. package/docs/standards/3-architecture-standards.md +41 -1
  91. package/docs/standards/4-code-quality-standards.md +26 -6
  92. package/docs/standards/5-styling-standards.md +35 -1
  93. package/docs/standards/6-security-rbac-standards.md +66 -0
  94. package/docs/standards/7-api-tech-stack-standards.md +25 -14
  95. package/docs/standards/8-testing-documentation-standards.md +31 -0
  96. package/docs/standards/9-operations-standards.md +19 -0
  97. package/docs/standards/README.md +20 -201
  98. package/docs/testing/test-setup-for-consumers.md +2 -0
  99. package/docs/troubleshooting/common-issues.md +17 -1
  100. package/docs/troubleshooting/organisation-context-setup.md +8 -0
  101. package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
  102. package/eslint-config-pace-core.cjs +20 -0
  103. package/package.json +14 -20
  104. package/scripts/{build-docs-incremental.js → build-docs.js} +3 -2
  105. package/scripts/setup.cjs +536 -0
  106. package/scripts/validate.cjs +480 -0
  107. package/src/__tests__/helpers/{__tests__/component-test-utils.test.tsx → component-test-utils.test.tsx} +3 -3
  108. package/src/__tests__/helpers/{__tests__/optimized-test-setup.test.ts → optimized-test-setup.test.ts} +2 -2
  109. package/src/__tests__/helpers/{__tests__/supabaseMock.test.ts → supabaseMock.test.ts} +2 -2
  110. package/src/__tests__/helpers/{__tests__/test-providers.test.tsx → test-providers.test.tsx} +1 -1
  111. package/src/__tests__/helpers/test-providers.tsx +37 -39
  112. package/src/__tests__/helpers/{__tests__/test-utils.test.tsx → test-utils.test.tsx} +4 -3
  113. package/src/__tests__/helpers/{__tests__/timer-utils.test.ts → timer-utils.test.ts} +2 -2
  114. package/src/assets/app-icons/index.test.ts +304 -0
  115. package/src/components/AddressField/AddressField.test.tsx +1 -1
  116. package/src/components/AddressField/AddressField.tsx +238 -212
  117. package/src/components/Button/Button.tsx +1 -1
  118. package/src/components/Card/Card.test.tsx +172 -17
  119. package/src/components/Card/Card.tsx +19 -10
  120. package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
  121. package/src/components/ContextSelector/{__tests__/ContextSelector.test.tsx → ContextSelector.test.tsx} +6 -6
  122. package/src/components/ContextSelector/ContextSelector.tsx +66 -280
  123. package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
  124. package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
  125. package/src/components/DataTable/AUDIT_REPORT.md +59 -44
  126. package/src/components/DataTable/{__tests__/DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx} +6 -6
  127. package/src/components/DataTable/{__tests__/DataTable.default-state.test.tsx → DataTable.default-state.test.tsx} +5 -5
  128. package/src/components/DataTable/{__tests__/DataTable.export.test.tsx → DataTable.export.test.tsx} +10 -10
  129. package/src/components/DataTable/{__tests__/DataTable.grouping-aggregation.test.tsx → DataTable.grouping-aggregation.test.tsx} +6 -6
  130. package/src/components/DataTable/{__tests__/DataTable.hooks.test.tsx → DataTable.hooks.test.tsx} +6 -6
  131. package/src/components/DataTable/{__tests__/DataTable.select-label-display.test.tsx → DataTable.select-label-display.test.tsx} +6 -6
  132. package/src/components/DataTable/DataTable.test.tsx +787 -416
  133. package/src/components/DataTable/DataTable.tsx +12 -12
  134. package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
  135. package/src/components/DataTable/{__tests__/DataTableCore.test-setup.ts → DataTableCore.test-setup.ts} +10 -9
  136. package/src/components/DataTable/{__tests__/DataTableCore.test.tsx → DataTableCore.test.tsx} +8 -8
  137. package/src/components/DataTable/{__tests__/README.md → README.md} +17 -7
  138. package/src/components/DataTable/TESTING.md +101 -0
  139. package/src/components/DataTable/{__tests__/a11y.basic.test.tsx → a11y.basic.test.tsx} +34 -34
  140. package/src/components/DataTable/components/DataTableCore.tsx +104 -864
  141. package/src/components/DataTable/components/{__tests__/GroupingDropdown.test.tsx → GroupingDropdown.test.tsx} +17 -8
  142. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +61 -559
  144. package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
  145. package/src/components/DataTable/context/{__tests__/DataTableContext.test.tsx → DataTableContext.test.tsx} +2 -2
  146. package/src/components/DataTable/context/DataTableContext.tsx +7 -6
  147. package/src/components/DataTable/core/{__tests__/ColumnFactory.test.ts → ColumnFactory.test.ts} +2 -2
  148. package/src/components/DataTable/hooks/{__tests__/useColumnOrderPersistence.test.ts → useColumnOrderPersistence.test.ts} +2 -2
  149. package/src/components/DataTable/hooks/{__tests__/useColumnVisibilityPersistence.test.ts → useColumnVisibilityPersistence.test.ts} +2 -2
  150. package/src/components/DataTable/hooks/{__tests__/useDataTableConfiguration.test.ts → useDataTableConfiguration.test.ts} +3 -3
  151. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
  152. package/src/components/DataTable/hooks/{__tests__/useDataTableDataPipeline.test.ts → useDataTableDataPipeline.test.ts} +6 -6
  153. package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
  154. package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
  155. package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
  156. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +238 -0
  157. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
  158. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
  159. package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
  160. package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
  161. package/src/components/DataTable/hooks/{__tests__/useDataTablePermissions.test.ts → useDataTablePermissions.test.ts} +11 -11
  162. package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
  163. package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
  164. package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
  165. package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
  166. package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
  167. package/src/components/DataTable/hooks/useDataTableScope.test.ts +110 -0
  168. package/src/components/DataTable/hooks/useDataTableScope.ts +123 -0
  169. package/src/components/DataTable/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +47 -5
  170. package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
  171. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
  172. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
  173. package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
  174. package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
  175. package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
  176. package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
  177. package/src/components/DataTable/hooks/{__tests__/useEffectiveColumnOrder.test.ts → useEffectiveColumnOrder.test.ts} +2 -2
  178. package/src/components/DataTable/hooks/{__tests__/useHierarchicalState.test.ts → useHierarchicalState.test.ts} +2 -2
  179. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.test.ts +3 -3
  180. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.ts +2 -2
  181. package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
  182. package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
  183. package/src/components/DataTable/hooks/{__tests__/useKeyboardNavigation.test.ts → useKeyboardNavigation.test.ts} +3 -3
  184. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
  185. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.test.ts +3 -3
  186. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.ts +3 -3
  187. package/src/components/DataTable/hooks/{__tests__/useServerSideDataEffect.test.ts → useServerSideDataEffect.test.ts} +2 -2
  188. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
  189. package/src/components/DataTable/hooks/{__tests__/useTableColumns.test.ts → useTableColumns.test.ts} +2 -2
  190. package/src/components/DataTable/hooks/{__tests__/useTableHandlers.test.ts → useTableHandlers.test.ts} +25 -4
  191. package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
  192. package/src/components/DataTable/index.ts +18 -17
  193. package/src/components/DataTable/{__tests__/keyboard.test.tsx → keyboard.test.tsx} +41 -63
  194. package/src/components/DataTable/{__tests__/mocks → mocks}/MockRBACProvider.tsx +1 -1
  195. package/src/components/DataTable/{__tests__/pagination.modes.test.tsx → pagination.modes.test.tsx} +6 -6
  196. package/src/components/DataTable/{__tests__/ssr.strict-mode.test.tsx → ssr.strict-mode.test.tsx} +2 -2
  197. package/src/components/DataTable/{__tests__/styles.test.ts → styles.test.ts} +1 -4
  198. package/src/components/DataTable/styles.ts +0 -1
  199. package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
  200. package/src/components/DataTable/{__tests__/test-utils → test-utils}/dataFactories.ts +2 -2
  201. package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
  202. package/src/components/DataTable/{__tests__/test-utils/sharedTestUtils.tsx → test-utils/sharedTestUtils.ts} +97 -66
  203. package/src/components/DataTable/{__tests__/test-utils.ts → test-utils.ts} +1 -1
  204. package/src/components/DataTable/types/actions.ts +71 -0
  205. package/src/components/DataTable/types/base.ts +39 -0
  206. package/src/components/DataTable/types/columns.ts +125 -0
  207. package/src/components/DataTable/types/export.ts +32 -0
  208. package/src/components/DataTable/types/features.ts +81 -0
  209. package/src/components/DataTable/types/hierarchical.ts +44 -0
  210. package/src/components/DataTable/types/index.ts +43 -0
  211. package/src/components/DataTable/types/pagination.ts +85 -0
  212. package/src/components/DataTable/types/performance.ts +47 -0
  213. package/src/components/DataTable/types/props.ts +62 -0
  214. package/src/components/DataTable/types/rbac.ts +45 -0
  215. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableCore.test.tsx +430 -28
  216. package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
  217. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableErrorBoundary.test.tsx +4 -4
  218. package/src/components/DataTable/{components → ui/layout}/DataTableErrorBoundary.tsx +7 -7
  219. package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
  220. package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
  221. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
  222. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
  223. package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
  224. package/src/components/DataTable/{components → ui/modals}/DataTableModals.tsx +36 -28
  225. package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
  226. package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
  227. package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
  228. package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
  229. package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
  230. package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
  231. package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
  232. package/src/components/DataTable/{components/__tests__ → ui/shared}/AccessDeniedPage.test.tsx +2 -2
  233. package/src/components/DataTable/{components → ui/shared}/AccessDeniedPage.tsx +2 -2
  234. package/src/components/DataTable/{components/__tests__ → ui/shared}/ActionButtons.test.tsx +6 -4
  235. package/src/components/DataTable/{components → ui/shared}/ActionButtons.tsx +4 -4
  236. package/src/components/DataTable/{components/__tests__ → ui/shared}/ColumnFilter.test.tsx +29 -16
  237. package/src/components/DataTable/{components → ui/shared}/ColumnFilter.tsx +4 -4
  238. package/src/components/DataTable/{components/__tests__ → ui/shared}/PaginationControls.test.tsx +38 -16
  239. package/src/components/DataTable/{components → ui/shared}/PaginationControls.tsx +21 -15
  240. package/src/components/DataTable/{components/__tests__ → ui/shared}/SortIndicator.test.tsx +2 -2
  241. package/src/components/DataTable/{components → ui/shared}/SortIndicator.tsx +1 -1
  242. package/src/components/DataTable/{components/__tests__ → ui/table}/EditFields.test.tsx +3 -3
  243. package/src/components/DataTable/{components → ui/table}/EditFields.tsx +138 -69
  244. package/src/components/DataTable/{components/__tests__ → ui/table}/EditableRow.test.tsx +36 -27
  245. package/src/components/DataTable/{components → ui/table}/EditableRow.tsx +86 -104
  246. package/src/components/DataTable/{components/__tests__ → ui/table}/EmptyState.test.tsx +2 -62
  247. package/src/components/DataTable/{components → ui/table}/EmptyState.tsx +7 -15
  248. package/src/components/DataTable/{components/__tests__ → ui/table}/FilterRow.test.tsx +5 -4
  249. package/src/components/DataTable/{components → ui/table}/FilterRow.tsx +3 -3
  250. package/src/components/DataTable/{components/__tests__ → ui/table}/LoadingState.test.tsx +6 -10
  251. package/src/components/DataTable/{components → ui/table}/LoadingState.tsx +4 -4
  252. package/src/components/DataTable/{components/__tests__ → ui/table}/RowComponent.test.tsx +412 -17
  253. package/src/components/DataTable/{components → ui/table}/RowComponent.tsx +183 -177
  254. package/src/components/DataTable/{components/__tests__ → ui/table}/UnifiedTableBody.test.tsx +425 -16
  255. package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
  256. package/src/components/DataTable/{components/__tests__ → ui/table}/cellValueUtils.test.ts +2 -2
  257. package/src/components/DataTable/{components → ui/table}/cellValueUtils.ts +1 -1
  258. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/BulkOperationsDropdown.test.tsx +12 -5
  259. package/src/components/DataTable/{components → ui/toolbar}/BulkOperationsDropdown.tsx +3 -3
  260. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/ColumnVisibilityDropdown.test.tsx +7 -4
  261. package/src/components/DataTable/{components → ui/toolbar}/ColumnVisibilityDropdown.tsx +7 -7
  262. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/DataTableToolbar.test.tsx +4 -4
  263. package/src/components/DataTable/{components → ui/toolbar}/DataTableToolbar.tsx +4 -4
  264. package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
  265. package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
  266. package/src/components/DataTable/utils/{__tests__/a11yUtils.test.ts → a11yUtils.test.ts} +2 -2
  267. package/src/components/DataTable/utils/{__tests__/aggregationUtils.test.ts → aggregationUtils.test.ts} +3 -3
  268. package/src/components/DataTable/utils/{__tests__/columnUtils.test.ts → columnUtils.test.ts} +2 -2
  269. package/src/components/DataTable/utils/csvParse.test.ts +74 -0
  270. package/src/components/DataTable/utils/csvParse.ts +65 -0
  271. package/src/components/DataTable/utils/{__tests__/errorHandling.test.ts → errorHandling.test.ts} +2 -2
  272. package/src/components/DataTable/utils/{__tests__/exportUtils.test.ts → exportUtils.test.ts} +3 -3
  273. package/src/components/DataTable/utils/{__tests__/flexibleImport.test.ts → flexibleImport.test.ts} +2 -2
  274. package/src/components/DataTable/utils/flexibleImport.ts +3 -186
  275. package/src/components/DataTable/utils/{__tests__/hierarchicalSorting.test.ts → hierarchicalSorting.test.ts} +3 -3
  276. package/src/components/DataTable/utils/{__tests__/hierarchicalUtils.test.ts → hierarchicalUtils.test.ts} +3 -3
  277. package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
  278. package/src/components/DataTable/utils/importDateParser.ts +114 -0
  279. package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
  280. package/src/components/DataTable/utils/importValueParser.ts +91 -0
  281. package/src/components/DataTable/utils/{__tests__/paginationUtils.test.ts → paginationUtils.test.ts} +2 -2
  282. package/src/components/DataTable/utils/paginationUtils.ts +6 -3
  283. package/src/components/DataTable/utils/{__tests__/performanceUtils.test.ts → performanceUtils.test.ts} +3 -3
  284. package/src/components/DataTable/utils/{__tests__/rowUtils.test.ts → rowUtils.test.ts} +3 -3
  285. package/src/components/DataTable/utils/{__tests__/selectFieldUtils.test.ts → selectFieldUtils.test.ts} +66 -3
  286. package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
  287. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
  288. package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
  289. package/src/components/Dialog/Dialog.test-utils.ts +49 -0
  290. package/src/components/Dialog/Dialog.test.tsx +896 -89
  291. package/src/components/Dialog/Dialog.tsx +174 -882
  292. package/src/components/Dialog/dialogLock.test.ts +238 -0
  293. package/src/components/Dialog/dialogLock.ts +98 -0
  294. package/src/components/Dialog/index.ts +2 -0
  295. package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
  296. package/src/components/Dialog/useDialogDimensions.ts +140 -0
  297. package/src/components/Dialog/useDialogLifecycle.test.ts +358 -0
  298. package/src/components/Dialog/useDialogLifecycle.ts +135 -0
  299. package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
  300. package/src/components/Dialog/useDialogPersistence.ts +357 -0
  301. package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
  302. package/src/components/FileDisplay/FileDisplay.tsx +24 -656
  303. package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
  304. package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
  305. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
  306. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
  307. package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
  308. package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
  309. package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
  310. package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
  311. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
  312. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
  313. package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
  314. package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
  315. package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
  316. package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
  317. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
  318. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
  319. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
  320. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
  321. package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
  322. package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
  323. package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
  324. package/src/components/FileDisplay/fallbackUtils.ts +44 -0
  325. package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
  326. package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
  327. package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
  328. package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
  329. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.test.ts +40 -42
  330. package/src/components/FileDisplay/useFileDisplay.ts +515 -0
  331. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.unit.test.ts +406 -77
  332. package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
  333. package/src/{hooks/public → components/FileDisplay}/usePublicFileDisplay.test.ts +94 -88
  334. package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
  335. package/src/components/FileUpload/FileUpload.test.tsx +16 -10
  336. package/src/components/FileUpload/FileUpload.tsx +107 -525
  337. package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
  338. package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
  339. package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
  340. package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
  341. package/src/components/FileUpload/useFileUploadManager.ts +454 -0
  342. package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
  343. package/src/components/FileUpload/useResolvedAppId.ts +77 -0
  344. package/src/components/Footer/Footer.test.tsx +6 -292
  345. package/src/components/Footer/Footer.tsx +8 -125
  346. package/src/components/Form/Form.test.tsx +44 -27
  347. package/src/components/Form/Form.tsx +64 -287
  348. package/src/components/Form/useFormPersistence.ts +257 -0
  349. package/src/components/Header/Header.test.tsx +17 -18
  350. package/src/components/Header/Header.tsx +10 -1
  351. package/src/components/Input/Input.tsx +1 -1
  352. package/src/components/Label/Label.test.tsx +1 -1
  353. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
  354. package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
  355. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
  356. package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
  357. package/src/components/NavigationMenu/index.ts +6 -1
  358. package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
  359. package/src/components/NavigationMenu/{__tests__/useNavigationFiltering.test.ts → useNavigationFiltering.test.ts} +68 -53
  360. package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
  361. package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
  362. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +77 -62
  363. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
  364. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
  365. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
  366. package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
  367. package/src/components/PaceAppLayout/useFilteredNavItems.ts +304 -0
  368. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +142 -0
  369. package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
  370. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
  371. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +79 -0
  372. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
  373. package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
  374. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
  376. package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
  377. package/src/components/Progress/Progress.tsx +1 -2
  378. package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
  379. package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
  380. package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
  381. package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
  382. package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
  383. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
  384. package/src/components/Select/Select.test.tsx +1 -1
  385. package/src/components/Select/Select.tsx +28 -18
  386. package/src/components/Select/{__tests__/context.test.tsx → context.test.tsx} +3 -3
  387. package/src/components/Select/{utils/__tests__/text.test.tsx → text.test.tsx} +2 -2
  388. package/src/components/Select/{utils/text.ts → text.ts} +1 -1
  389. package/src/components/Select/{hooks/__tests__/useSelectEvents.test.ts → useSelectEvents.test.ts} +5 -5
  390. package/src/components/Select/{hooks/useSelectEvents.ts → useSelectEvents.ts} +2 -2
  391. package/src/components/Select/{hooks/__tests__/useSelectSearch.test.tsx → useSelectSearch.test.tsx} +7 -7
  392. package/src/components/Select/{hooks/useSelectSearch.ts → useSelectSearch.ts} +2 -2
  393. package/src/components/Select/{hooks/__tests__/useSelectState.test.ts → useSelectState.test.ts} +16 -2
  394. package/src/components/Select/{hooks/useSelectState.ts → useSelectState.ts} +3 -3
  395. package/src/components/Table/Table.test.tsx +348 -0
  396. package/src/components/Tabs/Tabs.test.tsx +270 -0
  397. package/src/components/Tabs/Tabs.tsx +1 -1
  398. package/src/components/Toast/Toast.test.tsx +420 -0
  399. package/src/components/{__tests__/index.test.ts → index.test.ts} +2 -2
  400. package/src/constants/{__tests__/performance.test.ts → performance.test.ts} +2 -2
  401. package/src/hooks/{__tests__/ServiceHooks.test.tsx → ServiceHooks.test.tsx} +8 -8
  402. package/src/hooks/{__tests__/hooks.integration.test.tsx → hooks.integration.test.tsx} +11 -11
  403. package/src/hooks/index.ts +7 -4
  404. package/src/hooks/{__tests__/index.unit.test.ts → index.unit.test.ts} +2 -2
  405. package/src/hooks/public/usePublicEvent.test.ts +1 -1
  406. package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
  407. package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
  408. package/src/hooks/services/useAuth.ts +9 -7
  409. package/src/hooks/useAddressAutocomplete.test.ts +22 -22
  410. package/src/hooks/useAddressAutocomplete.ts +90 -75
  411. package/src/hooks/{__tests__/useAppConfig.unit.test.ts → useAppConfig.unit.test.ts} +328 -22
  412. package/src/hooks/{__tests__/useComponentPerformance.unit.test.tsx → useComponentPerformance.unit.test.tsx} +27 -41
  413. package/src/hooks/useDataTablePerformance.ts +100 -120
  414. package/src/hooks/{__tests__/useDataTablePerformance.unit.test.ts → useDataTablePerformance.unit.test.ts} +5 -5
  415. package/src/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +2 -2
  416. package/src/hooks/{__tests__/useDebounce.unit.test.ts → useDebounce.unit.test.ts} +2 -2
  417. package/src/hooks/useEventTheme.test.ts +4 -1
  418. package/src/hooks/useEventTheme.ts +49 -21
  419. package/src/hooks/useEvents.ts +41 -1
  420. package/src/hooks/{__tests__/useEvents.unit.test.ts → useEvents.unit.test.ts} +5 -5
  421. package/src/hooks/useFileReference.test.ts +44 -41
  422. package/src/hooks/useFileReference.ts +182 -173
  423. package/src/hooks/useFileUrl.ts +1 -1
  424. package/src/hooks/{__tests__/useFileUrl.unit.test.ts → useFileUrl.unit.test.ts} +26 -36
  425. package/src/hooks/{__tests__/useFileUrlCache.test.ts → useFileUrlCache.test.ts} +8 -8
  426. package/src/hooks/useFileUrlCache.ts +1 -1
  427. package/src/hooks/{__tests__/useFocusManagement.unit.test.ts → useFocusManagement.unit.test.ts} +2 -2
  428. package/src/hooks/{__tests__/useFocusTrap.unit.test.tsx → useFocusTrap.unit.test.tsx} +2 -2
  429. package/src/hooks/{__tests__/useFormDialog.test.ts → useFormDialog.test.ts} +2 -2
  430. package/src/hooks/useInactivityTracker.ts +138 -131
  431. package/src/hooks/{__tests__/useInactivityTracker.unit.test.ts → useInactivityTracker.unit.test.ts} +3 -3
  432. package/src/hooks/{__tests__/useIsMobile.unit.test.ts → useIsMobile.unit.test.ts} +2 -2
  433. package/src/hooks/useIsPrint.ts +62 -0
  434. package/src/hooks/useIsPrint.unit.test.ts +545 -0
  435. package/src/hooks/{__tests__/useKeyboardShortcuts.unit.test.ts → useKeyboardShortcuts.unit.test.ts} +2 -2
  436. package/src/hooks/{__tests__/useOrganisationPermissions.unit.test.tsx → useOrganisationPermissions.unit.test.tsx} +4 -4
  437. package/src/hooks/useOrganisationSecurity.test.ts +3 -3
  438. package/src/hooks/useOrganisationSecurity.ts +190 -201
  439. package/src/hooks/{__tests__/useOrganisationSecurity.unit.test.tsx → useOrganisationSecurity.unit.test.tsx} +61 -63
  440. package/src/hooks/{__tests__/useOrganisations.unit.test.ts → useOrganisations.unit.test.ts} +5 -5
  441. package/src/hooks/{__tests__/usePerformanceMonitor.unit.test.ts → usePerformanceMonitor.unit.test.ts} +13 -14
  442. package/src/hooks/{__tests__/usePermissionCache.test.ts → usePermissionCache.test.ts} +26 -27
  443. package/src/hooks/usePermissionCache.ts +276 -271
  444. package/src/hooks/{__tests__/usePreventTabReload.test.ts → usePreventTabReload.test.ts} +2 -2
  445. package/src/hooks/{__tests__/usePublicEvent.simple.test.ts → usePublicEvent.simple.test.ts} +4 -4
  446. package/src/hooks/{__tests__/usePublicEvent.test.ts → usePublicEvent.test.ts} +4 -4
  447. package/src/hooks/{__tests__/usePublicEvent.unit.test.ts → usePublicEvent.unit.test.ts} +4 -4
  448. package/src/hooks/{__tests__/usePublicFileDisplay.test.ts → usePublicFileDisplay.test.ts} +12 -12
  449. package/src/hooks/{__tests__/usePublicRouteParams.unit.test.ts → usePublicRouteParams.unit.test.ts} +3 -3
  450. package/src/hooks/{__tests__/useQueryCache.test.ts → useQueryCache.test.ts} +2 -2
  451. package/src/hooks/useQueryCache.ts +0 -2
  452. package/src/hooks/{__tests__/useRBAC.unit.test.ts → useRBAC.unit.test.ts} +55 -38
  453. package/src/hooks/{__tests__/useSessionDraft.test.ts → useSessionDraft.test.ts} +2 -2
  454. package/src/hooks/{__tests__/useSessionRestoration.unit.test.tsx → useSessionRestoration.unit.test.tsx} +10 -19
  455. package/src/hooks/useStorage.ts +21 -16
  456. package/src/hooks/{__tests__/useStorage.unit.test.ts → useStorage.unit.test.ts} +38 -75
  457. package/src/hooks/{__tests__/useToast.test.ts → useToast.test.ts} +2 -2
  458. package/src/hooks/{__tests__/useToast.unit.test.tsx → useToast.unit.test.tsx} +2 -2
  459. package/src/hooks/{__tests__/useZodForm.unit.test.tsx → useZodForm.unit.test.tsx} +2 -2
  460. package/src/icons/{__tests__/index.test.ts → index.test.ts} +2 -2
  461. package/src/icons/index.ts +2 -0
  462. package/src/{__tests__/index.test.ts → index.test.ts} +3 -7
  463. package/src/index.ts +15 -7
  464. package/src/providers/{__tests__/AuthProvider.test.tsx → AuthProvider.test.tsx} +3 -3
  465. package/src/providers/{__tests__/EventProvider.test.tsx → EventProvider.test.tsx} +3 -3
  466. package/src/providers/InactivityProvider.test-helper.tsx +40 -0
  467. package/src/providers/{__tests__/InactivityProvider.test.tsx → InactivityProvider.test.tsx} +14 -21
  468. package/src/providers/{__tests__/ProviderLifecycle.test.tsx → ProviderLifecycle.test.tsx} +4 -4
  469. package/src/providers/{__tests__/UnifiedAuthProvider.test.tsx → UnifiedAuthProvider.test.tsx} +1 -1
  470. package/src/providers/{__tests__/index.test.ts → index.test.ts} +2 -2
  471. package/src/providers/services/{__tests__/AuthServiceProvider.integration.test.tsx → AuthServiceProvider.integration.test.tsx} +4 -4
  472. package/src/providers/services/{__tests__/AuthServiceProvider.test.tsx → AuthServiceProvider.test.tsx} +7 -7
  473. package/src/providers/services/{__tests__/EventServiceProvider.test.tsx → EventServiceProvider.test.tsx} +7 -7
  474. package/src/providers/services/{__tests__/InactivityServiceProvider.test.tsx → InactivityServiceProvider.test.tsx} +5 -5
  475. package/src/providers/services/{__tests__/OrganisationServiceProvider.test.tsx → OrganisationServiceProvider.test.tsx} +6 -6
  476. package/src/providers/services/UnifiedAuthContext.ts +30 -27
  477. package/src/providers/services/{__tests__/UnifiedAuthProvider.advanced.test.tsx → UnifiedAuthProvider.advanced.test.tsx} +8 -9
  478. package/src/providers/services/{__tests__/UnifiedAuthProvider.appId.test.tsx → UnifiedAuthProvider.appId.test.tsx} +25 -25
  479. package/src/providers/services/{__tests__/UnifiedAuthProvider.integration.test.tsx → UnifiedAuthProvider.integration.test.tsx} +14 -11
  480. package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
  481. package/src/providers/services/{__tests__/contexts.test.tsx → contexts.test.tsx} +6 -6
  482. package/src/providers/services/{__tests__/useUnifiedAuth.test.tsx → useUnifiedAuth.test.tsx} +6 -6
  483. package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
  484. package/src/providers/useInactivity.test-helper.ts +27 -0
  485. package/src/rbac/{__tests__/adapters.comprehensive.test.tsx → adapters.comprehensive.test.tsx} +24 -24
  486. package/src/rbac/adapters.test.tsx +22 -22
  487. package/src/rbac/adapters.tsx +29 -29
  488. package/src/rbac/api.test.ts +973 -42
  489. package/src/rbac/api.ts +228 -253
  490. package/src/rbac/{__tests__/audit-batched.test.ts → audit-batched.test.ts} +6 -6
  491. package/src/rbac/audit.ts +4 -1
  492. package/src/rbac/{__tests__/auth-rbac-security.integration.test.tsx → auth-rbac-security.integration.test.tsx} +1 -1
  493. package/src/rbac/{__tests__/auth-rbac.e2e.test.tsx → auth-rbac.e2e.test.tsx} +27 -34
  494. package/src/rbac/cache-invalidation.test.ts +715 -0
  495. package/src/rbac/components/{__tests__/AccessDenied.test.tsx → AccessDenied.test.tsx} +3 -3
  496. package/src/rbac/components/{__tests__/NavigationGuard.test.tsx → NavigationGuard.test.tsx} +13 -11
  497. package/src/{__tests__/rbac/PagePermissionGuard.test.tsx → rbac/components/PagePermissionGuard.guard.test.tsx} +33 -19
  498. package/src/rbac/components/{__tests__/PagePermissionGuard.performance.test.tsx → PagePermissionGuard.performance.test.tsx} +30 -9
  499. package/src/rbac/components/{__tests__/PagePermissionGuard.race-condition.test.tsx → PagePermissionGuard.race-condition.test.tsx} +7 -7
  500. package/src/rbac/components/{__tests__/PagePermissionGuard.test.tsx → PagePermissionGuard.test.tsx} +10 -10
  501. package/src/rbac/components/PagePermissionGuard.tsx +177 -372
  502. package/src/rbac/components/{__tests__/PagePermissionGuard.verification.test.tsx → PagePermissionGuard.verification.test.tsx} +7 -7
  503. package/src/rbac/config.ts +58 -18
  504. package/src/rbac/{__tests__/engine.comprehensive.test.ts → engine.comprehensive.test.ts} +3 -3
  505. package/src/rbac/engine.test.ts +494 -0
  506. package/src/rbac/errors.ts +89 -55
  507. package/src/rbac/hooks/permissions/runPermissionCheck.ts +77 -0
  508. package/src/rbac/hooks/permissions/{__tests__/useAccessLevel.test.ts → useAccessLevel.test.ts} +40 -40
  509. package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
  510. package/src/rbac/hooks/permissions/{__tests__/useCan.test.ts → useCan.test.ts} +41 -41
  511. package/src/rbac/hooks/permissions/useCan.ts +170 -252
  512. package/src/rbac/hooks/permissions/{__tests__/useMultiplePermissions.test.ts → useMultiplePermissions.test.ts} +49 -49
  513. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +6 -2
  514. package/src/rbac/hooks/permissions/{__tests__/usePermissions.test.ts → usePermissions.test.ts} +10 -12
  515. package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
  516. package/src/rbac/hooks/useCan.test.ts +42 -42
  517. package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
  518. package/src/rbac/hooks/usePageGuardScope.ts +117 -0
  519. package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
  520. package/src/rbac/hooks/{__tests__/usePermissions.integration.test.ts → usePermissions.integration.test.ts} +9 -9
  521. package/src/{__tests__/hooks/usePermissions.test.ts → rbac/hooks/usePermissions.stability.test.ts} +18 -18
  522. package/src/rbac/hooks/usePermissions.test.ts +54 -54
  523. package/src/rbac/hooks/useRBAC.test.ts +313 -217
  524. package/src/rbac/hooks/useRBAC.ts +145 -81
  525. package/src/rbac/hooks/useResourcePermissions.test.ts +25 -25
  526. package/src/rbac/hooks/useResourcePermissions.ts +68 -134
  527. package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
  528. package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
  529. package/src/rbac/hooks/useRoleManagement.ts +153 -585
  530. package/src/rbac/hooks/{__tests__/useSecureSupabase.test.ts → useSecureSupabase.test.ts} +17 -17
  531. package/src/rbac/hooks/useSecureSupabase.ts +10 -2
  532. package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
  533. package/src/rbac/{__tests__/performance.test.ts → performance.test.ts} +1 -1
  534. package/src/rbac/{__tests__/rbac-core.test.tsx → rbac-core.test.tsx} +3 -3
  535. package/src/rbac/{__tests__/rbac-engine-core-logic.test.ts → rbac-engine-core-logic.test.ts} +2 -2
  536. package/src/rbac/{__tests__/rbac-engine-simplified.test.ts → rbac-engine-simplified.test.ts} +3 -3
  537. package/src/rbac/{__tests__/rbac-functions.test.ts → rbac-functions.test.ts} +57 -0
  538. package/src/rbac/{__tests__/rbac-role-isolation.test.ts → rbac-role-isolation.test.ts} +2 -2
  539. package/src/rbac/request-deduplication.test.ts +14 -9
  540. package/src/rbac/request-deduplication.ts +5 -4
  541. package/src/rbac/{__tests__/scenarios.user-role.test.tsx → scenarios.user-role.test.tsx} +23 -23
  542. package/src/rbac/secureClient.test.ts +514 -83
  543. package/src/rbac/secureClient.ts +8 -2
  544. package/src/rbac/security.test.ts +323 -0
  545. package/src/rbac/types/roleManagement.ts +66 -0
  546. package/src/rbac/utils/{__tests__/clientSecurity.test.ts → clientSecurity.test.ts} +4 -4
  547. package/src/rbac/utils/{__tests__/contextValidator.test.ts → contextValidator.test.ts} +4 -4
  548. package/src/rbac/utils/contextValidator.ts +5 -1
  549. package/src/rbac/utils/{__tests__/deep-equal.test.ts → deep-equal.test.ts} +1 -1
  550. package/src/rbac/utils/{__tests__/eventContext.test.ts → eventContext.test.ts} +36 -21
  551. package/src/rbac/utils/eventContext.ts +37 -33
  552. package/src/rbac/utils/fetchPermissionMap.ts +13 -0
  553. package/src/rbac/utils/permissionMapHelpers.ts +34 -0
  554. package/src/rbac/utils/roleManagementRpc.ts +303 -0
  555. package/src/services/{__tests__/AuthService.edge-cases.test.ts → AuthService.edge-cases.test.ts} +19 -19
  556. package/src/services/{__tests__/AuthService.restoreSession.test.ts → AuthService.restoreSession.test.ts} +2 -2
  557. package/src/services/{__tests__/AuthService.test.ts → AuthService.test.ts} +89 -55
  558. package/src/services/AuthService.ts +184 -205
  559. package/src/services/{__tests__/BaseService.edge-cases.test.ts → BaseService.edge-cases.test.ts} +3 -3
  560. package/src/services/{__tests__/BaseService.test.ts → BaseService.test.ts} +2 -2
  561. package/src/services/{__tests__/EventService.edge-cases.test.ts → EventService.edge-cases.test.ts} +27 -24
  562. package/src/services/{__tests__/EventService.eventColours.test.ts → EventService.eventColours.test.ts} +1 -1
  563. package/src/services/{__tests__/EventService.test.ts → EventService.test.ts} +256 -24
  564. package/src/services/EventService.ts +242 -312
  565. package/src/services/{__tests__/InactivityService.edge-cases.test.ts → InactivityService.edge-cases.test.ts} +3 -3
  566. package/src/services/{__tests__/InactivityService.lifecycle.test.ts → InactivityService.lifecycle.test.ts} +2 -2
  567. package/src/services/{__tests__/InactivityService.test.ts → InactivityService.test.ts} +179 -4
  568. package/src/services/InactivityService.ts +172 -213
  569. package/src/services/{__tests__/OrganisationService.edge-cases.test.ts → OrganisationService.edge-cases.test.ts} +5 -5
  570. package/src/services/{__tests__/OrganisationService.pagination.test.ts → OrganisationService.pagination.test.ts} +4 -4
  571. package/src/services/{__tests__/OrganisationService.test.ts → OrganisationService.test.ts} +410 -7
  572. package/src/services/OrganisationService.ts +184 -238
  573. package/src/services/base/BaseService.test.ts +1 -1
  574. package/src/services/interfaces/{__tests__/IAuthService.test.ts → IAuthService.test.ts} +21 -27
  575. package/src/services/interfaces/IAuthService.ts +10 -9
  576. package/src/services/interfaces/{__tests__/IEventService.test.ts → IEventService.test.ts} +4 -4
  577. package/src/services/interfaces/{__tests__/IInactivityService.test.ts → IInactivityService.test.ts} +3 -3
  578. package/src/services/interfaces/{__tests__/IOrganisationService.test.ts → IOrganisationService.test.ts} +3 -3
  579. package/src/styles/core.css +243 -12
  580. package/src/theming/{__tests__/parseEventColours.test.ts → parseEventColours.test.ts} +1 -1
  581. package/src/theming/{__tests__/runtime.test.ts → runtime.test.ts} +8 -17
  582. package/src/theming/runtime.ts +71 -2
  583. package/src/types/api-result.ts +53 -0
  584. package/src/types/{__tests__/core.test.ts → core.test.ts} +2 -2
  585. package/src/types/{__tests__/database-generated.test.ts → database-generated.test.ts} +3 -3
  586. package/src/types/database.generated.ts +45 -10
  587. package/src/types/event.ts +38 -18
  588. package/src/types/{__tests__/file-reference.test.ts → file-reference.test.ts} +13 -13
  589. package/src/types/file-reference.ts +37 -12
  590. package/src/types/{__tests__/guards.test.ts → guards.test.ts} +2 -2
  591. package/src/types/{__tests__/index.test.ts → index.test.ts} +2 -2
  592. package/src/types/index.ts +3 -0
  593. package/src/types/{__tests__/organisation.roles.test.ts → organisation.roles.test.ts} +1 -1
  594. package/src/types/{__tests__/organisation.test.ts → organisation.test.ts} +3 -31
  595. package/src/types/organisation.ts +15 -15
  596. package/src/types/supabase.ts +13 -4
  597. package/src/types/{__tests__/theme.test.ts → theme.test.ts} +1 -1
  598. package/src/types/{__tests__/type-validation.test.ts → type-validation.test.ts} +1 -1
  599. package/src/types/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  600. package/src/utils/app/appIdResolver.test.ts +98 -71
  601. package/src/utils/app/appIdResolver.ts +31 -20
  602. package/src/utils/{__tests__/appConfig.unit.test.ts → appConfig.unit.test.ts} +1 -1
  603. package/src/utils/{__tests__/audit.unit.test.ts → audit.unit.test.ts} +1 -1
  604. package/src/utils/{__tests__/auth-utils.unit.test.ts → auth-utils.unit.test.ts} +16 -17
  605. package/src/utils/{__tests__/bundleAnalysis.unit.test.ts → bundleAnalysis.unit.test.ts} +35 -35
  606. package/src/utils/{__tests__/cn.unit.test.ts → cn.unit.test.ts} +1 -1
  607. package/src/utils/context/organisationContext.test.ts +105 -91
  608. package/src/utils/context/organisationContext.ts +29 -40
  609. package/src/utils/core/{__tests__/cn.test.ts → cn.test.ts} +3 -3
  610. package/src/utils/core/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +2 -2
  611. package/src/utils/core/{__tests__/logger.test.ts → logger.test.ts} +2 -2
  612. package/src/utils/core/mergeRefs.ts +24 -0
  613. package/src/utils/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +1 -1
  614. package/src/utils/{__tests__/deviceFingerprint.unit.test.ts → deviceFingerprint.unit.test.ts} +1 -1
  615. package/src/utils/dynamic/createLazyComponent.tsx +9 -1
  616. package/src/utils/dynamic/{__tests__/dynamicUtils.test.ts → dynamicUtils.test.ts} +2 -2
  617. package/src/utils/dynamic/{__tests__/lazyLoad.test.tsx → lazyLoad.test.tsx} +2 -2
  618. package/src/utils/{__tests__/dynamicUtils.unit.test.ts → dynamicUtils.unit.test.ts} +1 -1
  619. package/src/utils/file-reference/{__tests__/file-reference.test.ts → file-reference.test.ts} +214 -289
  620. package/src/utils/file-reference/index.ts +330 -347
  621. package/src/utils/{__tests__/formatDate.unit.test.ts → formatDate.unit.test.ts} +2 -2
  622. package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
  623. package/src/utils/formatting/formatNumber.test.ts +1 -1
  624. package/src/utils/{__tests__/formatting.unit.test.ts → formatting.unit.test.ts} +1 -1
  625. package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
  626. package/src/utils/google-places/googlePlacesUtils.ts +67 -99
  627. package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
  628. package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
  629. package/src/utils/{__tests__/index.unit.test.ts → index.unit.test.ts} +1 -1
  630. package/src/utils/{__tests__/lazyLoad.unit.test.tsx → lazyLoad.unit.test.tsx} +13 -14
  631. package/src/utils/location/location.test.ts +1 -1
  632. package/src/utils/{__tests__/logger.unit.test.ts → logger.unit.test.ts} +1 -1
  633. package/src/utils/{__tests__/organisationContext.unit.test.ts → organisationContext.unit.test.ts} +37 -48
  634. package/src/utils/performance/{__tests__/bundleAnalysis.test.ts → bundleAnalysis.test.ts} +2 -2
  635. package/src/utils/performance/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  636. package/src/utils/performance/{__tests__/performanceBudgets.test.ts → performanceBudgets.test.ts} +2 -2
  637. package/src/utils/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  638. package/src/utils/{__tests__/performanceBudgets.unit.test.ts → performanceBudgets.unit.test.ts} +2 -2
  639. package/src/utils/{__tests__/permissionTypes.unit.test.ts → permissionTypes.unit.test.ts} +1 -1
  640. package/src/utils/{__tests__/permissionUtils.unit.test.ts → permissionUtils.unit.test.ts} +1 -1
  641. package/src/utils/permissions/{__tests__/permissionTypes.test.ts → permissionTypes.test.ts} +2 -2
  642. package/src/utils/persistence/{__tests__/keyDerivation.test.ts → keyDerivation.test.ts} +2 -2
  643. package/src/utils/persistence/{__tests__/sensitiveFieldDetection.test.ts → sensitiveFieldDetection.test.ts} +2 -2
  644. package/src/utils/{__tests__/request-deduplication.test.ts → request-deduplication.test.ts} +2 -2
  645. package/src/utils/{__tests__/sanitization.unit.test.ts → sanitization.unit.test.ts} +1 -1
  646. package/src/utils/{__tests__/schemaUtils.unit.test.ts → schemaUtils.unit.test.ts} +1 -1
  647. package/src/utils/{__tests__/secureDataAccess.unit.test.ts → secureDataAccess.unit.test.ts} +2 -2
  648. package/src/utils/{__tests__/secureErrors.unit.test.ts → secureErrors.unit.test.ts} +4 -4
  649. package/src/utils/{__tests__/secureStorage.unit.test.ts → secureStorage.unit.test.ts} +1 -1
  650. package/src/utils/security/auth-utils.ts +34 -23
  651. package/src/utils/security/secureDataAccess.ts +241 -281
  652. package/src/utils/security/secureErrors.test.ts +1 -1
  653. package/src/utils/security/secureStorage.test.ts +1 -1
  654. package/src/utils/security/security.test.ts +25 -17
  655. package/src/utils/security/security.ts +15 -18
  656. package/src/utils/security/securityMonitor.test.ts +1 -1
  657. package/src/utils/{__tests__/security.unit.test.ts → security.unit.test.ts} +21 -15
  658. package/src/utils/{__tests__/securityMonitor.unit.test.ts → securityMonitor.unit.test.ts} +1 -1
  659. package/src/utils/{__tests__/sessionTracking.unit.test.ts → sessionTracking.unit.test.ts} +12 -12
  660. package/src/utils/storage/{__tests__/config.unit.test.ts → config.unit.test.ts} +2 -2
  661. package/src/utils/storage/helpers.test.ts +88 -102
  662. package/src/utils/storage/helpers.ts +173 -251
  663. package/src/utils/storage/{__tests__/index.unit.test.ts → index.unit.test.ts} +3 -3
  664. package/src/utils/storage/types.ts +7 -0
  665. package/src/utils/supabase/createBaseClient.test.ts +1 -1
  666. package/src/utils/timezone/timezone.test.ts +1 -1
  667. package/src/utils/{__tests__/timezone.test.ts → timezone.test.ts} +2 -2
  668. package/src/utils/validation/{__tests__/common.test.ts → common.test.ts} +2 -2
  669. package/src/utils/validation/{__tests__/csrf.test.ts → csrf.test.ts} +56 -28
  670. package/src/utils/validation/csrf.ts +42 -41
  671. package/src/utils/validation/{__tests__/htmlSanitization.unit.test.ts → htmlSanitization.unit.test.ts} +2 -2
  672. package/src/utils/validation/{__tests__/passwordSchema.test.ts → passwordSchema.test.ts} +2 -2
  673. package/src/utils/validation/{__tests__/schema.test.ts → schema.test.ts} +2 -2
  674. package/src/utils/validation/{__tests__/sqlInjectionProtection.test.ts → sqlInjectionProtection.test.ts} +2 -2
  675. package/src/utils/validation/{__tests__/user.test.ts → user.test.ts} +2 -2
  676. package/src/utils/validation/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  677. package/src/utils/validation/{__tests__/validationUtils.test.ts → validationUtils.test.ts} +2 -2
  678. package/src/utils/{__tests__/validation.unit.test.ts → validation.unit.test.ts} +1 -1
  679. package/src/utils/{__tests__/validationUtils.unit.test.ts → validationUtils.unit.test.ts} +5 -2
  680. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
  681. package/dist/chunk-KPYQWGFQ.js +0 -183
  682. package/dist/types-D05dCGma.d.ts +0 -521
  683. package/scripts/eslint-audit.cjs +0 -222
  684. package/scripts/generate-docs.js +0 -157
  685. package/scripts/install-cursor-rules.cjs +0 -255
  686. package/scripts/install-eslint-config.cjs +0 -349
  687. package/scripts/setup-build-cache.js +0 -73
  688. package/scripts/validate-pre-publish.js +0 -145
  689. package/src/__tests__/integration/UserProfile.test.tsx +0 -124
  690. package/src/__tests__/public-recipe-view.test.ts +0 -228
  691. package/src/__tests__/rls-policies.test.ts +0 -472
  692. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
  693. package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
  694. package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
  695. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
  696. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
  697. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
  698. package/src/components/DataTable/core/ActionManager.ts +0 -235
  699. package/src/components/DataTable/core/ColumnManager.ts +0 -204
  700. package/src/components/DataTable/core/DataManager.ts +0 -190
  701. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
  702. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  703. package/src/components/DataTable/core/StateManager.ts +0 -312
  704. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
  705. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
  706. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
  707. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
  708. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
  709. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
  710. package/src/components/DataTable/core/interfaces.ts +0 -338
  711. package/src/components/DataTable/types.ts +0 -764
  712. package/src/hooks/public/usePublicFileDisplay.ts +0 -534
  713. package/src/hooks/useFileDisplay.ts +0 -748
  714. package/src/providers/OrganisationProvider.test.tsx +0 -40
  715. package/src/providers/OrganisationProvider.tsx +0 -92
  716. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
  717. package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
  718. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
  719. package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
  720. /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
  721. /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
  722. /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
  723. /package/src/providers/{__tests__/README.md → README.md} +0 -0
  724. /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
  725. /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
  726. /package/src/types/{__tests__/README.md → README.md} +0 -0
@@ -1,9 +1,9 @@
1
- import { useAppConfig } from './chunk-3GWSPISD.js';
2
- import { OrganisationContextRequiredError, getAccessLevel, isPermittedCached, isPermitted, getRBACLogger, getPermissionMap } from './chunk-LNHFAF4X.js';
1
+ import { useAppConfig } from './chunk-L5LFKKLJ.js';
2
+ import { OrganisationContextRequiredError, getAccessLevel, getRBACLogger, isPermittedCached, isPermitted, getPermissionMap } from './chunk-7A6IMHH2.js';
3
3
  import { cn, getCurrentAppName } from './chunk-UZNAFKGW.js';
4
4
  import { createLogger } from './chunk-BTHN5MKC.js';
5
5
  import * as React3 from 'react';
6
- import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
6
+ import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
7
7
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
8
8
  import { jsx, jsxs } from 'react/jsx-runtime';
9
9
  import { Slot } from '@radix-ui/react-slot';
@@ -31,7 +31,7 @@ var Tooltip = React3.forwardRef(({ children, content, delayDuration = 200 }, ref
31
31
  ] }) }));
32
32
  Tooltip.displayName = "Tooltip";
33
33
  function getButtonClasses(variant = "default", size = "default") {
34
- const baseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
34
+ const baseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 print:shadow-none";
35
35
  const variantClasses = {
36
36
  default: "bg-main-600 text-main-50 shadow hover:bg-acc-400",
37
37
  destructive: "bg-acc-600 text-acc-50 shadow-sm hover:bg-acc-400",
@@ -126,8 +126,25 @@ var IconButton = React3.forwardRef(
126
126
  }
127
127
  );
128
128
  IconButton.displayName = "IconButton";
129
+
130
+ // src/utils/core/mergeRefs.ts
131
+ function isMutableRefObject(ref) {
132
+ return ref != null && typeof ref === "object" && "current" in ref;
133
+ }
134
+ function mergeRefs(...refs) {
135
+ return (node) => {
136
+ refs.forEach((ref) => {
137
+ if (ref == null) return;
138
+ if (typeof ref === "function") {
139
+ ref(node);
140
+ } else if (isMutableRefObject(ref)) {
141
+ ref.current = node;
142
+ }
143
+ });
144
+ };
145
+ }
129
146
  function getCardClasses(variant = "default", size = "default") {
130
- const baseClasses = "rounded-lg border bg-card text-card-foreground shadow-sm";
147
+ const baseClasses = "rounded-lg border bg-card text-card-foreground shadow-sm print:shadow-none print:bg-transparent";
131
148
  const variantClasses = {
132
149
  default: "shadow-xl",
133
150
  outline: "border-2",
@@ -135,8 +152,8 @@ function getCardClasses(variant = "default", size = "default") {
135
152
  };
136
153
  const sizeClasses = {
137
154
  default: "",
138
- sm: "text-sm",
139
- lg: "text-lg"
155
+ sm: "card--sm",
156
+ lg: "card--lg"
140
157
  };
141
158
  return `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`;
142
159
  }
@@ -271,6 +288,18 @@ var HoverCard = React3.forwardRef(({ children, className, ...props }, ref) => {
271
288
  });
272
289
  HoverCard.displayName = "HoverCard";
273
290
  var HoverCardTrigger = React3.forwardRef(({ className, asChild, children, ...props }, ref) => {
291
+ if (asChild && React3.Children.count(children) === 1) {
292
+ const child = React3.Children.only(children);
293
+ if (React3.isValidElement(child)) {
294
+ const childEl = child;
295
+ const mergedRef = mergeRefs(ref, childEl.ref);
296
+ return React3.cloneElement(childEl, {
297
+ ...props,
298
+ className: cn("cursor-pointer", className, childEl.props?.className),
299
+ ref: mergedRef
300
+ });
301
+ }
302
+ }
274
303
  if (asChild) {
275
304
  return /* @__PURE__ */ jsx("span", { className: cn("cursor-pointer", className), children });
276
305
  }
@@ -294,7 +323,7 @@ var HoverCardContent = React3.forwardRef(({ className, ...props }, ref) => /* @_
294
323
  {
295
324
  ref,
296
325
  className: cn(
297
- "absolute z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-4 text-popover-foreground shadow-md",
326
+ "absolute z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-4 text-popover-foreground shadow-md",
298
327
  className
299
328
  ),
300
329
  role: "tooltip",
@@ -302,6 +331,125 @@ var HoverCardContent = React3.forwardRef(({ className, ...props }, ref) => /* @_
302
331
  }
303
332
  ));
304
333
  HoverCardContent.displayName = "HoverCardContent";
334
+ var log = createLogger("useResolvedScope");
335
+ var appIdCache = /* @__PURE__ */ new Map();
336
+ var CACHE_TTL = 5 * 60 * 1e3;
337
+ function useResolvedScope({
338
+ supabase,
339
+ selectedOrganisationId,
340
+ selectedEventId,
341
+ selectedEventOrganisationId
342
+ }) {
343
+ const immediateOrganisationId = selectedEventOrganisationId || selectedOrganisationId || void 0;
344
+ const immediateEventId = selectedEventId || void 0;
345
+ const [appId, setAppId] = useState(void 0);
346
+ const [isResolvingAppId, setIsResolvingAppId] = useState(false);
347
+ const [error, setError] = useState(null);
348
+ const appName = getCurrentAppName();
349
+ useEffect(() => {
350
+ let cancelled = false;
351
+ const resolveAppId = async () => {
352
+ if (!supabase && !selectedOrganisationId && !selectedEventId) {
353
+ if (!cancelled) {
354
+ setAppId(void 0);
355
+ setIsResolvingAppId(false);
356
+ setError(null);
357
+ }
358
+ return;
359
+ }
360
+ setIsResolvingAppId(true);
361
+ setError(null);
362
+ try {
363
+ const appName2 = getCurrentAppName();
364
+ let resolvedAppId = void 0;
365
+ if (supabase && appName2) {
366
+ try {
367
+ const { data: session } = await supabase.auth.getSession();
368
+ if (!session?.session) {
369
+ log.debug(`Skipping app resolution for "${appName2}" - user not authenticated`);
370
+ } else {
371
+ const cached = appIdCache.get(appName2);
372
+ const now = Date.now();
373
+ if (cached && now - cached.timestamp < CACHE_TTL) {
374
+ resolvedAppId = cached.appId;
375
+ } else {
376
+ const { data: app, error: error2 } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName2).eq("is_active", true).single();
377
+ if (error2) {
378
+ if (error2.code === "406" || error2.code === "PGRST116" || error2.message?.includes("406")) {
379
+ log.debug(`App resolution blocked by RLS for "${appName2}" - user may not be authenticated`);
380
+ resolvedAppId = void 0;
381
+ } else {
382
+ const { data: inactiveApp } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName2).single();
383
+ if (inactiveApp) {
384
+ log.error(`App "${appName2}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
385
+ resolvedAppId = void 0;
386
+ } else {
387
+ log.error(`App "${appName2}" not found in rbac_apps table`, { error: error2 });
388
+ resolvedAppId = void 0;
389
+ }
390
+ }
391
+ } else if (app) {
392
+ resolvedAppId = app.id;
393
+ appIdCache.set(appName2, { appId: resolvedAppId, timestamp: now });
394
+ }
395
+ }
396
+ }
397
+ } catch (error2) {
398
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
399
+ if (!errorMessage.includes("406") && !errorMessage.includes("PGRST116")) {
400
+ log.error("Unexpected error resolving app ID:", error2);
401
+ } else {
402
+ log.debug("App resolution skipped - authentication required");
403
+ }
404
+ }
405
+ }
406
+ if (!cancelled) {
407
+ setAppId(resolvedAppId);
408
+ setIsResolvingAppId(false);
409
+ setError(null);
410
+ }
411
+ } catch (err) {
412
+ if (!cancelled) {
413
+ setError(err);
414
+ setIsResolvingAppId(false);
415
+ }
416
+ }
417
+ };
418
+ resolveAppId();
419
+ return () => {
420
+ cancelled = true;
421
+ };
422
+ }, [supabase, selectedOrganisationId, selectedEventId]);
423
+ const immediateScope = useMemo(() => {
424
+ if (appName === "PORTAL" || appName === "ADMIN") {
425
+ return {
426
+ organisationId: void 0,
427
+ eventId: void 0,
428
+ appId: appId || void 0
429
+ };
430
+ }
431
+ const scope = {};
432
+ if (immediateOrganisationId) {
433
+ scope.organisationId = immediateOrganisationId;
434
+ }
435
+ if (immediateEventId) {
436
+ scope.eventId = immediateEventId;
437
+ }
438
+ if (appId) {
439
+ scope.appId = appId;
440
+ }
441
+ if (!scope.organisationId && !scope.appId) {
442
+ return null;
443
+ }
444
+ return scope;
445
+ }, [immediateOrganisationId, immediateEventId, appId, appName]);
446
+ return {
447
+ resolvedScope: immediateScope,
448
+ isLoading: isResolvingAppId,
449
+ // Only true while appId resolves
450
+ error
451
+ };
452
+ }
305
453
  function useAccessLevel(userId, scope) {
306
454
  const [accessLevel, setAccessLevel] = useState("viewer");
307
455
  const [isLoading, setIsLoading] = useState(true);
@@ -316,9 +464,15 @@ function useAccessLevel(userId, scope) {
316
464
  try {
317
465
  setIsLoading(true);
318
466
  setError(null);
319
- const { isSuperAdmin: checkSuperAdmin } = await import('./api-F47QJ7FX.js');
320
- const isSuperAdminUser = await checkSuperAdmin(userId);
321
- if (isSuperAdminUser) {
467
+ const { isSuperAdmin: checkSuperAdmin } = await import('./api-BZR2CYXL.js');
468
+ const superResult = await checkSuperAdmin(userId);
469
+ if (!superResult.ok) {
470
+ setError(new Error(superResult.error.message));
471
+ setAccessLevel("viewer");
472
+ setIsLoading(false);
473
+ return;
474
+ }
475
+ if (superResult.data) {
322
476
  setAccessLevel("super");
323
477
  setIsLoading(false);
324
478
  return;
@@ -330,8 +484,14 @@ function useAccessLevel(userId, scope) {
330
484
  setIsLoading(false);
331
485
  return;
332
486
  }
333
- const level = await getAccessLevel({ userId, scope }, appName);
334
- setAccessLevel(level);
487
+ const result = await getAccessLevel({ userId, scope }, appName);
488
+ if (!result.ok) {
489
+ setError(new Error(result.error.message));
490
+ setAccessLevel("viewer");
491
+ setIsLoading(false);
492
+ return;
493
+ }
494
+ setAccessLevel(result.data);
335
495
  } catch (err) {
336
496
  const error2 = err instanceof Error ? err : new Error("Failed to fetch access level");
337
497
  setError(error2);
@@ -362,91 +522,132 @@ function scopeEqual(a, b) {
362
522
  return a.organisationId === b.organisationId && a.eventId === b.eventId && a.appId === b.appId;
363
523
  }
364
524
 
525
+ // src/rbac/hooks/permissions/runPermissionCheck.ts
526
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
527
+ function isEmptyString(s) {
528
+ return s === null || s === void 0 || typeof s === "string" && s.trim() === "";
529
+ }
530
+ async function runPermissionCheck(params) {
531
+ const { userId, scope, permission, pageId, useCache, appName, isSuperAdmin } = params;
532
+ if (!userId) {
533
+ return { ok: true, data: false };
534
+ }
535
+ if (isSuperAdmin === true) {
536
+ return { ok: true, data: true };
537
+ }
538
+ if (isSuperAdmin === null) {
539
+ return { ok: true, data: false };
540
+ }
541
+ if (!scope || typeof scope !== "object") {
542
+ return { ok: true, data: false };
543
+ }
544
+ const organisationId = scope.organisationId;
545
+ const eventId = scope.eventId;
546
+ const appId = scope.appId;
547
+ const isPagePermission = permission.includes(":page.") || !!pageId;
548
+ const requiresOrgId = !isPagePermission;
549
+ if (requiresOrgId && isEmptyString(organisationId)) {
550
+ return { ok: true, data: false };
551
+ }
552
+ const isPageName = pageId && typeof pageId === "string" && !UUID_REGEX.test(pageId);
553
+ const needsAppIdForPageName = isPagePermission && !!isPageName;
554
+ if (needsAppIdForPageName && isEmptyString(appId)) {
555
+ return { ok: true, data: false };
556
+ }
557
+ const validScope = {
558
+ ...organisationId ? { organisationId } : {},
559
+ ...eventId ? { eventId } : {},
560
+ ...appId ? { appId } : {}
561
+ };
562
+ if (useCache) {
563
+ return isPermittedCached({ userId, scope: validScope, permission, pageId }, appName);
564
+ }
565
+ return isPermitted(
566
+ { userId, scope: validScope, permission, pageId },
567
+ appName,
568
+ isSuperAdmin === false ? false : null
569
+ );
570
+ }
571
+
365
572
  // src/rbac/hooks/permissions/useCan.ts
366
- function useCan(userId, scope, permission, pageId, useCache = true, precomputedSuperAdmin = null, appName) {
573
+ function useSuperAdminForCan(userId, precomputedSuperAdmin) {
367
574
  const [isSuperAdmin, setIsSuperAdmin] = useState(precomputedSuperAdmin ?? null);
368
- const initialCan = precomputedSuperAdmin === true ? true : false;
369
- const initialIsLoading = precomputedSuperAdmin === true ? false : true;
370
- const [can, setCan] = useState(initialCan);
371
- const [isLoading, setIsLoading] = useState(initialIsLoading);
372
- const [error, setError] = useState(null);
373
- const isValidScope = scope && typeof scope === "object";
374
- const organisationId = isValidScope ? scope.organisationId : void 0;
375
- const eventId = isValidScope ? scope.eventId : void 0;
376
- const appId = isValidScope ? scope.appId : void 0;
377
575
  useEffect(() => {
378
576
  if (precomputedSuperAdmin === true && isSuperAdmin !== true) {
379
577
  setIsSuperAdmin(true);
380
- setCan(true);
381
- setIsLoading(false);
382
- setError(null);
383
578
  } else if (precomputedSuperAdmin === false && isSuperAdmin !== false) {
384
579
  setIsSuperAdmin(false);
385
580
  }
386
581
  }, [precomputedSuperAdmin, isSuperAdmin]);
387
582
  useEffect(() => {
388
- if (precomputedSuperAdmin === null) {
389
- if (!userId) {
390
- setIsSuperAdmin(false);
391
- return;
392
- }
393
- let cancelled = false;
394
- const checkSuperAdmin = async () => {
395
- const startTime = Date.now();
396
- try {
397
- const { isSuperAdmin: checkSuperAdmin2 } = await import('./api-F47QJ7FX.js');
398
- const timeoutWarning = setTimeout(() => {
399
- if (!cancelled) {
400
- const logger = getRBACLogger();
401
- logger.warn("[useCan] Super admin check taking longer than 5 seconds", {
402
- userId,
403
- elapsedMs: Date.now() - startTime
404
- });
405
- }
406
- }, 5e3);
407
- const isSuper = await checkSuperAdmin2(userId);
408
- clearTimeout(timeoutWarning);
583
+ if (precomputedSuperAdmin !== null) return;
584
+ if (!userId) {
585
+ setIsSuperAdmin(false);
586
+ return;
587
+ }
588
+ let cancelled = false;
589
+ const checkSuperAdmin = async () => {
590
+ const startTime = Date.now();
591
+ try {
592
+ const { isSuperAdmin: checkSuperAdminFn } = await import('./api-BZR2CYXL.js');
593
+ const timeoutWarning = setTimeout(() => {
409
594
  if (!cancelled) {
410
- const elapsed = Date.now() - startTime;
411
- if (elapsed > 1e3) {
412
- const logger = getRBACLogger();
413
- logger.warn("[useCan] Super admin check took longer than expected", {
414
- userId,
415
- elapsedMs: elapsed
416
- });
417
- }
418
- setIsSuperAdmin(isSuper);
419
- if (isSuper) {
420
- setCan(true);
421
- setIsLoading(false);
422
- setError(null);
423
- }
595
+ getRBACLogger().warn("[useCan] Super admin check taking longer than 5 seconds", {
596
+ userId,
597
+ elapsedMs: Date.now() - startTime
598
+ });
424
599
  }
425
- } catch (err) {
426
- if (!cancelled) {
427
- const elapsed = Date.now() - startTime;
428
- const logger = getRBACLogger();
429
- logger.error("[useCan] Error checking super admin", {
600
+ }, 5e3);
601
+ const superResult = await checkSuperAdminFn(userId);
602
+ clearTimeout(timeoutWarning);
603
+ if (!cancelled) {
604
+ const elapsed = Date.now() - startTime;
605
+ if (elapsed > 1e3) {
606
+ getRBACLogger().warn("[useCan] Super admin check took longer than expected", {
430
607
  userId,
431
- error: err,
432
608
  elapsedMs: elapsed
433
609
  });
610
+ }
611
+ if (!superResult.ok) {
434
612
  setIsSuperAdmin(false);
613
+ return;
435
614
  }
615
+ const isSuper = superResult.data;
616
+ setIsSuperAdmin(isSuper);
436
617
  }
437
- };
438
- checkSuperAdmin();
439
- return () => {
440
- cancelled = true;
441
- };
442
- }
618
+ } catch (err) {
619
+ if (!cancelled) {
620
+ getRBACLogger().error("[useCan] Error checking super admin", {
621
+ userId,
622
+ error: err,
623
+ elapsedMs: Date.now() - startTime
624
+ });
625
+ setIsSuperAdmin(false);
626
+ }
627
+ }
628
+ };
629
+ checkSuperAdmin();
630
+ return () => {
631
+ cancelled = true;
632
+ };
443
633
  }, [userId, precomputedSuperAdmin]);
634
+ return { isSuperAdmin };
635
+ }
636
+ function useCan(userId, scope, permission, pageId, useCache = true, precomputedSuperAdmin = null, appName) {
637
+ const { isSuperAdmin } = useSuperAdminForCan(userId, precomputedSuperAdmin);
638
+ const initialCan = precomputedSuperAdmin === true ? true : false;
639
+ const initialIsLoading = precomputedSuperAdmin === true ? false : true;
640
+ const [can, setCan] = useState(initialCan);
641
+ const [isLoading, setIsLoading] = useState(initialIsLoading);
642
+ const [error, setError] = useState(null);
643
+ const isValidScope = scope && typeof scope === "object";
644
+ const organisationId = isValidScope ? scope.organisationId : void 0;
645
+ const eventId = isValidScope ? scope.eventId : void 0;
646
+ const appId = isValidScope ? scope.appId : void 0;
444
647
  useEffect(() => {
648
+ if (isSuperAdmin === true) return;
445
649
  const isPagePermission = permission.includes(":page.") || !!pageId;
446
650
  const requiresOrgId = !isPagePermission;
447
- if (isSuperAdmin === true) {
448
- return;
449
- }
450
651
  if (requiresOrgId && (!isValidScope || !organisationId || organisationId === null || typeof organisationId === "string" && organisationId.trim() === "")) {
451
652
  const timeoutId = setTimeout(() => {
452
653
  setError(new Error("Organisation context is required for permission checks"));
@@ -460,23 +661,22 @@ function useCan(userId, scope, permission, pageId, useCache = true, precomputedS
460
661
  }
461
662
  }, [isValidScope, organisationId, error, permission, pageId, isSuperAdmin]);
462
663
  const lastUserIdRef = useRef(null);
463
- useRef(null);
464
664
  const lastPermissionRef = useRef(null);
465
665
  const lastPageIdRef = useRef(null);
466
666
  const lastUseCacheRef = useRef(null);
467
667
  const lastIsSuperAdminRef = useRef(null);
668
+ const prevScopeRef = useRef(null);
468
669
  const stableScope = useMemo(() => {
469
- if (!isValidScope) {
470
- return null;
471
- }
472
- return {
473
- organisationId,
474
- eventId,
475
- appId
476
- };
670
+ if (!isValidScope) return null;
671
+ return { organisationId, eventId, appId };
477
672
  }, [isValidScope, organisationId, eventId, appId]);
478
- const prevScopeRef = useRef(null);
479
673
  useEffect(() => {
674
+ if (precomputedSuperAdmin === true) {
675
+ setCan(true);
676
+ setIsLoading(false);
677
+ setError(null);
678
+ return;
679
+ }
480
680
  const scopeChanged = !scopeEqual(prevScopeRef.current, stableScope);
481
681
  const isSuperAdminChanged = lastIsSuperAdminRef.current !== isSuperAdmin;
482
682
  if (lastUserIdRef.current !== userId || scopeChanged || lastPermissionRef.current !== permission || lastPageIdRef.current !== pageId || lastUseCacheRef.current !== useCache || isSuperAdminChanged) {
@@ -486,75 +686,55 @@ function useCan(userId, scope, permission, pageId, useCache = true, precomputedS
486
686
  lastPermissionRef.current = permission;
487
687
  lastPageIdRef.current = pageId;
488
688
  lastUseCacheRef.current = useCache;
489
- const checkPermission = async () => {
490
- if (!userId) {
491
- setCan(false);
492
- setIsLoading(false);
493
- return;
494
- }
495
- if (isSuperAdmin === true) {
496
- setCan(true);
497
- setIsLoading(false);
498
- setError(null);
499
- return;
500
- }
501
- if (isSuperAdmin === null) {
502
- setIsLoading(true);
503
- setCan(false);
504
- setError(null);
505
- return;
506
- }
507
- if (!isValidScope) {
508
- setIsLoading(true);
509
- setCan(false);
510
- setError(null);
511
- return;
512
- }
513
- const isPagePermission = permission.includes(":page.") || !!pageId;
514
- const requiresOrgId = !isPagePermission;
515
- const isPageName = pageId && typeof pageId === "string" && !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(pageId);
516
- const needsAppIdForPageName = isPagePermission && isPageName;
517
- if (requiresOrgId && (!organisationId || organisationId === null || typeof organisationId === "string" && organisationId.trim() === "")) {
518
- setIsLoading(true);
519
- setCan(false);
520
- setError(null);
521
- return;
522
- }
523
- if (needsAppIdForPageName && (!appId || appId === null || typeof appId === "string" && appId.trim() === "")) {
524
- setIsLoading(true);
689
+ if (!userId) {
690
+ setCan(false);
691
+ setIsLoading(false);
692
+ return;
693
+ }
694
+ if (isSuperAdmin === true) {
695
+ setCan(true);
696
+ setIsLoading(false);
697
+ setError(null);
698
+ return;
699
+ }
700
+ if (isSuperAdmin === null || !isValidScope) {
701
+ setIsLoading(true);
702
+ setCan(false);
703
+ setError(null);
704
+ return;
705
+ }
706
+ setIsLoading(true);
707
+ setError(null);
708
+ runPermissionCheck({
709
+ userId,
710
+ scope: stableScope,
711
+ permission,
712
+ pageId,
713
+ useCache,
714
+ appName,
715
+ isSuperAdmin
716
+ }).then((result) => {
717
+ if (!result.ok) {
718
+ setError(new Error(result.error.message));
525
719
  setCan(false);
526
- setError(null);
527
720
  return;
528
721
  }
529
- try {
530
- setIsLoading(true);
531
- setError(null);
532
- const validScope = {
533
- ...organisationId ? { organisationId } : {},
534
- ...eventId ? { eventId } : {},
535
- ...appId ? { appId } : {}
536
- };
537
- const result = useCache ? await isPermittedCached({ userId, scope: validScope, permission, pageId }, appName) : await isPermitted({ userId, scope: validScope, permission, pageId }, appName, isSuperAdmin === false ? false : null);
538
- setCan(result);
539
- } catch (err) {
540
- const logger = getRBACLogger();
541
- logger.error("Permission check error:", { userId, permission, error: err });
542
- setError(err instanceof Error ? err : new Error("Failed to check permission"));
543
- setCan(false);
544
- } finally {
545
- setIsLoading(false);
546
- }
547
- };
548
- checkPermission();
722
+ setCan(result.data);
723
+ setError(null);
724
+ }).catch((err) => {
725
+ getRBACLogger().error("Permission check error:", { userId, permission, error: err });
726
+ setError(err instanceof Error ? err : new Error("Failed to check permission"));
727
+ setCan(false);
728
+ }).finally(() => setIsLoading(false));
549
729
  }
550
- }, [userId, stableScope, permission, pageId, useCache, appName, isSuperAdmin, organisationId, eventId, appId, isValidScope]);
730
+ }, [userId, stableScope, permission, pageId, useCache, appName, isSuperAdmin, isValidScope, precomputedSuperAdmin]);
551
731
  const refetch = useCallback(async () => {
552
732
  if (!userId) {
553
733
  setCan(false);
554
734
  setIsLoading(false);
555
735
  return;
556
736
  }
557
- if (!isValidScope) {
737
+ if (!isValidScope || !stableScope) {
558
738
  setCan(false);
559
739
  setIsLoading(true);
560
740
  setError(null);
@@ -562,35 +742,46 @@ function useCan(userId, scope, permission, pageId, useCache = true, precomputedS
562
742
  }
563
743
  const isPagePermission = permission.includes(":page.") || !!pageId;
564
744
  const requiresOrgId = !isPagePermission;
565
- if (requiresOrgId && (!organisationId || organisationId === null || typeof organisationId === "string" && organisationId.trim() === "")) {
745
+ if (requiresOrgId && (!organisationId || typeof organisationId === "string" && organisationId.trim() === "")) {
566
746
  setCan(false);
567
747
  setIsLoading(true);
568
748
  setError(null);
569
749
  return;
570
750
  }
751
+ setIsLoading(true);
752
+ setError(null);
571
753
  try {
572
- setIsLoading(true);
573
- setError(null);
574
- const validScope = {
575
- ...organisationId ? { organisationId } : {},
576
- ...eventId ? { eventId } : {},
577
- ...appId ? { appId } : {}
578
- };
579
- const result = useCache ? await isPermittedCached({ userId, scope: validScope, permission, pageId }, appName) : await isPermitted({ userId, scope: validScope, permission, pageId }, appName, null);
580
- setCan(result);
754
+ const result = await runPermissionCheck({
755
+ userId,
756
+ scope: stableScope,
757
+ permission,
758
+ pageId,
759
+ useCache,
760
+ appName,
761
+ isSuperAdmin
762
+ });
763
+ if (!result.ok) {
764
+ setError(new Error(result.error.message));
765
+ setCan(false);
766
+ return;
767
+ }
768
+ setCan(result.data);
581
769
  } catch (err) {
582
770
  setError(err instanceof Error ? err : new Error("Failed to check permission"));
583
771
  setCan(false);
584
772
  } finally {
585
773
  setIsLoading(false);
586
774
  }
587
- }, [userId, isValidScope, organisationId, eventId, appId, permission, pageId, useCache, appName]);
588
- return useMemo(() => ({
589
- can,
590
- isLoading,
591
- error,
592
- refetch
593
- }), [can, isLoading, error, refetch]);
775
+ }, [userId, isValidScope, stableScope, organisationId, permission, pageId, useCache, appName, isSuperAdmin]);
776
+ return useMemo(
777
+ () => ({
778
+ can,
779
+ isLoading,
780
+ error,
781
+ refetch
782
+ }),
783
+ [can, isLoading, error, refetch]
784
+ );
594
785
  }
595
786
  function useMultiplePermissions(userId, scope, permissions, useCache = true) {
596
787
  const [results, setResults] = useState({});
@@ -621,7 +812,12 @@ function useMultiplePermissions(userId, scope, permissions, useCache = true) {
621
812
  const permissionResults = {};
622
813
  for (const permission of permissions) {
623
814
  const result = useCache ? await isPermittedCached({ userId, scope, permission }) : await isPermitted({ userId, scope, permission });
624
- permissionResults[permission] = result;
815
+ if (!result.ok) {
816
+ setError(new Error(result.error.message));
817
+ setResults({});
818
+ return;
819
+ }
820
+ permissionResults[permission] = result.data;
625
821
  }
626
822
  setResults(permissionResults);
627
823
  } catch (err) {
@@ -654,6 +850,37 @@ function useMultiplePermissions(userId, scope, permissions, useCache = true) {
654
850
  refetch: checkPermissions
655
851
  }), [results, isLoading, error, checkPermissions]);
656
852
  }
853
+
854
+ // src/rbac/utils/permissionMapHelpers.ts
855
+ function createPermissionMapHelpers(permissions) {
856
+ return {
857
+ hasPermission(permission) {
858
+ if (permissions["*"]) {
859
+ return true;
860
+ }
861
+ return permissions[permission] === true;
862
+ },
863
+ hasAnyPermission(permissionList) {
864
+ if (permissions["*"]) {
865
+ return true;
866
+ }
867
+ return permissionList.some((p) => permissions[p] === true);
868
+ },
869
+ hasAllPermissions(permissionList) {
870
+ if (permissions["*"]) {
871
+ return true;
872
+ }
873
+ return permissionList.every((p) => permissions[p] === true);
874
+ }
875
+ };
876
+ }
877
+
878
+ // src/rbac/utils/fetchPermissionMap.ts
879
+ async function fetchPermissionMapForScope(params) {
880
+ return getPermissionMap({ userId: params.userId, scope: params.scope });
881
+ }
882
+
883
+ // src/rbac/hooks/permissions/usePermissions.ts
657
884
  function usePermissions(userId, organisationId, eventId, appId) {
658
885
  const [permissions, setPermissions] = useState({});
659
886
  const [isLoading, setIsLoading] = useState(true);
@@ -696,11 +923,6 @@ function usePermissions(userId, organisationId, eventId, appId) {
696
923
  setIsLoading(false);
697
924
  return;
698
925
  }
699
- if (!userId) {
700
- setPermissions({});
701
- setIsLoading(false);
702
- return;
703
- }
704
926
  if (!orgId || orgId === null || typeof orgId === "string" && orgId.trim() === "") {
705
927
  setIsLoading(true);
706
928
  setError(null);
@@ -715,7 +937,14 @@ function usePermissions(userId, organisationId, eventId, appId) {
715
937
  eventId,
716
938
  appId
717
939
  };
718
- const permissionMap = await getPermissionMap({ userId, scope });
940
+ const result = await fetchPermissionMapForScope({ userId, scope });
941
+ if (!result.ok) {
942
+ setError(new Error(result.error.message));
943
+ setIsLoading(false);
944
+ isFetchingRef.current = false;
945
+ return;
946
+ }
947
+ const permissionMap = result.data;
719
948
  const permissionCount = Object.keys(permissionMap).length;
720
949
  setPermissions((prevPermissions) => {
721
950
  if (permissionCount === 0 && Object.keys(prevPermissions).length > 0) {
@@ -735,24 +964,10 @@ function usePermissions(userId, organisationId, eventId, appId) {
735
964
  };
736
965
  fetchPermissions();
737
966
  }, [fetchTrigger, userId, organisationId, eventId, appId, logger, orgId]);
738
- const hasPermission = useCallback((permission) => {
739
- if (permissions["*"]) {
740
- return true;
741
- }
742
- return permissions[permission] === true;
743
- }, [permissions]);
744
- const hasAnyPermission = useCallback((permissionList) => {
745
- if (permissions["*"]) {
746
- return true;
747
- }
748
- return permissionList.some((p) => permissions[p] === true);
749
- }, [permissions]);
750
- const hasAllPermissions = useCallback((permissionList) => {
751
- if (permissions["*"]) {
752
- return true;
753
- }
754
- return permissionList.every((p) => permissions[p] === true);
755
- }, [permissions]);
967
+ const { hasPermission, hasAnyPermission, hasAllPermissions } = useMemo(
968
+ () => createPermissionMapHelpers(permissions),
969
+ [permissions]
970
+ );
756
971
  const refetch = useCallback(async () => {
757
972
  if (isFetchingRef.current) {
758
973
  return;
@@ -776,145 +991,33 @@ function usePermissions(userId, organisationId, eventId, appId) {
776
991
  eventId,
777
992
  appId
778
993
  };
779
- const permissionMap = await getPermissionMap({ userId, scope });
780
- setPermissions(permissionMap);
994
+ const result = await fetchPermissionMapForScope({ userId, scope });
995
+ if (!result.ok) {
996
+ setError(new Error(result.error.message));
997
+ return;
998
+ }
999
+ setPermissions(result.data);
781
1000
  } catch (err) {
782
- const logger2 = getRBACLogger();
783
- logger2.error("Failed to refetch permissions:", err);
1001
+ const refetchLogger = getRBACLogger();
1002
+ refetchLogger.error("Failed to refetch permissions:", err);
784
1003
  setError(err instanceof Error ? err : new Error("Failed to fetch permissions"));
785
1004
  } finally {
786
1005
  setIsLoading(false);
787
1006
  isFetchingRef.current = false;
788
1007
  }
789
1008
  }, [userId, eventId, appId, orgId]);
790
- return useMemo(() => ({
791
- permissions,
792
- isLoading,
793
- error,
794
- hasPermission,
795
- hasAnyPermission,
796
- hasAllPermissions,
797
- refetch
798
- }), [permissions, isLoading, error, hasPermission, hasAnyPermission, hasAllPermissions, refetch]);
799
- }
800
- var log = createLogger("useResolvedScope");
801
- var appIdCache = /* @__PURE__ */ new Map();
802
- var CACHE_TTL = 5 * 60 * 1e3;
803
- function useResolvedScope({
804
- supabase,
805
- selectedOrganisationId,
806
- selectedEventId,
807
- selectedEventOrganisationId
808
- }) {
809
- const immediateOrganisationId = selectedEventOrganisationId || selectedOrganisationId || void 0;
810
- const immediateEventId = selectedEventId || void 0;
811
- const [appId, setAppId] = useState(void 0);
812
- const [isResolvingAppId, setIsResolvingAppId] = useState(false);
813
- const [error, setError] = useState(null);
814
- const appName = getCurrentAppName();
815
- useEffect(() => {
816
- let cancelled = false;
817
- const resolveAppId = async () => {
818
- if (!supabase && !selectedOrganisationId && !selectedEventId) {
819
- if (!cancelled) {
820
- setAppId(void 0);
821
- setIsResolvingAppId(false);
822
- setError(null);
823
- }
824
- return;
825
- }
826
- setIsResolvingAppId(true);
827
- setError(null);
828
- try {
829
- const appName2 = getCurrentAppName();
830
- let resolvedAppId = void 0;
831
- if (supabase && appName2) {
832
- try {
833
- const { data: session } = await supabase.auth.getSession();
834
- if (!session?.session) {
835
- log.debug(`Skipping app resolution for "${appName2}" - user not authenticated`);
836
- } else {
837
- const cached = appIdCache.get(appName2);
838
- const now = Date.now();
839
- if (cached && now - cached.timestamp < CACHE_TTL) {
840
- resolvedAppId = cached.appId;
841
- } else {
842
- const { data: app, error: error2 } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName2).eq("is_active", true).single();
843
- if (error2) {
844
- if (error2.code === "406" || error2.code === "PGRST116" || error2.message?.includes("406")) {
845
- log.debug(`App resolution blocked by RLS for "${appName2}" - user may not be authenticated`);
846
- resolvedAppId = void 0;
847
- } else {
848
- const { data: inactiveApp } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName2).single();
849
- if (inactiveApp) {
850
- log.error(`App "${appName2}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
851
- resolvedAppId = void 0;
852
- } else {
853
- log.error(`App "${appName2}" not found in rbac_apps table`, { error: error2 });
854
- resolvedAppId = void 0;
855
- }
856
- }
857
- } else if (app) {
858
- resolvedAppId = app.id;
859
- appIdCache.set(appName2, { appId: resolvedAppId, timestamp: now });
860
- }
861
- }
862
- }
863
- } catch (error2) {
864
- const errorMessage = error2 instanceof Error ? error2.message : String(error2);
865
- if (!errorMessage.includes("406") && !errorMessage.includes("PGRST116")) {
866
- log.error("Unexpected error resolving app ID:", error2);
867
- } else {
868
- log.debug("App resolution skipped - authentication required");
869
- }
870
- }
871
- }
872
- if (!cancelled) {
873
- setAppId(resolvedAppId);
874
- setIsResolvingAppId(false);
875
- setError(null);
876
- }
877
- } catch (err) {
878
- if (!cancelled) {
879
- setError(err);
880
- setIsResolvingAppId(false);
881
- }
882
- }
883
- };
884
- resolveAppId();
885
- return () => {
886
- cancelled = true;
887
- };
888
- }, [supabase, selectedOrganisationId, selectedEventId]);
889
- const immediateScope = useMemo(() => {
890
- if (appName === "PORTAL" || appName === "ADMIN") {
891
- return {
892
- organisationId: void 0,
893
- eventId: void 0,
894
- appId: appId || void 0
895
- };
896
- }
897
- const scope = {};
898
- if (immediateOrganisationId) {
899
- scope.organisationId = immediateOrganisationId;
900
- }
901
- if (immediateEventId) {
902
- scope.eventId = immediateEventId;
903
- }
904
- if (appId) {
905
- scope.appId = appId;
906
- }
907
- if (!scope.organisationId && !scope.appId) {
908
- return null;
909
- }
910
- return scope;
911
- }, [immediateOrganisationId, immediateEventId, appId, appName]);
912
- return {
913
- resolvedScope: immediateScope,
914
- isLoading: isResolvingAppId,
915
- // Only true while appId resolves
916
- error
917
- };
1009
+ return useMemo(
1010
+ () => ({
1011
+ permissions,
1012
+ isLoading,
1013
+ error,
1014
+ hasPermission,
1015
+ hasAnyPermission,
1016
+ hasAllPermissions,
1017
+ refetch
1018
+ }),
1019
+ [permissions, isLoading, error, hasPermission, hasAnyPermission, hasAllPermissions, refetch]
1020
+ );
918
1021
  }
919
1022
  var AlertContext = React3.createContext({ variant: "default" });
920
1023
  var getAlertClasses = (variant = "default") => {
@@ -974,4 +1077,4 @@ var AlertDescription = React3.forwardRef(({ className, ...props }, ref) => {
974
1077
  });
975
1078
  AlertDescription.displayName = "AlertDescription";
976
1079
 
977
- export { Alert, AlertDescription, AlertTitle, Button, ButtonGroup, Card, CardActions, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Tooltip, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger, scopeEqual, useAccessLevel, useCan, useMultiplePermissions, usePermissions, useResolvedScope };
1080
+ export { Alert, AlertDescription, AlertTitle, Button, ButtonGroup, Card, CardActions, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, IconButton, Tooltip, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger, mergeRefs, scopeEqual, useAccessLevel, useCan, useMultiplePermissions, usePermissions, useResolvedScope };