@jmruthers/pace-core 0.5.190 → 0.5.193

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 (334) hide show
  1. package/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
  2. package/dist/{DataTable-ON3IXISJ.js → DataTable-5FU7IESH.js} +7 -6
  3. package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
  4. package/dist/{PublicPageProvider-C4uxosp6.d.ts → PublicPageProvider-C0Sm_e5k.d.ts} +4 -2
  5. package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
  6. package/dist/{UnifiedAuthProvider-X5NXANVI.js → UnifiedAuthProvider-RGJTDE2C.js} +3 -3
  7. package/dist/{api-I6UCQ5S6.js → api-N774RPUA.js} +2 -2
  8. package/dist/chunk-6C4YBBJM 5.js +628 -0
  9. package/dist/chunk-7D4SUZUM.js 2.map +1 -0
  10. package/dist/{chunk-73HSNNOQ.js → chunk-7EQTDTTJ.js} +47 -74
  11. package/dist/chunk-7EQTDTTJ.js 2.map +1 -0
  12. package/dist/chunk-7EQTDTTJ.js.map +1 -0
  13. package/dist/{chunk-J2XXC7R5.js → chunk-7FLMSG37.js} +409 -244
  14. package/dist/chunk-7FLMSG37.js 2.map +1 -0
  15. package/dist/chunk-7FLMSG37.js.map +1 -0
  16. package/dist/{chunk-NIU6J6OX.js → chunk-BC4IJKSL.js} +23 -32
  17. package/dist/chunk-BC4IJKSL.js.map +1 -0
  18. package/dist/{chunk-SDMHPX3X.js → chunk-E3SPN4VZ 5.js } +198 -53
  19. package/dist/chunk-E3SPN4VZ.js +12917 -0
  20. package/dist/{chunk-SDMHPX3X.js.map → chunk-E3SPN4VZ.js.map} +1 -1
  21. package/dist/chunk-E66EQZE6 5.js +37 -0
  22. package/dist/chunk-E66EQZE6.js 2.map +1 -0
  23. package/dist/{chunk-DZWK57KZ.js → chunk-G37KK66H.js} +1 -1
  24. package/dist/{chunk-DZWK57KZ.js.map → chunk-G37KK66H.js.map} +1 -1
  25. package/dist/{chunk-STYK4OH2.js → chunk-HWIIPPNI.js} +44 -225
  26. package/dist/chunk-HWIIPPNI.js.map +1 -0
  27. package/dist/chunk-I7PSE6JW 5.js +191 -0
  28. package/dist/chunk-I7PSE6JW.js 2.map +1 -0
  29. package/dist/{chunk-Y4BUBBHD.js → chunk-IIELH4DL.js} +211 -136
  30. package/dist/chunk-IIELH4DL.js.map +1 -0
  31. package/dist/{chunk-RUYZKXOD.js → chunk-KNC55RTG.js} +17 -5
  32. package/dist/chunk-KNC55RTG.js 5.map +1 -0
  33. package/dist/chunk-KNC55RTG.js.map +1 -0
  34. package/dist/chunk-KQCRWDSA.js 5.map +1 -0
  35. package/dist/{chunk-4QYC5L4K.js → chunk-LFNCN2SP.js} +26 -30
  36. package/dist/chunk-LFNCN2SP.js 2.map +1 -0
  37. package/dist/chunk-LFNCN2SP.js.map +1 -0
  38. package/dist/chunk-LMC26NLJ 2.js +84 -0
  39. package/dist/{chunk-VVBAW5A5.js → chunk-NOAYCWCX 5.js } +118 -110
  40. package/dist/chunk-NOAYCWCX.js +4993 -0
  41. package/dist/chunk-NOAYCWCX.js.map +1 -0
  42. package/dist/chunk-QWWZ5CAQ.js 3.map +1 -0
  43. package/dist/chunk-QXHPKYJV 3.js +113 -0
  44. package/dist/chunk-R77UEZ4E 3.js +68 -0
  45. package/dist/chunk-VBXEHIUJ.js 6.map +1 -0
  46. package/dist/{chunk-HQVPB5MZ.js → chunk-XNXXZ43G.js} +77 -33
  47. package/dist/chunk-XNXXZ43G.js.map +1 -0
  48. package/dist/chunk-ZSAAAMVR 6.js +25 -0
  49. package/dist/components.d.ts +4 -4
  50. package/dist/components.js +8 -8
  51. package/dist/components.js 5.map +1 -0
  52. package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
  53. package/dist/hooks.d.ts +12 -12
  54. package/dist/hooks.js +9 -9
  55. package/dist/index.d.ts +11 -11
  56. package/dist/index.js +20 -27
  57. package/dist/index.js.map +1 -1
  58. package/dist/providers.d.ts +3 -3
  59. package/dist/providers.js +2 -2
  60. package/dist/rbac/index.d.ts +2 -20
  61. package/dist/rbac/index.js +7 -9
  62. package/dist/styles/index 2.js +12 -0
  63. package/dist/styles/index.js 5.map +1 -0
  64. package/dist/theming/runtime 5.js +19 -0
  65. package/dist/theming/runtime.js 5.map +1 -0
  66. package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
  67. package/dist/types.d.ts +2 -2
  68. package/dist/{usePublicRouteParams-DxIDS4bC.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +1 -1
  69. package/dist/utils.d.ts +8 -8
  70. package/dist/utils.js +2 -2
  71. package/docs/api/classes/ColumnFactory.md +1 -1
  72. package/docs/api/classes/ErrorBoundary.md +1 -1
  73. package/docs/api/classes/InvalidScopeError.md +1 -1
  74. package/docs/api/classes/Logger.md +1 -1
  75. package/docs/api/classes/MissingUserContextError.md +1 -1
  76. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  77. package/docs/api/classes/PermissionDeniedError.md +2 -2
  78. package/docs/api/classes/RBACAuditManager.md +2 -2
  79. package/docs/api/classes/RBACCache.md +1 -1
  80. package/docs/api/classes/RBACEngine.md +2 -2
  81. package/docs/api/classes/RBACError.md +1 -1
  82. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  83. package/docs/api/classes/SecureSupabaseClient.md +10 -10
  84. package/docs/api/classes/StorageUtils.md +1 -1
  85. package/docs/api/enums/FileCategory.md +1 -1
  86. package/docs/api/enums/LogLevel.md +1 -1
  87. package/docs/api/enums/RBACErrorCode.md +1 -1
  88. package/docs/api/enums/RPCFunction.md +1 -1
  89. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  90. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  91. package/docs/api/interfaces/AggregateConfig.md +1 -1
  92. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  93. package/docs/api/interfaces/AvatarProps.md +1 -1
  94. package/docs/api/interfaces/BadgeProps.md +1 -1
  95. package/docs/api/interfaces/ButtonProps.md +1 -1
  96. package/docs/api/interfaces/CalendarProps.md +1 -1
  97. package/docs/api/interfaces/CardProps.md +1 -1
  98. package/docs/api/interfaces/ColorPalette.md +1 -1
  99. package/docs/api/interfaces/ColorShade.md +1 -1
  100. package/docs/api/interfaces/ComplianceResult.md +1 -1
  101. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  102. package/docs/api/interfaces/DataRecord.md +1 -1
  103. package/docs/api/interfaces/DataTableAction.md +1 -1
  104. package/docs/api/interfaces/DataTableColumn.md +1 -1
  105. package/docs/api/interfaces/DataTableProps.md +1 -1
  106. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  107. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  109. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  110. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  112. package/docs/api/interfaces/ExportColumn.md +1 -1
  113. package/docs/api/interfaces/ExportOptions.md +1 -1
  114. package/docs/api/interfaces/FileDisplayProps.md +24 -11
  115. package/docs/api/interfaces/FileMetadata.md +1 -1
  116. package/docs/api/interfaces/FileReference.md +1 -1
  117. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  118. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  119. package/docs/api/interfaces/FileUploadProps.md +1 -1
  120. package/docs/api/interfaces/FooterProps.md +1 -1
  121. package/docs/api/interfaces/FormFieldProps.md +1 -1
  122. package/docs/api/interfaces/FormProps.md +1 -1
  123. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  124. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  125. package/docs/api/interfaces/InputProps.md +1 -1
  126. package/docs/api/interfaces/LabelProps.md +1 -1
  127. package/docs/api/interfaces/LoggerConfig.md +1 -1
  128. package/docs/api/interfaces/LoginFormProps.md +1 -1
  129. package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
  130. package/docs/api/interfaces/NavigationContextType.md +1 -1
  131. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  132. package/docs/api/interfaces/NavigationItem.md +1 -1
  133. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  134. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  135. package/docs/api/interfaces/Organisation.md +1 -1
  136. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  137. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  138. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  139. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  140. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  141. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  142. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  143. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  144. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  145. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  146. package/docs/api/interfaces/PaletteData.md +1 -1
  147. package/docs/api/interfaces/ParsedAddress.md +2 -2
  148. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  149. package/docs/api/interfaces/ProgressProps.md +1 -1
  150. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  151. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  152. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  153. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  154. package/docs/api/interfaces/QuickFix.md +1 -1
  155. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  156. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  157. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  158. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  159. package/docs/api/interfaces/RBACConfig.md +2 -2
  160. package/docs/api/interfaces/RBACContext.md +1 -1
  161. package/docs/api/interfaces/RBACLogger.md +1 -1
  162. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  163. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  164. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  165. package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
  166. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  167. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  168. package/docs/api/interfaces/RBACResult.md +1 -1
  169. package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
  170. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  171. package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
  172. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  173. package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
  174. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  175. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  176. package/docs/api/interfaces/RBACRolesListResult.md +2 -2
  177. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  178. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  179. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  180. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  181. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  182. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  183. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  184. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  185. package/docs/api/interfaces/RouteConfig.md +2 -2
  186. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  187. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  188. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  189. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  190. package/docs/api/interfaces/SetupIssue.md +1 -1
  191. package/docs/api/interfaces/StorageConfig.md +1 -1
  192. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  193. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  194. package/docs/api/interfaces/StorageListOptions.md +1 -1
  195. package/docs/api/interfaces/StorageListResult.md +1 -1
  196. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  197. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  198. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  199. package/docs/api/interfaces/StyleImport.md +1 -1
  200. package/docs/api/interfaces/SwitchProps.md +1 -1
  201. package/docs/api/interfaces/TabsContentProps.md +1 -1
  202. package/docs/api/interfaces/TabsListProps.md +1 -1
  203. package/docs/api/interfaces/TabsProps.md +1 -1
  204. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  205. package/docs/api/interfaces/TextareaProps.md +1 -1
  206. package/docs/api/interfaces/ToastActionElement.md +1 -1
  207. package/docs/api/interfaces/ToastProps.md +1 -1
  208. package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
  209. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  210. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  211. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  212. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  213. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  214. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  215. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  216. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  217. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  218. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  219. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  220. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  221. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  222. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  223. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  224. package/docs/api/interfaces/UserEventAccess.md +1 -1
  225. package/docs/api/interfaces/UserMenuProps.md +1 -1
  226. package/docs/api/interfaces/UserProfile.md +1 -1
  227. package/docs/api/modules.md +202 -217
  228. package/docs/migration/README.md +18 -0
  229. package/docs/migration/database-changes-december-2025.md +768 -0
  230. package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
  231. package/docs/rbac/event-based-apps.md +124 -6
  232. package/package.json +1 -1
  233. package/scripts/check-pace-core-compliance.cjs +292 -57
  234. package/src/__tests__/public-recipe-view.test.ts +10 -10
  235. package/src/__tests__/rls-policies.test.ts +16 -14
  236. package/src/components/AddressField/README.md +6 -6
  237. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
  238. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
  239. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
  240. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
  241. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
  242. package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
  243. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +75 -11
  244. package/src/components/DataTable/components/UnifiedTableBody.tsx +85 -14
  245. package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
  246. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -1
  247. package/src/components/FileDisplay/FileDisplay.tsx +16 -4
  248. package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
  249. package/src/components/NavigationMenu/NavigationMenu.tsx +1 -10
  250. package/src/components/OrganisationSelector/OrganisationSelector.tsx +35 -16
  251. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +25 -2
  252. package/src/components/PaceAppLayout/PaceAppLayout.tsx +97 -68
  253. package/src/components/PaceLoginPage/PaceLoginPage.tsx +0 -7
  254. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
  255. package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
  256. package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
  257. package/src/components/Select/Select.test.tsx +4 -1
  258. package/src/components/Select/Select.tsx +60 -15
  259. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +192 -0
  260. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +741 -0
  261. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +703 -0
  262. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +581 -0
  263. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +23 -15
  264. package/src/hooks/public/usePublicEvent.ts +8 -8
  265. package/src/hooks/public/usePublicFileDisplay.ts +2 -2
  266. package/src/hooks/services/useAuthService.ts +21 -3
  267. package/src/hooks/services/useEventService.ts +21 -3
  268. package/src/hooks/services/useInactivityService.ts +21 -3
  269. package/src/hooks/services/useOrganisationService.ts +21 -3
  270. package/src/hooks/useFileDisplay.ts +18 -26
  271. package/src/hooks/useQueryCache.ts +6 -6
  272. package/src/hooks/useSecureDataAccess.test.ts +24 -17
  273. package/src/hooks/useSecureDataAccess.ts +18 -13
  274. package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
  275. package/src/providers/services/EventServiceProvider.tsx +0 -8
  276. package/src/providers/services/UnifiedAuthProvider.tsx +174 -24
  277. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +10 -16
  278. package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
  279. package/src/rbac/adapters.tsx +3 -22
  280. package/src/rbac/api.test.ts +2 -2
  281. package/src/rbac/api.ts +7 -1
  282. package/src/rbac/components/EnhancedNavigationMenu.tsx +2 -15
  283. package/src/rbac/components/NavigationGuard.tsx +1 -10
  284. package/src/rbac/components/NavigationProvider.tsx +0 -1
  285. package/src/rbac/components/PermissionEnforcer.tsx +45 -12
  286. package/src/rbac/components/SecureDataProvider.tsx +0 -1
  287. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
  288. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
  289. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
  290. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
  291. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
  292. package/src/rbac/engine.ts +14 -2
  293. package/src/rbac/hooks/index.ts +0 -3
  294. package/src/rbac/hooks/usePermissions.ts +51 -11
  295. package/src/rbac/hooks/useRBAC.simple.test.ts +95 -0
  296. package/src/rbac/hooks/useRBAC.ts +3 -13
  297. package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
  298. package/src/rbac/hooks/useResolvedScope.ts +58 -33
  299. package/src/rbac/hooks/useSecureSupabase.ts +4 -9
  300. package/src/rbac/secureClient.ts +31 -0
  301. package/src/rbac/utils/__tests__/eventContext.test.ts +2 -2
  302. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +490 -0
  303. package/src/rbac/utils/eventContext.ts +5 -2
  304. package/src/services/AuthService.ts +37 -8
  305. package/src/services/EventService.ts +4 -57
  306. package/src/services/InactivityService.ts +127 -34
  307. package/src/services/OrganisationService.ts +160 -149
  308. package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
  309. package/src/services/__tests__/OrganisationService.test.ts +218 -86
  310. package/src/types/database.generated.ts +166 -201
  311. package/src/types/supabase.ts +2 -2
  312. package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
  313. package/src/utils/file-reference/index.ts +4 -4
  314. package/src/utils/google-places/googlePlacesUtils.ts +1 -1
  315. package/src/utils/google-places/types.ts +1 -1
  316. package/src/utils/request-deduplication.ts +4 -4
  317. package/src/utils/security/secureDataAccess.test.ts +1 -1
  318. package/src/utils/security/secureDataAccess.ts +7 -4
  319. package/src/utils/storage/README.md +1 -1
  320. package/dist/chunk-4QYC5L4K.js.map +0 -1
  321. package/dist/chunk-73HSNNOQ.js.map +0 -1
  322. package/dist/chunk-HQVPB5MZ.js.map +0 -1
  323. package/dist/chunk-J2XXC7R5.js.map +0 -1
  324. package/dist/chunk-NIU6J6OX.js.map +0 -1
  325. package/dist/chunk-RUYZKXOD.js.map +0 -1
  326. package/dist/chunk-STYK4OH2.js.map +0 -1
  327. package/dist/chunk-VVBAW5A5.js.map +0 -1
  328. package/dist/chunk-Y4BUBBHD.js.map +0 -1
  329. package/scripts/check-pace-core-compliance.js +0 -512
  330. package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
  331. package/src/utils/context/superAdminOverride.ts +0 -58
  332. /package/dist/{DataTable-ON3IXISJ.js.map → DataTable-5FU7IESH.js.map} +0 -0
  333. /package/dist/{UnifiedAuthProvider-X5NXANVI.js.map → UnifiedAuthProvider-RGJTDE2C.js.map} +0 -0
  334. /package/dist/{api-I6UCQ5S6.js.map → api-N774RPUA.js.map} +0 -0
@@ -0,0 +1,581 @@
1
+ import React from 'react';
2
+ import { renderHook, waitFor, act } from '@testing-library/react';
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
4
+ import { usePublicEvent, clearPublicEventCache, getPublicEventCacheStats } from '../public/usePublicEvent';
5
+ import { usePublicPageContext } from '../../components/PublicLayout/PublicPageProvider';
6
+
7
+ // Mock the PublicPageProvider
8
+ vi.mock('../../components/PublicLayout/PublicPageProvider', () => ({
9
+ usePublicPageContext: vi.fn(() => ({
10
+ environment: {
11
+ supabaseUrl: 'https://test.supabase.co',
12
+ supabaseKey: 'test-anon-key'
13
+ }
14
+ }))
15
+ }));
16
+
17
+ // Mock Supabase client
18
+ const mockSupabaseClient = {
19
+ rpc: vi.fn(),
20
+ from: vi.fn(() => ({
21
+ select: vi.fn(() => ({
22
+ eq: vi.fn(() => ({
23
+ eq: vi.fn(() => ({
24
+ not: vi.fn(() => ({
25
+ limit: vi.fn(() => ({
26
+ single: vi.fn()
27
+ }))
28
+ }))
29
+ }))
30
+ }))
31
+ }))
32
+ }))
33
+ };
34
+
35
+ // Helper to create table query mocks
36
+ const createTableQueryMock = () => ({
37
+ data: null,
38
+ error: null,
39
+ mockResolvedValueOnce: vi.fn(),
40
+ mockResolvedValue: vi.fn()
41
+ });
42
+
43
+ // Helper to create a complete table query chain
44
+ const createTableQueryChain = (finalResult: any) => {
45
+ const mockChain = {
46
+ select: vi.fn().mockReturnThis(),
47
+ eq: vi.fn().mockReturnThis(),
48
+ not: vi.fn().mockReturnThis(),
49
+ limit: vi.fn().mockReturnThis(),
50
+ single: vi.fn().mockResolvedValue(finalResult)
51
+ };
52
+ return mockChain;
53
+ };
54
+
55
+ // Mock createClient
56
+ vi.mock('@supabase/supabase-js', () => ({
57
+ createClient: vi.fn(() => mockSupabaseClient)
58
+ }));
59
+
60
+ // Mock environment variables
61
+ const originalEnv = import.meta.env;
62
+
63
+ describe('usePublicEvent', () => {
64
+ beforeEach(() => {
65
+ vi.clearAllMocks();
66
+ clearPublicEventCache();
67
+
68
+ // Reset environment
69
+ Object.defineProperty(import.meta, 'env', {
70
+ value: {
71
+ VITE_SUPABASE_URL: 'https://test.supabase.co',
72
+ VITE_SUPABASE_ANON_KEY: 'test-anon-key'
73
+ },
74
+ writable: true
75
+ });
76
+
77
+ // Mock window object
78
+ Object.defineProperty(window, 'location', {
79
+ value: { href: 'https://test.com' },
80
+ writable: true
81
+ });
82
+
83
+ // Re-establish mock implementations after clearAllMocks
84
+ mockSupabaseClient.rpc.mockImplementation(() =>
85
+ Promise.resolve({
86
+ data: null,
87
+ error: null
88
+ })
89
+ );
90
+
91
+ // Ensure the mock is properly configured
92
+ expect(mockSupabaseClient.rpc).toBeDefined();
93
+ });
94
+
95
+ afterEach(() => {
96
+ vi.clearAllMocks();
97
+ clearPublicEventCache();
98
+ Object.defineProperty(import.meta, 'env', {
99
+ value: originalEnv,
100
+ writable: true
101
+ });
102
+ });
103
+
104
+ describe('Basic Functionality', () => {
105
+ it('should initialize with loading state', () => {
106
+ const { result } = renderHook(() => usePublicEvent('test-event'));
107
+
108
+ expect(result.current.isLoading).toBe(true);
109
+ expect(result.current.event).toBe(null);
110
+ expect(result.current.error).toBe(null);
111
+ });
112
+
113
+ it('should fetch event data successfully via RPC', async () => {
114
+ const mockEventData = {
115
+ event_id: '123',
116
+ event_name: 'Test Event',
117
+ event_date: '2024-01-01',
118
+ event_venue: 'Test Venue',
119
+ event_participants: 100,
120
+ event_colours: { primary: '#000000' },
121
+ organisation_id: 'org-123',
122
+ event_days: 1,
123
+ event_typicalunit: 'km',
124
+ event_rounddown: false,
125
+ event_youthmultiplier: 1.0,
126
+ event_catering_email: 'test@example.com',
127
+ event_news: 'Test news',
128
+ event_billing: 'Test billing',
129
+ event_footer: 'Test footer',
130
+ event_email: 'event@example.com',
131
+ event_logo: null
132
+ };
133
+
134
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
135
+ data: [mockEventData],
136
+ error: null
137
+ });
138
+
139
+ const { result } = renderHook(() => usePublicEvent('test-event'));
140
+
141
+ await waitFor(() => {
142
+ expect(result.current.isLoading).toBe(false);
143
+ }, { interval: 10 });
144
+
145
+ expect(result.current.event).toEqual({
146
+ id: '123',
147
+ event_id: '123',
148
+ event_name: 'Test Event',
149
+ event_code: 'test-event',
150
+ event_date: '2024-01-01',
151
+ event_venue: 'Test Venue',
152
+ event_participants: 100,
153
+ event_logo: null,
154
+ event_colours: { primary: '#000000' },
155
+ organisation_id: 'org-123',
156
+ is_visible: true,
157
+ created_at: expect.any(String),
158
+ updated_at: expect.any(String)
159
+ });
160
+ expect(result.current.error).toBe(null);
161
+ });
162
+
163
+ it('should handle event not found', async () => {
164
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
165
+ data: [],
166
+ error: null
167
+ });
168
+
169
+ const { result } = renderHook(() => usePublicEvent('nonexistent-event'));
170
+
171
+ await waitFor(() => {
172
+ expect(result.current.isLoading).toBe(false);
173
+ }, { interval: 10 });
174
+
175
+ expect(result.current.event).toBe(null);
176
+ expect(result.current.error).toEqual(new Error('Event not found'));
177
+ });
178
+
179
+ it('should handle invalid event code', async () => {
180
+ const { result } = renderHook(() => usePublicEvent(''));
181
+
182
+ await waitFor(() => {
183
+ expect(result.current.isLoading).toBe(false);
184
+ }, { interval: 10 });
185
+
186
+ expect(result.current.event).toBe(null);
187
+ expect(result.current.error).toBeInstanceOf(Error);
188
+ expect(result.current.error?.message).toContain('Invalid event code or Supabase client not available');
189
+ });
190
+ });
191
+
192
+ describe('Caching', () => {
193
+ it('should cache event data', async () => {
194
+ const mockEventData = {
195
+ event_id: '123',
196
+ event_name: 'Test Event',
197
+ event_date: '2024-01-01',
198
+ event_venue: 'Test Venue',
199
+ event_participants: 100,
200
+ event_colours: { primary: '#000000' },
201
+ organisation_id: 'org-123',
202
+ event_days: 1,
203
+ event_typicalunit: 'km',
204
+ event_rounddown: false,
205
+ event_youthmultiplier: 1.0,
206
+ event_catering_email: 'test@example.com',
207
+ event_news: 'Test news',
208
+ event_billing: 'Test billing',
209
+ event_footer: 'Test footer',
210
+ event_email: 'event@example.com'
211
+ };
212
+
213
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
214
+ data: [mockEventData],
215
+ error: null
216
+ });
217
+
218
+ const { result, rerender } = renderHook(() => usePublicEvent('test-event'));
219
+
220
+ await waitFor(() => {
221
+ expect(result.current.isLoading).toBe(false);
222
+ }, { interval: 10 });
223
+
224
+ // Rerender with same event code - should use cache
225
+ rerender();
226
+
227
+ // Should not call RPC again
228
+ expect(mockSupabaseClient.rpc).toHaveBeenCalledTimes(1);
229
+ });
230
+
231
+ it('should respect cache TTL', async () => {
232
+ const mockEventData = {
233
+ event_id: '123',
234
+ event_name: 'Test Event',
235
+ event_date: '2024-01-01',
236
+ event_venue: 'Test Venue',
237
+ event_participants: 100,
238
+ event_colours: { primary: '#000000' },
239
+ organisation_id: 'org-123',
240
+ event_days: 1,
241
+ event_typicalunit: 'km',
242
+ event_rounddown: false,
243
+ event_youthmultiplier: 1.0,
244
+ event_catering_email: 'test@example.com',
245
+ event_news: 'Test news',
246
+ event_billing: 'Test billing',
247
+ event_footer: 'Test footer',
248
+ event_email: 'event@example.com'
249
+ };
250
+
251
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
252
+ data: [mockEventData],
253
+ error: null
254
+ });
255
+
256
+ const { result } = renderHook(() => usePublicEvent('test-event', { cacheTtl: 100 }));
257
+
258
+ await waitFor(() => {
259
+ expect(result.current.isLoading).toBe(false);
260
+ }, { interval: 10 });
261
+
262
+ // Wait for cache to expire
263
+ await new Promise(resolve => setTimeout(resolve, 150));
264
+
265
+ // Rerender should fetch again
266
+ const { result: result2 } = renderHook(() => usePublicEvent('test-event', { cacheTtl: 100 }));
267
+
268
+ await waitFor(() => {
269
+ expect(result2.current.isLoading).toBe(false);
270
+ }, { interval: 10 });
271
+
272
+ expect(mockSupabaseClient.rpc).toHaveBeenCalledTimes(2);
273
+ });
274
+
275
+ it('should disable caching when requested', async () => {
276
+ const mockEventData = {
277
+ event_id: '123',
278
+ event_name: 'Test Event',
279
+ event_date: '2024-01-01',
280
+ event_venue: 'Test Venue',
281
+ event_participants: 100,
282
+ event_colours: { primary: '#000000' },
283
+ organisation_id: 'org-123',
284
+ event_days: 1,
285
+ event_typicalunit: 'km',
286
+ event_rounddown: false,
287
+ event_youthmultiplier: 1.0,
288
+ event_catering_email: 'test@example.com',
289
+ event_news: 'Test news',
290
+ event_billing: 'Test billing',
291
+ event_footer: 'Test footer',
292
+ event_email: 'event@example.com',
293
+ event_logo: null
294
+ };
295
+
296
+ // Clear any existing cache
297
+ const { clearPublicEventCache } = await import('../public/usePublicEvent');
298
+ clearPublicEventCache();
299
+
300
+ // Use mockImplementation to handle multiple calls
301
+ let callCount = 0;
302
+ mockSupabaseClient.rpc.mockImplementation(() => {
303
+ callCount++;
304
+ return Promise.resolve({
305
+ data: [mockEventData],
306
+ error: null
307
+ });
308
+ });
309
+
310
+ const { result, rerender } = renderHook(
311
+ ({ eventCode }) => usePublicEvent(eventCode, { enableCache: false }),
312
+ { initialProps: { eventCode: 'test-event' } }
313
+ );
314
+
315
+ await waitFor(() => {
316
+ expect(result.current.isLoading).toBe(false);
317
+ }, { interval: 10 });
318
+
319
+ // Change the event code to force a new fetch
320
+ rerender({ eventCode: 'test-event-2' });
321
+
322
+ await waitFor(() => {
323
+ expect(result.current.isLoading).toBe(false);
324
+ }, { interval: 10 });
325
+
326
+ expect(callCount).toBe(2);
327
+ });
328
+ });
329
+
330
+ describe('Error Handling', () => {
331
+ it('should handle RPC errors', async () => {
332
+ // Mock the RPC call to return an error object
333
+ const testError = { message: 'Database error', details: 'Test error details', hint: null, code: 'TEST_ERROR' };
334
+ mockSupabaseClient.rpc.mockImplementation(() =>
335
+ Promise.resolve({
336
+ data: null,
337
+ error: testError
338
+ })
339
+ );
340
+
341
+ const { result } = renderHook(() => usePublicEvent('test-event'));
342
+
343
+ await waitFor(() => {
344
+ expect(result.current.isLoading).toBe(false);
345
+ }, { interval: 10 });
346
+
347
+ expect(result.current.error).toBeInstanceOf(Error);
348
+ expect(result.current.error?.message).toBe('Database error');
349
+ expect(result.current.event).toBe(null);
350
+
351
+ // Verify the mock was called
352
+ expect(mockSupabaseClient.rpc).toHaveBeenCalledWith('get_public_event_by_code', {
353
+ event_code_param: 'test-event'
354
+ });
355
+ });
356
+
357
+ it('should handle missing Supabase client', async () => {
358
+ // Mock the PublicPageProvider to return null environment
359
+ const mockUsePublicPageContext = vi.mocked(usePublicPageContext);
360
+ mockUsePublicPageContext.mockReturnValueOnce({
361
+ environment: {
362
+ supabaseUrl: '',
363
+ supabaseKey: ''
364
+ }
365
+ });
366
+
367
+ // Mock createClient to return null when environment is empty
368
+ const { createClient } = await import('@supabase/supabase-js');
369
+ vi.mocked(createClient).mockReturnValueOnce(null as any);
370
+
371
+ const { result } = renderHook(() => usePublicEvent('test-event'));
372
+
373
+ await waitFor(() => {
374
+ expect(result.current.isLoading).toBe(false);
375
+ }, { interval: 10 });
376
+
377
+ expect(result.current.error).toBeInstanceOf(Error);
378
+ expect(result.current.error?.message).toContain('Invalid event code or Supabase client not available');
379
+ expect(result.current.event).toBe(null);
380
+ });
381
+ });
382
+
383
+ describe('Provider Context Integration', () => {
384
+ it('should use PublicPageContext when available', async () => {
385
+ const mockContext = {
386
+ environment: {
387
+ supabaseUrl: 'https://context.supabase.co',
388
+ supabaseKey: 'context-anon-key'
389
+ }
390
+ };
391
+
392
+ vi.mocked(usePublicPageContext).mockReturnValue(mockContext);
393
+
394
+ const mockEventData = {
395
+ event_id: '123',
396
+ event_name: 'Test Event',
397
+ event_date: '2024-01-01',
398
+ event_venue: 'Test Venue',
399
+ event_participants: 100,
400
+ event_colours: { primary: '#000000' },
401
+ organisation_id: 'org-123',
402
+ event_days: 1,
403
+ event_typicalunit: 'km',
404
+ event_rounddown: false,
405
+ event_youthmultiplier: 1.0,
406
+ event_catering_email: 'test@example.com',
407
+ event_news: 'Test news',
408
+ event_billing: 'Test billing',
409
+ event_footer: 'Test footer',
410
+ event_email: 'event@example.com',
411
+ event_logo: null
412
+ };
413
+
414
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
415
+ data: [mockEventData],
416
+ error: null
417
+ });
418
+
419
+ const { result } = renderHook(() => usePublicEvent('test-event'));
420
+
421
+ await waitFor(() => {
422
+ expect(result.current.isLoading).toBe(false);
423
+ }, { interval: 10 });
424
+
425
+ expect(result.current.event).toBeTruthy();
426
+ });
427
+ });
428
+
429
+ describe('Refetch Functionality', () => {
430
+ it('should refetch data when refetch is called', async () => {
431
+ const mockEventData = {
432
+ event_id: '123',
433
+ event_name: 'Test Event',
434
+ event_date: '2024-01-01',
435
+ event_venue: 'Test Venue',
436
+ event_participants: 100,
437
+ event_colours: { primary: '#000000' },
438
+ organisation_id: 'org-123',
439
+ event_days: 1,
440
+ event_typicalunit: 'km',
441
+ event_rounddown: false,
442
+ event_youthmultiplier: 1.0,
443
+ event_catering_email: 'test@example.com',
444
+ event_news: 'Test news',
445
+ event_billing: 'Test billing',
446
+ event_footer: 'Test footer',
447
+ event_email: 'event@example.com'
448
+ };
449
+
450
+ mockSupabaseClient.rpc.mockResolvedValue({
451
+ data: [mockEventData],
452
+ error: null
453
+ });
454
+
455
+ const { result } = renderHook(() => usePublicEvent('test-event'));
456
+
457
+ await waitFor(() => {
458
+ expect(result.current.isLoading).toBe(false);
459
+ }, { interval: 10 });
460
+
461
+ // Call refetch
462
+ await act(async () => {
463
+ await result.current.refetch();
464
+ });
465
+
466
+ expect(mockSupabaseClient.rpc).toHaveBeenCalledTimes(2);
467
+ });
468
+
469
+ it('should clear cache when refetch is called', async () => {
470
+ const mockEventData = {
471
+ event_id: '123',
472
+ event_name: 'Test Event',
473
+ event_date: '2024-01-01',
474
+ event_venue: 'Test Venue',
475
+ event_participants: 100,
476
+ event_colours: { primary: '#000000' },
477
+ organisation_id: 'org-123',
478
+ event_days: 1,
479
+ event_typicalunit: 'km',
480
+ event_rounddown: false,
481
+ event_youthmultiplier: 1.0,
482
+ event_catering_email: 'test@example.com',
483
+ event_news: 'Test news',
484
+ event_billing: 'Test billing',
485
+ event_footer: 'Test footer',
486
+ event_email: 'event@example.com'
487
+ };
488
+
489
+ mockSupabaseClient.rpc.mockResolvedValue({
490
+ data: [mockEventData],
491
+ error: null
492
+ });
493
+
494
+ const { result } = renderHook(() => usePublicEvent('test-event'));
495
+
496
+ await waitFor(() => {
497
+ expect(result.current.isLoading).toBe(false);
498
+ }, { interval: 10 });
499
+
500
+ // Call refetch
501
+ await act(async () => {
502
+ await result.current.refetch();
503
+ });
504
+
505
+ // Should call RPC again (cache was cleared)
506
+ expect(mockSupabaseClient.rpc).toHaveBeenCalledTimes(2);
507
+ });
508
+ });
509
+
510
+ describe('Cache Management Utilities', () => {
511
+ it('should clear public event cache', () => {
512
+ // Add some data to cache
513
+ const stats = getPublicEventCacheStats();
514
+ expect(stats.size).toBe(0);
515
+
516
+ // Clear cache
517
+ clearPublicEventCache();
518
+
519
+ const statsAfter = getPublicEventCacheStats();
520
+ expect(statsAfter.size).toBe(0);
521
+ });
522
+
523
+ it('should get cache statistics', () => {
524
+ const stats = getPublicEventCacheStats();
525
+ expect(stats).toEqual({
526
+ size: 0,
527
+ keys: []
528
+ });
529
+ });
530
+ });
531
+
532
+ describe('Edge Cases', () => {
533
+ it('should handle null event data from RPC', async () => {
534
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
535
+ data: null,
536
+ error: null
537
+ });
538
+
539
+ const { result } = renderHook(() => usePublicEvent('test-event'));
540
+
541
+ await waitFor(() => {
542
+ expect(result.current.isLoading).toBe(false);
543
+ }, { interval: 10 });
544
+
545
+ expect(result.current.event).toBe(null);
546
+ expect(result.current.error).toEqual(new Error('Event not found'));
547
+ });
548
+
549
+ it('should handle empty event data array from RPC', async () => {
550
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
551
+ data: [],
552
+ error: null
553
+ });
554
+
555
+ const { result } = renderHook(() => usePublicEvent('test-event'));
556
+
557
+ await waitFor(() => {
558
+ expect(result.current.isLoading).toBe(false);
559
+ }, { interval: 10 });
560
+
561
+ expect(result.current.event).toBe(null);
562
+ expect(result.current.error).toEqual(new Error('Event not found'));
563
+ });
564
+
565
+ it('should handle undefined event data from RPC', async () => {
566
+ mockSupabaseClient.rpc.mockResolvedValueOnce({
567
+ data: [undefined],
568
+ error: null
569
+ });
570
+
571
+ const { result } = renderHook(() => usePublicEvent('test-event'));
572
+
573
+ await waitFor(() => {
574
+ expect(result.current.isLoading).toBe(false);
575
+ }, { interval: 10 });
576
+
577
+ expect(result.current.event).toBe(null);
578
+ expect(result.current.error).toEqual(new Error('Event not found'));
579
+ });
580
+ });
581
+ });
@@ -5,7 +5,7 @@ import { useUnifiedAuth } from '../../providers';
5
5
  import { useOrganisations } from '../../hooks/useOrganisations';
