@jmruthers/pace-core 0.5.189 → 0.5.190

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 (420) 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-GUFUNZ3N.js → DataTable-ON3IXISJ.js} +8 -8
  4. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-C4uxosp6.d.ts} +83 -24
  5. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  6. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-X5NXANVI.js} +4 -2
  7. package/dist/{api-YP7XD5L6.js → api-I6UCQ5S6.js} +4 -2
  8. package/dist/{chunk-DDM4CCYT.js → chunk-4QYC5L4K.js} +60 -35
  9. package/dist/chunk-4QYC5L4K.js.map +1 -0
  10. package/dist/{chunk-IM4QE42D.js → chunk-73HSNNOQ.js} +141 -326
  11. package/dist/chunk-73HSNNOQ.js.map +1 -0
  12. package/dist/{chunk-YHCN776L.js → chunk-DZWK57KZ.js} +2 -75
  13. package/dist/chunk-DZWK57KZ.js.map +1 -0
  14. package/dist/{chunk-3GOZZZYH.js → chunk-HQVPB5MZ.js} +238 -301
  15. package/dist/chunk-HQVPB5MZ.js.map +1 -0
  16. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  17. package/dist/chunk-HW3OVDUF.js.map +1 -0
  18. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  19. package/dist/chunk-I7PSE6JW.js.map +1 -0
  20. package/dist/{chunk-VGZZXKBR.js → chunk-J2XXC7R5.js} +280 -52
  21. package/dist/chunk-J2XXC7R5.js.map +1 -0
  22. package/dist/{chunk-UCQSRW7Z.js → chunk-NIU6J6OX.js} +425 -378
  23. package/dist/chunk-NIU6J6OX.js.map +1 -0
  24. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  25. package/dist/{chunk-HEHYGYOX.js → chunk-RUYZKXOD.js} +401 -46
  26. package/dist/chunk-RUYZKXOD.js.map +1 -0
  27. package/dist/{chunk-2UUZZJFT.js → chunk-SDMHPX3X.js} +176 -160
  28. package/dist/{chunk-2UUZZJFT.js.map → chunk-SDMHPX3X.js.map} +1 -1
  29. package/dist/{chunk-MX64ZF6I.js → chunk-STYK4OH2.js} +11 -11
  30. package/dist/chunk-STYK4OH2.js.map +1 -0
  31. package/dist/{chunk-YGPFYGA6.js → chunk-VVBAW5A5.js} +822 -498
  32. package/dist/chunk-VVBAW5A5.js.map +1 -0
  33. package/dist/chunk-Y4BUBBHD.js +614 -0
  34. package/dist/chunk-Y4BUBBHD.js.map +1 -0
  35. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  36. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  37. package/dist/components.d.ts +3 -4
  38. package/dist/components.js +19 -19
  39. package/dist/components.js.map +1 -1
  40. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  41. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  42. package/dist/hooks.d.ts +10 -5
  43. package/dist/hooks.js +14 -8
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +13 -11
  46. package/dist/index.js +79 -69
  47. package/dist/index.js.map +1 -1
  48. package/dist/providers.d.ts +3 -3
  49. package/dist/providers.js +3 -1
  50. package/dist/rbac/index.d.ts +76 -12
  51. package/dist/rbac/index.js +12 -9
  52. package/dist/types.d.ts +1 -1
  53. package/dist/types.js +1 -1
  54. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-DxIDS4bC.d.ts} +16 -9
  55. package/dist/utils.js +16 -16
  56. package/docs/README.md +2 -2
  57. package/docs/api/classes/ColumnFactory.md +1 -1
  58. package/docs/api/classes/ErrorBoundary.md +1 -1
  59. package/docs/api/classes/InvalidScopeError.md +2 -2
  60. package/docs/api/classes/Logger.md +1 -1
  61. package/docs/api/classes/MissingUserContextError.md +2 -2
  62. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  63. package/docs/api/classes/PermissionDeniedError.md +1 -1
  64. package/docs/api/classes/RBACAuditManager.md +1 -1
  65. package/docs/api/classes/RBACCache.md +1 -1
  66. package/docs/api/classes/RBACEngine.md +4 -4
  67. package/docs/api/classes/RBACError.md +1 -1
  68. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  69. package/docs/api/classes/SecureSupabaseClient.md +21 -16
  70. package/docs/api/classes/StorageUtils.md +7 -4
  71. package/docs/api/enums/FileCategory.md +1 -1
  72. package/docs/api/enums/LogLevel.md +1 -1
  73. package/docs/api/enums/RBACErrorCode.md +1 -1
  74. package/docs/api/enums/RPCFunction.md +1 -1
  75. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  76. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  77. package/docs/api/interfaces/AggregateConfig.md +1 -1
  78. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  79. package/docs/api/interfaces/AvatarProps.md +1 -1
  80. package/docs/api/interfaces/BadgeProps.md +1 -1
  81. package/docs/api/interfaces/ButtonProps.md +1 -1
  82. package/docs/api/interfaces/CalendarProps.md +20 -6
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/ComplianceResult.md +1 -1
  87. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  88. package/docs/api/interfaces/DataRecord.md +1 -1
  89. package/docs/api/interfaces/DataTableAction.md +1 -1
  90. package/docs/api/interfaces/DataTableColumn.md +1 -1
  91. package/docs/api/interfaces/DataTableProps.md +1 -1
  92. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  93. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  94. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  95. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  96. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  97. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  98. package/docs/api/interfaces/ExportColumn.md +1 -1
  99. package/docs/api/interfaces/ExportOptions.md +1 -1
  100. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  101. package/docs/api/interfaces/FileMetadata.md +1 -1
  102. package/docs/api/interfaces/FileReference.md +2 -2
  103. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  104. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  105. package/docs/api/interfaces/FileUploadProps.md +30 -19
  106. package/docs/api/interfaces/FooterProps.md +1 -1
  107. package/docs/api/interfaces/FormFieldProps.md +1 -1
  108. package/docs/api/interfaces/FormProps.md +1 -1
  109. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  110. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  111. package/docs/api/interfaces/InputProps.md +1 -1
  112. package/docs/api/interfaces/LabelProps.md +1 -1
  113. package/docs/api/interfaces/LoggerConfig.md +1 -1
  114. package/docs/api/interfaces/LoginFormProps.md +1 -1
  115. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  116. package/docs/api/interfaces/NavigationContextType.md +9 -9
  117. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  118. package/docs/api/interfaces/NavigationItem.md +1 -1
  119. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  120. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  121. package/docs/api/interfaces/Organisation.md +1 -1
  122. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  123. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  124. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  125. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  126. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  127. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  128. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  129. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  130. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  131. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  132. package/docs/api/interfaces/PaletteData.md +1 -1
  133. package/docs/api/interfaces/ParsedAddress.md +1 -1
  134. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  135. package/docs/api/interfaces/ProgressProps.md +3 -11
  136. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  137. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  138. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  139. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  140. package/docs/api/interfaces/QuickFix.md +1 -1
  141. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  142. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  143. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  144. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  145. package/docs/api/interfaces/RBACConfig.md +1 -1
  146. package/docs/api/interfaces/RBACContext.md +1 -1
  147. package/docs/api/interfaces/RBACLogger.md +1 -1
  148. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  149. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  150. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  151. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  152. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  153. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  154. package/docs/api/interfaces/RBACResult.md +1 -1
  155. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  156. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  157. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  158. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  161. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  162. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  163. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  164. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  165. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  166. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  167. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  168. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  169. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  170. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  171. package/docs/api/interfaces/RouteConfig.md +10 -10
  172. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  173. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  174. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  175. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  176. package/docs/api/interfaces/SetupIssue.md +1 -1
  177. package/docs/api/interfaces/StorageConfig.md +4 -4
  178. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  179. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  180. package/docs/api/interfaces/StorageListOptions.md +22 -9
  181. package/docs/api/interfaces/StorageListResult.md +4 -4
  182. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  183. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  184. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  185. package/docs/api/interfaces/StyleImport.md +1 -1
  186. package/docs/api/interfaces/SwitchProps.md +1 -1
  187. package/docs/api/interfaces/TabsContentProps.md +1 -1
  188. package/docs/api/interfaces/TabsListProps.md +1 -1
  189. package/docs/api/interfaces/TabsProps.md +1 -1
  190. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  191. package/docs/api/interfaces/TextareaProps.md +1 -1
  192. package/docs/api/interfaces/ToastActionElement.md +1 -1
  193. package/docs/api/interfaces/ToastProps.md +1 -1
  194. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  195. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  196. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  197. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  198. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  199. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  200. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  201. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  202. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  203. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  205. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  207. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  208. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  209. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  210. package/docs/api/interfaces/UserEventAccess.md +11 -11
  211. package/docs/api/interfaces/UserMenuProps.md +1 -1
  212. package/docs/api/interfaces/UserProfile.md +1 -1
  213. package/docs/api/modules.md +151 -92
  214. package/docs/api-reference/components.md +15 -7
  215. package/docs/api-reference/providers.md +2 -2
  216. package/docs/api-reference/rpc-functions.md +1 -0
  217. package/docs/best-practices/README.md +1 -1
  218. package/docs/best-practices/deployment.md +8 -8
  219. package/docs/getting-started/examples/README.md +2 -2
  220. package/docs/getting-started/installation-guide.md +4 -4
  221. package/docs/getting-started/quick-start.md +3 -3
  222. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  223. package/docs/rbac/compliance/compliance-guide.md +2 -2
  224. package/docs/rbac/event-based-apps.md +2 -2
  225. package/docs/rbac/getting-started.md +2 -2
  226. package/docs/rbac/quick-start.md +2 -2
  227. package/docs/security/README.md +4 -4
  228. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  229. package/docs/troubleshooting/README.md +2 -2
  230. package/docs/troubleshooting/migration.md +3 -3
  231. package/package.json +1 -3
  232. package/scripts/check-pace-core-compliance.cjs +1 -1
  233. package/scripts/check-pace-core-compliance.js +1 -1
  234. package/src/__tests__/fixtures/supabase.ts +301 -0
  235. package/src/__tests__/public-recipe-view.test.ts +9 -9
  236. package/src/__tests__/rls-policies.test.ts +197 -61
  237. package/src/components/AddressField/AddressField.test.tsx +42 -0
  238. package/src/components/AddressField/AddressField.tsx +71 -60
  239. package/src/components/AddressField/README.md +1 -0
  240. package/src/components/Alert/Alert.test.tsx +50 -10
  241. package/src/components/Alert/Alert.tsx +5 -3
  242. package/src/components/Avatar/Avatar.test.tsx +95 -43
  243. package/src/components/Avatar/Avatar.tsx +16 -16
  244. package/src/components/Button/Button.test.tsx +2 -1
  245. package/src/components/Button/Button.tsx +3 -3
  246. package/src/components/Calendar/Calendar.test.tsx +53 -37
  247. package/src/components/Calendar/Calendar.tsx +409 -82
  248. package/src/components/Card/Card.test.tsx +7 -4
  249. package/src/components/Card/Card.tsx +3 -6
  250. package/src/components/Checkbox/Checkbox.tsx +2 -2
  251. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  252. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  253. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  254. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  255. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  256. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  257. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  258. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  259. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  260. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  261. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  262. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  264. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  265. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  266. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  267. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  268. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  269. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  270. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  271. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  272. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  273. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  274. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  275. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  276. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  277. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  278. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  280. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  281. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  282. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  283. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  284. package/src/components/Dialog/Dialog.tsx +2 -2
  285. package/src/components/EventSelector/EventSelector.tsx +7 -7
  286. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  287. package/src/components/FileUpload/FileUpload.tsx +7 -4
  288. package/src/components/Header/Header.test.tsx +28 -0
  289. package/src/components/Header/Header.tsx +22 -9
  290. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  291. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  292. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  293. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  294. package/src/components/OrganisationSelector/OrganisationSelector.tsx +8 -8
  295. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  296. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  297. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  298. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  299. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  300. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  301. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  302. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  303. package/src/components/Progress/Progress.test.tsx +18 -19
  304. package/src/components/Progress/Progress.tsx +31 -32
  305. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  306. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  307. package/src/components/Select/Select.tsx +5 -5
  308. package/src/components/Switch/Switch.test.tsx +2 -1
  309. package/src/components/Switch/Switch.tsx +1 -1
  310. package/src/components/Toast/Toast.tsx +1 -1
  311. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  312. package/src/components/UserMenu/UserMenu.tsx +3 -3
  313. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  314. package/src/eslint-rules/pace-core-compliance.js +0 -2
  315. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  316. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  317. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  318. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  319. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  320. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  321. package/src/hooks/__tests__/{usePublicEvent.unit.test.ts → usePublicEvent.test.ts} +28 -1
  322. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  323. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +58 -16
  324. package/src/hooks/index.ts +1 -1
  325. package/src/hooks/public/usePublicEvent.ts +2 -2
  326. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  327. package/src/hooks/useAppConfig.ts +24 -5
  328. package/src/hooks/useFileDisplay.ts +297 -34
  329. package/src/hooks/useFileReference.ts +56 -11
  330. package/src/hooks/useFileUrl.ts +1 -1
  331. package/src/hooks/useInactivityTracker.ts +16 -7
  332. package/src/hooks/usePermissionCache.test.ts +85 -8
  333. package/src/hooks/useQueryCache.ts +21 -0
  334. package/src/hooks/useSecureDataAccess.test.ts +80 -35
  335. package/src/hooks/useSecureDataAccess.ts +80 -37
  336. package/src/providers/services/EventServiceProvider.tsx +37 -17
  337. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  338. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  339. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  340. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  341. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  342. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  343. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  344. package/src/rbac/api.ts +240 -36
  345. package/src/rbac/cache-invalidation.ts +21 -7
  346. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  347. package/src/rbac/components/NavigationGuard.tsx +23 -63
  348. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  349. package/src/rbac/components/NavigationProvider.tsx +13 -11
  350. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  351. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  352. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  353. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  354. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  355. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  356. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  357. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  358. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  359. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  360. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  361. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  362. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  363. package/src/rbac/engine.ts +4 -2
  364. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  365. package/src/rbac/hooks/index.ts +3 -0
  366. package/src/rbac/hooks/useCan.test.ts +101 -53
  367. package/src/rbac/hooks/usePermissions.ts +108 -41
  368. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  369. package/src/rbac/hooks/useRBAC.ts +83 -40
  370. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  371. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  372. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  373. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  374. package/src/rbac/request-deduplication.ts +1 -1
  375. package/src/rbac/secureClient.ts +72 -12
  376. package/src/rbac/security.ts +29 -23
  377. package/src/rbac/types.ts +10 -0
  378. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  379. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  380. package/src/rbac/utils/__tests__/eventContext.test.ts +6 -1
  381. package/src/rbac/utils/contextValidator.ts +288 -0
  382. package/src/rbac/utils/eventContext.ts +48 -2
  383. package/src/services/EventService.ts +165 -21
  384. package/src/services/OrganisationService.ts +37 -2
  385. package/src/services/__tests__/EventService.test.ts +26 -21
  386. package/src/types/file-reference.ts +13 -10
  387. package/src/utils/app/appNameResolver.test.ts +346 -73
  388. package/src/utils/context/superAdminOverride.ts +58 -0
  389. package/src/utils/file-reference/index.ts +61 -33
  390. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  391. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  392. package/src/utils/storage/helpers.test.ts +1 -1
  393. package/src/utils/storage/helpers.ts +38 -19
  394. package/src/utils/storage/types.ts +15 -8
  395. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  396. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  397. package/src/vite-env.d.ts +2 -2
  398. package/dist/chunk-3GOZZZYH.js.map +0 -1
  399. package/dist/chunk-DDM4CCYT.js.map +0 -1
  400. package/dist/chunk-E7UAOUMY.js +0 -75
  401. package/dist/chunk-E7UAOUMY.js.map +0 -1
  402. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  403. package/dist/chunk-HEHYGYOX.js.map +0 -1
  404. package/dist/chunk-IM4QE42D.js.map +0 -1
  405. package/dist/chunk-MX64ZF6I.js.map +0 -1
  406. package/dist/chunk-SAUPYVLF.js.map +0 -1
  407. package/dist/chunk-THRPYOFK.js.map +0 -1
  408. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  409. package/dist/chunk-VGZZXKBR.js.map +0 -1
  410. package/dist/chunk-YGPFYGA6.js.map +0 -1
  411. package/dist/chunk-YHCN776L.js.map +0 -1
  412. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
  413. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
  414. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +0 -703
  415. package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
  416. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
  417. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-ON3IXISJ.js.map} +0 -0
  418. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-X5NXANVI.js.map} +0 -0
  419. /package/dist/{api-YP7XD5L6.js.map → api-I6UCQ5S6.js.map} +0 -0
  420. /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
