@jmruthers/pace-core 0.6.1 → 0.6.2

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 (502) hide show
  1. package/CHANGELOG.md +43 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +18 -91
  3. package/cursor-rules/01-standards-compliance.mdc +16 -47
  4. package/cursor-rules/02-project-structure.mdc +4 -4
  5. package/cursor-rules/03-solid-principles.mdc +45 -164
  6. package/cursor-rules/04-testing-standards.mdc +22 -69
  7. package/cursor-rules/05-bug-reports-and-features.mdc +2 -2
  8. package/cursor-rules/06-code-quality.mdc +42 -125
  9. package/cursor-rules/07-tech-stack-compliance.mdc +33 -128
  10. package/cursor-rules/08-markup-quality.mdc +452 -0
  11. package/cursor-rules/CHANGELOG.md +18 -0
  12. package/cursor-rules/README.md +2 -1
  13. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-TPTKCX4D.js} +10 -9
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +356 -111
  17. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  18. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  19. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  20. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  21. package/dist/chunk-24UVZUZG.js.map +1 -0
  22. package/dist/{chunk-4N5C5XZU.js → chunk-2UOI2FG5.js} +4 -4
  23. package/dist/chunk-2UOI2FG5.js.map +1 -0
  24. package/dist/{chunk-T33XF5ZC.js → chunk-3XC4CPTD.js} +4317 -3963
  25. package/dist/chunk-3XC4CPTD.js.map +1 -0
  26. package/dist/{chunk-4ZC4GX36.js → chunk-6J4GEEJR.js} +172 -45
  27. package/dist/chunk-6J4GEEJR.js.map +1 -0
  28. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  29. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-EHMR7VYL.js} +4 -4
  31. package/dist/chunk-EHMR7VYL.js.map +1 -0
  32. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  33. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  34. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  35. package/dist/chunk-FFQEQTNW.js.map +1 -0
  36. package/dist/chunk-FMUCXFII.js +76 -0
  37. package/dist/chunk-FMUCXFII.js.map +1 -0
  38. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  39. package/dist/chunk-L4OXEN46.js.map +1 -0
  40. package/dist/{chunk-R77UEZ4E.js → chunk-M43Y4SSO.js} +1 -1
  41. package/dist/chunk-M43Y4SSO.js.map +1 -0
  42. package/dist/{chunk-3XTALGJF.js → chunk-MMZ7JXPU.js} +60 -223
  43. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  44. package/dist/{chunk-GLK6VM3F.js → chunk-NECFR5MM.js} +254 -170
  45. package/dist/chunk-NECFR5MM.js.map +1 -0
  46. package/dist/{chunk-JBKQ3SAO.js → chunk-SFZUDBL5.js} +40 -4
  47. package/dist/chunk-SFZUDBL5.js.map +1 -0
  48. package/dist/{chunk-XM25TVIE.js → chunk-XWQCNGTQ.js} +724 -363
  49. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  50. package/dist/components.d.ts +5 -5
  51. package/dist/components.js +14 -11
  52. package/dist/components.js.map +1 -1
  53. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  54. package/dist/hooks.d.ts +55 -122
  55. package/dist/hooks.js +8 -12
  56. package/dist/hooks.js.map +1 -1
  57. package/dist/index.d.ts +60 -13
  58. package/dist/index.js +19 -19
  59. package/dist/index.js.map +1 -1
  60. package/dist/providers.d.ts +21 -3
  61. package/dist/providers.js +2 -2
  62. package/dist/rbac/index.d.ts +145 -114
  63. package/dist/rbac/index.js +8 -11
  64. package/dist/theming/runtime.d.ts +1 -13
  65. package/dist/theming/runtime.js +1 -1
  66. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  67. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  68. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  69. package/dist/types.d.ts +2 -2
  70. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +31 -1
  71. package/dist/utils.d.ts +4 -5
  72. package/dist/utils.js +14 -14
  73. package/dist/utils.js.map +1 -1
  74. package/docs/api/README.md +7 -1
  75. package/docs/api/classes/ColumnFactory.md +8 -8
  76. package/docs/api/classes/InvalidScopeError.md +4 -4
  77. package/docs/api/classes/Logger.md +1 -1
  78. package/docs/api/classes/MissingUserContextError.md +4 -4
  79. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  80. package/docs/api/classes/PermissionDeniedError.md +4 -4
  81. package/docs/api/classes/RBACAuditManager.md +1 -1
  82. package/docs/api/classes/RBACCache.md +1 -1
  83. package/docs/api/classes/RBACEngine.md +1 -1
  84. package/docs/api/classes/RBACError.md +4 -4
  85. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  86. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  87. package/docs/api/classes/StorageUtils.md +1 -1
  88. package/docs/api/enums/FileCategory.md +1 -1
  89. package/docs/api/enums/LogLevel.md +1 -1
  90. package/docs/api/enums/RBACErrorCode.md +1 -1
  91. package/docs/api/enums/RPCFunction.md +1 -1
  92. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  93. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  94. package/docs/api/interfaces/AggregateConfig.md +4 -4
  95. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  96. package/docs/api/interfaces/AvatarProps.md +1 -1
  97. package/docs/api/interfaces/BadgeProps.md +9 -2
  98. package/docs/api/interfaces/ButtonProps.md +7 -4
  99. package/docs/api/interfaces/CalendarProps.md +8 -5
  100. package/docs/api/interfaces/CardProps.md +8 -5
  101. package/docs/api/interfaces/ColorPalette.md +1 -1
  102. package/docs/api/interfaces/ColorShade.md +1 -1
  103. package/docs/api/interfaces/ComplianceResult.md +1 -1
  104. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  105. package/docs/api/interfaces/DataRecord.md +1 -1
  106. package/docs/api/interfaces/DataTableAction.md +24 -21
  107. package/docs/api/interfaces/DataTableColumn.md +31 -31
  108. package/docs/api/interfaces/DataTableProps.md +1 -1
  109. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  110. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  111. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  112. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  113. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  114. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  115. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  116. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  117. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  118. package/docs/api/interfaces/ExportColumn.md +1 -1
  119. package/docs/api/interfaces/ExportOptions.md +8 -8
  120. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  121. package/docs/api/interfaces/FileMetadata.md +1 -1
  122. package/docs/api/interfaces/FileReference.md +1 -1
  123. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  124. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  125. package/docs/api/interfaces/FileUploadProps.md +26 -23
  126. package/docs/api/interfaces/FooterProps.md +10 -8
  127. package/docs/api/interfaces/FormFieldProps.md +10 -10
  128. package/docs/api/interfaces/FormProps.md +1 -1
  129. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  130. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  131. package/docs/api/interfaces/InputProps.md +7 -4
  132. package/docs/api/interfaces/LabelProps.md +1 -1
  133. package/docs/api/interfaces/LoggerConfig.md +1 -1
  134. package/docs/api/interfaces/LoginFormProps.md +14 -11
  135. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  136. package/docs/api/interfaces/NavigationContextType.md +1 -1
  137. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  138. package/docs/api/interfaces/NavigationItem.md +11 -11
  139. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  140. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  141. package/docs/api/interfaces/Organisation.md +1 -1
  142. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  143. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  144. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  145. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  146. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  147. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  148. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  149. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  150. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  151. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  152. package/docs/api/interfaces/PaletteData.md +1 -1
  153. package/docs/api/interfaces/ParsedAddress.md +1 -1
  154. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  155. package/docs/api/interfaces/ProgressProps.md +1 -1
  156. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  157. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  158. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  159. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  160. package/docs/api/interfaces/QuickFix.md +1 -1
  161. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  162. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  163. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  164. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  165. package/docs/api/interfaces/RBACConfig.md +1 -1
  166. package/docs/api/interfaces/RBACContext.md +1 -1
  167. package/docs/api/interfaces/RBACLogger.md +1 -1
  168. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  169. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  170. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  171. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  172. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  173. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  174. package/docs/api/interfaces/RBACResult.md +1 -1
  175. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  176. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  177. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  178. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  181. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  182. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  183. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  184. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  185. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  186. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  187. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  188. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  189. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  190. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  191. package/docs/api/interfaces/RouteConfig.md +1 -1
  192. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  193. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  194. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  195. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  196. package/docs/api/interfaces/SetupIssue.md +1 -1
  197. package/docs/api/interfaces/StorageConfig.md +1 -1
  198. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  199. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  200. package/docs/api/interfaces/StorageListOptions.md +1 -1
  201. package/docs/api/interfaces/StorageListResult.md +1 -1
  202. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  203. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  204. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  205. package/docs/api/interfaces/StyleImport.md +1 -1
  206. package/docs/api/interfaces/SwitchProps.md +1 -1
  207. package/docs/api/interfaces/TabsContentProps.md +1 -1
  208. package/docs/api/interfaces/TabsListProps.md +1 -1
  209. package/docs/api/interfaces/TabsProps.md +1 -1
  210. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  211. package/docs/api/interfaces/TextareaProps.md +1 -1
  212. package/docs/api/interfaces/ToastActionElement.md +4 -1
  213. package/docs/api/interfaces/ToastProps.md +1 -1
  214. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  215. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  216. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  217. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  218. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  219. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  220. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  221. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  222. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  223. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  224. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  225. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  226. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  227. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  228. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  229. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  230. package/docs/api/interfaces/UserEventAccess.md +14 -11
  231. package/docs/api/interfaces/UserMenuProps.md +8 -6
  232. package/docs/api/interfaces/UserProfile.md +1 -1
  233. package/docs/api/modules.md +575 -634
  234. package/docs/architecture/database-schema-requirements.md +161 -0
  235. package/docs/core-concepts/rbac-system.md +3 -3
  236. package/docs/documentation-index.md +2 -4
  237. package/docs/getting-started/cursor-rules.md +2 -1
  238. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  239. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  240. package/docs/migration/README.md +52 -6
  241. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  242. package/docs/migration/database-changes-december-2025.md +3 -3
  243. package/docs/rbac/event-based-apps.md +1 -1
  244. package/docs/rbac/getting-started.md +1 -1
  245. package/docs/rbac/quick-start.md +1 -1
  246. package/docs/standards/README.md +1 -0
  247. package/package.json +2 -1
  248. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  249. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  250. package/scripts/audit/core/checks/bundle.cjs +142 -0
  251. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +714 -687
  252. package/scripts/audit/core/checks/config.cjs +54 -0
  253. package/scripts/audit/core/checks/coverage.cjs +84 -0
  254. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  255. package/scripts/audit/core/checks/documentation.cjs +203 -0
  256. package/scripts/audit/core/checks/environment.cjs +128 -0
  257. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  258. package/scripts/audit/core/checks/forms.cjs +172 -0
  259. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  260. package/scripts/audit/core/checks/hooks.cjs +334 -0
  261. package/scripts/audit/core/checks/imports.cjs +244 -0
  262. package/scripts/audit/core/checks/performance.cjs +325 -0
  263. package/scripts/audit/core/checks/routes.cjs +117 -0
  264. package/scripts/audit/core/checks/state.cjs +130 -0
  265. package/scripts/audit/core/checks/structure.cjs +65 -0
  266. package/scripts/audit/core/checks/style.cjs +584 -0
  267. package/scripts/audit/core/checks/testing.cjs +122 -0
  268. package/scripts/audit/core/checks/typescript.cjs +61 -0
  269. package/scripts/audit/core/scanner.cjs +199 -0
  270. package/scripts/audit/core/utils.cjs +137 -0
  271. package/scripts/audit/index.cjs +223 -0
  272. package/scripts/audit/reporters/console.cjs +151 -0
  273. package/scripts/audit/reporters/json.cjs +54 -0
  274. package/scripts/audit/reporters/markdown.cjs +124 -0
  275. package/scripts/audit-consuming-app.cjs +61 -936
  276. package/scripts/build-docs/build-decision.js +240 -0
  277. package/scripts/build-docs/cache-utils.js +105 -0
  278. package/scripts/build-docs/content-normalization.js +150 -0
  279. package/scripts/build-docs/file-utils.js +105 -0
  280. package/scripts/build-docs/git-utils.js +86 -0
  281. package/scripts/build-docs/hash-utils.js +116 -0
  282. package/scripts/build-docs/typedoc-runner.js +220 -0
  283. package/scripts/build-docs-incremental.js +77 -913
  284. package/scripts/utils/command-runner.js +16 -11
  285. package/scripts/validate-formats.js +61 -56
  286. package/scripts/validate-master.js +74 -69
  287. package/scripts/validate-pre-publish.js +70 -65
  288. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  289. package/src/components/Alert/Alert.test.tsx +12 -18
  290. package/src/components/Alert/Alert.tsx +5 -7
  291. package/src/components/Avatar/Avatar.test.tsx +4 -4
  292. package/src/components/Badge/Badge.tsx +14 -0
  293. package/src/components/Button/Button.tsx +22 -0
  294. package/src/components/Calendar/Calendar.tsx +8 -2
  295. package/src/components/Card/Card.tsx +4 -0
  296. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  297. package/src/components/Checkbox/Checkbox.tsx +2 -2
  298. package/src/components/DataTable/DataTable.tsx +38 -4
  299. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  300. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  301. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  302. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  303. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  304. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  305. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  306. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  307. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  308. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  309. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  310. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  311. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  312. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  313. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  314. package/src/components/DataTable/components/EditFields.tsx +307 -0
  315. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  316. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  317. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  318. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  319. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  320. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  321. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  322. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  323. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  324. package/src/components/DataTable/components/UnifiedTableBody.tsx +61 -849
  325. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  326. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  327. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  328. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  329. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  330. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  331. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  332. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  333. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  334. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  335. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  336. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  337. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  338. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  339. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  340. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  341. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  342. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  343. package/src/components/DataTable/styles.ts +6 -6
  344. package/src/components/DataTable/types.ts +6 -10
  345. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  346. package/src/components/DataTable/utils/debugTools.ts +18 -113
  347. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  348. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  349. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  350. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  351. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  352. package/src/components/Dialog/Dialog.tsx +2 -2
  353. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  354. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  355. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  356. package/src/components/ErrorBoundary/index.ts +27 -2
  357. package/src/components/EventSelector/EventSelector.tsx +3 -0
  358. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  359. package/src/components/FileUpload/FileUpload.tsx +22 -2
  360. package/src/components/Footer/Footer.test.tsx +16 -16
  361. package/src/components/Footer/Footer.tsx +14 -11
  362. package/src/components/Form/Form.tsx +1 -0
  363. package/src/components/Header/Header.tsx +21 -10
  364. package/src/components/Input/Input.test.tsx +2 -2
  365. package/src/components/Input/Input.tsx +8 -4
  366. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  367. package/src/components/LoginForm/LoginForm.tsx +4 -0
  368. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  369. package/src/components/NavigationMenu/types.ts +56 -0
  370. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  371. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  372. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +4 -2
  373. package/src/components/PaceAppLayout/PaceAppLayout.tsx +32 -11
  374. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  376. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  377. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  378. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  379. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  380. package/src/components/Select/Select.tsx +80 -434
  381. package/src/components/Select/context.ts +23 -0
  382. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  383. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  384. package/src/components/Select/hooks/useSelectState.ts +104 -0
  385. package/src/components/Select/index.ts +9 -1
  386. package/src/components/Select/types.ts +123 -0
  387. package/src/components/Select/utils/text.ts +26 -0
  388. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  389. package/src/components/Switch/Switch.tsx +4 -4
  390. package/src/components/Tabs/Tabs.tsx +1 -1
  391. package/src/components/Toast/Toast.tsx +4 -0
  392. package/src/components/Tooltip/Tooltip.tsx +2 -2
  393. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  394. package/src/components/UserMenu/UserMenu.tsx +21 -18
  395. package/src/components/index.ts +2 -2
  396. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  397. package/src/hooks/index.ts +1 -2
  398. package/src/hooks/public/usePublicEvent.ts +4 -0
  399. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  400. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  401. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  402. package/src/hooks/services/useAuth.ts +32 -0
  403. package/src/hooks/services/useCurrentEvent.ts +6 -0
  404. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  405. package/src/hooks/useDebounce.ts +9 -0
  406. package/src/hooks/useEventTheme.ts +6 -0
  407. package/src/hooks/useFileDisplay.ts +4 -0
  408. package/src/hooks/useFileReference.ts +25 -7
  409. package/src/hooks/useFileUrl.ts +11 -1
  410. package/src/hooks/useFocusManagement.ts +14 -0
  411. package/src/hooks/useFocusTrap.ts +3 -0
  412. package/src/hooks/useInactivityTracker.ts +3 -0
  413. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  414. package/src/hooks/useOrganisationPermissions.ts +4 -0
  415. package/src/hooks/useOrganisationSecurity.ts +4 -0
  416. package/src/hooks/usePerformanceMonitor.ts +4 -0
  417. package/src/hooks/usePermissionCache.ts +7 -0
  418. package/src/hooks/useQueryCache.ts +12 -1
  419. package/src/hooks/useSessionRestoration.ts +4 -0
  420. package/src/hooks/useStorage.ts +4 -0
  421. package/src/hooks/useToast.ts +1 -1
  422. package/src/index.ts +2 -1
  423. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  424. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  425. package/src/providers/services/EventServiceProvider.tsx +18 -0
  426. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  427. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  428. package/src/providers/services/UnifiedAuthProvider.tsx +36 -0
  429. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  430. package/src/rbac/README.md +1 -1
  431. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +2 -2
  432. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  433. package/src/rbac/adapters.tsx +14 -5
  434. package/src/rbac/api.ts +100 -67
  435. package/src/rbac/components/NavigationProvider.tsx +4 -1
  436. package/src/rbac/components/PagePermissionGuard.tsx +157 -17
  437. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  438. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  439. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  440. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  441. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  442. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  443. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  444. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  445. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  446. package/src/rbac/engine.ts +38 -14
  447. package/src/rbac/hooks/permissions/index.ts +7 -0
  448. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  449. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  450. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  451. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  452. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  453. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  454. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  455. package/src/rbac/hooks/useCan.test.ts +71 -64
  456. package/src/rbac/hooks/usePermissions.ts +14 -995
  457. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  458. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  459. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  460. package/src/rbac/permissions.ts +0 -30
  461. package/src/rbac/secureClient.ts +200 -61
  462. package/src/rbac/types.ts +8 -0
  463. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  464. package/src/theming/parseEventColours.ts +5 -19
  465. package/src/types/vitest-globals.d.ts +51 -26
  466. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  467. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  468. package/src/utils/__tests__/index.unit.test.ts +2 -2
  469. package/src/utils/audit/audit.ts +0 -3
  470. package/src/utils/core/cn.ts +1 -1
  471. package/src/utils/file-reference/index.ts +53 -1
  472. package/src/utils/formatting/formatting.ts +8 -18
  473. package/src/utils/index.ts +0 -1
  474. package/dist/chunk-3QRJFVBR.js.map +0 -1
  475. package/dist/chunk-3XTALGJF.js.map +0 -1
  476. package/dist/chunk-4N5C5XZU.js.map +0 -1
  477. package/dist/chunk-4ZC4GX36.js.map +0 -1
  478. package/dist/chunk-BYFSK72L.js.map +0 -1
  479. package/dist/chunk-EXUD6RNJ.js +0 -451
  480. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  481. package/dist/chunk-GLK6VM3F.js.map +0 -1
  482. package/dist/chunk-I7PSE6JW.js.map +0 -1
  483. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  484. package/dist/chunk-KNC55RTG.js.map +0 -1
  485. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  486. package/dist/chunk-R77UEZ4E.js.map +0 -1
  487. package/dist/chunk-SQGMNID3.js.map +0 -1
  488. package/dist/chunk-T33XF5ZC.js.map +0 -1
  489. package/dist/chunk-XM25TVIE.js.map +0 -1
  490. package/docs/api/classes/ErrorBoundary.md +0 -144
  491. package/docs/migration/quick-migration-guide.md +0 -356
  492. package/docs/migration/service-architecture.md +0 -281
  493. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  494. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  495. package/src/hooks/useSecureDataAccess.ts +0 -681
  496. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  497. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  498. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  499. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  500. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  501. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  502. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Removed
