@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,472 @@
1
+ # Person-Scoped Profiles Migration Guide
2
+
3
+ **Version:** 0.5.190+
4
+ **Migration Date:** 2025-12-05
5
+ **Breaking Changes:** Yes
6
+
7
+ ## Overview
8
+
9
+ Profiles (membership, medical, and contact) have been migrated from **organisation-scoped** to **person-scoped**. Each person now has:
10
+
11
+ - **One membership profile** (`pace_member`) - regardless of organisation
12
+ - **One medical profile** (`medi_profile`) - regardless of organisation
13
+ - **Multiple contact profiles** (`pace_contact`) - person-scoped, multiple per type allowed
14
+
15
+ This change means profiles are no longer tied to specific organisations and are shared across all organisations a person belongs to.
16
+
17
+ ## What Changed
18
+
19
+ ### Tables Modified
20
+
21
+ #### 1. `pace_member`
22
+ - **Removed:** `organisation_id` column
23
+ - **Added:** Unique constraint on `person_id` (one membership per person)
24
+ - **Impact:** A person can now only have ONE membership record, regardless of how many organisations they belong to
25
+
26
+ #### 2. `medi_profile`
27
+ - **Removed:** `organisation_id` column
28
+ - **Impact:** One medical profile per person (via member relationship)
29
+
30
+ #### 3. `pace_contact`
31
+ - **Removed:** `organisation_id` and `member_id` columns
32
+ - **Added:** `person_id` column (NOT NULL, FK to `pace_person`)
33
+ - **Impact:** Contacts are now directly linked to persons, not members
34
+
35
+ #### 4. Related Tables (organisation_id removed)
36
+ - `medi_condition`
37
+ - `medi_diet`
38
+ - `medi_action_plan`
39
+ - `medi_profile_versions`
40
+ - `pace_consent`
41
+ - `pace_identification`
42
+ - `pace_qualification`
43
+
44
+ ### RLS Policy Changes
45
+
46
+ All RLS policies for these tables have been updated to:
47
+ - Remove organisation-based access checks
48
+ - Use person-scoped access control instead
49
+ - Allow access based on person ownership, not organisation membership
50
+
51
+ ## Breaking Changes
52
+
53
+ ### 1. Queries Filtering by `organisation_id`
54
+
55
+ **Before:**
56
+ ```typescript
57
+ // ❌ This will fail - organisation_id column no longer exists
58
+ const { data } = await supabase
59
+ .from('pace_member')
60
+ .select('*')
61
+ .eq('organisation_id', orgId);
62
+ ```
63
+
64
+ **After:**
65
+ ```typescript
66
+ // ✅ Filter by person_id instead
67
+ const { data } = await supabase
68
+ .from('pace_member')
69
+ .select('*')
70
+ .eq('person_id', personId);
71
+ ```
72
+
73
+ ### 2. Joins Using `organisation_id`
74
+
75
+ **Before:**
76
+ ```typescript
77
+ // ❌ This will fail
78
+ const { data } = await supabase
79
+ .from('pace_member')
80
+ .select('*, organisations(*)')
81
+ .eq('organisation_id', orgId);
82
+ ```
83
+
84
+ **After:**
85
+ ```typescript
86
+ // ✅ Join via person → user → organisation memberships
87
+ const { data } = await supabase
88
+ .from('pace_member')
89
+ .select('*, pace_person(*, user_profiles(*))')
90
+ .eq('person_id', personId);
91
+ ```
92
+
93
+ ### 3. Contact Queries Using `member_id`
94
+
95
+ **Before:**
96
+ ```typescript
97
+ // ❌ This will fail - member_id column no longer exists
98
+ const { data } = await supabase
99
+ .from('pace_contact')
100
+ .select('*')
101
+ .eq('member_id', memberId);
102
+ ```
103
+
104
+ **After:**
105
+ ```typescript
106
+ // ✅ Use person_id instead
107
+ const { data } = await supabase
108
+ .from('pace_contact')
109
+ .select('*')
110
+ .eq('person_id', personId);
111
+ ```
112
+
113
+ ### 4. Insert/Update Operations
114
+
115
+ **Before:**
116
+ ```typescript
117
+ // ❌ This will fail - organisation_id required
118
+ await supabase
119
+ .from('pace_member')
120
+ .insert({
121
+ person_id: personId,
122
+ organisation_id: orgId, // ❌ Column doesn't exist
123
+ membership_number: '12345'
124
+ });
125
+ ```
126
+
127
+ **After:**
128
+ ```typescript
129
+ // ✅ No organisation_id needed
130
+ await supabase
131
+ .from('pace_member')
132
+ .insert({
133
+ person_id: personId,
134
+ membership_number: '12345'
135
+ });
136
+ ```
137
+
138
+ ## Impact Assessment Checklist
139
+
140
+ Use this checklist to identify areas in your app that need updates:
141
+
142
+ ### Database Queries
143
+
144
+ - [ ] Search codebase for `pace_member` queries filtering by `organisation_id`
145
+ - [ ] Search codebase for `medi_profile` queries filtering by `organisation_id`
146
+ - [ ] Search codebase for `pace_contact` queries using `member_id`
147
+ - [ ] Search codebase for `pace_consent` queries filtering by `organisation_id`
148
+ - [ ] Search codebase for `pace_identification` queries filtering by `organisation_id`
149
+ - [ ] Search codebase for `pace_qualification` queries filtering by `organisation_id`
150
+ - [ ] Search codebase for `medi_condition`, `medi_diet`, `medi_action_plan` queries filtering by `organisation_id`
151
+
152
+ ### TypeScript Types
153
+
154
+ - [ ] Update TypeScript types (regenerate from database schema)
155
+ - [ ] Remove `organisation_id` from type definitions for profile tables
156
+ - [ ] Update `pace_contact` types to use `person_id` instead of `member_id`
157
+
158
+ ### UI Components
159
+
160
+ - [ ] Review profile display components - remove organisation context assumptions
161
+ - [ ] Update forms that create/edit profiles - remove organisation_id fields
162
+ - [ ] Update contact management - use person_id instead of member_id
163
+ - [ ] Review profile selection/filtering UI - remove organisation filters
164
+
165
+ ### Business Logic
166
+
167
+ - [ ] Review code that assumes multiple memberships per person
168
+ - [ ] Update logic that creates profiles per organisation
169
+ - [ ] Review permission checks that rely on organisation_id for profiles
170
+ - [ ] Update any code that merges/duplicates profiles across organisations
171
+
172
+ ### Data Access Patterns
173
+
174
+ - [ ] Review use of `useSecureDataAccess` hook with profile tables
175
+ - [ ] Update any custom data access utilities
176
+ - [ ] Review RPC functions that query profile tables
177
+
178
+ ## Code Migration Examples
179
+
180
+ ### Example 1: Fetching Member Profile
181
+
182
+ **Before:**
183
+ ```typescript
184
+ async function getMemberProfile(personId: string, orgId: string) {
185
+ const { data } = await supabase
186
+ .from('pace_member')
187
+ .select('*')
188
+ .eq('person_id', personId)
189
+ .eq('organisation_id', orgId) // ❌
190
+ .single();
191
+ return data;
192
+ }
193
+ ```
194
+
195
+ **After:**
196
+ ```typescript
197
+ async function getMemberProfile(personId: string) {
198
+ // ✅ No organisation_id needed - one profile per person
199
+ const { data } = await supabase
200
+ .from('pace_member')
201
+ .select('*')
202
+ .eq('person_id', personId)
203
+ .single();
204
+ return data;
205
+ }
206
+ ```
207
+
208
+ ### Example 2: Fetching Contacts
209
+
210
+ **Before:**
211
+ ```typescript
212
+ async function getContacts(memberId: string) {
213
+ const { data } = await supabase
214
+ .from('pace_contact')
215
+ .select('*')
216
+ .eq('member_id', memberId) // ❌
217
+ .eq('organisation_id', orgId); // ❌
218
+ return data;
219
+ }
220
+ ```
221
+
222
+ **After:**
223
+ ```typescript
224
+ async function getContacts(personId: string) {
225
+ // ✅ Use person_id directly
226
+ const { data } = await supabase
227
+ .from('pace_contact')
228
+ .select('*')
229
+ .eq('person_id', personId);
230
+ return data;
231
+ }
232
+ ```
233
+
234
+ ### Example 3: Creating Medical Profile
235
+
236
+ **Before:**
237
+ ```typescript
238
+ async function createMedicalProfile(memberId: string, orgId: string, data: MedicalData) {
239
+ const { data: profile } = await supabase
240
+ .from('medi_profile')
241
+ .insert({
242
+ member_id: memberId,
243
+ organisation_id: orgId, // ❌
244
+ ...data
245
+ })
246
+ .select()
247
+ .single();
248
+ return profile;
249
+ }
250
+ ```
251
+
252
+ **After:**
253
+ ```typescript
254
+ async function createMedicalProfile(memberId: string, data: MedicalData) {
255
+ // ✅ No organisation_id needed
256
+ const { data: profile } = await supabase
257
+ .from('medi_profile')
258
+ .insert({
259
+ member_id: memberId,
260
+ ...data
261
+ })
262
+ .select()
263
+ .single();
264
+ return profile;
265
+ }
266
+ ```
267
+
268
+ ### Example 4: Getting Person's Member in Organisation Context
269
+
270
+ **Before:**
271
+ ```typescript
272
+ // ❌ This pattern no longer works
273
+ const member = await getMemberForPersonInOrg(personId, orgId);
274
+ ```
275
+
276
+ **After:**
277
+ ```typescript
278
+ // ✅ Get the person's single membership
279
+ const { data: member } = await supabase
280
+ .from('pace_member')
281
+ .select('*')
282
+ .eq('person_id', personId)
283
+ .single();
284
+
285
+ // If you need to check organisation access, check via rbac_organisation_roles
286
+ const { data: orgRoles } = await supabase
287
+ .from('rbac_organisation_roles')
288
+ .select('organisation_id')
289
+ .eq('user_id', userId)
290
+ .eq('organisation_id', orgId)
291
+ .eq('status', 'active');
292
+ ```
293
+
294
+ ## Testing Recommendations
295
+
296
+ ### 1. Unit Tests
297
+
298
+ - [ ] Update test fixtures to remove `organisation_id` from profile records
299
+ - [ ] Update mock data generators
300
+ - [ ] Fix tests that assert organisation_id values
301
+
302
+ ### 2. Integration Tests
303
+
304
+ - [ ] Test profile creation without organisation_id
305
+ - [ ] Test profile queries by person_id
306
+ - [ ] Test contact management with person_id
307
+ - [ ] Verify RLS policies work correctly
308
+
309
+ ### 3. E2E Tests
310
+
311
+ - [ ] Test profile display across different organisations
312
+ - [ ] Verify profiles are shared correctly
313
+ - [ ] Test contact management flows
314
+ - [ ] Verify permission checks still work
315
+
316
+ ### 4. Data Validation
317
+
318
+ - [ ] Verify no duplicate memberships exist per person
319
+ - [ ] Verify medical profiles are correctly linked
320
+ - [ ] Verify contacts are correctly migrated to person_id
321
+
322
+ ## Common Patterns to Update
323
+
324
+ ### Pattern 1: Organisation-Scoped Profile Lists
325
+
326
+ **Before:**
327
+ ```typescript
328
+ // Get all members in an organisation
329
+ const { data } = await supabase
330
+ .from('pace_member')
331
+ .select('*')
332
+ .eq('organisation_id', orgId);
333
+ ```
334
+
335
+ **After:**
336
+ ```typescript
337
+ // Get all members in an organisation via person → user → org roles
338
+ const { data: orgMembers } = await supabase
339
+ .from('rbac_organisation_roles')
340
+ .select(`
341
+ organisation_id,
342
+ user_id,
343
+ pace_person!inner(
344
+ id,
345
+ pace_member(*)
346
+ )
347
+ `)
348
+ .eq('organisation_id', orgId)
349
+ .eq('status', 'active');
350
+ ```
351
+
352
+ ### Pattern 2: Profile Existence Checks
353
+
354
+ **Before:**
355
+ ```typescript
356
+ // Check if member exists in organisation
357
+ const { data } = await supabase
358
+ .from('pace_member')
359
+ .select('id')
360
+ .eq('person_id', personId)
361
+ .eq('organisation_id', orgId)
362
+ .single();
363
+ ```
364
+
365
+ **After:**
366
+ ```typescript
367
+ // Check if person has a membership (regardless of org)
368
+ const { data } = await supabase
369
+ .from('pace_member')
370
+ .select('id')
371
+ .eq('person_id', personId)
372
+ .single();
373
+ ```
374
+
375
+ ### Pattern 3: Profile Creation with Organisation Context
376
+
377
+ **Before:**
378
+ ```typescript
379
+ // Create profile for person in organisation
380
+ await supabase
381
+ .from('pace_member')
382
+ .insert({
383
+ person_id: personId,
384
+ organisation_id: orgId,
385
+ membership_number: generateNumber()
386
+ });
387
+ ```
388
+
389
+ **After:**
390
+ ```typescript
391
+ // Create profile for person (one per person, not per org)
392
+ // Check if already exists first
393
+ const { data: existing } = await supabase
394
+ .from('pace_member')
395
+ .select('id')
396
+ .eq('person_id', personId)
397
+ .single();
398
+
399
+ if (!existing) {
400
+ await supabase
401
+ .from('pace_member')
402
+ .insert({
403
+ person_id: personId,
404
+ membership_number: generateNumber()
405
+ });
406
+ }
407
+ ```
408
+
409
+ ## TypeScript Type Updates
410
+
411
+ After applying migrations, regenerate your database types:
412
+
413
+ ```bash
414
+ npx supabase gen types typescript --project-id <your-project-id> > src/types/database.generated.ts
415
+ ```
416
+
417
+ The updated types will reflect:
418
+ - Removed `organisation_id` from profile tables
419
+ - `pace_contact` using `person_id` instead of `member_id`
420
+ - Updated relationships
421
+
422
+ ## RLS Policy Behavior
423
+
424
+ RLS policies now work as follows:
425
+
426
+ 1. **Person Ownership**: Users can access profiles for persons they own (via `pace_person.user_id`)
427
+ 2. **Contact Permissions**: Users can access contacts where they are the contact person or own the person
428
+ 3. **No Organisation Filtering**: Profiles are accessible regardless of organisation context
429
+ 4. **Super Admin Override**: Super admins can access all profiles
430
+
431
+ ## Migration Support
432
+
433
+ If you encounter issues:
434
+
435
+ 1. **Check Migration Status**: Verify all migrations are applied
436
+ 2. **Verify Types**: Regenerate TypeScript types from current schema
437
+ 3. **Review RLS**: Ensure RLS policies are correctly applied
438
+ 4. **Check Logs**: Review Supabase logs for RLS policy violations
439
+
440
+ ## RPC Functions Updated
441
+
442
+ The following RPC functions have been updated to work with person-scoped profiles:
443
+
444
+ - **`data_pace_linked_profiles_list`** - Now uses `person_id` from `pace_contact` instead of `member_id`
445
+ - **`data_pace_contacts_list`** - Now uses `person_id` from `pace_contact` instead of `member_id`
446
+ - **`data_pace_contact_get`** - Now uses `person_id` from `pace_contact` instead of `member_id`
447
+
448
+ These functions now:
449
+ - Join `pace_contact` via `person_id` instead of `member_id`
450
+ - Get `member_id` from `pace_member` via `person_id` join
451
+ - Get `organisation_id` from user's organisation roles (since profiles are no longer organisation-scoped)
452
+
453
+ If you have custom RPC functions that reference `pace_contact.member_id` or profile table `organisation_id` columns, you'll need to update them similarly.
454
+
455
+ ## Questions?
456
+
457
+ For questions or issues related to this migration:
458
+ - Review the migration files in `supabase/migrations/`
459
+ - Check RLS policy definitions in the migration files
460
+ - Review the pace-core documentation for updated API patterns
461
+ - Check for custom RPC functions that may need updates
462
+
463
+ ## Summary
464
+
465
+ **Key Takeaways:**
466
+ - Profiles are now person-scoped, not organisation-scoped
467
+ - Remove all `organisation_id` filters/queries for profile tables
468
+ - Use `person_id` instead of `member_id` for contacts
469
+ - One membership per person (enforced by unique constraint)
470
+ - Update all TypeScript types after migration
471
+ - Test thoroughly, especially cross-organisation scenarios
472
+
@@ -152,7 +152,7 @@ import { createClient } from '@supabase/supabase-js';
152
152
 