- lastUpdated: 2025-01-28T00:00:00+11:00
3
- version: 0.5.181
4
- reviewedBy: database-performance-audit
2
+ lastUpdated: 2025-01-02T00:00:00+11:00
3
+ version: 0.5.182
4
+ reviewedBy: rls-audit-and-fixes
5
5
  ---
6
6
 
7
7
  # RBAC and RLS Standard
@@ -138,6 +138,24 @@ These functions are available for use in RLS policies:
138
138
  - **Purpose**: Returns the current organisation context from the session
139
139
  - **Usage**: `get_organisation_context()`
140
140
 
141
+ #### `is_authenticated_user()`
142
+ - **Returns**: `boolean`
143
+ - **Purpose**: Checks if the current user is authenticated (not anonymous)
144
+ - **Usage**: `is_authenticated_user()`
145
+ - **Note**: Use this instead of `(SELECT auth.role()) = 'authenticated'` in policies
146
+
147
+ #### `is_service_role()`
148
+ - **Returns**: `boolean`
149
+ - **Purpose**: Checks if the current user has service_role
150
+ - **Usage**: `is_service_role()`
151
+ - **Note**: Use this instead of `(SELECT auth.role()) = 'service_role'` in policies
152
+
153
+ #### `get_effective_user_id()`
154
+ - **Returns**: `UUID`
155
+ - **Purpose**: Returns the current user ID (auth.uid()) in a STABLE function
156
+ - **Usage**: `get_effective_user_id()`
157
+ - **Note**: Use this instead of `(SELECT auth.uid())` or inline `auth.uid()` in policies
158
+
141
159
  ### Event Helper Functions
