@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
@@ -76,14 +76,15 @@ describe('App ID Resolver', () => {
76
76
 
77
77
  const result = await getAppId(mockSupabase as any, 'MY_APP');
78
78
 
79
- expect(result).toBe('app-123');
79
+ expect(result.ok).toBe(true);
80
+ expect(result.data).toBe('app-123');
80
81
  expect(mockSupabase.from).toHaveBeenCalledWith('rbac_apps');
81
82
  expect(mockQueryBuilder.select).toHaveBeenCalledWith('id');
82
83
  expect(mockQueryBuilder.ilike).toHaveBeenCalledWith('name', 'MY_APP');
83
84
  expect(mockQueryBuilder.eq).toHaveBeenCalledWith('is_active', true);
84
85
  }, TEST_TIMEOUT);
85
86
 
86
- it('returns null when app not found', async () => {
87
+ it('returns err when app not found', async () => {
87
88
  mockQueryBuilder.single.mockResolvedValue({
88
89
  data: null,
89
90
  error: { message: 'No rows found' }
@@ -91,7 +92,8 @@ describe('App ID Resolver', () => {
91
92
 
92
93
  const result = await getAppId(mockSupabase as any, 'NONEXISTENT_APP');
93
94
 
94
- expect(result).toBeNull();
95
+ expect(result.ok).toBe(false);
96
+ expect(result.error.message).toBe('No rows found');
95
97
  }, TEST_TIMEOUT);
96
98
 
97
99
  it('handles database errors gracefully', async () => {
@@ -102,7 +104,8 @@ describe('App ID Resolver', () => {
102
104
 
103
105
  const result = await getAppId(mockSupabase as any, 'MY_APP');
104
106
 
105
- expect(result).toBeNull();
107
+ expect(result.ok).toBe(false);
108
+ expect(result.error.message).toBe('Database error');
106
109
  const logger = getMockLogger();
107
110
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
108
111
  'Failed to resolve app ID for app name:',
@@ -116,7 +119,8 @@ describe('App ID Resolver', () => {
116
119
 
117
120
  const result = await getAppId(mockSupabase as any, 'MY_APP');
118
121
 
119
- expect(result).toBeNull();
122
+ expect(result.ok).toBe(false);
123
+ expect(result.error.message).toContain('Network error');
120
124
  const logger = getMockLogger();
121
125
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
122
126
  'Error resolving app ID for app name:',
@@ -129,14 +133,17 @@ describe('App ID Resolver', () => {
129
133
  const result1 = await getAppId(mockSupabase as any, null as any);
130
134
  const result2 = await getAppId(mockSupabase as any, undefined as any);
131
135
 
132
- expect(result1).toBeNull();
133
- expect(result2).toBeNull();
136
+ expect(result1.ok).toBe(true);
137
+ expect(result1.data).toBeNull();
138
+ expect(result2.ok).toBe(true);
139
+ expect(result2.data).toBeNull();
134
140
  });
135
141
 
136
142
  it('handles empty app name', async () => {
137
143
  const result = await getAppId(mockSupabase as any, '');
138
144
 
139
- expect(result).toBeNull();
145
+ expect(result.ok).toBe(true);
146
+ expect(result.data).toBeNull();
140
147
  }, TEST_TIMEOUT);
141
148
  });
142
149
 
@@ -157,7 +164,8 @@ describe('App ID Resolver', () => {
157
164
 
158
165
  const result = await getAppIds(mockSupabase as any, ['MY_APP']);
159
166
 
160
- expect(result).toEqual({ 'MY_APP': 'app-123' });
167
+ expect(result.ok).toBe(true);
168
+ expect(result.data).toEqual({ 'MY_APP': 'app-123' });
161
169
  }, TEST_TIMEOUT);
162
170
 
163
171
  it('resolves multiple app IDs', async () => {
@@ -180,7 +188,8 @@ describe('App ID Resolver', () => {
180
188
 
181
189
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP', 'MISSING_APP']);
182
190
 
183
- expect(result).toEqual({
191
+ expect(result.ok).toBe(true);
192
+ expect(result.data).toEqual({
184
193
  'MY_APP': 'app-123',
185
194
  'ANOTHER_APP': 'app-456',
186
195
  'MISSING_APP': null
@@ -207,16 +216,18 @@ describe('App ID Resolver', () => {
207
216
 
208
217
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
209
218
 
210
- expect(result).toEqual({
219
+ expect(result.ok).toBe(true);
220
+ expect(result.data).toEqual({
211
221
  'MY_APP': 'app-123',
212
222
  'ANOTHER_APP': 'app-456'
213
223
  });
214
224
  });
215
225
 
216
- it('returns empty object for empty app names array', async () => {
226
+ it('returns ok with empty object for empty app names array', async () => {
217
227
  const result = await getAppIds(mockSupabase as any, []);
218
228
 
219
- expect(result).toEqual({});
229
+ expect(result.ok).toBe(true);
230
+ expect(result.data).toEqual({});
220
231
  });
221
232
 
222
233
  it('handles database errors gracefully', async () => {
@@ -235,7 +246,8 @@ describe('App ID Resolver', () => {
235
246
 
236
247
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
237
248
 
238
- expect(result).toEqual({});
249
+ expect(result.ok).toBe(false);
250
+ expect(result.error.message).toBe('Database error');
239
251
  const logger = getMockLogger();
240
252
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
241
253
  'Failed to resolve app IDs for app names:',
@@ -257,7 +269,8 @@ describe('App ID Resolver', () => {
257
269
 
258
270
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
259
271
 
260
- expect(result).toEqual({});
272
+ expect(result.ok).toBe(false);
273
+ expect(result.error.message).toContain('Network error');
261
274
  const logger = getMockLogger();
262
275
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
263
276
  'Error resolving app IDs for app names:',
@@ -270,8 +283,8 @@ describe('App ID Resolver', () => {
270
283
  const result1 = await getAppIds(mockSupabase as any, null as any);
271
284
  const result2 = await getAppIds(mockSupabase as any, undefined as any);
272
285
 
273
- expect(result1).toEqual({});
274
- expect(result2).toEqual({});
286
+ expect(result1.ok).toBe(false);
287
+ expect(result2.ok).toBe(false);
275
288
  }, TEST_TIMEOUT);
276
289
 
277
290
  it('handles duplicate app names in array', async () => {
@@ -290,11 +303,11 @@ describe('App ID Resolver', () => {
290
303
 
291
304
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'MY_APP', 'MY_APP']);
292
305
 
293
- expect(result).toEqual({
306
+ expect(result.ok).toBe(true);
307
+ expect(result.data).toEqual({
294
308
  'MY_APP': 'app-123'
295
309
  });
296
- // All three entries should map to the same ID
297
- expect(result['MY_APP']).toBe('app-123');
310
+ expect(result.data!['MY_APP']).toBe('app-123');
298
311
  }, TEST_TIMEOUT);
299
312
 
300
313
  it('handles app names with different cases correctly', async () => {
@@ -316,8 +329,9 @@ describe('App ID Resolver', () => {
316
329
 
317
330
  const result = await getAppIds(mockSupabase as any, ['MY_APP', 'another_app']);
318
331
 
319
- expect(result['MY_APP']).toBe('app-123');
320
- expect(result['another_app']).toBe('app-456');
332
+ expect(result.ok).toBe(true);
333
+ expect(result.data!['MY_APP']).toBe('app-123');
334
+ expect(result.data!['another_app']).toBe('app-456');
321
335
  }, TEST_TIMEOUT);
322
336
  });
323
337
 
@@ -337,9 +351,11 @@ describe('App ID Resolver', () => {
337
351
  const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
338
352
  const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
339
353
 
340
- expect(result1).toBe('app-123');
341
- expect(result2).toBe('app-123');
342
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1); // Should only call once due to caching
354
+ expect(result1.ok).toBe(true);
355
+ expect(result1.data).toBe('app-123');
356
+ expect(result2.ok).toBe(true);
357
+ expect(result2.data).toBe('app-123');
358
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
343
359
  }, TEST_TIMEOUT);
344
360
 
345
361
  it('expires cached results after TTL', async () => {
@@ -351,14 +367,15 @@ describe('App ID Resolver', () => {
351
367
  });
352
368
 
353
369
  const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
354
- expect(result1).toBe('app-123');
370
+ expect(result1.ok).toBe(true);
371
+ expect(result1.data).toBe('app-123');
355
372
 
356
- // Clear cache to simulate TTL expiration
357
373
  resolver.clearCacheForApp('MY_APP');
358
374
 
359
375
  const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
360
- expect(result2).toBe('app-123');
361
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2); // Should call again after cache clear
376
+ expect(result2.ok).toBe(true);
377
+ expect(result2.data).toBe('app-123');
378
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
362
379
  });
363
380
 
364
381
  it('handles cache misses gracefully', async () => {
@@ -369,7 +386,8 @@ describe('App ID Resolver', () => {
369
386
 
370
387
  const result = await resolver.getAppId(mockSupabase as any, 'NONEXISTENT_APP');
371
388
 
372
- expect(result).toBeNull();
389
+ expect(result.ok).toBe(false);
390
+ expect(result.error.message).toBe('No rows found');
373
391
  }, TEST_TIMEOUT);
374
392
 
375
393
  it('handles database errors gracefully', async () => {
@@ -380,7 +398,8 @@ describe('App ID Resolver', () => {
380
398
 
381
399
  const result = await resolver.getAppId(mockSupabase as any, 'MY_APP');
382
400
 
383
- expect(result).toBeNull();
401
+ expect(result.ok).toBe(false);
402
+ expect(result.error.message).toBe('Database error');
384
403
  const logger = getMockLogger();
385
404
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
386
405
  'Failed to resolve app ID for app name:',
@@ -395,12 +414,12 @@ describe('App ID Resolver', () => {
395
414
  .mockResolvedValueOnce({ data: { id: 'app-123' }, error: null });
396
415
 
397
416
  const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
398
- expect(result1).toBeNull();
417
+ expect(result1.ok).toBe(false);
399
418
 
400
- // Clear cache and try again - should succeed this time
401
419
  resolver.clearCacheForApp('MY_APP');
402
420
  const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
403
- expect(result2).toBe('app-123');
421
+ expect(result2.ok).toBe(true);
422
+ expect(result2.data).toBe('app-123');
404
423
  }, TEST_TIMEOUT);
405
424
 
406
425
  it('clears cache correctly', async () => {
@@ -414,8 +433,9 @@ describe('App ID Resolver', () => {
414
433
 
415
434
  const result = await resolver.getAppId(mockSupabase as any, 'MY_APP');
416
435
 
417
- expect(result).toBe('app-123');
418
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2); // Should call again after cache clear
436
+ expect(result.ok).toBe(true);
437
+ expect(result.data).toBe('app-123');
438
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
419
439
  });
420
440
 
421
441
  it('handles multiple apps with different cache states', async () => {
@@ -428,27 +448,30 @@ describe('App ID Resolver', () => {
428
448
  const result2 = await resolver.getAppId(mockSupabase as any, 'APP2');
429
449
  const result3 = await resolver.getAppId(mockSupabase as any, 'APP3');
430
450
 
431
- expect(result1).toBe('app-1');
432
- expect(result2).toBe('app-2');
433
- expect(result3).toBe('app-3');
451
+ expect(result1.ok).toBe(true);
452
+ expect(result1.data).toBe('app-1');
453
+ expect(result2.ok).toBe(true);
454
+ expect(result2.data).toBe('app-2');
455
+ expect(result3.ok).toBe(true);
456
+ expect(result3.data).toBe('app-3');
434
457
  expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
435
458
 
436
- // Second calls should use cache
437
459
  const cached1 = await resolver.getAppId(mockSupabase as any, 'APP1');
438
460
  const cached2 = await resolver.getAppId(mockSupabase as any, 'APP2');
439
461
  const cached3 = await resolver.getAppId(mockSupabase as any, 'APP3');
440
462
 
441
- expect(cached1).toBe('app-1');
442
- expect(cached2).toBe('app-2');
443
- expect(cached3).toBe('app-3');
444
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3); // No additional calls
463
+ expect(cached1.ok).toBe(true);
464
+ expect(cached1.data).toBe('app-1');
465
+ expect(cached2.ok).toBe(true);
466
+ expect(cached2.data).toBe('app-2');
467
+ expect(cached3.ok).toBe(true);
468
+ expect(cached3.data).toBe('app-3');
469
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
445
470
  }, TEST_TIMEOUT);
446
471
 
447
472
  it('handles cache expiration with TTL', async () => {
448
- // Create resolver with short TTL for testing
449
473
  const shortTTLResolver = new CachedAppIdResolver();
450
- // Access private ttl property via type assertion for testing
451
- (shortTTLResolver as any).ttl = 100; // 100ms TTL
474
+ (shortTTLResolver as any).ttl = 100;
452
475
 
453
476
  mockQueryBuilder.single.mockResolvedValue({
454
477
  data: { id: 'app-123' },
@@ -456,22 +479,23 @@ describe('App ID Resolver', () => {
456
479
  });
457
480
 
458
481
  const result1 = await shortTTLResolver.getAppId(mockSupabase as any, 'MY_APP');
459
- expect(result1).toBe('app-123');
482
+ expect(result1.ok).toBe(true);
483
+ expect(result1.data).toBe('app-123');
460
484
  expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
461
485
 
462
- // Wait for TTL to expire
463
486
  await new Promise(resolve => setTimeout(resolve, 150));
464
487
 
465
488
  const result2 = await shortTTLResolver.getAppId(mockSupabase as any, 'MY_APP');
466
- expect(result2).toBe('app-123');
467
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2); // Should call again after TTL
489
+ expect(result2.ok).toBe(true);
490
+ expect(result2.data).toBe('app-123');
491
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
468
492
  }, TEST_TIMEOUT);
469
493
 
470
494
  it('clears cache for specific app while keeping others', async () => {
471
495
  mockQueryBuilder.single
472
496
  .mockResolvedValueOnce({ data: { id: 'app-1' }, error: null })
473
497
  .mockResolvedValueOnce({ data: { id: 'app-2' }, error: null })
474
- .mockResolvedValueOnce({ data: { id: 'app-1' }, error: null }); // Re-fetch after clear
498
+ .mockResolvedValueOnce({ data: { id: 'app-1' }, error: null });
475
499
 
476
500
  await resolver.getAppId(mockSupabase as any, 'APP1');
477
501
  await resolver.getAppId(mockSupabase as any, 'APP2');
@@ -480,31 +504,30 @@ describe('App ID Resolver', () => {
480
504
 
481
505
  resolver.clearCacheForApp('APP1');
482
506
 
483
- // APP1 should be re-fetched, APP2 should still be cached
484
507
  await resolver.getAppId(mockSupabase as any, 'APP1');
485
508
  await resolver.getAppId(mockSupabase as any, 'APP2');
486
509
 
487
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3); // Only APP1 re-fetched
510
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
488
511
  }, TEST_TIMEOUT);
489
512
 
490
513
  it('handles clearing cache for non-existent app', () => {
491
514
  expect(() => resolver.clearCacheForApp('NONEXISTENT')).not.toThrow();
492
515
  }, TEST_TIMEOUT);
493
516
 
494
- it('handles null results in cache', async () => {
517
+ it('does not cache error results', async () => {
495
518
  mockQueryBuilder.single.mockResolvedValue({
496
519
  data: null,
497
520
  error: { message: 'Not found' }
498
521
  });
499
522
 
500
523
  const result1 = await resolver.getAppId(mockSupabase as any, 'MISSING_APP');
501
- expect(result1).toBeNull();
524
+ expect(result1.ok).toBe(false);
525
+ expect(result1.error.message).toBe('Not found');
502
526
  expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
503
527
 
504
- // Should use cached null result
505
528
  const result2 = await resolver.getAppId(mockSupabase as any, 'MISSING_APP');
506
- expect(result2).toBeNull();
507
- expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1); // Still cached
529
+ expect(result2.ok).toBe(false);
530
+ expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
508
531
  }, TEST_TIMEOUT);
509
532
 
510
533
  it('handles singleton instance correctly', async () => {
@@ -516,7 +539,8 @@ describe('App ID Resolver', () => {
516
539
  });
517
540
 
518
541
  const result = await cachedAppIdResolver.getAppId(mockSupabase as any, 'MY_APP');
519
- expect(result).toBe('app-123');
542
+ expect(result.ok).toBe(true);
543
+ expect(result.data).toBe('app-123');
520
544
  }, TEST_TIMEOUT);
521
545
  });
522
546
 
@@ -536,7 +560,8 @@ describe('App ID Resolver', () => {
536
560
 
537
561
  const result = await getAppId(mockClient as any, 'MY_APP');
538
562
 
539
- expect(result).toBe('app-123');
563
+ expect(result.ok).toBe(true);
564
+ expect(result.data).toBe('app-123');
540
565
  expect(mockClient.from).toHaveBeenCalledWith('rbac_apps');
541
566
  });
542
567
 
@@ -567,7 +592,8 @@ describe('App ID Resolver', () => {
567
592
 
568
593
  const result = await getAppIds(mockSupabase as any, appNames);
569
594
 
570
- expect(result).toEqual({
595
+ expect(result.ok).toBe(true);
596
+ expect(result.data).toEqual({
571
597
  'MY_APP': 'app-123',
572
598
  'my-app': 'app-456',
573
599
  'my_app': null,
@@ -583,7 +609,8 @@ describe('App ID Resolver', () => {
583
609
 
584
610
  const result = await getAppId(mockSupabase as any, 'MY_APP');
585
611
 
586
- expect(result).toBeNull();
612
+ expect(result.ok).toBe(false);
613
+ expect(result.error.message).toContain('Request timeout');
587
614
  const logger = getMockLogger();
588
615
  expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
589
616
  'Error resolving app ID for app name:',
@@ -600,7 +627,8 @@ describe('App ID Resolver', () => {
600
627
 
601
628
  const result = await getAppId(mockSupabase as any, 'MY_APP');
602
629
 
603
- expect(result).toBeNull();
630
+ expect(result.ok).toBe(true);
631
+ expect(result.data).toBeNull();
604
632
  }, TEST_TIMEOUT);
605
633
 
606
634
  it('handles null data responses', async () => {
@@ -611,7 +639,8 @@ describe('App ID Resolver', () => {
611
639
 
612
640
  const result = await getAppId(mockSupabase as any, 'MY_APP');
613
641
 
614
- expect(result).toBeNull();
642
+ expect(result.ok).toBe(true);
643
+ expect(result.data).toBeNull();
615
644
  }, TEST_TIMEOUT);
616
645
  });
617
646
 
@@ -636,8 +665,9 @@ describe('App ID Resolver', () => {
636
665
  const result = await getAppIds(mockSupabase as any, appNames);
637
666
  const endTime = Date.now();
638
667
 
639
- expect(Object.keys(result)).toHaveLength(100);
640
- expect(endTime - startTime).toBeLessThan(1000); // Should complete within 1 second
668
+ expect(result.ok).toBe(true);
669
+ expect(Object.keys(result.data!)).toHaveLength(100);
670
+ expect(endTime - startTime).toBeLessThan(1000);
641
671
  });
642
672
 
643
673
  it('caches results efficiently', async () => {
@@ -650,16 +680,13 @@ describe('App ID Resolver', () => {
650
680
 
651
681
  const startTime = Date.now();
652
682
 
653
- // First call - should hit database
654
683
  await resolver.getAppId(mockSupabase as any, 'MY_APP');
655
-
656
- // Second call - should hit cache
657
684
  await resolver.getAppId(mockSupabase as any, 'MY_APP');
658
685
 
659
686
  const endTime = Date.now();
660
687
 
661
688
  expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
662
- expect(endTime - startTime).toBeLessThan(100); // Should be very fast due to caching
689
+ expect(endTime - startTime).toBeLessThan(100);
663
690
  }, TEST_TIMEOUT);
664
691
  });
665
692
  });
@@ -9,21 +9,30 @@
9
9
 
10
10
  import type { SupabaseClient } from '@supabase/supabase-js';
11
11
  import type { Database } from '../../types/database';
12
+ import { ok, err, type ApiResult, type ApiError } from '../../types/api-result';
12
13
  import { createLogger } from '../core/logger';
13
14
 
14
15
  const log = createLogger('AppIdResolver');
15
16
 
17
+ function toApiError(error: unknown): ApiError {
18
+ const message = error instanceof Error ? error.message : 'Unknown error';
19
+ const code = error instanceof Error && (error as Error & { code?: string }).code
20
+ ? (error as Error & { code: string }).code
21
+ : 'APP_ID_RESOLVER_ERROR';
22
+ return { code, message };
23
+ }
24
+
16
25
  /**
17
26
  * Resolves an app name to its corresponding app ID
18
27
  *
19
28
  * @param supabase - Supabase client instance
20
29
  * @param appName - The app name to resolve
21
- * @returns Promise resolving to the app ID or null if not found
30
+ * @returns Promise resolving to ApiResult with app ID or null if not found
22
31
  */
23
32
  export async function getAppId(
24
33
  supabase: SupabaseClient<Database>,
25
34
  appName: string
26
- ): Promise<string | null> {
35
+ ): Promise<ApiResult<string | null>> {
27
36
  try {
28
37
  const { data, error } = await supabase
29
38
  .from('rbac_apps')
@@ -34,13 +43,13 @@ export async function getAppId(
34
43
 
35
44
  if (error) {
36
45
  log.error('Failed to resolve app ID for app name:', appName, error);
37
- return null;
46
+ return err({ code: 'APP_ID_RESOLVE_ERROR', message: error.message });
38
47
  }
39
48
 
40
- return (data as { id: string } | null)?.id || null;
41
- } catch (error) {
42
- log.error('Error resolving app ID for app name:', appName, error);
43
- return null;
49
+ return ok((data as { id: string } | null)?.id ?? null);
50
+ } catch (e) {
51
+ log.error('Error resolving app ID for app name:', appName, e);
52
+ return err(toApiError(e));
44
53
  }
45
54
  }
46
55
 
@@ -49,12 +58,12 @@ export async function getAppId(
49
58
  *
50
59
  * @param supabase - Supabase client instance
51
60
  * @param appNames - Array of app names to resolve
52
- * @returns Promise resolving to a map of app names to app IDs
61
+ * @returns Promise resolving to ApiResult with map of app names to app IDs
53
62
  */
54
63
  export async function getAppIds(
55
64
  supabase: SupabaseClient<Database>,
56
65
  appNames: string[]
57
- ): Promise<Record<string, string | null>> {
66
+ ): Promise<ApiResult<Record<string, string | null>>> {
58
67
  try {
59
68
  // For case-insensitive matching with multiple values, we need to use OR conditions
60
69
  // since PostgreSQL doesn't support case-insensitive IN with ILIKE
@@ -68,7 +77,7 @@ export async function getAppIds(
68
77
 
69
78
  if (error) {
70
79
  log.error('Failed to resolve app IDs for app names:', appNames, error);
71
- return {};
80
+ return err({ code: 'APP_IDS_RESOLVE_ERROR', message: error.message });
72
81
  }
73
82
 
74
83
  const result: Record<string, string | null> = {};
@@ -89,10 +98,10 @@ export async function getAppIds(
89
98
  }
90
99
  });
91
100
 
92
- return result;
93
- } catch (error) {
94
- log.error('Error resolving app IDs for app names:', appNames, error);
95
- return {};
101
+ return ok(result);
102
+ } catch (e) {
103
+ log.error('Error resolving app IDs for app names:', appNames, e);
104
+ return err(toApiError(e));
96
105
  }
97
106
  }
98
107
 
@@ -106,18 +115,20 @@ export class CachedAppIdResolver {
106
115
  async getAppId(
107
116
  supabase: SupabaseClient<Database>,
108
117
  appName: string
109
- ): Promise<string | null> {
118
+ ): Promise<ApiResult<string | null>> {
110
119
  const now = Date.now();
111
120
  const cached = this.cache.get(appName);
112
121
 
113
122
  if (cached && cached.expires > now) {
114
- return cached.id;
123
+ return ok(cached.id);
115
124
  }
116
125
 
117
- const id = await getAppId(supabase, appName);
118
- this.cache.set(appName, { id, expires: now + this.ttl });
119
-
120
- return id;
126
+ const result = await getAppId(supabase, appName);
127
+ if (!result.ok) {
128
+ return result;
129
+ }
130
+ this.cache.set(appName, { id: result.data, expires: now + this.ttl });
131
+ return ok(result.data);
121
132
  }
122
133
 
123
134
  clearCache(): void {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from '../app/appConfig';
2
+ import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './app/appConfig';
3
3
 
4
4
  describe('App Configuration Utilities', () => {
5
5
  beforeEach(() => {
@@ -4,7 +4,7 @@ import {
4
4
  logAuthEvent,
5
5
  logPermissionEvent,
6
6
  logSecurityEvent
7
- } from '../audit/audit';
7
+ } from './audit/audit';
8
8
 
9
9
  describe('Audit Logger Utility', () => {
10
10
  beforeEach(() => {
@@ -5,47 +5,46 @@ import {
5
5
  resetPassword,
6
6
  updatePassword,
7
7
  auditLogger
8
- } from '../security/auth-utils';
8
+ } from './security/auth-utils';
9
9
 
10
10
  describe('Auth Utils', () => {
11
11
  beforeEach(() => {
12
12
  vi.restoreAllMocks();
13
13
  });
14
14
 
15
- it('signInWithEmail logs and returns error', async () => {
15
+ it('signInWithEmail returns ApiResult error', async () => {
16
16
  const result = await signInWithEmail({ email: 'test@example.com', password: 'pw' });
17
- expect(result).toHaveProperty('error');
18
- expect(result.error).toBeInstanceOf(Error);
17
+ expect(result.ok).toBe(false);
18
+ expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
19
19
  });
20
20
 
21
- it('signUpWithEmail logs and returns error', async () => {
21
+ it('signUpWithEmail returns ApiResult error', async () => {
22
22
  const result = await signUpWithEmail({ email: 'new@example.com', password: 'pw' });
23
- expect(result).toHaveProperty('error');
24
- expect(result.error).toBeInstanceOf(Error);
23
+ expect(result.ok).toBe(false);
24
+ expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
25
25
  });
26
26
 
27
- it('resetPassword logs and returns error', async () => {
27
+ it('resetPassword returns ApiResult error', async () => {
28
28
  const result = await resetPassword('reset@example.com');
29
- expect(result).toHaveProperty('error');
30
- expect(result.error).toBeInstanceOf(Error);
29
+ expect(result.ok).toBe(false);
30
+ expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
31
31
  });
32
32
 
33
- it('updatePassword calls supabaseClient.auth.updateUser and returns error if thrown', async () => {
33
+ it('updatePassword calls supabaseClient.auth.updateUser and returns ok', async () => {
34
34
  const updateUser = vi.fn().mockResolvedValue({ error: undefined });
35
35
  const supabaseClient = { auth: { updateUser } } as any;
36
36
  const result = await updatePassword(supabaseClient, 'newpw');
37
37
  expect(updateUser).toHaveBeenCalledWith({ password: 'newpw' });
38
- expect(result).toEqual({ error: undefined });
38
+ expect(result.ok).toBe(true);
39
+ expect(result.data).toBeUndefined();
39
40
  });
40
41
 
41
- it('updatePassword returns error if thrown', async () => {
42
+ it('updatePassword returns ApiResult error if thrown', async () => {
42
43
  const updateUser = vi.fn().mockRejectedValue(new Error('fail'));
43
44
  const supabaseClient = { auth: { updateUser } } as any;
44
45
  const result = await updatePassword(supabaseClient, 'pw');
45
- expect(result.error).toBeInstanceOf(Error);
46
- if (result.error) {
47
- expect(result.error.message).toBe('fail');
48
- }
46
+ expect(result.ok).toBe(false);
47
+ expect(result.error.message).toBe('fail');
49
48
  });
50
49
 
51
50
  it('auditLogger.log logs event', () => {