@jmruthers/pace-core 0.5.189 → 0.5.191

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 (438) hide show
  1. package/core-usage-manifest.json +0 -4
  2. package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
  3. package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
  4. package/dist/{DataTable-GUFUNZ3N.js → DataTable-WKRZD47S.js} +8 -8
  5. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-ULXC_u6U.d.ts} +84 -25
  6. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  7. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-FTSG5XH7.js} +4 -2
  8. package/dist/{api-YP7XD5L6.js → api-IHKALJZD.js} +4 -2
  9. package/dist/{chunk-VGZZXKBR.js → chunk-6LTQQAT6.js} +351 -157
  10. package/dist/chunk-6LTQQAT6.js.map +1 -0
  11. package/dist/{chunk-MX64ZF6I.js → chunk-6TQDD426.js} +15 -15
  12. package/dist/chunk-6TQDD426.js.map +1 -0
  13. package/dist/{chunk-YHCN776L.js → chunk-G37KK66H.js} +2 -75
  14. package/dist/chunk-G37KK66H.js.map +1 -0
  15. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  16. package/dist/chunk-HW3OVDUF.js.map +1 -0
  17. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  18. package/dist/chunk-I7PSE6JW.js.map +1 -0
  19. package/dist/{chunk-IM4QE42D.js → chunk-LOMZXPSN.js} +141 -326
  20. package/dist/chunk-LOMZXPSN.js.map +1 -0
  21. package/dist/chunk-OETXORNB.js +614 -0
  22. package/dist/chunk-OETXORNB.js.map +1 -0
  23. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  24. package/dist/{chunk-HEHYGYOX.js → chunk-ROXMHMY2.js} +403 -46
  25. package/dist/chunk-ROXMHMY2.js.map +1 -0
  26. package/dist/{chunk-2UUZZJFT.js → chunk-ULHIJK66.js} +228 -177
  27. package/dist/{chunk-2UUZZJFT.js.map → chunk-ULHIJK66.js.map} +1 -1
  28. package/dist/{chunk-YGPFYGA6.js → chunk-VKB2CO4Z.js} +838 -503
  29. package/dist/chunk-VKB2CO4Z.js.map +1 -0
  30. package/dist/{chunk-3GOZZZYH.js → chunk-VRGWKHDB.js} +238 -301
  31. package/dist/chunk-VRGWKHDB.js.map +1 -0
  32. package/dist/{chunk-UCQSRW7Z.js → chunk-XNYQOL3Z.js} +431 -384
  33. package/dist/chunk-XNYQOL3Z.js.map +1 -0
  34. package/dist/{chunk-DDM4CCYT.js → chunk-XYXSXPUK.js} +79 -59
  35. package/dist/chunk-XYXSXPUK.js.map +1 -0
  36. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  37. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  38. package/dist/components.d.ts +5 -6
  39. package/dist/components.js +19 -19
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
  42. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  43. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  44. package/dist/hooks.d.ts +20 -15
  45. package/dist/hooks.js +14 -8
  46. package/dist/hooks.js.map +1 -1
  47. package/dist/index.d.ts +17 -15
  48. package/dist/index.js +86 -81
  49. package/dist/index.js.map +1 -1
  50. package/dist/providers.d.ts +3 -3
  51. package/dist/providers.js +3 -1
  52. package/dist/rbac/index.d.ts +77 -13
  53. package/dist/rbac/index.js +12 -9
  54. package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
  55. package/dist/types.d.ts +3 -3
  56. package/dist/types.js +1 -1
  57. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +17 -10
  58. package/dist/utils.d.ts +8 -8
  59. package/dist/utils.js +16 -16
  60. package/docs/README.md +2 -2
  61. package/docs/api/classes/ColumnFactory.md +1 -1
  62. package/docs/api/classes/ErrorBoundary.md +1 -1
  63. package/docs/api/classes/InvalidScopeError.md +2 -2
  64. package/docs/api/classes/Logger.md +1 -1
  65. package/docs/api/classes/MissingUserContextError.md +2 -2
  66. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  67. package/docs/api/classes/PermissionDeniedError.md +1 -1
  68. package/docs/api/classes/RBACAuditManager.md +2 -2
  69. package/docs/api/classes/RBACCache.md +1 -1
  70. package/docs/api/classes/RBACEngine.md +5 -5
  71. package/docs/api/classes/RBACError.md +1 -1
  72. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  73. package/docs/api/classes/SecureSupabaseClient.md +25 -20
  74. package/docs/api/classes/StorageUtils.md +7 -4
  75. package/docs/api/enums/FileCategory.md +1 -1
  76. package/docs/api/enums/LogLevel.md +1 -1
  77. package/docs/api/enums/RBACErrorCode.md +1 -1
  78. package/docs/api/enums/RPCFunction.md +1 -1
  79. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  80. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +1 -1
  82. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  83. package/docs/api/interfaces/AvatarProps.md +1 -1
  84. package/docs/api/interfaces/BadgeProps.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CalendarProps.md +20 -6
  87. package/docs/api/interfaces/CardProps.md +1 -1
  88. package/docs/api/interfaces/ColorPalette.md +1 -1
  89. package/docs/api/interfaces/ColorShade.md +1 -1
  90. package/docs/api/interfaces/ComplianceResult.md +1 -1
  91. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  92. package/docs/api/interfaces/DataRecord.md +1 -1
  93. package/docs/api/interfaces/DataTableAction.md +1 -1
  94. package/docs/api/interfaces/DataTableColumn.md +1 -1
  95. package/docs/api/interfaces/DataTableProps.md +1 -1
  96. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  97. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  98. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  99. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  100. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  101. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  102. package/docs/api/interfaces/ExportColumn.md +1 -1
  103. package/docs/api/interfaces/ExportOptions.md +1 -1
  104. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  105. package/docs/api/interfaces/FileMetadata.md +1 -1
  106. package/docs/api/interfaces/FileReference.md +2 -2
  107. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  108. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  109. package/docs/api/interfaces/FileUploadProps.md +30 -19
  110. package/docs/api/interfaces/FooterProps.md +1 -1
  111. package/docs/api/interfaces/FormFieldProps.md +1 -1
  112. package/docs/api/interfaces/FormProps.md +1 -1
  113. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  114. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  115. package/docs/api/interfaces/InputProps.md +1 -1
  116. package/docs/api/interfaces/LabelProps.md +1 -1
  117. package/docs/api/interfaces/LoggerConfig.md +1 -1
  118. package/docs/api/interfaces/LoginFormProps.md +1 -1
  119. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  120. package/docs/api/interfaces/NavigationContextType.md +9 -9
  121. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  122. package/docs/api/interfaces/NavigationItem.md +1 -1
  123. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  124. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  125. package/docs/api/interfaces/Organisation.md +1 -1
  126. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  127. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  128. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  129. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  130. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  131. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  132. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  133. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  134. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  135. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  136. package/docs/api/interfaces/PaletteData.md +1 -1
  137. package/docs/api/interfaces/ParsedAddress.md +2 -2
  138. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  139. package/docs/api/interfaces/ProgressProps.md +3 -11
  140. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  141. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  142. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  143. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  144. package/docs/api/interfaces/QuickFix.md +1 -1
  145. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  146. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  147. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  148. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  149. package/docs/api/interfaces/RBACConfig.md +2 -2
  150. package/docs/api/interfaces/RBACContext.md +1 -1
  151. package/docs/api/interfaces/RBACLogger.md +1 -1
  152. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  153. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  154. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  155. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  156. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  157. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  158. package/docs/api/interfaces/RBACResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  161. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  162. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  163. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  164. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  165. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  166. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  167. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  168. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  169. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  170. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  171. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  172. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  173. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  174. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  175. package/docs/api/interfaces/RouteConfig.md +10 -10
  176. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  177. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  178. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  179. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  180. package/docs/api/interfaces/SetupIssue.md +1 -1
  181. package/docs/api/interfaces/StorageConfig.md +4 -4
  182. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  183. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  184. package/docs/api/interfaces/StorageListOptions.md +22 -9
  185. package/docs/api/interfaces/StorageListResult.md +4 -4
  186. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  187. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  188. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  189. package/docs/api/interfaces/StyleImport.md +1 -1
  190. package/docs/api/interfaces/SwitchProps.md +1 -1
  191. package/docs/api/interfaces/TabsContentProps.md +1 -1
  192. package/docs/api/interfaces/TabsListProps.md +1 -1
  193. package/docs/api/interfaces/TabsProps.md +1 -1
  194. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  195. package/docs/api/interfaces/TextareaProps.md +1 -1
  196. package/docs/api/interfaces/ToastActionElement.md +1 -1
  197. package/docs/api/interfaces/ToastProps.md +1 -1
  198. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  199. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  200. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  201. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  202. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  203. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  205. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  207. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  208. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  209. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  210. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  211. package/docs/api/interfaces/UseResolvedScopeOptions.md +5 -5
  212. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  213. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  214. package/docs/api/interfaces/UserEventAccess.md +11 -11
  215. package/docs/api/interfaces/UserMenuProps.md +1 -1
  216. package/docs/api/interfaces/UserProfile.md +1 -1
  217. package/docs/api/modules.md +165 -106
  218. package/docs/api-reference/components.md +15 -7
  219. package/docs/api-reference/providers.md +2 -2
  220. package/docs/api-reference/rpc-functions.md +1 -0
  221. package/docs/best-practices/README.md +1 -1
  222. package/docs/best-practices/deployment.md +8 -8
  223. package/docs/getting-started/examples/README.md +2 -2
  224. package/docs/getting-started/installation-guide.md +4 -4
  225. package/docs/getting-started/quick-start.md +3 -3
  226. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  227. package/docs/migration/README.md +18 -0
  228. package/docs/migration/database-changes-december-2025.md +767 -0
  229. package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
  230. package/docs/rbac/compliance/compliance-guide.md +2 -2
  231. package/docs/rbac/event-based-apps.md +2 -2
  232. package/docs/rbac/getting-started.md +2 -2
  233. package/docs/rbac/quick-start.md +2 -2
  234. package/docs/security/README.md +4 -4
  235. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  236. package/docs/troubleshooting/README.md +2 -2
  237. package/docs/troubleshooting/migration.md +3 -3
  238. package/package.json +1 -3
  239. package/scripts/check-pace-core-compliance.cjs +1 -1
  240. package/scripts/check-pace-core-compliance.js +1 -1
  241. package/src/__tests__/fixtures/supabase.ts +301 -0
  242. package/src/__tests__/public-recipe-view.test.ts +19 -19
  243. package/src/__tests__/rls-policies.test.ts +210 -74
  244. package/src/components/AddressField/AddressField.test.tsx +42 -0
  245. package/src/components/AddressField/AddressField.tsx +71 -60
  246. package/src/components/AddressField/README.md +7 -6
  247. package/src/components/Alert/Alert.test.tsx +50 -10
  248. package/src/components/Alert/Alert.tsx +5 -3
  249. package/src/components/Avatar/Avatar.test.tsx +95 -43
  250. package/src/components/Avatar/Avatar.tsx +16 -16
  251. package/src/components/Button/Button.test.tsx +2 -1
  252. package/src/components/Button/Button.tsx +3 -3
  253. package/src/components/Calendar/Calendar.test.tsx +53 -37
  254. package/src/components/Calendar/Calendar.tsx +409 -82
  255. package/src/components/Card/Card.test.tsx +7 -4
  256. package/src/components/Card/Card.tsx +3 -6
  257. package/src/components/Checkbox/Checkbox.tsx +2 -2
  258. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  259. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  260. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  261. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  262. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  263. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  264. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  265. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  266. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  267. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  268. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  269. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  270. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  271. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  272. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  273. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  274. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  275. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  276. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  277. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  278. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  279. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  280. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  281. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  282. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  283. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  284. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  285. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  286. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  287. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  288. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  289. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  290. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  291. package/src/components/Dialog/Dialog.tsx +2 -2
  292. package/src/components/EventSelector/EventSelector.tsx +7 -7
  293. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  294. package/src/components/FileUpload/FileUpload.tsx +7 -4
  295. package/src/components/Header/Header.test.tsx +28 -0
  296. package/src/components/Header/Header.tsx +22 -9
  297. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  298. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  299. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  301. package/src/components/OrganisationSelector/OrganisationSelector.tsx +42 -22
  302. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  303. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  304. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  305. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  306. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  307. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  308. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  309. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  310. package/src/components/Progress/Progress.test.tsx +18 -19
  311. package/src/components/Progress/Progress.tsx +31 -32
  312. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  313. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  314. package/src/components/Select/Select.test.tsx +4 -1
  315. package/src/components/Select/Select.tsx +65 -20
  316. package/src/components/Switch/Switch.test.tsx +2 -1
  317. package/src/components/Switch/Switch.tsx +1 -1
  318. package/src/components/Toast/Toast.tsx +1 -1
  319. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  320. package/src/components/UserMenu/UserMenu.tsx +3 -3
  321. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  322. package/src/eslint-rules/pace-core-compliance.js +0 -2
  323. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  324. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  325. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  326. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  327. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  328. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  329. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -1
  330. package/src/hooks/__tests__/usePublicEvent.test.ts +608 -0
  331. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  332. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +67 -24
  333. package/src/hooks/index.ts +1 -1
  334. package/src/hooks/public/usePublicEvent.ts +10 -10
  335. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  336. package/src/hooks/useAppConfig.ts +24 -5
  337. package/src/hooks/useFileDisplay.ts +298 -36
  338. package/src/hooks/useFileReference.ts +56 -11
  339. package/src/hooks/useFileUrl.ts +1 -1
  340. package/src/hooks/useInactivityTracker.ts +16 -7
  341. package/src/hooks/usePermissionCache.test.ts +85 -8
  342. package/src/hooks/useQueryCache.ts +27 -6
  343. package/src/hooks/useSecureDataAccess.test.ts +87 -42
  344. package/src/hooks/useSecureDataAccess.ts +95 -48
  345. package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
  346. package/src/providers/services/EventServiceProvider.tsx +37 -17
  347. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  348. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  349. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  350. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  351. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  352. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  353. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  354. package/src/rbac/api.ts +240 -36
  355. package/src/rbac/cache-invalidation.ts +21 -7
  356. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  357. package/src/rbac/components/NavigationGuard.tsx +23 -63
  358. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  359. package/src/rbac/components/NavigationProvider.tsx +13 -11
  360. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  361. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  362. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  363. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  364. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  365. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  366. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  367. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  368. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  369. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  370. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  371. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  372. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  373. package/src/rbac/engine.ts +4 -2
  374. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  375. package/src/rbac/hooks/index.ts +3 -0
  376. package/src/rbac/hooks/useCan.test.ts +101 -53
  377. package/src/rbac/hooks/usePermissions.ts +108 -41
  378. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  379. package/src/rbac/hooks/useRBAC.ts +83 -40
  380. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  381. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  382. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  383. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  384. package/src/rbac/request-deduplication.ts +1 -1
  385. package/src/rbac/secureClient.ts +72 -12
  386. package/src/rbac/security.ts +29 -23
  387. package/src/rbac/types.ts +10 -0
  388. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  389. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  390. package/src/rbac/utils/__tests__/eventContext.test.ts +8 -3
  391. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +74 -12
  392. package/src/rbac/utils/contextValidator.ts +288 -0
  393. package/src/rbac/utils/eventContext.ts +52 -3
  394. package/src/services/AuthService.ts +37 -8
  395. package/src/services/EventService.ts +165 -21
  396. package/src/services/OrganisationService.ts +125 -137
  397. package/src/services/__tests__/EventService.test.ts +26 -21
  398. package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
  399. package/src/services/__tests__/OrganisationService.test.ts +218 -86
  400. package/src/types/database.generated.ts +166 -201
  401. package/src/types/file-reference.ts +13 -10
  402. package/src/types/supabase.ts +2 -2
  403. package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
  404. package/src/utils/app/appNameResolver.test.ts +346 -73
  405. package/src/utils/context/superAdminOverride.ts +58 -0
  406. package/src/utils/file-reference/index.ts +65 -37
  407. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  408. package/src/utils/google-places/googlePlacesUtils.ts +1 -1
  409. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  410. package/src/utils/google-places/types.ts +1 -1
  411. package/src/utils/request-deduplication.ts +4 -4
  412. package/src/utils/security/secureDataAccess.test.ts +1 -1
  413. package/src/utils/security/secureDataAccess.ts +7 -4
  414. package/src/utils/storage/README.md +1 -1
  415. package/src/utils/storage/helpers.test.ts +1 -1
  416. package/src/utils/storage/helpers.ts +38 -19
  417. package/src/utils/storage/types.ts +15 -8
  418. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  419. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  420. package/src/vite-env.d.ts +2 -2
  421. package/dist/chunk-3GOZZZYH.js.map +0 -1
  422. package/dist/chunk-DDM4CCYT.js.map +0 -1
  423. package/dist/chunk-E7UAOUMY.js +0 -75
  424. package/dist/chunk-E7UAOUMY.js.map +0 -1
  425. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  426. package/dist/chunk-HEHYGYOX.js.map +0 -1
  427. package/dist/chunk-IM4QE42D.js.map +0 -1
  428. package/dist/chunk-MX64ZF6I.js.map +0 -1
  429. package/dist/chunk-SAUPYVLF.js.map +0 -1
  430. package/dist/chunk-THRPYOFK.js.map +0 -1
  431. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  432. package/dist/chunk-VGZZXKBR.js.map +0 -1
  433. package/dist/chunk-YGPFYGA6.js.map +0 -1
  434. package/dist/chunk-YHCN776L.js.map +0 -1
  435. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-WKRZD47S.js.map} +0 -0
  436. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-FTSG5XH7.js.map} +0 -0
  437. /package/dist/{api-YP7XD5L6.js.map → api-IHKALJZD.js.map} +0 -0
  438. /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