142
160
 
143
161
  #### `get_unit_event_id(p_unit_id TEXT)`
@@ -170,8 +188,24 @@ These functions are available for use in RLS policies:
170
188
 
171
189
  ## RLS Policy Patterns
172
190
 
191
+ This section documents the standard RLS policy patterns used throughout the codebase. All patterns follow the principles of using helper functions, enforcing security by default, and maintaining consistent structure.
192
+
193
+ ### Policy Naming Convention
194
+
195
+ Policies follow this naming pattern:
196
+ - `rbac_{operation}_{table_name}_{scope}` for authenticated policies
197
+ - `{operation}_{table_name}_{scope}` for public/anonymous policies
198
+
199
+ Examples:
200
+ - `rbac_select_cake_dish_authenticated` - Authenticated SELECT policy
201
+ - `event_public_select` - Public SELECT policy for events
202
+ - `rbac_insert_file_references` - INSERT policy (no scope suffix if only one)
203
+
173
204
  ### Standard Organisation-Scoped Policy
174
205
 
206
+ **Use Case:** Tables where rows belong to an organisation and access is controlled by organisation membership.
207
+
208
+ **Pattern:**
175
209
  ```sql
176
210
  CREATE POLICY "rbac_select_table_name" ON table_name
177
211
  FOR SELECT TO authenticated
@@ -184,8 +218,18 @@ USING (
184
218
  );
185
219
  ```