11
+ - **DataTable Debug Tools Exports**: Removed all public exports from `packages/core/src/components/DataTable/utils/debugTools.ts` as they were unused. The debug tools functionality remains available internally for development but is no longer exported. Removed exports include:
12
+ - `DebugLevel` enum
13
+ - `DebugConfig` interface
14
+ - `DEFAULT_DEBUG_CONFIG` constant
15
+ - `DebugLogEntry` interface
16
+ - `PerformanceTimelineEntry` interface
17
+ - `MemorySnapshot` interface
18
+ - `RenderPerformanceData` interface
19
+ - `DataTableDebugger` class
20
+ - `dataTableDebugger` instance
21
+ - `profile` decorator function
22
+ - `MemoryMonitor` class
23
+ - `usePerformanceDebugger` hook
24
+ - `setupDevTools` function
25
+ - **DataTable Type Exports**: Removed duplicative type exports from `packages/core/src/components/DataTable/types.ts`:
26
+ - `PartialDataRecord<TData>` - Use `Partial<TData>` instead
27
+ - `CompleteDataRecord<TData>` - Use `TData` directly instead
28
+ - **Flexible Import Helper Functions**: Removed unused helper functions from `packages/core/src/components/DataTable/utils/flexibleImport.ts`:
29
+ - `createImportOptions()` - Not used anywhere in the codebase
30
+ - `createRegionalImportOptions()` - Not used anywhere in the codebase
31
+ - `testDateParsing()` - Not used anywhere in the codebase
32
+
33
+ ### Migration Notes
34
+ - If you were using `PartialDataRecord` or `CompleteDataRecord`, replace them with `Partial<TData>` and `TData` respectively
35
+ - If you were using any of the debug tools exports, they are no longer available. The debug tools remain functional internally but are not exposed as public APIs
36
+ - If you were using `createImportOptions()`, `createRegionalImportOptions()`, or `testDateParsing()`, you'll need to implement similar functionality yourself or use the `flexibleImport()` function directly with manual options
37
+
10
38
  ## [0.6.0] - 2025-01-28
