@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,7 +1,7 @@
1
1
  /**
2
2
  * @file Unified Auth Provider Integration Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Providers/Services/__tests__
4
+ * @module Providers/Services
5
5
  * @since 0.1.0
6
6
  *
7
7
  * Integration tests for UnifiedAuthProvider.
@@ -10,14 +10,14 @@
10
10
 
11
11
  import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
12
12
  import { render, screen, waitFor } from '@testing-library/react';
13
- import { UnifiedAuthProvider, useUnifiedAuth } from '../UnifiedAuthProvider';
13
+ import { UnifiedAuthProvider, useUnifiedAuth } from './UnifiedAuthProvider';
14
14
  import { type SupabaseClient } from '@supabase/supabase-js';
15
- import { Logger, LogLevel } from '../../../utils/core/logger';
15
+ import { Logger, LogLevel } from '../../utils/core/logger';
16
16
 
17
- // Unmock UnifiedAuthProvider to test the real implementation
18
- vi.unmock('../../../providers/services/UnifiedAuthProvider');
17
+ // Unmock so we test the real UnifiedAuthProvider (global setup mocks it with user-123 / Test App)
18
+ vi.unmock('./UnifiedAuthProvider');
19
19
 
20
- // Mock Supabase client
20
+ // Mock Supabase client - getSession/getUser must return Promises so AuthService.restoreSession() gets null session
21
21
  const createMockSupabaseClient = (): SupabaseClient => ({
22
22
  auth: {
23
23
  signInWithPassword: vi.fn(),
@@ -26,9 +26,12 @@ const createMockSupabaseClient = (): SupabaseClient => ({
26
26
  resetPasswordForEmail: vi.fn(),
27
27
  updateUser: vi.fn(),
28
28
  refreshSession: vi.fn(),
29
- getSession: vi.fn(),
30
- getUser: vi.fn(),
31
- onAuthStateChange: vi.fn(),
29
+ getSession: vi.fn().mockResolvedValue({ data: { session: null }, error: null }),
30
+ getUser: vi.fn().mockResolvedValue({ data: { user: null }, error: null }),
31
+ onAuthStateChange: vi.fn().mockReturnValue({
32
+ data: { subscription: { unsubscribe: vi.fn() } },
33
+ error: null,
34
+ }),
32
35
  },
33
36
  from: vi.fn(),
34
37
  rpc: vi.fn(),
@@ -47,8 +50,8 @@ function TestComponent() {
47
50
  <p data-testid="app-name">{auth.appName}</p>
48
51
  <p data-testid="permissions-count">{0}</p>
49
52
  <p data-testid="roles-count">{0}</p>
50
- <p data-testid="organisations-count">{auth.organisations.length}</p>
51
- <p data-testid="events-count">{auth.events.length}</p>
53
+ <p data-testid="organisations-count">{auth.organisations?.length ?? 0}</p>
54
+ <p data-testid="events-count">{auth.events?.length ?? 0}</p>
52
55
  </section>
53
56
  );
54
57
  }
@@ -8,7 +8,8 @@
8
8
  * Note: RBAC functionality is available via useRBAC() hook from '@jmruthers/pace-core/rbac'
9
9
  */
10
10
 
11
- import React, { useMemo, useCallback, useRef, useEffect, useState, useReducer } from 'react';
11
+ import React, { useMemo, useCallback, useRef, useEffect, useState } from 'react';
12
+ import { flushSync } from 'react-dom';
12
13
  import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
13
14
  import type { Event } from '../../types/event';
14
15
  import type { SessionRestorationState } from '../../types/auth';
@@ -24,7 +25,15 @@ import { useInactivityService } from '../../hooks/services/useInactivityService'
24
25
  import { useSessionRestoration } from '../../hooks/useSessionRestoration';
25
26
  import { logger } from '../../utils/core/logger';
26
27
  import { setupRBAC, isRBACInitialized } from '../../rbac/api';