186
220
 
187
- ### Standard Event-Scoped Policy
221
+ **Example:** `organisations`, `organisation_app_access`
222
+
223
+ **Notes:**
224
+ - Always check `organisation_id IS NOT NULL` first
225
+ - Super admin check comes before organisation access check
226
+ - Use `check_user_organisation_access()` for basic membership checks
188
227
 
228
+ ### RBAC Permission-Based Policy
229
+
230
+ **Use Case:** Tables that require specific page-level permissions (most common pattern for app tables).
231
+
232
+ **Pattern:**
189
233
  ```sql
190
234
  CREATE POLICY "rbac_select_table_name" ON table_name
191
235
  FOR SELECT TO authenticated
@@ -193,14 +237,22 @@ USING (
193
237
  organisation_id IS NOT NULL
194
238
  AND (
195
239
  is_super_admin()
196
- OR check_user_event_access(event_id)
240
+ OR check_rbac_permission_with_context(
241
+ 'read:page.table_name',
242
+ 'table_name',
243
+ organisation_id,
244
+ event_id, -- NULL if not event-scoped
245
+ get_app_id('APP_NAME')
246
+ )
197
247
  )
198
248
  );
199
249
  ```
200
250
 
201
- ### RBAC Permission-Based Policy
251
+ **Example:** `cake_dish`, `cake_item`, `base_application`
202
252
 