@@ -0,0 +1,301 @@
1
+ /**
2
+ * @file Supabase Test Fixtures
3
+ * @package @jmruthers/pace-core
4
+ * @module TestFixtures/Supabase
5
+ * @since 1.0.0
6
+ *
7
+ * Shared Supabase client fixtures and mock data generators for tests.
8
+ * Reduces repeated mock setup across test files.
9
+ */
10
+
11
+ import { createMockSupabaseClient, createMockQueryBuilder } from '../helpers/supabaseMock';
12
+ import type { User, Session } from '@supabase/supabase-js';
13
+ import { TEST_FIXTURES } from './test-data';
14
+
15
+ /**
16
+ * Creates a standard mock Supabase client with common RBAC mocks
17
+ */
18
+ export function createTestSupabaseClient(overrides: {
19
+ user?: User;
20
+ session?: Session;
21
+ rpcResponses?: Record<string, any>;
22
+ tableData?: Record<string, any[]>;
23
+ } = {}) {
24
+ const mockUser = overrides.user || {
25
+ id: TEST_FIXTURES.users.basic.id,
26
+ email: TEST_FIXTURES.users.basic.email,
27
+ user_metadata: {},
28
+ app_metadata: {},
29
+ aud: 'authenticated',
30
+ created_at: '2024-01-01T00:00:00Z',
31
+ } as User;
32
+
33
+ const mockSession = overrides.session || {
34
+ access_token: 'test-access-token',
35
+ refresh_token: 'test-refresh-token',
36
+ expires_at: Date.now() + 3600000,
37
+ expires_in: 3600,
38
+ token_type: 'bearer',
39
+ user: mockUser,
40
+ } as Session;
41
+
42
+ const client = createMockSupabaseClient();
43
+ if (!overrides.tableData) {
44
+ throw new Error('createTestSupabaseClient requires tableData overrides for tests');
45
+ }
46
+
47
+
48
+ // Setup auth mocks
49
+ vi.spyOn(client.auth, 'getSession').mockResolvedValue({
50
+ data: { session: mockSession },
51
+ error: null
52
+ });
53
+
54
+ vi.spyOn(client.auth, 'getUser').mockResolvedValue({
55
+ data: { user: mockUser },
56
+ error: null
57
+ });
58
+
59
+ // Setup default RPC responses
60
+ const defaultRpcResponses: Record<string, any> = {
61
+ rbac_page_access_check: { data: true, error: null },
62
+ rbac_permissions_get: {
63
+ data: [
64
+ {
65
+ permission_type: 'organisation_access',
66
+ role_name: 'member',
67
+ context_id: TEST_FIXTURES.organisations.basic.id
68
+ }
69
+ ],
70
+ error: null
71
+ },
72
+ rbac_access_validate: {
73
+ data: [{
74
+ has_access: true,
75
+ access_level: 'organisation',
76
+ context_id: TEST_FIXTURES.organisations.basic.id
77
+ }],
78
+ error: null
79
+ },
80
+ ...overrides.rpcResponses
81
+ };
82
+
83
+ client.rpc.mockImplementation((functionName: string, params?: any) => {
84
+ const response = defaultRpcResponses[functionName];
85
+ if (response) {
86
+ // If response is a function, call it with params
87
+ if (typeof response === 'function') {
88
+ return response(params);
89
+ }
90
+ return Promise.resolve(response);
91
+ }
92
+ return Promise.resolve({ data: null, error: null });
93
+ });
94
+
95
+ // Setup default table data
96
+ // CRITICAL: Capture organisations from overrides BEFORE any processing
97
+ // This ensures we use the exact organisations provided, not defaults
98
+ const organisationsData = overrides.tableData?.organisations
99
+ ? [...overrides.tableData.organisations] // Create a copy to avoid mutations
100
+ : [TEST_FIXTURES.organisations.basic];
101
+
102
+ // Ensure all organisations have is_active: true (required by OrganisationService)
103
+ // But preserve all other properties including name
104
+ const processedOrganisations = organisationsData.map((org: any) => {
105
+ // If is_active is already set, return org as-is to preserve all properties including name
106
+ if (org.is_active !== undefined) {
107
+ return org;
108
+ }
109
+ // Only add is_active if missing, preserving all other properties
110
+ return {
111
+ ...org, // Preserve ALL existing properties including name
112
+ is_active: true
113
+ };
114
+ });
115
+
116
+ const defaultTableData: Record<string, any> = {
117
+ organisations: processedOrganisations, // Use processed organisations
118
+ event: overrides.tableData?.event ?? [TEST_FIXTURES.events.basic],
119
+ rbac_global_roles: overrides.tableData?.rbac_global_roles ?? [],
120
+ rbac_apps: overrides.tableData?.rbac_apps ?? [{ id: 'app-123', name: 'TEST_APP', is_active: true }],
121
+ rbac_app_pages: overrides.tableData?.rbac_app_pages ?? [{ id: 'page-123', page_name: 'dashboard', app_id: 'app-123' }],
122
+ };
123
+
124
+ // Apply any additional table data that wasn't explicitly handled above
125
+ if (overrides.tableData) {
126
+ for (const [key, value] of Object.entries(overrides.tableData)) {
127
+ if (!(key in defaultTableData)) {
128
+ defaultTableData[key] = value;
129
+ }
130
+ }
131
+ }
132
+
133
+ // Mock from() to return a builder that resolves with table-specific data
134
+ // CRITICAL: Capture processedOrganisations in closure to ensure it's always used
135
+ const organisationsForMock = processedOrganisations;
136
+
137
+ // Override the from() mock completely - don't use the default one from createMockSupabaseClient
138
+ client.from = vi.fn().mockImplementation((table: string) => {
139
+ // For organisations table, always use the captured processedOrganisations
140
+ // This ensures we use the correct organisations even if defaultTableData is modified
141
+ let tableData: any;
142
+ if (table === 'organisations') {
143
+ tableData = organisationsForMock;
144
+ } else {
145
+ tableData = defaultTableData[table as keyof typeof defaultTableData];
146
+ }
147
+
148
+ // Ensure data is always an array
149
+ const data = Array.isArray(tableData) ? tableData : (tableData ? [tableData] : []);
150
+ // Create response in the format Supabase returns: { data: [...], error: null }
151
+ const response = { data, error: null };
152
+
153
+ // Create a fresh builder for each call to ensure data is correct
154
+ // We'll completely override the builder to use our response
155
+ // IMPORTANT: All chainable methods must return the builder itself (not 'this')
156
+ const builder: any = {};
157
+
158
+ // Define chainable methods that return the builder
159
+ const chainableMethods = ['select', 'insert', 'update', 'delete', 'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'ilike', 'in', 'not', 'is', 'or', 'and', 'filter', 'match', 'order', 'offset'];
160
+ chainableMethods.forEach(method => {
161
+ builder[method] = vi.fn().mockReturnValue(builder);
162
+ });
163
+
164
+ // Methods that resolve with data
165
+ builder.limit = vi.fn().mockResolvedValue(response);
166
+ builder.single = vi.fn().mockResolvedValue({ data: data[0] || null, error: null });
167
+ builder.maybeSingle = vi.fn().mockResolvedValue({ data: data[0] || null, error: null });
168
+
169
+ // Thenable interface - CRITICAL: must resolve with the correct response
170
+ builder.then = vi.fn().mockImplementation((resolve, reject) => {
171
+ Promise.resolve(response).then(resolve, reject);
172
+ });
173
+
174
+ builder.catch = vi.fn().mockImplementation((onRejected) => {
175
+ return Promise.resolve(response).catch(onRejected);
176
+ });
177
+
178
+ builder.finally = vi.fn().mockImplementation((onFinally) => {
179
+ return Promise.resolve(response).finally(onFinally);
180
+ });
181
+
182
+ builder.range = vi.fn().mockImplementation((min: number, max: number) => {
183
+ // Return a thenable builder that resolves with the sliced data
184
+ const rangedData = data.slice(min, max + 1);
185
+ const rangedResponse = { data: rangedData, error: null };
186
+ const rangedBuilder = Object.assign({}, builder);
187
+ rangedBuilder.then = vi.fn().mockImplementation((resolve, reject) => {
188
+ Promise.resolve(rangedResponse).then(resolve, reject);
189
+ });
190
+ rangedBuilder.catch = vi.fn().mockImplementation((onRejected) => {
191
+ return Promise.resolve(rangedResponse).catch(onRejected);
192
+ });
193
+ rangedBuilder.finally = vi.fn().mockImplementation((onFinally) => {
194
+ return Promise.resolve(rangedResponse).finally(onFinally);
195
+ });
196
+ // Ensure chainable methods still work
197
+ chainableMethods.forEach(method => {
198
+ rangedBuilder[method] = vi.fn().mockReturnValue(rangedBuilder);
199
+ });
200
+ return rangedBuilder;
201
+ });
202
+
203
+ return builder;
204
+ });
205
+
206
+ return client;
207
+ }
208
+
209
+ /**
210
+ * Creates mock user data
211
+ */
212
+ export function createMockUser(overrides: Partial<User> = {}): User {
213
+ return {
214
+ id: TEST_FIXTURES.users.basic.id,
215
+ email: TEST_FIXTURES.users.basic.email,
216
+ user_metadata: {},
217
+ app_metadata: {},
218
+ aud: 'authenticated',
219
+ created_at: '2024-01-01T00:00:00Z',
220
+ ...overrides
221
+ } as User;
222
+ }
223
+
224
+ /**
225
+ * Creates mock session data
226
+ */
227
+ export function createMockSession(user?: User, overrides: Partial<Session> = {}): Session {
228
+ const mockUser = user || createMockUser();
229
+ return {
230
+ access_token: 'test-access-token',
231
+ refresh_token: 'test-refresh-token',
232
+ expires_at: Date.now() + 3600000,
233
+ expires_in: 3600,
234
+ token_type: 'bearer',
235
+ user: mockUser,
236
+ ...overrides
237
+ } as Session;
238
+ }
239
+
240
+ /**
241
+ * Creates mock organisation data
242
+ */
243
+ export function createMockOrganisation(overrides: Partial<typeof TEST_FIXTURES.organisations.basic> & { is_active?: boolean; display_name?: string; name?: string } = {}) {
244
+ // Extract name from overrides if provided, otherwise use default
245
+ const orgName = overrides.name ?? TEST_FIXTURES.organisations.basic.name;
246
+ const displayName = overrides.display_name ?? orgName;
247
+
248
+ // Build the organisation object, ensuring overrides take precedence
249
+ return {
250
+ ...TEST_FIXTURES.organisations.basic,
251
+ // Set required fields with defaults
252
+ is_active: true, // Required by OrganisationService - only active orgs are used
253
+ subscription_tier: 'basic',
254
+ settings: {},
255
+ parent_id: null,
256
+ created_at: '2023-01-01T00:00:00Z',
257
+ updated_at: '2023-01-01T00:00:00Z',
258
+ // Apply name and display_name (these should come before overrides to ensure they're set)
259
+ name: orgName, // Explicitly set name (used by UI components)
260
+ display_name: displayName, // display_name defaults to name
261
+ // Apply all overrides last to ensure they take precedence (including name if provided)
262
+ ...overrides
263
+ };
264
+ }
265
+
266
+ /**
267
+ * Creates mock event data
268
+ */
269
+ export function createMockEvent(overrides: Partial<typeof TEST_FIXTURES.events.basic> = {}) {
270
+ return {
271
+ ...TEST_FIXTURES.events.basic,
272
+ ...overrides
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Creates a Supabase client configured for organisation-scoped data access tests
278
+ */
279
+ export function createOrganisationScopedSupabaseClient(organisationId: string) {
280
+ return createTestSupabaseClient({
281
+ tableData: {
282
+ organisations: [createMockOrganisation({ id: organisationId })],
283
+ event: [createMockEvent({ organisation_id: organisationId })]
284
+ },
285
+ rpcResponses: {
286
+ rbac_permissions_get: {
287
+ data: [{
288
+ permission_type: 'organisation_access',
289
+ role_name: 'member',
290
+ context_id: organisationId
291
+ }],
292
+ error: null
293
+ }
294
+ }
295
+ });
296
+ }
297
+
298
+ // Re-export vi for convenience
299
+ import { vi } from 'vitest';
300
+ export { vi };
301
+
@@ -19,10 +19,10 @@ const TEST_TIMEOUT = 5000;
19
19
  const PERFORMANCE_THRESHOLD = 500; // 500ms for public view queries
20
20
 
21
21
  // Check if we're using real test-db (via environment variables)
22
- const USE_REAL_DB = !!(process.env.SUPABASE_URL && process.env.VITE_SUPABASE_ANON_KEY);
22
+ const USE_REAL_DB = !!(process.env.SUPABASE_URL && process.env.VITE_SUPABASE_PUBLISHABLE_KEY);
23
23
  const TEST_SUPABASE_URL = process.env.SUPABASE_URL || process.env.VITE_SUPABASE_URL;
24
- const TEST_SUPABASE_ANON_KEY = process.env.TEST_SUPABASE_ANON_KEY || process.env.VITE_SUPABASE_ANON_KEY;
25
- const TEST_SUPABASE_SERVICE_ROLE_KEY = process.env.TEST_SUPABASE_SERVICE_ROLE_KEY;
24
+ const TEST_SUPABASE_PUBLISHABLE_KEY = process.env.VITE_SUPABASE_PUBLISHABLE_KEY;
25
+ const TEST_SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY;
26
26
 
27
27
  let anonClient: SupabaseClient<Database>;
28
28
  let authenticatedClient: SupabaseClient<Database>;
@@ -43,14 +43,14 @@ const privateEvent = {
43
43
  organisation_id: 'org-1' as any
44
44
  };
45
45
 
46
- describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('Public Recipe View - Anonymous Access', () => {
46
+ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_PUBLISHABLE_KEY)('Public Recipe View - Anonymous Access', () => {
47
47
  beforeEach(() => {
48
- if (USE_REAL_DB && TEST_SUPABASE_URL && TEST_SUPABASE_ANON_KEY) {
49
- anonClient = createClient<Database>(TEST_SUPABASE_URL, TEST_SUPABASE_ANON_KEY);
50
- authenticatedClient = createClient<Database>(TEST_SUPABASE_URL, TEST_SUPABASE_SERVICE_ROLE_KEY || TEST_SUPABASE_ANON_KEY);
48
+ if (USE_REAL_DB && TEST_SUPABASE_URL && TEST_SUPABASE_PUBLISHABLE_KEY) {
49
+ anonClient = createClient<Database>(TEST_SUPABASE_URL, TEST_SUPABASE_PUBLISHABLE_KEY);
50
+ authenticatedClient = createClient<Database>(TEST_SUPABASE_URL, TEST_SUPABASE_SERVICE_ROLE_KEY || TEST_SUPABASE_PUBLISHABLE_KEY);
51
51
  } else {
52
52
  // This should not happen due to skipIf, but provide fallback
53
- throw new Error('Test database credentials not available. Set SUPABASE_URL and VITE_SUPABASE_ANON_KEY environment variables.');
53
+ throw new Error('Test database credentials not available. Set SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY environment variables.');
54
54
  }
55
55
  });
56
56
 
@@ -58,7 +58,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
58
58
  it('should allow anonymous access when event.public_readable = true', async () => {
59
59
  const start = Date.now();
60
60
  const { data, error } = await anonClient
61
- .from('public_recipe_details')
61
+ .from('cake_public_recipe_details')
62
62
  .select('*')
63
63
  .eq('event_id', publicEvent.event_id);
64
64
  const duration = Date.now() - start;
@@ -70,7 +70,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
70
70
 
71
71
  it('should block anonymous access when event.public_readable = false', async () => {
72
72
  const { data, error } = await anonClient
73
- .from('public_recipe_details')
73
+ .from('cake_public_recipe_details')
74
74
  .select('*')
75
75
  .eq('event_id', privateEvent.event_id);
76
76
 
@@ -80,7 +80,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
80
80
 
81
81
  it('should block anonymous access when event.is_visible = false', async () => {
82
82
  const { data, error } = await anonClient
83
- .from('public_recipe_details')
83
+ .from('cake_public_recipe_details')
84
84
  .select('*')
85
85
  .eq('event_id', 'hidden-event-1');
86
86
 
@@ -92,7 +92,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
92
92
  describe('View Column Exposure', () => {
93
93
  it('should expose only expected columns', async () => {
94
94
  const { data, error } = await anonClient
95
- .from('public_recipe_details')
95
+ .from('cake_public_recipe_details')
96
96
  .select('*')
97
97
  .eq('event_id', publicEvent.event_id)
98
98
  .limit(1)
@@ -119,7 +119,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
119
119
  it('should filter by meal type', async () => {
120
120
  const start = Date.now();
121
121
  const { data, error } = await anonClient
122
- .from('public_recipe_details')
122
+ .from('cake_public_recipe_details')
123
123
  .select('*')
124
124
  .eq('event_id', publicEvent.event_id)
125
125
  .eq('mealtype_name', 'Breakfast');
@@ -134,7 +134,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
134
134
  // This test would verify that diet filters work correctly
135
135
  // Adjust based on actual view structure
136
136
  const { data, error } = await anonClient
137
- .from('public_recipe_details')
137
+ .from('cake_public_recipe_details')
138
138
  .select('*')
139
139
  .eq('event_id', publicEvent.event_id)
140
140
  .eq('dish_dietnote', 'Vegetarian');
@@ -148,7 +148,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
148
148
  it('should complete view queries in < 500ms', async () => {
149
149
  const start = Date.now();
150
150
  await anonClient
151
- .from('public_recipe_details')
151
+ .from('cake_public_recipe_details')
152
152
  .select('*')
153
153
  .eq('event_id', publicEvent.event_id)
154
154
  .limit(100);
@@ -160,7 +160,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
160
160
  it('should handle filtered queries efficiently', async () => {
161
161
  const start = Date.now();
162
162
  await anonClient
163
- .from('public_recipe_details')
163
+ .from('cake_public_recipe_details')
164
164
  .select('*')
165
165
  .eq('event_id', publicEvent.event_id)
166
166
  .eq('mealtype_name', 'Breakfast')
@@ -172,10 +172,10 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
172
172
  });
173
173
  });
174
174
 
175
- describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('Public Recipe View - Authenticated Access', () => {
175
+ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_PUBLISHABLE_KEY)('Public Recipe View - Authenticated Access', () => {
176
176
  it('should allow authenticated users to view public recipes', async () => {
177
177
  const { data, error } = await authenticatedClient
178
- .from('public_recipe_details')
178
+ .from('cake_public_recipe_details')
179
179
  .select('*')
180
180
  .eq('event_id', publicEvent.event_id);
181
181
 
@@ -188,7 +188,7 @@ describe.skipIf(!USE_REAL_DB || !TEST_SUPABASE_URL || !TEST_SUPABASE_ANON_KEY)('
188
188
  // recipes from events in their organisation, even if not public_readable
189
189
  // (This depends on the view definition and RLS policies)
190
190
  const { data, error } = await authenticatedClient
191
- .from('public_recipe_details')
191
+ .from('cake_public_recipe_details')
192
192
  .select('*')
193
193
  .eq('event_id', privateEvent.event_id);
194
194