153
153
  const supabase = createClient(
154
154
  import.meta.env.VITE_SUPABASE_URL,
155
- import.meta.env.VITE_SUPABASE_ANON_KEY
155
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
156
156
  );
157
157
 
158
158
  // ⚠️ REQUIRED: Call setupRBAC before rendering
@@ -266,7 +266,7 @@ import { createClient } from '@supabase/supabase-js';
266
266
 
267
267
  export const supabase = createClient(
268
268
  import.meta.env.VITE_SUPABASE_URL,
269
- import.meta.env.VITE_SUPABASE_ANON_KEY
269
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
270
270
  );
271
271
  ```
272
272
 
@@ -89,7 +89,7 @@ Create `.env.local`:
89
89
  ```bash
90
90
  # .env.local
91
91
  VITE_SUPABASE_URL=https://your-project.supabase.co
92
- VITE_SUPABASE_ANON_KEY=your-anon-key-here
92
+ VITE_SUPABASE_PUBLISHABLE_KEY=your-publishable-key-here
93
93
  VITE_APP_NAME=pace-trac
94
94
  ```
95
95
 
@@ -225,7 +225,7 @@ Create `src/lib/supabase.ts`:
225
225
  import { createClient } from '@supabase/supabase-js'
226
226
 
227
227
  const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
228
- const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
228
+ const supabasePublishableKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
229
229
 
230
230
  if (!supabaseUrl || !supabaseAnonKey) {
231
231
  throw new Error('Missing Supabase environment variables')
@@ -99,7 +99,7 @@ import '@jmruthers/pace-core/src/styles/core.css';
99
99
  // Initialize Supabase
100
100
  const supabase = createClient(
101
101
  import.meta.env.VITE_SUPABASE_URL!,
102
- import.meta.env.VITE_SUPABASE_ANON_KEY!
102
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY!
103
103
  );
104
104
 
105
105
  // ⚠️ REQUIRED: Setup RBAC before rendering
@@ -258,7 +258,7 @@ import App from './App';
258
258
  // Initialize Supabase
259
259
  const supabase = createClient(
260
260
  import.meta.env.VITE_SUPABASE_URL!,
261
- import.meta.env.VITE_SUPABASE_ANON_KEY!
261
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY!
262
262
  );
263
263
 
264
264
  // ⚠️ REQUIRED: Setup RBAC before rendering
@@ -88,7 +88,7 @@ Create `.env.local`:
88
88
  # .env.local
89
89
  VITE_SUPABASE_URL=https://your-project.supabase.co
90
90
  # Accepts both legacy anon keys and modern publishable keys (sb_publishable_...)
91
- VITE_SUPABASE_ANON_KEY=your-publishable-key-or-anon-key-here
91
+ VITE_SUPABASE_PUBLISHABLE_KEY=your-publishable-key-here
92
92
  VITE_APP_NAME=user-manager
93
93
  ```