253
+ **Full CRUD Example:**
203
254
  ```sql
255
+ -- SELECT
204
256
  CREATE POLICY "rbac_select_table_name" ON table_name
205
257
  FOR SELECT TO authenticated
206
258
  USING (
@@ -216,12 +268,171 @@ USING (
216
268
  )
217
269
  )
218
270
  );
271
+
272
+ -- INSERT
273
+ CREATE POLICY "rbac_insert_table_name" ON table_name
274
+ FOR INSERT TO authenticated
275
+ WITH CHECK (
276
+ organisation_id IS NOT NULL
277
+ AND (
278
+ is_super_admin()
279
+ OR check_rbac_permission_with_context(
280
+ 'create:page.table_name',
281
+ 'table_name',
282
+ organisation_id,
283
+ event_id,
284
+ get_app_id('APP_NAME')
285
+ )
286
+ )
287
+ );
288
+
289
+ -- UPDATE
290
+ CREATE POLICY "rbac_update_table_name" ON table_name
291
+ FOR UPDATE TO authenticated
292
+ USING (
293
+ organisation_id IS NOT NULL
294
+ AND (
295
+ is_super_admin()
296
+ OR check_rbac_permission_with_context(
297
+ 'update:page.table_name',
298
+ 'table_name',
299
+ organisation_id,
300
+ event_id,
301
+ get_app_id('APP_NAME')
302
+ )
303
+ )
304
+ )
305
+ WITH CHECK (
306
+ organisation_id IS NOT NULL
307
+ AND (
308
+ is_super_admin()
309
+ OR check_rbac_permission_with_context(
310
+ 'update:page.table_name',
311
+ 'table_name',
312
+ organisation_id,
313
+ event_id,
314
+ get_app_id('APP_NAME')
315
+ )
316
+ )
317
+ );
318
+
319
+ -- DELETE
320
+ CREATE POLICY "rbac_delete_table_name" ON table_name
321
+ FOR DELETE TO authenticated
322
+ USING (
323
+ organisation_id IS NOT NULL
324
+ AND (
325
+ is_super_admin()
326
+ OR check_rbac_permission_with_context(
327
+ 'delete:page.table_name',
328
+ 'table_name',
329
+ organisation_id,
330
+ event_id,
331
+ get_app_id('APP_NAME')
332
+ )
333
+ )
334
+ );
335
+ ```
336
+
337
+ **Notes:**
338
+ - Always use `check_rbac_permission_with_context()` instead of calling `rbac_check_permission_simplified()` with `auth.uid()` directly
339
+ - The wrapper function is STABLE SECURITY DEFINER and ensures optimal performance
340
+ - Permission format: `{operation}:page.{page_name}` (e.g., `'read:page.dishes'`, `'create:page.items'`)
341
+ - Use `get_app_id('APP_NAME')` to get the app UUID (never hardcode)
342
+
343
+ ### Standard Event-Scoped Policy
344
+
345
+ **Use Case:** Tables where rows belong to an event and access is controlled by event membership.
346
+
347
+ **Pattern:**
348
+ ```sql
349
+ CREATE POLICY "rbac_select_table_name" ON table_name
350
+ FOR SELECT TO authenticated
351
+ USING (
352
+ organisation_id IS NOT NULL
353
+ AND (
354
+ is_super_admin()
355
+ OR check_user_event_access(event_id)
356
+ )
357
+ );
358
+ ```
359
+
360
+ **Example:** Event-specific data that doesn't require page-level permissions
361
+
362
+ **Note:** For event-scoped data that also requires page permissions, combine with RBAC permission pattern.
363
+
364
+ ### User-Scoped Data Policy
365
+
366
+ **Use Case:** Tables where rows belong to individual users (organisation_id IS NULL) and users can only access their own data.
367
+
368
+ **Pattern:**
369
+ ```sql
370
+ CREATE POLICY "rbac_select_table_name" ON table_name
371
+ FOR SELECT TO authenticated
372
+ USING (
373
+ organisation_id IS NULL
374
+ AND get_effective_user_id() = user_id
375
+ );
376
+ ```
377
+
378
+ **Example:** User profile data, user-scoped file references
379
+
380
+ **Multi-Condition Pattern (Organisation OR User-Scoped):**
381
+ ```sql
382
+ CREATE POLICY "rbac_select_table_name" ON table_name
383
+ FOR SELECT
384
+ USING (
385
+ -- Organisation-scoped access
386
+ (
387
+ organisation_id IS NOT NULL
388
+ AND is_authenticated_user()
389
+ AND (
390
+ is_super_admin()
391
+ OR check_user_organisation_access(organisation_id)
392
+ )
393
+ )
394
+ OR
395
+ -- User-scoped access
396
+ (
397
+ organisation_id IS NULL
398
+ AND is_authenticated_user()
399
+ AND get_effective_user_id() = user_id
400
+ )
401
+ );
402
+ ```
403
+
404
+ **Example:** `file_references`, `pace_address` (can be either organisation or user-scoped)
405
+
406
+ ### Service Role Policy
407
+
408
+ **Use Case:** Allow service_role to bypass RLS for system operations.
409
+
410
+ **Pattern:**
411
+ ```sql
412
+ CREATE POLICY "rbac_select_table_name" ON table_name
413
+ FOR SELECT
414
+ USING (
415
+ is_service_role()
416
+ OR (
417
+ -- Other conditions for authenticated users
418
+ is_authenticated_user()
419
+ AND ...
420
+ )
421
+ );
219
422
  ```