6
6
  import { testDataGenerators } from '../../__tests__/helpers/test-utils';
7
7
  import { useResolvedScope } from '../../rbac/hooks/useResolvedScope';
8
- import { useSuperAdminBypass } from '../../rbac/hooks/useSuperAdminBypass';
8
+ import { useOrganisationSecurity } from '../useOrganisationSecurity';
9
9
 
10
10
  // Mock dependencies
11
11
  vi.mock('../../providers', () => ({
@@ -28,8 +28,8 @@ vi.mock('../../rbac/hooks/useResolvedScope', () => ({
28
28
  useResolvedScope: vi.fn(),
29
29
  }));
30
30
 
31
- vi.mock('../../rbac/hooks/useSuperAdminBypass', () => ({
32
- useSuperAdminBypass: vi.fn(),
31
+ vi.mock('../useOrganisationSecurity', () => ({
32
+ useOrganisationSecurity: vi.fn(),
33
33
  }));
34
34
 
35
35
  const mockUseUnifiedAuth = {
@@ -114,10 +114,17 @@ describe('useSecureDataAccess', () => {
114
114
  isLoading: false,
115
115
  error: null,
116
116
  });
117
- // Default mock for useSuperAdminBypass - not super admin
118
- vi.mocked(useSuperAdminBypass).mockReturnValue({
119
- isSuperAdmin: false,
120
- });
117
+ // Default mock for useOrganisationSecurity - not super admin
118
+ vi.mocked(useOrganisationSecurity).mockReturnValue({
119
+ superAdminContext: { isSuperAdmin: false, hasGlobalAccess: false, canManageAllOrganisations: false },
120
+ validateOrganisationAccess: vi.fn(),
121
+ hasMinimumRole: vi.fn(),
122
+ canAccessChildOrganisations: vi.fn(),
123
+ checkPermission: vi.fn(),
124
+ getPermissions: vi.fn(),
125
+ logOrganisationAccess: vi.fn(),
126
+ canManageOrganisation: vi.fn(),
127
+ } as any);
121
128
  });
122
129
 
123
130
  describe('validateContext', () => {
@@ -400,7 +407,7 @@ describe('useSecureDataAccess', () => {
400
407
 
401
408
  const { result } = renderHook(() => useSecureDataAccess());
402
409
 
403
- const data = await result.current.secureUpdate('event', { name: 'Updated' }, { id: 1 });
410
+ const data = await result.current.secureUpdate('core_events', { name: 'Updated' }, { id: 1 });
404
411
 
405
412
  expect(data).toEqual([{ id: 1, name: 'Updated', organisation_id: 'org-123' }]);
406
413
  });
@@ -421,7 +428,7 @@ describe('useSecureDataAccess', () => {
421
428
 
422
429
  const { result } = renderHook(() => useSecureDataAccess());
423
430
 
424
- await expect(result.current.secureUpdate('event', { name: 'Updated' }, { id: 1 })).rejects.toThrow('Update failed');
431
+ await expect(result.current.secureUpdate('core_events', { name: 'Updated' }, { id: 1 })).rejects.toThrow('Update failed');
425
432
  });
426
433
 
427
434
  it('should return empty array when no data updated', async () => {
@@ -440,7 +447,7 @@ describe('useSecureDataAccess', () => {
440
447
 
441
448
  const { result } = renderHook(() => useSecureDataAccess());
442
449
 
443
- const data = await result.current.secureUpdate('event', { name: 'Updated' }, { id: 1 });
450
+ const data = await result.current.secureUpdate('core_events', { name: 'Updated' }, { id: 1 });
444
451
 
445
452
  expect(data).toEqual([]);
446
453
  });
@@ -461,9 +468,9 @@ describe('useSecureDataAccess', () => {
461
468
 
462
469
  const { result } = renderHook(() => useSecureDataAccess());
463
470
 
464
- await result.current.secureDelete('event', { id: 1 });
471
+ await result.current.secureDelete('core_events', { id: 1 });
465
472
 
466
- expect(mockSupabase.from).toHaveBeenCalledWith('event');
473
+ expect(mockSupabase.from).toHaveBeenCalledWith('core_events');
467
474
  });
468
475
 
469
476
  it('should handle delete errors', async () => {
@@ -480,7 +487,8 @@ describe('useSecureDataAccess', () => {
480
487
 
481
488
  const { result } = renderHook(() => useSecureDataAccess());
482
489
 
483
- await expect(result.current.secureDelete('event', { id: 1 })).rejects.toThrow('Delete failed');
490
+ // The implementation throws the error, so the promise should reject
491
+ await expect(result.current.secureDelete('core_events', { id: 1 })).rejects.toThrow('Delete failed');
484
492
  });
485
493
  });
486
494
 
@@ -605,12 +613,12 @@ describe('useSecureDataAccess', () => {
605
613
  const { result } = renderHook(() => useSecureDataAccess());
606
614
 
607
615
  // Verify the actual behavior: secure update works correctly
608
- const updateResult = await result.current.secureUpdate('event', { name: 'Updated' }, { id: 1 });
616
+ const updateResult = await result.current.secureUpdate('core_events', { name: 'Updated' }, { id: 1 });
609
617
 
610
618
  // Test the actual functionality: update executes and returns results
611
619
  expect(updateResult).toEqual([{ id: 1, name: 'Updated' }]);
612
620
  // Verify security: organisation filter is applied
613
- expect(mockSupabase.from).toHaveBeenCalledWith('event');
621
+ expect(mockSupabase.from).toHaveBeenCalledWith('core_events');
614
622
  // Verify the operation completed successfully (organisation filter is applied internally)
615
623
 
616
624
  consoleSpy.mockRestore();