94
94
 
@@ -213,7 +213,7 @@ Create `src/lib/supabase.ts`:
213
213
  import { createClient } from '@supabase/supabase-js'
214
214
 
215
215
  const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
216
- const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
216
+ const supabasePublishableKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
217
217
 
218
218
  if (!supabaseUrl || !supabaseAnonKey) {
219
219
  throw new Error('Missing Supabase environment variables')
@@ -139,10 +139,10 @@ function ProtectedComponent() {
139
139
 
140
140
  ### 3. Inactivity Auto-Logout
141
141
 
142
- PACE Core includes built-in inactivity tracking for enhanced security:
142
+ PACE Core includes built-in inactivity tracking for enhanced security. **All inactivity timeout props are mandatory** - apps must explicitly configure them:
143
143
 
144
- - **Automatic logout** after 30 minutes of inactivity (configurable)
145
- - **Warning modal** appears 60 seconds before logout
144
+ - **Automatic logout** after configured period of inactivity (must be configured)
145
+ - **Warning modal** appears before logout (must be configured)
146
146
  - **Cross-tab synchronization** - activity in any tab resets the timer
147
147
  - **Persistence** - survives page reloads and browser restarts
148
148
  - **Production-safe** - cannot be disabled in production builds
@@ -597,7 +597,7 @@ Secure configuration using environment variables:
597
597
  ```bash
598
598
  # Authentication
599
599
  VITE_SUPABASE_URL=your_supabase_url
600
- VITE_SUPABASE_ANON_KEY=your_anon_key
600
+ VITE_SUPABASE_PUBLISHABLE_KEY=your_publishable_key
601
601
  VITE_SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
602
602
 
603
603
  # Security