220
423
 
221
- **Note**: Always use `check_rbac_permission_with_context()` instead of calling `rbac_check_permission_simplified()` with `auth.uid()` directly. The wrapper function is STABLE SECURITY DEFINER and ensures optimal performance.
424
+ **Example:** `file_references` (service_role can access all files for system operations)
425
+
426
+ **Notes:**
427
+ - Service role check should be first in OR conditions
428
+ - Service role bypasses all other security checks
429
+ - Use sparingly - only for tables that need system-level access
222
430
 
223
431
  ### Public Access Policy
224
432
 
433
+ **Use Case:** Tables where some data should be publicly accessible (anonymous users).
434
+
435
+ **Pattern:**
225
436
  ```sql
226
437
  CREATE POLICY "public_select_table_name" ON table_name
227
438
  FOR SELECT TO anon
@@ -230,6 +441,195 @@ USING (
230
441
  );
231
442
  ```
232
443
 
444
+ **Alternative Pattern (Simple Public Flag):**
445
+ ```sql
446
+ CREATE POLICY "public_select_table_name" ON table_name
447
+ FOR SELECT TO anon
448
+ USING (
449
+ is_public = true
450
+ AND organisation_id IS NOT NULL
451
+ );
452
+ ```
453
+
454
+ **Example:** `event` (public events), `forms` (published forms)
455
+
456
+ **Combined Public + Authenticated Pattern:**
457
+ ```sql
458
+ -- Public access
459
+ CREATE POLICY "public_select_table_name" ON table_name
460
+ FOR SELECT TO anon
461
+ USING (
462
+ is_public = true
463
+ AND organisation_id IS NOT NULL
464
+ );
465
+
466
+ -- Authenticated access (with additional permissions)
467
+ CREATE POLICY "rbac_select_table_name" ON table_name
468
+ FOR SELECT TO authenticated
469
+ USING (
470
+ (is_public = true AND organisation_id IS NOT NULL)
471
+ OR (
472
+ organisation_id IS NOT NULL
473
+ AND (
474
+ is_super_admin()
475
+ OR check_user_organisation_access(organisation_id)
476
+ )
477
+ )
478
+ );
479
+ ```
480
+
481
+ ### Complex Multi-Condition Policy
482
+
483
+ **Use Case:** Tables that need multiple access patterns (service role, public, organisation-scoped, user-scoped).
484
+
485
+ **Pattern:**
486
+ ```sql
487
+ CREATE POLICY "rbac_select_table_name" ON table_name
488
+ FOR SELECT
489
+ USING (
490
+ -- Service role can access all
491
+ is_service_role()
492
+ -- Public access
493
+ OR (is_public = true)
494
+ -- Organisation-scoped authenticated access
495
+ OR (
496
+ is_authenticated_user()
497
+ AND organisation_id IS NOT NULL
498
+ AND (
499
+ is_super_admin()
500
+ OR check_user_organisation_access(organisation_id)
501
+ )
502
+ )
503
+ -- User-scoped authenticated access
504
+ OR (
505
+ is_authenticated_user()
506
+ AND organisation_id IS NULL
507
+ AND get_effective_user_id() = user_id
508
+ )
509
+ );
510
+ ```
511
+
512
+ **Example:** `file_references` (supports all access patterns)
513
+
514
+ **Notes:**
515
+ - Order matters: most permissive first (service_role), then public, then authenticated
516
+ - Each condition should be mutually exclusive where possible
517
+ - Use helper functions for all checks (never inline auth calls)
518
+
519
+ ### Read-Only Type Table Policy
520
+
521
+ **Use Case:** Reference/lookup tables that authenticated users should be able to read but not modify.
522
+
523
+ **Pattern:**
524
+ ```sql
525
+ CREATE POLICY "read_table_name" ON table_name
526
+ FOR SELECT
527
+ USING (is_authenticated_user());
528
+ ```
529
+
530
+ **Example:** `pace_gender_type`, `pace_phone_type`, `medi_condition_type`
531
+
532
+ **Notes:**
533
+ - No INSERT/UPDATE/DELETE policies needed
534
+ - Super simple - just check if user is authenticated
535
+ - These tables typically don't have organisation_id
536
+
537
+ ### Super Admin Only Policy
538
+
539
+ **Use Case:** Tables that only super admins should access.
540
+
541
+ **Pattern:**
542
+ ```sql
543
+ CREATE POLICY "rbac_select_table_name" ON table_name
544
+ FOR SELECT TO authenticated
545
+ USING (is_super_admin());
546
+ ```
547
+
548
+ **Example:** `rbac_global_roles`, `rbac_policy_configs`
549
+
550
+ **Full CRUD Example:**
551
+ ```sql
552
+ -- All operations restricted to super admin
553
+ CREATE POLICY "rbac_select_table_name" ON table_name
554
+ FOR SELECT TO authenticated
555
+ USING (is_super_admin());
556
+
557
+ CREATE POLICY "rbac_insert_table_name" ON table_name
558
+ FOR INSERT TO authenticated
559
+ WITH CHECK (is_super_admin());
560
+
561
+ CREATE POLICY "rbac_update_table_name" ON table_name
562
+ FOR UPDATE TO authenticated
563
+ USING (is_super_admin())
564
+ WITH CHECK (is_super_admin());
565
+
566
+ CREATE POLICY "rbac_delete_table_name" ON table_name
567
+ FOR DELETE TO authenticated
568
+ USING (is_super_admin());
569
+ ```
570
+
571
+ ### Common Patterns Summary
572
+
573
+ | Pattern | Use Case | Key Helper Functions |
574
+ |---------|----------|---------------------|
575
+ | Organisation-Scoped | Basic org membership | `check_user_organisation_access()` |
576
+ | RBAC Permission-Based | Page-level permissions | `check_rbac_permission_with_context()`, `get_app_id()` |
577
+ | Event-Scoped | Event membership | `check_user_event_access()` |
578
+ | User-Scoped | Personal data | `get_effective_user_id()` |
579
+ | Service Role | System operations | `is_service_role()` |
580
+ | Public Access | Anonymous users | `check_public_event_access()` or `is_public` flag |
581
+ | Read-Only Types | Reference tables | `is_authenticated_user()` |
582
+ | Super Admin Only | Admin-only tables | `is_super_admin()` |
583
+
584
+ ### Policy Best Practices
585
+
586
+ 1. **Always use helper functions** - Never inline `auth.uid()`, `auth.role()`, or `current_setting()`
587
+ 2. **Check NULL first** - Always check `organisation_id IS NOT NULL` before using it
588
+ 3. **Super admin first** - Super admin checks should come before other checks in OR conditions
589
+ 4. **Service role first** - Service role checks should be the first condition in multi-condition policies
590
+ 5. **Consistent naming** - Follow the naming convention: `rbac_{operation}_{table}_{scope}`
591
+ 6. **Document exceptions** - If a policy deviates from standard patterns, add a comment explaining why
592
+ 7. **Test thoroughly** - Test with different user roles (super_admin, org_admin, member, anon)
593
+ 8. **Avoid `true OR ...`** - Never use `true OR ...` conditions as they bypass all security checks
594
+
595
+ ### Common Pitfalls to Avoid
596
+
597
+ **❌ DON'T:**
598
+ ```sql
599
+ -- Inline auth calls
600
+ USING (user_id = auth.uid())
601
+
602
+ -- Security bypass
603
+ USING (true OR check_user_organisation_access(organisation_id))
604
+
605
+ -- Missing NULL check
606
+ USING (check_user_organisation_access(organisation_id))
607
+
608
+ -- Direct current_setting
609
+ USING (organisation_id = current_setting('app.organisation_id')::UUID)
610
+
611
+ -- Public policy without proper checks
612
+ USING (true) -- Allows anyone!
613
+ ```
614
+
615
+ **✅ DO:**
616
+ ```sql
617
+ -- Use helper functions
618
+ USING (get_effective_user_id() = user_id)
619
+
620
+ -- Proper security checks
621
+ USING (check_user_organisation_access(organisation_id))
622
+
623
+ -- NULL check first
624
+ USING (organisation_id IS NOT NULL AND check_user_organisation_access(organisation_id))
625
+
626
+ -- Use helper function
627
+ USING (organisation_id = get_organisation_context())
628
+
629
+ -- Proper public policy
630
+ USING (is_public = true AND organisation_id IS NOT NULL)
631
+ ```
632
+
233
633
  ## App Ownership