27
- import { UnifiedAuthContext, type UnifiedAuthContextType } from './UnifiedAuthContext';
28
+ import { setPrintAppName } from '../../theming/runtime';
29
+ import { UnifiedAuthContext } from './UnifiedAuthContext';
30
+ import {
31
+ useAppIdResolution,
32
+ useUnifiedAuthSubscriptions,
33
+ useUnifiedAuthContextValue,
34
+ type UnifiedAuthContextState,
35
+ type UnifiedAuthContextCallbacks,
36
+ } from './useUnifiedAuthContextValue';
28
37
 
29
38
  // Re-export UserEventAccess type
30
39
  /**
@@ -69,230 +78,40 @@ export interface UnifiedAuthProviderProps {
69
78
  dangerouslyDisableInactivity?: boolean; // Dev-only; must not disable in production
70
79
  }
71
80
 
72
- // Internal component that combines all contexts
73
- function UnifiedAuthContextProvider({
74
- children,
75
- appName,
76
- supabaseClient: supabaseClientProp,
77
- ..._props
78
- }: UnifiedAuthProviderProps) {
79
- const authService = useAuthService();
80
- const organisationService = useOrganisationService();
81
- const inactivityService = useInactivityService();
82
- const sessionRestorationState = useSessionRestoration();
83
- const {
84
- hasTimedOut: sessionRestorationTimedOut,
85
- timeoutMs: sessionRestorationTimeoutMs,
86
- isRestoring,
87
- restorationComplete,
88
- restorationError,
89
- } = sessionRestorationState;
90
- const sessionRestoration: SessionRestorationState = useMemo(() => ({
91
- isRestoring,
92
- restorationComplete,
93
- restorationError,
94
- }), [isRestoring, restorationComplete, restorationError]);
95
-
96
- // App config removed - scope is now page-level only (rbac_app_pages.scope_type)
97
-
98
- // Call hook unconditionally - if provider is missing, it will throw
99
- // Errors should be handled by error boundaries at a higher level
100
- // We cannot conditionally call hooks
101
- const eventService = useEventService();
102
-
103
- // Get current auth state - these will trigger re-renders when services change
104
- const currentUser = authService.getUser();
105
- const currentSession = authService.getSession();
81
+ /** Build state and callbacks from services. Extracted to keep UnifiedAuthContextProvider under max-lines. */
82
+ function useUnifiedAuthStateAndCallbacks(
83
+ authService: ReturnType<typeof useAuthService>,
84
+ organisationService: ReturnType<typeof useOrganisationService>,
85
+ eventService: ReturnType<typeof useEventService>,
86
+ inactivityService: ReturnType<typeof useInactivityService>,
87
+ sessionRestoration: SessionRestorationState,
88
+ sessionRestorationTimedOut: boolean,
89
+ sessionRestorationTimeoutMs: number,
90
+ appName: string,
91
+ userOverride?: User | null,
92
+ sessionOverride?: Session | null
93
+ ): { state: UnifiedAuthContextState; callbacks: UnifiedAuthContextCallbacks } {
94
+ const currentUser = userOverride !== undefined ? userOverride : authService.getUser();
95
+ const currentSession = sessionOverride !== undefined ? sessionOverride : authService.getSession();
106
96
  const isAuth = !!(currentUser && currentSession);
107
-
108
- // Stabilize supabase client reference to prevent infinite re-renders
109
- // Memoize the supabaseClient prop to ensure a stable reference across renders
110
- // This is critical for preventing infinite loops when supabase is used in useEffect dependency arrays
111
- // The reference will only change when supabaseClientProp actually changes (different instance)
112
- // If the consuming app creates the client once and reuses it, this will be stable
113
- const supabase = useMemo(() => supabaseClientProp, [supabaseClientProp]);
114
-
115
- // Resolve appId immediately when user logs in (don't wait for organisation/event)
116
- // This makes appId available early for navigation menu filtering
117
- const [appId, setAppId] = useState<string | undefined>(undefined);
118
-
119
-
120
- const isResolvingAppIdRef = useRef(false);
121
- const resolvedAppIdRef = useRef<string | undefined>(undefined);
122
- const resolvedUserIdRef = useRef<string | undefined>(undefined);
123
-
124
- useEffect(() => {
125
- // Clear appId when user logs out or changes
126
- if (!isAuth) {
127
- // User logged out - clear all refs and state
128
- resolvedAppIdRef.current = undefined;
129
- resolvedUserIdRef.current = undefined;
130
- setAppId(undefined);
131
- return;
132
- }
133
-
134
- // User changed - clear previous resolution to allow re-resolution for new user
135
- if (currentUser?.id && resolvedUserIdRef.current && resolvedUserIdRef.current !== currentUser.id) {
136
- resolvedAppIdRef.current = undefined;
137
- resolvedUserIdRef.current = undefined;
138
- setAppId(undefined);
139
- }
140
-
141
- // Resolve appId as soon as we have user + supabase + appName
142
- // Don't wait for organisation or event - appId resolution only needs user + appName
143
- // Extract userId to stable const to prevent reference issues
144
- const currentUserId = currentUser?.id;
145
-
146
- // Only resolve if we haven't already resolved for this user
147
- if (
148
- isAuth &&
149
- currentUserId &&
150
- supabase &&
151
- appName &&
152
- resolvedUserIdRef.current !== currentUserId && // Haven't resolved for this user yet
153
- !isResolvingAppIdRef.current
154
- ) {
155
- // CRITICAL FIX: Set refs IMMEDIATELY (synchronously) before async operation
156
- // This prevents race conditions where effect re-runs before async completes
157
- isResolvingAppIdRef.current = true;
158
- resolvedUserIdRef.current = currentUserId; // Set BEFORE async, not after
159
-
160
- const userId = currentUserId;
161
- const appNameValue = appName;
162
-
163
- // Resolve appId immediately
164
- import('../../rbac/api').then(async ({ resolveAppContext, setupRBAC }) => {
165
- try {
166
- // Ensure RBAC is initialized (idempotent - safe to call multiple times)
167
- setupRBAC(supabase);
168
-
169
- const result = await resolveAppContext({
170
- userId,
171
- appName: appNameValue
172
- });
173
-
174
- if (result?.appId) {
175
- resolvedAppIdRef.current = result.appId;
176
- // resolvedUserIdRef already set above to prevent race conditions
177
- setAppId(result.appId);
178
- } else {
179
- // No appId returned - reset ref to allow retry
180
- resolvedUserIdRef.current = undefined;
181
- }
182
- } catch (error) {
183
- logger.error('UnifiedAuthProvider', 'Failed to resolve appId on login', {
184
- error: error instanceof Error ? error.message : String(error),
185
- appName: appNameValue,
186
- userId
187
- });
188
- // Reset ref on error to allow retry
189
- resolvedUserIdRef.current = undefined;
190
- } finally {
191
- isResolvingAppIdRef.current = false;
192
- }
193
- }).catch((importError) => {
194
- logger.error('UnifiedAuthProvider', 'Failed to import RBAC API', importError);
195
- isResolvingAppIdRef.current = false;
196
- // Reset ref on import error to allow retry
197
- resolvedUserIdRef.current = undefined;
198
- });
199
- }
200
- }, [isAuth, currentUser?.id, supabase, appName]); // Removed appId from deps - it's the output, not an input. currentUser?.id is stable primitive.
201
-
202
97
 
203
- // Subscribe to service state changes to trigger re-renders
204
- // Use useReducer to force updates when services notify
205
- const [, forceUpdate] = useReducer(x => x + 1, 0);
206
- const forceUpdateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
207
-
208
- const debouncedForceUpdate = useCallback(() => {
209
- if (forceUpdateTimeoutRef.current) {
210
- clearTimeout(forceUpdateTimeoutRef.current);
211
- }
212
-
213
- forceUpdateTimeoutRef.current = setTimeout(() => {
214
- forceUpdate();
215
- forceUpdateTimeoutRef.current = null;
216
- }, 100); // Batch updates - 100ms debounce to prevent excessive re-renders
217
- // Reduced from 16ms to 100ms to better batch service state updates
218
- // and prevent flickering when multiple services update in quick succession
219
- }, [forceUpdate]);
220
-
221
- // Use refs for services to avoid dependency on service instances
222
- // This prevents re-subscriptions when service instances change reference
223
- const authServiceRef = useRef(authService);
224
- const organisationServiceRef = useRef(organisationService);
225
- const eventServiceRef = useRef(eventService);
226
- const inactivityServiceRef = useRef(inactivityService);
227
-
228
- // Update refs when services change
229
- useEffect(() => {
230
- authServiceRef.current = authService;
231
- organisationServiceRef.current = organisationService;
232
- eventServiceRef.current = eventService;
233
- inactivityServiceRef.current = inactivityService;
234
- }, [authService, organisationService, eventService, inactivityService]);
235
-
236
- // Subscribe using refs - only depends on debouncedForceUpdate
237
- // This prevents re-subscriptions when service instances change
238
- useEffect(() => {
239
- // Subscribe to all service changes using current refs
240
- const unsubscribeAuth = authServiceRef.current.subscribe(debouncedForceUpdate);
241
- const unsubscribeOrg = organisationServiceRef.current.subscribe(debouncedForceUpdate);
242
- const unsubscribeEvent = eventServiceRef.current.subscribe(debouncedForceUpdate);
243
- const unsubscribeInactivity = inactivityServiceRef.current.subscribe(debouncedForceUpdate);
244
-
245
- return () => {
246
- unsubscribeAuth();
247
- unsubscribeOrg();
248
- unsubscribeEvent();
249
- unsubscribeInactivity();
250
-
251
- if (forceUpdateTimeoutRef.current) {
252
- clearTimeout(forceUpdateTimeoutRef.current);
253
- }
254
- };
255
- }, [debouncedForceUpdate]);
256
-
257
- // Get loading states - these will trigger re-renders when services change
258
98
  const authLoading = authService.isLoading();
259
99
  const orgLoading = organisationService.isLoading();
260
100
  const eventLoading = eventService.isLoading();
261
101
  const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
262
- // For ADMIN/PORTAL apps, don't block on organisation loading (super admins can proceed)
263
102
  const shouldIncludeOrgLoading = appName !== 'ADMIN' && appName !== 'PORTAL';
264
103
  const totalLoading = restorationLoading || authLoading || (shouldIncludeOrgLoading ? orgLoading : false) || eventLoading;
265
-
266
- // Extract all primitive values from services to use in dependencies
267
104
  const authError = authService.getError();
268
- // supabase is already declared above (line 198)
269
- const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
105
+ const selectedOrganisation = organisationService.getSelectedOrganisation();
270
106
  const organisationError = organisationService.getError();
271
-
272
- // Scope is now page-level only - use whatever organisation is selected
273
- // No app-level scope determination needed
274
- const selectedOrganisation = rawSelectedOrganisation;
275
107
  const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
276
108
  const isContextReady = organisationService.isContextReady();
277
-
278
- // Get raw data from services
279
109
  const rawEvents = eventService.getEvents();
280
110
  const rawOrganisations = organisationService.getOrganisations();
281
111
  const rawUserMemberships = organisationService.getUserMemberships();
282
-
283
- // Memoize arrays to prevent unnecessary context updates when service returns same data
284
- const events = useMemo(() => {
285
- return rawEvents;
286
- }, [rawEvents]);
287
-
288
- const organisations = useMemo(() => {
289
- return rawOrganisations;
290
- }, [rawOrganisations]);
291
-
292
- const userMemberships = useMemo(() => {
293
- return rawUserMemberships;
294
- }, [rawUserMemberships]);
295
-
112
+ const events = useMemo(() => rawEvents, [rawEvents]);
113
+ const organisations = useMemo(() => rawOrganisations, [rawOrganisations]);
114
+ const userMemberships = useMemo(() => rawUserMemberships, [rawUserMemberships]);
296
115
  const selectedEvent = eventService.getSelectedEvent();
297
116
  const eventError = eventService.getError();
298
117
  const showInactivityWarning = inactivityService.getShowInactivityWarning();
@@ -301,8 +120,6 @@ function UnifiedAuthContextProvider({
301
120
  const timeRemaining = inactivityService.getTimeRemaining();
302
121
  const showWarning = inactivityService.isWarningShown();
303
122
  const isTracking = inactivityService.isTracking();
304
-
305
- // Memoize inactivity values to prevent unnecessary context updates
306
123
  const inactivityState = useMemo(() => ({
307
124
  showInactivityWarning,
308
125
  inactivityTimeRemaining,
@@ -310,25 +127,15 @@ function UnifiedAuthContextProvider({
310
127
  timeRemaining,
311
128
  showWarning,
312
129
  isTracking,
313
- }), [
314
- showInactivityWarning,
315
- inactivityTimeRemaining,
316
- isIdle,
317
- timeRemaining,
318
- showWarning,
319
- isTracking,
320
- ]);
321
-
130
+ }), [showInactivityWarning, inactivityTimeRemaining, isIdle, timeRemaining, showWarning, isTracking]);
322
131
  const hasErrors = !!(authError || organisationError || eventError || sessionRestoration.restorationError);
323
132
 
324
- // Wrap all functions in useCallback to ensure stable references
325
133
  const signIn = useCallback((email: string, password?: string) => authService.signIn(email, password), [authService]);
326
134
  const signUp = useCallback((email: string, password: string) => authService.signUp(email, password), [authService]);
327
135
  const signOut = useCallback(() => authService.signOut(), [authService]);
328
136
  const resetPassword = useCallback((email: string) => authService.resetPassword(email), [authService]);
329
137
  const updatePassword = useCallback((password: string) => authService.updatePassword(password), [authService]);
330
138
  const refreshSession = useCallback(() => authService.refreshSession(), [authService]);
331
-
332
139
  const switchOrganisation = useCallback((orgId: string) => organisationService.switchOrganisation(orgId), [organisationService]);
333
140
  const getUserRole = useCallback((orgId?: string) => organisationService.getUserRole(orgId), [organisationService]);
334
141
  const validateOrganisationAccess = useCallback((orgId: string) => organisationService.validateOrganisationAccess(orgId), [organisationService]);
@@ -336,10 +143,8 @@ function UnifiedAuthContextProvider({
336
143
  const ensureOrganisationContext = useCallback(() => organisationService.ensureOrganisationContext(), [organisationService]);
337
144
  const isOrganisationSecure = useCallback(() => organisationService.isOrganisationSecure(), [organisationService]);
338
145
  const getPrimaryOrganisation = useCallback(() => organisationService.getPrimaryOrganisation(), [organisationService]);
339
-
340
146
  const setSelectedEvent = useCallback((event: Event | null) => eventService.setSelectedEvent(event), [eventService]);
341
147
  const refreshEvents = useCallback(() => eventService.refreshEvents(), [eventService]);
342
-
343
148
  const resetActivity = useCallback(() => inactivityService.resetActivity(), [inactivityService]);
344
149
  const startTracking = useCallback(() => inactivityService.startTracking(), [inactivityService]);
345
150
  const stopTracking = useCallback(() => inactivityService.stopTracking(), [inactivityService]);
@@ -347,115 +152,12 @@ function UnifiedAuthContextProvider({
347
152
  const handleStaySignedIn = useCallback(() => inactivityService.handleStaySignedIn(), [inactivityService]);
348
153
  const handleSignOutNow = useCallback(() => inactivityService.handleSignOutNow(), [inactivityService]);
349
154
 
350
- // Use ref to track previous state for conditional logging (dev only)
351
- const prevStateRef = useRef<{
352
- isAuthenticated: boolean;
353
- userEmail: string | undefined;
354
- totalLoading: boolean;
355
- } | null>(null);
356
-
357
- // Only log when state actually changes (dev mode detection)
358
- const isDev = import.meta.env.DEV || import.meta.env.MODE === 'development';
359
- if (isDev) {
360
- const currentState = {
361
- isAuthenticated: isAuth,
362
- userEmail: currentUser?.email,
363
- totalLoading,
364
- };
365
-
366
- const prevState = prevStateRef.current;
367
- if (!prevState ||
368
- prevState.isAuthenticated !== currentState.isAuthenticated ||
369
- prevState.userEmail !== currentState.userEmail ||
370
- prevState.totalLoading !== currentState.totalLoading) {
371
- // State change detected, notify subscribers
372
- prevStateRef.current = currentState;
373
- }
374
- }
375
-
376
- // Memoized combined context value - only depends on primitive values
377
- const contextValue = useMemo<UnifiedAuthContextType>(() => {
378
- return {
379
- // Auth state
380
- user: currentUser,
381
- session: currentSession,
382
- isAuthenticated: isAuth,
383
- authLoading: authLoading,
384
- authError: authError,
385
- supabase: supabase,
386
-
387
- // Auth methods
388
- signIn,
389
- signUp,
390
- signOut,
391
- resetPassword,
392
- updatePassword,
393
- refreshSession,
394
-
395
- // Organisation state
396
- selectedOrganisation: selectedOrganisation,
397
- selectedOrganisationId: selectedOrganisation?.id || null,
398
- organisations: organisations,
399
- userMemberships: userMemberships,
400
- organisationLoading: orgLoading,
401
- organisationError: organisationError,
402
- hasValidOrganisationContext: hasValidOrganisationContext,
403
- isContextReady: isContextReady,
404
-
405
- // Organisation methods
406
- switchOrganisation,
407
- getUserRole,
408
- validateOrganisationAccess,
409
- refreshOrganisations,
410
- ensureOrganisationContext,
411
- isOrganisationSecure,
412
- getPrimaryOrganisation,
413
-
414
- // Event state
415
- events: events,
416
- selectedEvent: selectedEvent,
417
- selectedEventId: selectedEvent?.event_id || null,
418
- eventLoading: eventLoading,
419
- eventError: eventError,
420
-
421
- // Event methods
422
- setSelectedEvent,
423
- refreshEvents,
424
-
425
- // Inactivity state
426
- showInactivityWarning: inactivityState.showInactivityWarning,
427
- inactivityTimeRemaining: inactivityState.inactivityTimeRemaining,
428
- isIdle: inactivityState.isIdle,
429
- timeRemaining: inactivityState.timeRemaining,
430
- showWarning: inactivityState.showWarning,
431
- isTracking: inactivityState.isTracking,
432
-
433
- // Inactivity methods
434
- resetActivity,
435
- startTracking,
436
- stopTracking,
437
- handleIdleLogout,
438
- handleStaySignedIn,
439
- handleSignOutNow,
440
-
441
- // Additional unified properties
442
- appName,
443
- appId, // Resolved immediately on login
444
- isLoading: totalLoading,
445
- hasErrors: hasErrors,
446
- sessionRestoration: sessionRestoration,
447
- sessionRestorationTimedOut,
448
- sessionRestorationTimeoutMs,
449
- };
450
- }, [
451
- // All primitive values extracted from services
452
- // Note: Arrays/objects from services are stable references (same reference unless data changes)
155
+ const state: UnifiedAuthContextState = useMemo(() => ({
453
156
  currentUser,
454
157
  currentSession,
455
158
  isAuth,
456
159
  authLoading,
457
160
  authError,
458
- supabase,
459
161
  selectedOrganisation,
460
162
  organisations,
461
163
  userMemberships,
@@ -467,38 +169,86 @@ function UnifiedAuthContextProvider({
467
169
  selectedEvent,
468
170
  eventLoading,
469
171
  eventError,
470
- inactivityState, // Use memoized object instead of individual values
172
+ inactivityState,
471
173
  totalLoading,
472
174
  hasErrors,
473
- appName,
474
- appId,
475
175
  sessionRestoration,
476
176
  sessionRestorationTimedOut,
477
177
  sessionRestorationTimeoutMs,
478
- // Stable function references from useCallback (services are stable, so callbacks are too)
479
- signIn,
480
- signUp,
481
- signOut,
482
- resetPassword,
483
- updatePassword,
484
- refreshSession,
485
- switchOrganisation,
486
- getUserRole,
487
- validateOrganisationAccess,
488
- refreshOrganisations,
489
- ensureOrganisationContext,
490
- isOrganisationSecure,
491
- getPrimaryOrganisation,
492
- setSelectedEvent,
493
- refreshEvents,
494
- resetActivity,
495
- startTracking,
496
- stopTracking,
497
- handleIdleLogout,
498
- handleStaySignedIn,
499
- handleSignOutNow,
178
+ }), [
179
+ currentUser, currentSession, isAuth, authLoading, authError, selectedOrganisation, organisations,
180
+ userMemberships, orgLoading, organisationError, hasValidOrganisationContext, isContextReady,
181
+ events, selectedEvent, eventLoading, eventError, inactivityState, totalLoading, hasErrors,
182
+ sessionRestoration, sessionRestorationTimedOut, sessionRestorationTimeoutMs,
183
+ ]);
184
+
185
+ const callbacks: UnifiedAuthContextCallbacks = useMemo(() => ({
186
+ signIn, signUp, signOut, resetPassword, updatePassword, refreshSession,
187
+ switchOrganisation, getUserRole, validateOrganisationAccess, refreshOrganisations,
188
+ ensureOrganisationContext, isOrganisationSecure, getPrimaryOrganisation,
189
+ setSelectedEvent, refreshEvents, resetActivity, startTracking, stopTracking,
190
+ handleIdleLogout, handleStaySignedIn, handleSignOutNow,
191
+ }), [
192
+ signIn, signUp, signOut, resetPassword, updatePassword, refreshSession,
193
+ switchOrganisation, getUserRole, validateOrganisationAccess, refreshOrganisations,
194
+ ensureOrganisationContext, isOrganisationSecure, getPrimaryOrganisation,
195
+ setSelectedEvent, refreshEvents, resetActivity, startTracking, stopTracking,
196
+ handleIdleLogout, handleStaySignedIn, handleSignOutNow,
500
197
  ]);
501
198
 
199
+ return { state, callbacks };
200
+ }
201
+
202
+ // Internal component that combines all contexts.
203
+ // When user/session are passed from ServiceAwareProviders, they are the subscription-updated values
204
+ // and must be used for the context so consumers see the same state (avoids stale authService.getUser() in same tick).
205
+ function UnifiedAuthContextProvider({
206
+ children,
207
+ appName,
208
+ supabaseClient: supabaseClientProp,
209
+ user: userFromParent,
210
+ session: sessionFromParent,
211
+ }: UnifiedAuthProviderProps & { user?: User | null; session?: Session | null }) {
212
+ const authService = useAuthService();
213
+ const organisationService = useOrganisationService();
214
+ const inactivityService = useInactivityService();
215
+ const eventService = useEventService();
216
+ const sessionRestorationState = useSessionRestoration();
217
+ const sessionRestoration: SessionRestorationState = useMemo(() => ({
218
+ isRestoring: sessionRestorationState.isRestoring,
219
+ restorationComplete: sessionRestorationState.restorationComplete,
220
+ restorationError: sessionRestorationState.restorationError,
221
+ }), [sessionRestorationState.isRestoring, sessionRestorationState.restorationComplete, sessionRestorationState.restorationError]);
222
+ const { hasTimedOut: sessionRestorationTimedOut, timeoutMs: sessionRestorationTimeoutMs } = sessionRestorationState;
223
+
224
+ const currentUser = userFromParent !== undefined ? userFromParent : authService.getUser();
225
+ const currentSession = sessionFromParent !== undefined ? sessionFromParent : authService.getSession();
226
+ const isAuth = !!(currentUser && currentSession);
227
+ const supabase = useMemo(() => supabaseClientProp, [supabaseClientProp]);
228
+
229
+ const appId = useAppIdResolution(supabase, appName, isAuth, currentUser?.id);
230
+ useUnifiedAuthSubscriptions(authService, organisationService, eventService, inactivityService);
231
+
232
+ const { state, callbacks } = useUnifiedAuthStateAndCallbacks(
233
+ authService,
234
+ organisationService,
235
+ eventService,
236
+ inactivityService,
237
+ sessionRestoration,
238
+ sessionRestorationTimedOut,
239
+ sessionRestorationTimeoutMs,
240
+ appName,
241
+ currentUser,
242
+ currentSession
243
+ );
244
+
245
+ const contextValue = useUnifiedAuthContextValue(state, callbacks, appId, appName, supabase);
246
+
247
+ // Set --print-app-name once when app mounts so print headers/footers use the correct app name
248
+ useEffect(() => {
249
+ if (appName) setPrintAppName(appName);
250
+ }, [appName]);
251
+
502
252
  return (
503
253
  <UnifiedAuthContext.Provider value={contextValue}>
504
254
  {children}
@@ -574,15 +324,18 @@ function ServiceAwareProviders({
574
324
  const [userState, setUserState] = useState(() => authService.getUser());
575
325
  const [sessionState, setSessionState] = useState(() => authService.getSession());
576
326
 
577
- // Subscribe directly to auth service changes and update state immediately
327
+ // Subscribe directly to auth service changes and update state immediately.
328
+ // flushSync ensures the context updates before the next tick so consumers (e.g. PaceLoginPage
329
+ // useEffect, ProtectedRoute) see isAuthenticated/user on the very next render and avoid
330
+ // redirect-to-login races when navigation happens after signIn.
578
331
  useEffect(() => {
579
332
  const unsubscribe = authService.subscribe(() => {
580
- // Update state immediately when auth service notifies (bypasses debounce)
581
333
  const newUser = authService.getUser();
582
334
  const newSession = authService.getSession();
583
-
584
- setUserState(newUser);
585
- setSessionState(newSession);
335
+ flushSync(() => {
336
+ setUserState(newUser);
337
+ setSessionState(newSession);
338
+ });
586
339
  });
587
340
  return unsubscribe;
588
341
  }, [authService]);
@@ -616,6 +369,8 @@ function ServiceAwareProviders({
616
369
  <UnifiedAuthContextProvider
617
370
  appName={appName}
618
371
  supabaseClient={supabaseClient}
372
+ user={user}
373
+ session={session}
619
374
  persistState={persistState}
620
375
  enablePersistence={enablePersistence}
621
376
  requireOrganisationContext={requireOrganisationContext}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Service Contexts Unit Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Providers/Services/__tests__
4
+ * @module Providers/Services
5
5
  * @since 0.1.0
6
6
  *
7
7
  * Comprehensive unit tests for service context files covering:
@@ -13,11 +13,11 @@
13
13
  import React from 'react';
14
14
  import { render, screen } from '@testing-library/react';
15
15
  import { describe, it, expect, vi } from 'vitest';
16
- import { AuthServiceContext, type AuthServiceContextType } from '../AuthServiceContext';
17
- import { EventServiceContext, type EventServiceContextType } from '../EventServiceContext';
18
- import { InactivityServiceContext, type InactivityServiceContextType } from '../InactivityServiceContext';
19
- import { OrganisationServiceContext, type OrganisationServiceContextType } from '../OrganisationServiceContext';
20
- import { UnifiedAuthContext, type UnifiedAuthContextType } from '../UnifiedAuthContext';
16
+ import { AuthServiceContext, type AuthServiceContextType } from './AuthServiceContext';
17
+ import { EventServiceContext, type EventServiceContextType } from './EventServiceContext';
18
+ import { InactivityServiceContext, type InactivityServiceContextType } from './InactivityServiceContext';
19
+ import { OrganisationServiceContext, type OrganisationServiceContextType } from './OrganisationServiceContext';
20
+ import { UnifiedAuthContext, type UnifiedAuthContextType } from './UnifiedAuthContext';
21
21
 
22
22
  // Following testing standards: use timeout parameter to prevent hanging
23
23
  const TEST_TIMEOUT = 10000; // 10 seconds per test