11
39
 
12
40
  ### Changed
@@ -14,25 +42,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
42
  - **BREAKING**: Updated peer dependencies to require React ^19.0.0
15
43
  - **BREAKING**: Updated @types/react to ^19.2.7 and @types/react-dom to ^19.2.3
16
44
  - **BREAKING**: Updated @vitejs/plugin-react to ^5.1.2
45
+ - **BREAKING**: Database schema changes (table naming standardization, person-scoped profiles)
17
46
  - Fixed TypeScript errors related to React 19's stricter type system in Button and Select components
18
47
  - Updated vitest.config.ts to remove duplicate configuration keys
19
48
 
20
49
  ### Added
21
50
  - **React Compiler**: Added `babel-plugin-react-compiler` for automatic component optimizations
22
51
  - **React Compiler Configuration**: Configured React Compiler in vite.config.ts and vitest.config.ts
23
- - **Migration Guide**: Added React 19 migration guide at `docs/migration/REACT_19_MIGRATION.md`
24
- - Updated documentation to reflect React 19 requirements
25
-
26
- ### Technical Details
27
- - React Compiler automatically optimizes components during development and in consuming apps
28
- - TypeScript types updated to handle React 19's stricter `child.props` typing
29
- - All error boundaries verified compatible with React 19 error handling changes
30
- - All tests pass with React 19 and React Compiler enabled
52
+ - **Migration Guides**: Added comprehensive migration documentation
31
53
 