234
634
 
235
635
  Tables are assigned to specific apps for RBAC permission checking:
@@ -333,6 +733,29 @@ Monitor:
333
733
 
334
734
  ## Migration Guidelines
335
735
 
736
+ ### Migration Filename Requirements
737
+
738
+ **CRITICAL**: Migration filenames **MUST** use real timestamps, not guessed or placeholder dates.
739
+
740
+ 1. **Always use the current timestamp** when creating migration files
741
+ 2. **Format**: `YYYYMMDDHHMMSS_descriptive_name.sql`
742
+ 3. **How to get the timestamp**:
743
+ ```bash
744
+ date +"%Y%m%d%H%M%S"
745
+ ```
746
+ 4. **Never guess or use placeholder dates** - This causes migration ordering issues and conflicts
747
+ 5. **Verify the timestamp is after the latest migration** in `supabase/migrations/`
748
+
749
+ **Example**:
750
+ ```bash
751
+ # Get current timestamp
752
+ date +"%Y%m%d%H%M%S"
753
+ # Output: 20251201124800
754
+
755
+ # Use it in filename
756
+ 20251201124800_allow_medi_action_plan_null_condition_id.sql
757
+ ```
758
+
336
759
  ### Creating New RLS Policies
337
760
 
338
761
  1. **Use helper functions** - Never inline `auth.uid()` or `current_setting()`
@@ -413,7 +413,7 @@ npm run build -- --debug
413
413
  // Verify environment variables
414
414
  console.log('Environment:', {
415
415
  supabaseUrl: import.meta.env.VITE_SUPABASE_URL,
416
- supabaseKey: import.meta.env.VITE_SUPABASE_ANON_KEY,
416
+ supabaseKey: import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY,
417
417
  appName: import.meta.env.VITE_APP_NAME,
418
418
  });
419
419
  ```
@@ -431,7 +431,7 @@ console.log('Environment:', {
431
431
  # Example deployment config
432
432
  env:
433
433
  VITE_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
434
- VITE_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
434
+ VITE_SUPABASE_PUBLISHABLE_KEY: ${{ secrets.SUPABASE_PUBLISHABLE_KEY }}
435
435
  VITE_APP_NAME: "My App"
436
436
  ```
437
437
 
@@ -403,7 +403,7 @@ VITE_DEBUG_MODE=true
403
403
 
404
404
  # New environment variables
405
405
  VITE_SUPABASE_URL=https://your-project.supabase.co
406
- VITE_SUPABASE_ANON_KEY=your-anon-key
406
+ VITE_SUPABASE_PUBLISHABLE_KEY=your-publishable-key
407
407
  VITE_APP_ENV=development
408
408
  VITE_DEBUG=false
409
409
 
@@ -420,7 +420,7 @@ cp .env .env.backup
420
420
  cat > .env << EOF
421
421
  # Supabase Configuration
422
422
  VITE_SUPABASE_URL=${VITE_SUPABASE_URL:-https://your-project.supabase.co}
423
- VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY:-your-anon-key}
423
+ VITE_SUPABASE_PUBLISHABLE_KEY=${VITE_SUPABASE_PUBLISHABLE_KEY:-your-publishable-key}
424
424
 
425
425
  # Application Configuration
426
426
  VITE_APP_ENV=${VITE_APP_ENV:-development}
@@ -706,7 +706,7 @@ export class MigrationValidation {
706
706
  static validateConfiguration(config: any) {
707
707
  const required = [
708
708
  'VITE_SUPABASE_URL',
709
- 'VITE_SUPABASE_ANON_KEY',
709
+ 'VITE_SUPABASE_PUBLISHABLE_KEY',
710
710
  ];
711
711
 
712
712
  const warnings = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmruthers/pace-core",
3
- "version": "0.5.189",
3
+ "version": "0.5.190",
4
4
  "description": "Clean, modern React component library with Tailwind v4 styling and native utilities",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -155,7 +155,6 @@
155
155
  "clean": "rimraf dist",
156
156
  "_comment_test": "Test suite with various configurations",
157
157
  "test": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192 --max-semi-space-size=128\" vitest run --config ../../vitest.config.ts",
158
- "test:memory-optimized": "node ../../scripts/run-tests-memory-optimized.js",
159
158
  "test:watch": "vitest --watch --config ../../vitest.config.ts",
160
159
  "test:coverage": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192 --max-semi-space-size=128\" vitest run --coverage --config ../../vitest.config.ts --reporter=dot",
161
160
  "test:ui": "vitest --ui --config ../../vitest.config.ts",
@@ -200,7 +199,6 @@
200
199
  "@radix-ui/react-checkbox": "^1.0.0",
201
200
  "@radix-ui/react-dialog": "^1.0.0",
202
201
  "@radix-ui/react-label": "^2.0.0",
203
- "@radix-ui/react-progress": "^1.0.0",
204
202
  "@radix-ui/react-slot": "^1.0.0",
205
203
  "@radix-ui/react-switch": "^1.1.0",
206
204
  "@radix-ui/react-tabs": "^1.0.0",
@@ -567,7 +567,7 @@ function scanFile(filePath, manifest) {
567
567
  // - Using in createClient
568
568
  // - Comments/documentation
569
569
  const supabaseUrlPattern = /(SUPABASE_URL|VITE_SUPABASE_URL|NEXT_PUBLIC_SUPABASE_URL|REACT_APP_SUPABASE_URL)/g;
570
- const supabaseKeyPattern = /(SUPABASE_ANON_KEY|VITE_SUPABASE_ANON_KEY|NEXT_PUBLIC_SUPABASE_ANON_KEY|REACT_APP_SUPABASE_ANON_KEY)/g;
570
+ const supabaseKeyPattern = /(SUPABASE_ANON_KEY|VITE_SUPABASE_PUBLISHABLE_KEY|NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY|REACT_APP_SUPABASE_PUBLISHABLE_KEY)/g;
571
571
  const urlMatches = content.match(supabaseUrlPattern);
572
572
  const keyMatches = content.match(supabaseKeyPattern);
573
573
 
@@ -213,7 +213,7 @@ function scanFile(filePath, manifest) {
213
213
 
214
214
  // Check for Supabase URL/key configuration in multiple places
215
215
  const supabaseUrlPattern = /(SUPABASE_URL|VITE_SUPABASE_URL|NEXT_PUBLIC_SUPABASE_URL|REACT_APP_SUPABASE_URL)/g;
216
- const supabaseKeyPattern = /(SUPABASE_ANON_KEY|VITE_SUPABASE_ANON_KEY|NEXT_PUBLIC_SUPABASE_ANON_KEY|REACT_APP_SUPABASE_ANON_KEY)/g;
216
+ const supabaseKeyPattern = /(SUPABASE_ANON_KEY|VITE_SUPABASE_PUBLISHABLE_KEY|NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY|REACT_APP_SUPABASE_PUBLISHABLE_KEY)/g;
217
217
  const urlMatches = content.match(supabaseUrlPattern);
218
218
  const keyMatches = content.match(supabaseKeyPattern);
219
219