32
54
  ### Migration Notes
55
+
56
+ **⚠️ CRITICAL**: This version includes major breaking changes. See migration guides for detailed instructions:
57
+
58
+ - **React 19 Upgrade**: See [React 19 Migration Guide](./docs/migration/V0.6.0_REACT_19_MIGRATION.md)
59
+ - **Complete Migration Guide**: See [v0.5.190 → v0.6.1 Migration Guide](./docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md)
60
+ - **Database Changes**: See [Database Changes December 2025](./docs/migration/database-changes-december-2025.md)
61
+ - **Table Naming**: See [Database Changes December 2025](./docs/migration/database-changes-december-2025.md#change-1-table-naming-standardization)
62
+ - **Person-Scoped Profiles**: See [Person-Scoped Profiles Migration Guide](./docs/migration/V0.5.190_person-scoped-profiles-migration-guide.md)
63
+
64
+ **Quick Summary:**
33
65
  - Consuming apps must upgrade to React 19.2.3+
34
- - Consuming apps should install and configure React Compiler for optimal performance
35
- - See `docs/migration/REACT_19_MIGRATION.md` for complete migration instructions
66
+ - Database migrations required for table naming and person-scoped profiles
67
+ - All table names updated to follow `app_entity` naming convention
68
+ - Profiles are now person-scoped instead of organisation-scoped
36
69
 
37
70
  ## [Unreleased]
38
71
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  description: Enforce pace-core usage patterns and prevent custom solutions when pace-core provides functionality
3
3
  globs: ["src/**/*.{ts,tsx,js,jsx}"]
4
- alwaysApply: true
5
- paceCoreVersion: "0.5.x"
6
- rulesVersion: "2025-01-15"
4
+ alwaysApply: false
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # pace-core Compliance Guide
9
9
 
@@ -31,16 +31,8 @@ This guide ensures consuming apps use pace-core components, hooks, and utilities
31
31
 
32
32
  **Example:**
33
33
  ```tsx
34
- // ❌ WRONG - Custom button
35
- function CustomButton() {
36
- return <button className="btn">Click me</button>;
37
- }
38
-
39
- // ✅ CORRECT - Use pace-core
40
- import { Button } from '@jmruthers/pace-core';
41
- function MyComponent() {
42
- return <Button>Click me</Button>;
43
- }
34
+ // ❌ WRONG: <button className="btn">Click me</button>
35
+ // CORRECT: import { Button } from '@jmruthers/pace-core'; <Button>Click me</Button>
44
36
  ```
45
37
 
46
38
  ### Hooks
@@ -59,19 +51,8 @@ function MyComponent() {
59
51
 
60
52
  **Example:**
61
53
  ```tsx
62
- // ❌ WRONG - Custom debounce hook
63
- function useCustomDebounce(value: string, delay: number) {
64
- const [debounced, setDebounced] = useState(value);
65
- useEffect(() => {
66
- const timer = setTimeout(() => setDebounced(value), delay);
67
- return () => clearTimeout(timer);
68
- }, [value, delay]);
69
- return debounced;
70
- }
71
-
72
- // ✅ CORRECT - Use pace-core
73
- import { useDebounce } from '@jmruthers/pace-core';
74
- const debouncedValue = useDebounce(value, 500);
54
+ // ❌ WRONG: Custom useDebounce hook implementation
55
+ // ✅ CORRECT: import { useDebounce } from '@jmruthers/pace-core'; const debouncedValue = useDebounce(value, 500);
75
56
  ```
76
57
 
77
58
  ### Utilities
@@ -90,14 +71,8 @@ const debouncedValue = useDebounce(value, 500);
90
71
 
91
72
  **Example:**
92
73
  ```tsx
93
- // ❌ WRONG - Custom date formatting
94
- function formatDateCustom(date: Date): string {
95
- return new Intl.DateTimeFormat('en-US').format(date);
96
- }
97
-
98
- // ✅ CORRECT - Use pace-core
99
- import { formatDate } from '@jmruthers/pace-core';
100
- const formatted = formatDate(date);
74
+ // ❌ WRONG: Custom formatDate implementation
75
+ // CORRECT: import { formatDate } from '@jmruthers/pace-core'; const formatted = formatDate(date);
101
76
  ```
102
77
 
103
78
  ## MUST: Use Secure Supabase Client
@@ -105,15 +80,8 @@ const formatted = formatDate(date);
105
80
  **You MUST use `useSecureSupabase()` for all database operations.** Never use the base Supabase client directly.
106
81
 
107
82
  ```tsx
108
- // ❌ WRONG - Direct Supabase client
109
- import { createClient } from '@supabase/supabase-js';
110
- const supabase = createClient(...);
111
- await supabase.from('users').select('*');
112
-
113
- // ✅ CORRECT - Use secure client
114
- import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
115
- const secureSupabase = useSecureSupabase();
116
- await secureSupabase.from('users').select('*');
83
+ // ❌ WRONG: import { createClient } from '@supabase/supabase-js'; const supabase = createClient(...);
84
+ // ✅ CORRECT: import { useSecureSupabase } from '@jmruthers/pace-core/rbac'; const secureSupabase = useSecureSupabase();
117
85
  ```
118
86
 
119
87
  ## MUST: Setup RBAC Before Use
@@ -124,9 +92,7 @@ await secureSupabase.from('users').select('*');
124
92
  // main.tsx - MUST be first
125
93
  import { setupRBAC } from '@jmruthers/pace-core/rbac';
126
94
  setupRBAC(supabase);
127
-
128
95
  // Then render app
129
- ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
130
96
  ```
131
97
 
132
98
  ## MUST: Read Documentation Before Using Components
@@ -184,27 +150,13 @@ ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
184
150
 
185
151
  **❌ WRONG - Guessing props:**
186
152
  ```tsx
187
- // Don't guess - this might not work!
188
- <DataTable
189
- data={data}
190
- columns={columns}
191
- // Missing required rbac prop - will error!
192
- />
153
+ <DataTable data={data} columns={columns} /> // Missing required rbac prop
193
154
  ```
194
155
 
195
156
  **✅ CORRECT - Read documentation first:**
196
157
  ```tsx
197
- // 1. Read DataTable docs in implementation-guides/data-tables.md
198
- // 2. Understand required props (rbac is mandatory)
199
- // 3. Use correct props
200
158
  import { DataTable } from '@jmruthers/pace-core';
201
-
202
- <DataTable
203
- data={data}
204
- columns={columns}
205
- rbac={{ pageName: 'users' }} // Required - found in docs
206
- features={{ search: true, pagination: true }}
207
- />
159
+ <DataTable data={data} columns={columns} rbac={{ pageName: 'users' }} features={{ search: true }} />
208
160
  ```
209
161
 
210
162
  ### Documentation Checklist
@@ -249,16 +201,9 @@ Before using any pace-core component:
249
201
 
250
202
  ```tsx
251
203
  import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
252
-
253
- function App() {
254
- return (
255
- <UnifiedAuthProvider supabaseClient={supabase} appName="Your App">
256
- <OrganisationProvider>
257
- {/* Your app */}
258
- </OrganisationProvider>
259
- </UnifiedAuthProvider>
260
- );
261
- }
204
+ <UnifiedAuthProvider supabaseClient={supabase} appName="Your App">
205
+ <OrganisationProvider>{/* Your app */}</OrganisationProvider>
206
+ </UnifiedAuthProvider>
262
207
  ```
263
208
 
264
209
  ## MUST: Import Core Styles
@@ -296,26 +241,8 @@ import '@jmruthers/pace-core/styles/core.css';
296
241
 
297
242
  **Example:**
298
243
  ```tsx
299
- // ❌ WRONG - Inline styles
300
- <div style={{ backgroundColor: 'blue', padding: '10px', color: 'white' }}>
301
- Content
302
- </div>
303
-
304
- // ❌ WRONG - Inline styles on pace-core component
305
- <Button style={{ backgroundColor: 'red' }}>Click me</Button>
306
-
307
- // ✅ CORRECT - Use pace-core component with Tailwind classes
308
- <Card className="bg-main-500 p-4 text-white">
309
- <CardContent>Content</CardContent>
310
- </Card>
311
-
312
- // ✅ CORRECT - Use pace-core component as-is (already styled)
313
- <Button variant="default">Click me</Button>
314
-
315
- // ✅ CORRECT - Use Tailwind for layout/spacing only
316
- <div className="flex items-center gap-4 p-4">
317
- <Button>Action</Button>
318
- </div>
244
+ // ❌ WRONG: <div style={{ backgroundColor: 'blue' }}> or <Button style={{...}}>
245
+ // ✅ CORRECT: <Card className="bg-main-500 p-4"> or <Button variant="default"> or <div className="flex gap-4">
319
246
  ```
320
247
 
321
248
  ### When Tailwind Classes Are Acceptable
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  description: Enforce compliance with all pace-core standards across architecture, API, components, code style, security, testing, and RBAC/RLS
3
3
  globs: ["src/**/*.{ts,tsx,js,jsx}", "supabase/migrations/**/*.sql"]
4
- alwaysApply: true
5
- paceCoreVersion: "0.5.x"
6
- rulesVersion: "2025-01-15"
4
+ alwaysApply: false
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # Standards Compliance Guide
9
9
 
@@ -26,34 +26,16 @@ This guide ensures consuming apps comply with all pace-core standards. Follow th
26
26
  **RLS policies MUST use helper functions, NEVER subqueries.**
27
27
 
28
28
  ```sql
29
- -- ❌ WRONG - Subquery in RLS policy (causes N+1 queries)
30
- CREATE POLICY rbac_select_users ON users
31
- FOR SELECT USING (
32
- organisation_id IN (
33
- SELECT organisation_id FROM organisation_memberships
34
- WHERE user_id = auth.uid()
35
- )
36
- );
37
-
38
- -- ✅ CORRECT - Helper function
39
- CREATE OR REPLACE FUNCTION get_user_organisation_ids()
40
- RETURNS uuid[]
41
- LANGUAGE plpgsql
42
- STABLE
43
- SECURITY DEFINER
44
- SET search_path TO public
45
- AS $$
46
- BEGIN
47
- RETURN ARRAY(
48
- SELECT organisation_id
49
- FROM organisation_memberships
50
- WHERE user_id = get_effective_user_id()
51
- );
52
- END;
29
+ -- ❌ WRONG: Subquery in RLS policy (causes N+1 queries)
30
+ CREATE POLICY rbac_select_users ON users FOR SELECT USING (
31
+ organisation_id IN (SELECT organisation_id FROM organisation_memberships WHERE user_id = auth.uid())
32
+ );
33
+
34
+ -- CORRECT: Helper function with STABLE SECURITY DEFINER
35
+ CREATE OR REPLACE FUNCTION get_user_organisation_ids() RETURNS uuid[] LANGUAGE plpgsql STABLE SECURITY DEFINER SET search_path TO public AS $$
36
+ BEGIN RETURN ARRAY(SELECT organisation_id FROM organisation_memberships WHERE user_id = get_effective_user_id()); END;
53
37
  $$;
54
-
55
- CREATE POLICY rbac_select_users ON users
56
- FOR SELECT USING (organisation_id = ANY(get_user_organisation_ids()));
38
+ CREATE POLICY rbac_select_users ON users FOR SELECT USING (organisation_id = ANY(get_user_organisation_ids()));
57
39
  ```
58
40
 
59
41
  ### MUST: Test Database Migrations
@@ -72,14 +54,8 @@ CREATE POLICY rbac_select_users ON users
72
54
  - Bulk operations: `_bulk` suffix (e.g., `app_cake_dish_create_bulk`)
73
55
 
74
56
  ```sql
75
- -- ✅ CORRECT
76
- CREATE FUNCTION data_cake_dishes_list(...)
77
- CREATE FUNCTION app_cake_dish_create(...)
78
- CREATE FUNCTION app_cake_dish_create_bulk(...)
79
-
80
- -- ❌ WRONG
81
- CREATE FUNCTION getDishes(...)
82
- CREATE FUNCTION create_dish(...)
57
+ -- ✅ CORRECT: data_cake_dishes_list, app_cake_dish_create, app_cake_dish_create_bulk
58
+ -- WRONG: getDishes, create_dish (wrong naming pattern)
83
59
  ```
84
60
 
85
61
  ### MUST: Use ApiResult Shape
@@ -87,15 +63,8 @@ CREATE FUNCTION create_dish(...)
87
63
  **All RPCs MUST return ApiResult shape:**
88
64
 
89
65
  ```typescript
90
- type ApiResult<T> =
91
- | { ok: true; data: T }
92
- | { ok: false; error: ApiError };
93
-
94
- type ApiError = {
95
- code: string;
96
- message: string;
97
- details?: object;
98
- };
66
+ type ApiResult<T> = { ok: true; data: T } | { ok: false; error: ApiError };
67
+ type ApiError = { code: string; message: string; details?: object };
99
68
  ```
100
69
 
101
70
  ### MUST: Enforce RLS in RPCs
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  description: Define standard folder structure and file organization for consuming apps
3
- globs: ["**/*.{ts,tsx,js,jsx,md}"]
4
- alwaysApply: true
5
- paceCoreVersion: "0.5.x"
6
- rulesVersion: "2025-01-15"
3
+ globs: ["**/*.{ts,tsx,js,jsx,md}", "src/**"]
4
+ alwaysApply: false
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # Project Structure Standard
9
9
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  description: Enforce SOLID architecture principles in consuming apps
3
3
  globs: ["src/**/*.{ts,tsx}"]
4
- alwaysApply: true
5
- paceCoreVersion: "0.5.x"
6
- rulesVersion: "2025-01-15"
4
+ alwaysApply: false
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # SOLID Principles Guide
9
9
 
@@ -18,36 +18,19 @@ This guide enforces SOLID architecture principles to ensure maintainable, extens
18
18
  **Each function/component SHOULD do one thing:**
19
19
 
20
20
  ```tsx
21
- // ❌ WRONG - Multiple responsibilities
22
- function UserProfile({ userId }: { userId: string }) {
21
+ // ❌ WRONG: Multiple responsibilities (fetching, formatting, rendering in one component)
22
+ function UserProfile({ userId }) {
23
23
  const [user, setUser] = useState(null);
24
24
  const [events, setEvents] = useState([]);
25
-
26
- useEffect(() => {
27
- // Fetching user
28
- fetchUser(userId).then(setUser);
29
- // Fetching events
30
- fetchEvents(userId).then(setEvents);
31
- // Formatting data
32
- const formatted = formatUserData(user);
33
- // Rendering UI
34
- return <div>...</div>;
35
- }, [userId]);
36
-
25
+ useEffect(() => { fetchUser(userId).then(setUser); fetchEvents(userId).then(setEvents); }, [userId]);
37
26
  return <div>...</div>;
38
27
  }
39
28
 
40
- // ✅ CORRECT - Separated responsibilities
41
- function UserProfile({ userId }: { userId: string }) {
29
+ // ✅ CORRECT: Separated responsibilities (hooks for data, components for UI)
30
+ function UserProfile({ userId }) {
42
31
  const user = useUser(userId);
43
32
  const events = useUserEvents(userId);
44
-
45
- return (
46
- <div>
47
- <UserInfo user={user} />
48
- <UserEvents events={events} />
49
- </div>
50
- );
33
+ return <div><UserInfo user={user} /><UserEvents events={events} /></div>;
51
34
  }
52
35
  ```
53
36
 
@@ -56,37 +39,19 @@ function UserProfile({ userId }: { userId: string }) {
56
39
  **Complex logic SHOULD be extracted into hooks, services, or utilities:**
57
40
 
58
41
  ```tsx
59
- // ❌ WRONG - Business logic in component
42
+ // ❌ WRONG: Business logic in component (filtering, sorting, formatting)
60
43
  function EventList() {
61
44
  const [events, setEvents] = useState([]);
62
45
  const [filtered, setFiltered] = useState([]);
63
-
64
- useEffect(() => {
65
- fetchEvents().then(setEvents);
66
- }, []);
67
-
68
- useEffect(() => {
69
- const filtered = events
70
- .filter(e => e.status === 'active')
71
- .sort((a, b) => a.date - b.date)
72
- .map(e => ({ ...e, formattedDate: formatDate(e.date) }));
73
- setFiltered(filtered);
74
- }, [events]);
75
-
46
+ useEffect(() => { /* complex filtering/sorting logic */ }, [events]);
76
47
  return <div>{filtered.map(...)}</div>;
77
48
  }
78
49
 
79
- // ✅ CORRECT - Logic in hook
50
+ // ✅ CORRECT: Logic extracted to hook
80
51
  function useFilteredEvents() {
81
52
  const events = useEvents();
82
- return useMemo(() => {
83
- return events
84
- .filter(e => e.status === 'active')
85
- .sort((a, b) => a.date - b.date)
86
- .map(e => ({ ...e, formattedDate: formatDate(e.date) }));
87
- }, [events]);
53
+ return useMemo(() => events.filter(...).sort(...).map(...), [events]);
88
54
  }
89
-
90
55
  function EventList() {
91
56
  const filteredEvents = useFilteredEvents();
92
57
  return <div>{filteredEvents.map(...)}</div>;
@@ -102,28 +67,16 @@ function EventList() {
102
67
  **Extend functionality through composition, not modification:**
103
68
 
104
69
  ```tsx
105
- // ❌ WRONG - Modifying base component
106
- function BaseButton({ onClick, ...props }) {
107
- return <button onClick={onClick} {...props} />;
108
- }
109
-
70
+ // ❌ WRONG: Modifying base component behavior
110
71
  function SpecialButton({ onClick, ...props }) {
111
- // Modifying base behavior
112
- const handleClick = (e) => {
113
- trackEvent('button-click');
114
- onClick?.(e);
115
- };
116
- return <BaseButton onClick={handleClick} {...props} />;
72
+ const handleClick = (e) => { trackEvent('button-click'); onClick?.(e); };
73
+ return <BaseButton onClick={handleClick} {...props} />; // Modifies base
117
74
  }
118
75
 
119
- // ✅ CORRECT - Composition with pace-core
76
+ // ✅ CORRECT: Composition with pace-core (extend, don't modify)
120
77
  import { Button } from '@jmruthers/pace-core';
121
-
122
78
  function SpecialButton({ onClick, ...props }) {
123
- const handleClick = (e) => {
124
- trackEvent('button-click');
125
- onClick?.(e);
126
- };
79
+ const handleClick = (e) => { trackEvent('button-click'); onClick?.(e); };
127
80
  return <Button onClick={handleClick} {...props} />;
128
81
  }
129
82
  ```
@@ -133,13 +86,8 @@ function SpecialButton({ onClick, ...props }) {
133
86
  **Extend behavior through configuration:**
134
87
 
135
88
  ```tsx
136
- // ✅ CORRECT - Configurable behavior
137
- interface DataTableConfig {
138
- columns: Column[];
139
- features: FeatureConfig;
140
- rbac: RBACConfig;
141
- }
142
-
89
+ // ✅ CORRECT: Extend through configuration, not code changes
90
+ interface DataTableConfig { columns: Column[]; features: FeatureConfig; rbac: RBACConfig; }
143
91
  function MyDataTable({ config }: { config: DataTableConfig }) {
144
92
  return <DataTable {...config} />;
145
93
  }
@@ -154,22 +102,12 @@ function MyDataTable({ config }: { config: DataTableConfig }) {
154
102
  **Derived components/hooks MUST maintain the same interface:**
155
103
 
156
104
  ```tsx
157
- // ✅ CORRECT - Maintains interface
158
- interface BaseHook {
159
- data: Data | null;
160
- isLoading: boolean;
161
- error: Error | null;
162
- }
163
-
105
+ // ✅ CORRECT: Derived hooks maintain same interface (substitutable)
106
+ interface BaseHook { data: Data | null; isLoading: boolean; error: Error | null; }
164
107
  function useBaseData(): BaseHook { ... }
165
-
166
108
  function useExtendedData(): BaseHook {
167
109
  const base = useBaseData();
168
- // Extends but maintains same interface
169
- return {
170
- ...base,
171
- // Additional properties are optional
172
- };
110
+ return { ...base }; // Maintains interface, extends behavior
173
111
  }
174
112
  ```
175
113
 
@@ -182,7 +120,7 @@ function useExtendedData(): BaseHook {
182
120
  **Interfaces SHOULD be small and focused:**
183
121
 
184
122
  ```tsx
185
- // ❌ WRONG - Large interface
123
+ // ❌ WRONG: Large interface with many responsibilities
186
124
  interface UserService {
187
125
  getUser(id: string): Promise<User>;
188
126
  createUser(data: UserData): Promise<User>;
@@ -190,24 +128,12 @@ interface UserService {
190
128
  deleteUser(id: string): Promise<void>;
191
129
  getUserEvents(id: string): Promise<Event[]>;
192
130
  getUserOrganisations(id: string): Promise<Organisation[]>;
193
- // ... many more methods
194
- }
195
-
196
- // ✅ CORRECT - Segregated interfaces
197
- interface UserReader {
198
- getUser(id: string): Promise<User>;
199
- getUserEvents(id: string): Promise<Event[]>;
200
131
  }
201
132
 
202
- interface UserWriter {
203
- createUser(data: UserData): Promise<User>;
204
- updateUser(id: string, data: Partial<User>): Promise<User>;
205
- deleteUser(id: string): Promise<void>;
206
- }
207
-
208
- interface UserOrganisationService {
209
- getUserOrganisations(id: string): Promise<Organisation[]>;
210
- }
133
+ // CORRECT: Segregated interfaces (focused, specific)
134
+ interface UserReader { getUser(id: string): Promise<User>; getUserEvents(id: string): Promise<Event[]>; }
135
+ interface UserWriter { createUser(data: UserData): Promise<User>; updateUser(id: string, data: Partial<User>): Promise<User>; deleteUser(id: string): Promise<void>; }
136
+ interface UserOrganisationService { getUserOrganisations(id: string): Promise<Organisation[]>; }
211
137
  ```
212
138
 
213
139
  ### SHOULD: Use Specific Props
@@ -215,22 +141,12 @@ interface UserOrganisationService {
215
141
  **Component props SHOULD be specific, not generic:**
216
142
 
217
143
  ```tsx
218
- // ❌ WRONG - Generic props object
219
- function UserCard({ user, config }: { user: User; config: any }) {
220
- // ...
221
- }
222
-
223
- // ✅ CORRECT - Specific props
224
- interface UserCardProps {
225
- user: User;
226
- showEmail?: boolean;
227
- showAvatar?: boolean;
228
- onEdit?: (user: User) => void;
229
- }
144
+ // ❌ WRONG: Generic props object (config: any)
145
+ function UserCard({ user, config }: { user: User; config: any }) { ... }
230
146
 
231
- function UserCard({ user, showEmail, showAvatar, onEdit }: UserCardProps) {
232
- // ...
233
- }
147
+ // CORRECT: Specific, focused props interface
148
+ interface UserCardProps { user: User; showEmail?: boolean; showAvatar?: boolean; onEdit?: (user: User) => void; }
149
+ function UserCard({ user, showEmail, showAvatar, onEdit }: UserCardProps) { ... }
234
150
  ```
235
151
 
236
152
  ## Dependency Inversion Principle (DIP)
@@ -242,50 +158,25 @@ function UserCard({ user, showEmail, showAvatar, onEdit }: UserCardProps) {
242
158
  **Depend on interfaces/types, not concrete implementations:**
243
159
 
244
160
  ```tsx
245
- // ❌ WRONG - Direct dependency on implementation
161
+ // ❌ WRONG: Direct dependency on implementation (tight coupling)
246
162
  function UserService() {
247
163
  const supabase = useSecureSupabase();
248
-
249
164
  async function getUser(id: string) {
250
- const { data } = await supabase
251
- .from('users')
252
- .select('*')
253
- .eq('id', id)
254
- .single();
165
+ const { data } = await supabase.from('users').select('*').eq('id', id).single();
255
166
  return data;
256
167
  }
257
-
258
168
  return { getUser };
259
169
  }
260
170
 
261
- // ✅ CORRECT - Abstracted interface
262
- interface UserRepository {
263
- getUser(id: string): Promise<User | null>;
264
- }
265
-
171
+ // ✅ CORRECT: Abstracted interface (depend on abstraction)
172
+ interface UserRepository { getUser(id: string): Promise<User | null>; }
266
173
  function createUserRepository(supabase: SupabaseClient): UserRepository {
267
- return {
268
- async getUser(id: string) {
269
- const { data } = await supabase
270
- .from('users')
271
- .select('*')
272
- .eq('id', id)
273
- .single();
274
- return data;
275
- }
276
- };
174
+ return { async getUser(id: string) { /* implementation */ } };
277
175
  }
278
-
279
176
  function useUserService() {
280
177
  const supabase = useSecureSupabase();
281
- const repository = useMemo(
282
- () => createUserRepository(supabase),
283
- [supabase]
284
- );
285
-
286
- return {
287
- getUser: repository.getUser,
288
- };
178
+ const repository = useMemo(() => createUserRepository(supabase), [supabase]);
179
+ return { getUser: repository.getUser };
289
180
  }
290
181
  ```
291
182
 
@@ -294,22 +185,12 @@ function useUserService() {
294
185
  **Inject dependencies rather than creating them:**
295
186
 
296
187
  ```tsx
297
- // ❌ WRONG - Hard-coded dependency
298
- function EventService() {
299
- const api = new ApiClient('https://api.example.com');
300
- // ...
301
- }
188
+ // ❌ WRONG: Hard-coded dependency
189
+ function EventService() { const api = new ApiClient('https://api.example.com'); }
302
190
 
303
- // ✅ CORRECT - Injected dependency
304
- function EventService(api: ApiClient) {
305
- // ...
306
- }
307
-
308
- // Or with React context
309
- function useEventService() {
310
- const api = useApiClient(); // From context
311
- return useMemo(() => new EventService(api), [api]);
312
- }
191
+ // ✅ CORRECT: Injected dependency (dependency injection)
192
+ function EventService(api: ApiClient) { ... }
193
+ // Or with React context: const api = useApiClient(); useMemo(() => new EventService(api), [api]);
313
194
  ```
314
195
 
315
196
  ## SOLID Checklist