@jmruthers/pace-core 0.6.1 → 0.6.3

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 (549) hide show
  1. package/CHANGELOG.md +88 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +46 -87
  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-Cb34EQs3.d.ts} +63 -1
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-THFPBKTP.js} +12 -10
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DEMpysFR.d.ts} +394 -171
  17. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +30 -8
  18. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
  19. package/dist/{api-N774RPUA.js → api-IAGWF3ZG.js} +10 -10
  20. package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
  21. package/dist/{chunk-JBKQ3SAO.js → chunk-2T2IG7T7.js} +107 -57
  22. package/dist/chunk-2T2IG7T7.js.map +1 -0
  23. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  24. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  25. package/dist/{chunk-3XTALGJF.js → chunk-6Z7LTB3D.js} +69 -240
  26. package/dist/chunk-6Z7LTB3D.js.map +1 -0
  27. package/dist/{chunk-4ZC4GX36.js → chunk-CNCQDFLN.js} +199 -46
  28. package/dist/chunk-CNCQDFLN.js.map +1 -0
  29. package/dist/chunk-DGUM43GV.js +11 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-DWUBLJJM.js} +361 -187
  31. package/dist/chunk-DWUBLJJM.js.map +1 -0
  32. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  33. package/dist/chunk-FFQEQTNW.js.map +1 -0
  34. package/dist/chunk-FMUCXFII.js +76 -0
  35. package/dist/chunk-FMUCXFII.js.map +1 -0
  36. package/dist/{chunk-4N5C5XZU.js → chunk-HFZBI76P.js} +4 -4
  37. package/dist/chunk-HFZBI76P.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-I7PSE6JW.js → chunk-M7MPQISP.js} +3 -76
  43. package/dist/chunk-M7MPQISP.js.map +1 -0
  44. package/dist/chunk-PQBSKX33.js +7793 -0
  45. package/dist/chunk-PQBSKX33.js.map +1 -0
  46. package/dist/chunk-QRPVRXYT.js +226 -0
  47. package/dist/chunk-QRPVRXYT.js.map +1 -0
  48. package/dist/{chunk-KNC55RTG.js → chunk-RWEBCB47.js} +194 -416
  49. package/dist/chunk-RWEBCB47.js.map +1 -0
  50. package/dist/{chunk-XM25TVIE.js → chunk-YDQHOZNA.js} +843 -388
  51. package/dist/chunk-YDQHOZNA.js.map +1 -0
  52. package/dist/{chunk-GLK6VM3F.js → chunk-ZNIWI3UC.js} +739 -737
  53. package/dist/chunk-ZNIWI3UC.js.map +1 -0
  54. package/dist/components.d.ts +5 -5
  55. package/dist/components.js +18 -16
  56. package/dist/components.js.map +1 -1
  57. package/dist/contextValidator-3JNZKUTX.js +9 -0
  58. package/dist/contextValidator-3JNZKUTX.js.map +1 -0
  59. package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
  60. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  61. package/dist/hooks.d.ts +55 -122
  62. package/dist/hooks.js +10 -13
  63. package/dist/hooks.js.map +1 -1
  64. package/dist/index.d.ts +60 -13
  65. package/dist/index.js +30 -25
  66. package/dist/index.js.map +1 -1
  67. package/dist/providers.d.ts +21 -3
  68. package/dist/providers.js +4 -3
  69. package/dist/rbac/index.d.ts +210 -139
  70. package/dist/rbac/index.js +17 -13
  71. package/dist/styles/index.js +1 -1
  72. package/dist/theming/runtime.d.ts +1 -13
  73. package/dist/theming/runtime.js +2 -2
  74. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  75. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  76. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  77. package/dist/types.d.ts +2 -2
  78. package/dist/types.js +1 -1
  79. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +38 -17
  80. package/dist/utils.d.ts +4 -5
  81. package/dist/utils.js +17 -19
  82. package/dist/utils.js.map +1 -1
  83. package/docs/api/README.md +21 -17
  84. package/docs/api/modules.md +4191 -2967
  85. package/docs/architecture/database-schema-requirements.md +161 -0
  86. package/docs/components/context-selector.md +126 -0
  87. package/docs/core-concepts/rbac-system.md +3 -3
  88. package/docs/documentation-index.md +2 -4
  89. package/docs/getting-started/cursor-rules.md +2 -1
  90. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  91. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  92. package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
  93. package/docs/migration/README.md +52 -6
  94. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  95. package/docs/migration/database-changes-december-2025.md +3 -3
  96. package/docs/pace-mint-fix-auto-selection.md +218 -0
  97. package/docs/pace-mint-rbac-setup.md +391 -0
  98. package/docs/rbac/event-based-apps.md +1 -1
  99. package/docs/rbac/getting-started.md +1 -1
  100. package/docs/rbac/quick-start.md +1 -1
  101. package/docs/rbac/secure-client-protection.md +330 -0
  102. package/docs/standards/README.md +1 -0
  103. package/package.json +4 -3
  104. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  105. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  106. package/scripts/audit/core/checks/bundle.cjs +142 -0
  107. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +784 -685
  108. package/scripts/audit/core/checks/config.cjs +54 -0
  109. package/scripts/audit/core/checks/coverage.cjs +84 -0
  110. package/scripts/audit/core/checks/dependencies.cjs +985 -0
  111. package/scripts/audit/core/checks/documentation.cjs +268 -0
  112. package/scripts/audit/core/checks/environment.cjs +116 -0
  113. package/scripts/audit/core/checks/error-handling.cjs +340 -0
  114. package/scripts/audit/core/checks/forms.cjs +172 -0
  115. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  116. package/scripts/audit/core/checks/hooks.cjs +334 -0
  117. package/scripts/audit/core/checks/imports.cjs +244 -0
  118. package/scripts/audit/core/checks/performance.cjs +325 -0
  119. package/scripts/audit/core/checks/routes.cjs +117 -0
  120. package/scripts/audit/core/checks/state.cjs +130 -0
  121. package/scripts/audit/core/checks/structure.cjs +65 -0
  122. package/scripts/audit/core/checks/style.cjs +584 -0
  123. package/scripts/audit/core/checks/testing.cjs +122 -0
  124. package/scripts/audit/core/checks/typescript.cjs +61 -0
  125. package/scripts/audit/core/scanner.cjs +199 -0
  126. package/scripts/audit/core/utils.cjs +137 -0
  127. package/scripts/audit/index.cjs +223 -0
  128. package/scripts/audit/reporters/console.cjs +151 -0
  129. package/scripts/audit/reporters/json.cjs +54 -0
  130. package/scripts/audit/reporters/markdown.cjs +124 -0
  131. package/scripts/audit-consuming-app.cjs +61 -936
  132. package/scripts/build-docs/build-decision.js +240 -0
  133. package/scripts/build-docs/cache-utils.js +105 -0
  134. package/scripts/build-docs/content-normalization.js +150 -0
  135. package/scripts/build-docs/file-utils.js +105 -0
  136. package/scripts/build-docs/git-utils.js +86 -0
  137. package/scripts/build-docs/hash-utils.js +116 -0
  138. package/scripts/build-docs/typedoc-runner.js +220 -0
  139. package/scripts/build-docs-incremental.js +77 -913
  140. package/scripts/utils/command-runner.js +16 -11
  141. package/scripts/validate-formats.js +61 -56
  142. package/scripts/validate-master.js +74 -69
  143. package/scripts/validate-pre-publish.js +70 -65
  144. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  145. package/src/components/Alert/Alert.test.tsx +12 -18
  146. package/src/components/Alert/Alert.tsx +5 -7
  147. package/src/components/Avatar/Avatar.test.tsx +4 -4
  148. package/src/components/Badge/Badge.tsx +14 -0
  149. package/src/components/Button/Button.tsx +22 -0
  150. package/src/components/Calendar/Calendar.tsx +8 -2
  151. package/src/components/Card/Card.tsx +4 -0
  152. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  153. package/src/components/Checkbox/Checkbox.tsx +2 -2
  154. package/src/components/ContextSelector/ContextSelector.tsx +384 -0
  155. package/src/components/ContextSelector/index.ts +3 -0
  156. package/src/components/DataTable/DataTable.tsx +38 -4
  157. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  158. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  159. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  160. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  161. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  162. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  163. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  164. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  165. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  166. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  167. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  168. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  169. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  170. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  171. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  172. package/src/components/DataTable/components/EditFields.tsx +307 -0
  173. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  174. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  175. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  176. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  177. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  178. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  179. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  180. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  181. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  182. package/src/components/DataTable/components/UnifiedTableBody.tsx +63 -851
  183. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  184. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  185. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  186. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  187. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  188. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  189. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  190. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  191. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  192. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  193. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  194. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  195. package/src/components/DataTable/hooks/useDataTablePermissions.ts +127 -33
  196. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  197. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  198. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  199. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  200. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  201. package/src/components/DataTable/styles.ts +6 -6
  202. package/src/components/DataTable/types.ts +6 -10
  203. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  204. package/src/components/DataTable/utils/debugTools.ts +18 -113
  205. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  206. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  207. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  208. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  209. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  210. package/src/components/Dialog/Dialog.tsx +31 -3
  211. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  212. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  213. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  214. package/src/components/ErrorBoundary/index.ts +27 -2
  215. package/src/components/FileDisplay/FileDisplay.tsx +74 -28
  216. package/src/components/FileUpload/FileUpload.tsx +22 -2
  217. package/src/components/Footer/Footer.test.tsx +16 -16
  218. package/src/components/Footer/Footer.tsx +14 -11
  219. package/src/components/Form/Form.tsx +1 -0
  220. package/src/components/Header/Header.test.tsx +43 -73
  221. package/src/components/Header/Header.tsx +59 -49
  222. package/src/components/Input/Input.test.tsx +2 -2
  223. package/src/components/Input/Input.tsx +8 -4
  224. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  225. package/src/components/LoginForm/LoginForm.tsx +4 -0
  226. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  227. package/src/components/NavigationMenu/types.ts +56 -0
  228. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  229. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
  230. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
  231. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
  232. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +13 -11
  233. package/src/components/PaceAppLayout/PaceAppLayout.tsx +167 -44
  234. package/src/components/PaceAppLayout/README.md +14 -17
  235. package/src/components/PaceAppLayout/test-setup.tsx +3 -4
  236. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  237. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  238. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  239. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  240. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  241. package/src/components/Select/Select.tsx +80 -434
  242. package/src/components/Select/context.ts +23 -0
  243. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  244. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  245. package/src/components/Select/hooks/useSelectState.ts +104 -0
  246. package/src/components/Select/index.ts +9 -1
  247. package/src/components/Select/types.ts +123 -0
  248. package/src/components/Select/utils/text.ts +26 -0
  249. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  250. package/src/components/Switch/Switch.tsx +4 -4
  251. package/src/components/Tabs/Tabs.tsx +1 -1
  252. package/src/components/Toast/Toast.tsx +4 -0
  253. package/src/components/Tooltip/Tooltip.tsx +2 -2
  254. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  255. package/src/components/UserMenu/UserMenu.tsx +21 -18
  256. package/src/components/index.ts +7 -7
  257. package/src/eslint-rules/pace-core-compliance.cjs +106 -0
  258. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  259. package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
  260. package/src/hooks/index.ts +1 -2
  261. package/src/hooks/public/usePublicEvent.ts +4 -0
  262. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  263. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  264. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  265. package/src/hooks/services/useAuth.ts +32 -0
  266. package/src/hooks/services/useCurrentEvent.ts +6 -0
  267. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  268. package/src/hooks/useAppConfig.ts +15 -30
  269. package/src/hooks/useDebounce.ts +9 -0
  270. package/src/hooks/useEventTheme.ts +6 -0
  271. package/src/hooks/useFileDisplay.ts +81 -50
  272. package/src/hooks/useFileReference.ts +25 -7
  273. package/src/hooks/useFileUrl.ts +11 -1
  274. package/src/hooks/useFocusManagement.ts +14 -0
  275. package/src/hooks/useFocusTrap.ts +3 -0
  276. package/src/hooks/useInactivityTracker.ts +3 -0
  277. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  278. package/src/hooks/useOrganisationPermissions.ts +4 -0
  279. package/src/hooks/useOrganisationSecurity.ts +4 -0
  280. package/src/hooks/usePerformanceMonitor.ts +4 -0
  281. package/src/hooks/usePermissionCache.ts +7 -0
  282. package/src/hooks/useQueryCache.ts +12 -1
  283. package/src/hooks/useSessionRestoration.ts +4 -0
  284. package/src/hooks/useStorage.ts +4 -0
  285. package/src/hooks/useToast.ts +1 -1
  286. package/src/index.ts +6 -6
  287. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  288. package/src/providers/services/AuthServiceProvider.tsx +35 -7
  289. package/src/providers/services/EventServiceProvider.tsx +51 -5
  290. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  291. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +126 -134
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  294. package/src/rbac/README.md +1 -1
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
  296. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  297. package/src/rbac/adapters.tsx +12 -3
  298. package/src/rbac/api.test.ts +59 -51
  299. package/src/rbac/api.ts +246 -167
  300. package/src/rbac/components/NavigationProvider.tsx +4 -1
  301. package/src/rbac/components/PagePermissionGuard.tsx +185 -17
  302. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  303. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  304. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  305. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  306. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  307. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  308. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  309. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  310. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  311. package/src/rbac/engine.ts +38 -14
  312. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
  313. package/src/rbac/hooks/permissions/index.ts +7 -0
  314. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  315. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  316. package/src/rbac/hooks/permissions/useCan.ts +377 -0
  317. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  318. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  319. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  320. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  321. package/src/rbac/hooks/useCan.test.ts +64 -66
  322. package/src/rbac/hooks/usePermissions.ts +14 -995
  323. package/src/rbac/hooks/useRBAC.test.ts +1 -5
  324. package/src/rbac/hooks/useRBAC.ts +36 -37
  325. package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
  326. package/src/rbac/hooks/useResolvedScope.ts +35 -40
  327. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  328. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  329. package/src/rbac/hooks/useSecureSupabase.ts +27 -7
  330. package/src/rbac/index.ts +7 -0
  331. package/src/rbac/permissions.ts +0 -30
  332. package/src/rbac/secureClient.test.ts +22 -18
  333. package/src/rbac/secureClient.ts +294 -68
  334. package/src/rbac/security.ts +0 -17
  335. package/src/rbac/types.ts +9 -0
  336. package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
  337. package/src/rbac/utils/clientSecurity.ts +93 -0
  338. package/src/rbac/utils/contextValidator.ts +77 -168
  339. package/src/services/AuthService.ts +39 -7
  340. package/src/services/EventService.ts +186 -54
  341. package/src/services/OrganisationService.ts +81 -14
  342. package/src/services/__tests__/EventService.test.ts +1 -2
  343. package/src/services/base/BaseService.ts +3 -0
  344. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  345. package/src/theming/parseEventColours.ts +5 -19
  346. package/src/types/vitest-globals.d.ts +51 -26
  347. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  348. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  349. package/src/utils/__tests__/index.unit.test.ts +2 -2
  350. package/src/utils/audit/audit.ts +0 -3
  351. package/src/utils/core/cn.ts +1 -1
  352. package/src/utils/dynamic/dynamicUtils.ts +7 -4
  353. package/src/utils/file-reference/index.ts +53 -1
  354. package/src/utils/formatting/formatting.ts +8 -18
  355. package/src/utils/index.ts +0 -1
  356. package/dist/chunk-3QRJFVBR.js.map +0 -1
  357. package/dist/chunk-3XTALGJF.js.map +0 -1
  358. package/dist/chunk-4N5C5XZU.js.map +0 -1
  359. package/dist/chunk-4ZC4GX36.js.map +0 -1
  360. package/dist/chunk-7D4SUZUM.js +0 -38
  361. package/dist/chunk-BYFSK72L.js.map +0 -1
  362. package/dist/chunk-EXUD6RNJ.js +0 -451
  363. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  364. package/dist/chunk-GLK6VM3F.js.map +0 -1
  365. package/dist/chunk-I7PSE6JW.js.map +0 -1
  366. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  367. package/dist/chunk-KNC55RTG.js.map +0 -1
  368. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  369. package/dist/chunk-R77UEZ4E.js.map +0 -1
  370. package/dist/chunk-SQGMNID3.js.map +0 -1
  371. package/dist/chunk-T33XF5ZC.js +0 -12922
  372. package/dist/chunk-T33XF5ZC.js.map +0 -1
  373. package/dist/chunk-XM25TVIE.js.map +0 -1
  374. package/docs/api/classes/ColumnFactory.md +0 -243
  375. package/docs/api/classes/ErrorBoundary.md +0 -144
  376. package/docs/api/classes/InvalidScopeError.md +0 -73
  377. package/docs/api/classes/Logger.md +0 -178
  378. package/docs/api/classes/MissingUserContextError.md +0 -66
  379. package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
  380. package/docs/api/classes/PermissionDeniedError.md +0 -73
  381. package/docs/api/classes/RBACAuditManager.md +0 -297
  382. package/docs/api/classes/RBACCache.md +0 -322
  383. package/docs/api/classes/RBACEngine.md +0 -171
  384. package/docs/api/classes/RBACError.md +0 -76
  385. package/docs/api/classes/RBACNotInitializedError.md +0 -66
  386. package/docs/api/classes/SecureSupabaseClient.md +0 -160
  387. package/docs/api/classes/StorageUtils.md +0 -328
  388. package/docs/api/enums/FileCategory.md +0 -184
  389. package/docs/api/enums/LogLevel.md +0 -54
  390. package/docs/api/enums/RBACErrorCode.md +0 -228
  391. package/docs/api/enums/RPCFunction.md +0 -118
  392. package/docs/api/interfaces/AddressFieldProps.md +0 -241
  393. package/docs/api/interfaces/AddressFieldRef.md +0 -94
  394. package/docs/api/interfaces/AggregateConfig.md +0 -43
  395. package/docs/api/interfaces/AutocompleteOptions.md +0 -75
  396. package/docs/api/interfaces/AvatarProps.md +0 -128
  397. package/docs/api/interfaces/BadgeProps.md +0 -27
  398. package/docs/api/interfaces/ButtonProps.md +0 -53
  399. package/docs/api/interfaces/CalendarProps.md +0 -70
  400. package/docs/api/interfaces/CardProps.md +0 -66
  401. package/docs/api/interfaces/ColorPalette.md +0 -7
  402. package/docs/api/interfaces/ColorShade.md +0 -66
  403. package/docs/api/interfaces/ComplianceResult.md +0 -30
  404. package/docs/api/interfaces/DataAccessRecord.md +0 -96
  405. package/docs/api/interfaces/DataRecord.md +0 -11
  406. package/docs/api/interfaces/DataTableAction.md +0 -249
  407. package/docs/api/interfaces/DataTableColumn.md +0 -504
  408. package/docs/api/interfaces/DataTableProps.md +0 -625
  409. package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
  410. package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
  411. package/docs/api/interfaces/DatabaseIssue.md +0 -41
  412. package/docs/api/interfaces/EmptyStateConfig.md +0 -61
  413. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
  414. package/docs/api/interfaces/EventAppRoleData.md +0 -71
  415. package/docs/api/interfaces/ExportColumn.md +0 -90
  416. package/docs/api/interfaces/ExportOptions.md +0 -126
  417. package/docs/api/interfaces/FileDisplayProps.md +0 -249
  418. package/docs/api/interfaces/FileMetadata.md +0 -129
  419. package/docs/api/interfaces/FileReference.md +0 -118
  420. package/docs/api/interfaces/FileSizeLimits.md +0 -7
  421. package/docs/api/interfaces/FileUploadOptions.md +0 -139
  422. package/docs/api/interfaces/FileUploadProps.md +0 -293
  423. package/docs/api/interfaces/FooterProps.md +0 -105
  424. package/docs/api/interfaces/FormFieldProps.md +0 -166
  425. package/docs/api/interfaces/FormProps.md +0 -113
  426. package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
  427. package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
  428. package/docs/api/interfaces/InputProps.md +0 -53
  429. package/docs/api/interfaces/LabelProps.md +0 -107
  430. package/docs/api/interfaces/LoggerConfig.md +0 -62
  431. package/docs/api/interfaces/LoginFormProps.md +0 -184
  432. package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
  433. package/docs/api/interfaces/NavigationContextType.md +0 -164
  434. package/docs/api/interfaces/NavigationGuardProps.md +0 -139
  435. package/docs/api/interfaces/NavigationItem.md +0 -120
  436. package/docs/api/interfaces/NavigationMenuProps.md +0 -221
  437. package/docs/api/interfaces/NavigationProviderProps.md +0 -117
  438. package/docs/api/interfaces/Organisation.md +0 -140
  439. package/docs/api/interfaces/OrganisationContextType.md +0 -388
  440. package/docs/api/interfaces/OrganisationMembership.md +0 -140
  441. package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
  442. package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
  443. package/docs/api/interfaces/PaceAppLayoutProps.md +0 -406
  444. package/docs/api/interfaces/PaceLoginPageProps.md +0 -47
  445. package/docs/api/interfaces/PageAccessRecord.md +0 -85
  446. package/docs/api/interfaces/PagePermissionContextType.md +0 -140
  447. package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
  448. package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
  449. package/docs/api/interfaces/PaletteData.md +0 -41
  450. package/docs/api/interfaces/ParsedAddress.md +0 -120
  451. package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
  452. package/docs/api/interfaces/ProgressProps.md +0 -42
  453. package/docs/api/interfaces/ProtectedRouteProps.md +0 -97
  454. package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
  455. package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
  456. package/docs/api/interfaces/PublicPageLayoutProps.md +0 -198
  457. package/docs/api/interfaces/QuickFix.md +0 -52
  458. package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
  459. package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
  460. package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
  461. package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
  462. package/docs/api/interfaces/RBACConfig.md +0 -133
  463. package/docs/api/interfaces/RBACContext.md +0 -52
  464. package/docs/api/interfaces/RBACLogger.md +0 -112
  465. package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
  466. package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
  467. package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
  468. package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
  469. package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
  470. package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
  471. package/docs/api/interfaces/RBACResult.md +0 -58
  472. package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
  473. package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
  474. package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
  475. package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
  476. package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
  477. package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
  478. package/docs/api/interfaces/RBACRolesListParams.md +0 -52
  479. package/docs/api/interfaces/RBACRolesListResult.md +0 -74
  480. package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
  481. package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
  482. package/docs/api/interfaces/ResourcePermissions.md +0 -155
  483. package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
  484. package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
  485. package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
  486. package/docs/api/interfaces/RoleManagementResult.md +0 -52
  487. package/docs/api/interfaces/RouteAccessRecord.md +0 -107
  488. package/docs/api/interfaces/RouteConfig.md +0 -134
  489. package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
  490. package/docs/api/interfaces/SecureDataContextType.md +0 -168
  491. package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
  492. package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
  493. package/docs/api/interfaces/SetupIssue.md +0 -41
  494. package/docs/api/interfaces/StorageConfig.md +0 -41
  495. package/docs/api/interfaces/StorageFileInfo.md +0 -74
  496. package/docs/api/interfaces/StorageFileMetadata.md +0 -151
  497. package/docs/api/interfaces/StorageListOptions.md +0 -99
  498. package/docs/api/interfaces/StorageListResult.md +0 -41
  499. package/docs/api/interfaces/StorageUploadOptions.md +0 -101
  500. package/docs/api/interfaces/StorageUploadResult.md +0 -63
  501. package/docs/api/interfaces/StorageUrlOptions.md +0 -60
  502. package/docs/api/interfaces/StyleImport.md +0 -19
  503. package/docs/api/interfaces/SwitchProps.md +0 -34
  504. package/docs/api/interfaces/TabsContentProps.md +0 -9
  505. package/docs/api/interfaces/TabsListProps.md +0 -9
  506. package/docs/api/interfaces/TabsProps.md +0 -9
  507. package/docs/api/interfaces/TabsTriggerProps.md +0 -50
  508. package/docs/api/interfaces/TextareaProps.md +0 -53
  509. package/docs/api/interfaces/ToastActionElement.md +0 -9
  510. package/docs/api/interfaces/ToastProps.md +0 -9
  511. package/docs/api/interfaces/UnifiedAuthContextType.md +0 -820
  512. package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -171
  513. package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
  514. package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
  515. package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -136
  516. package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
  517. package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
  518. package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
  519. package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
  520. package/docs/api/interfaces/UsePublicEventReturn.md +0 -68
  521. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
  522. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -120
  523. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -94
  524. package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
  525. package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
  526. package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
  527. package/docs/api/interfaces/UserEventAccess.md +0 -118
  528. package/docs/api/interfaces/UserMenuProps.md +0 -86
  529. package/docs/api/interfaces/UserProfile.md +0 -63
  530. package/docs/migration/quick-migration-guide.md +0 -356
  531. package/docs/migration/service-architecture.md +0 -281
  532. package/src/components/EventSelector/EventSelector.test.tsx +0 -720
  533. package/src/components/EventSelector/EventSelector.tsx +0 -420
  534. package/src/components/EventSelector/index.ts +0 -3
  535. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
  536. package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -324
  537. package/src/components/OrganisationSelector/index.ts +0 -9
  538. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  539. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  540. package/src/hooks/useSecureDataAccess.ts +0 -681
  541. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-THFPBKTP.js.map} +0 -0
  542. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
  543. /package/dist/{api-N774RPUA.js.map → api-IAGWF3ZG.js.map} +0 -0
  544. /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
  545. /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
  546. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  547. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  548. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  549. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  description: Enforce code quality standards including TypeScript, ESLint, formatting, performance, and accessibility
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
  # Code Quality Guide
9
9
 
@@ -36,27 +36,17 @@ This guide enforces code quality standards to ensure maintainable, performant, a
36
36
  **MUST NOT use `any` type. Use `unknown` if type is truly unknown:**
37
37
 
38
38
  ```tsx
39
- // ❌ WRONG - Using any
40
- function processData(data: any) {
41
- return data.value;
42
- }
39
+ // ❌ WRONG: Using any
40
+ function processData(data: any) { return data.value; }
43
41
 
44
- // ✅ CORRECT - Using unknown with type guard
42
+ // ✅ CORRECT: Using unknown with type guard or proper types
45
43
  function processData(data: unknown) {
46
44
  if (typeof data === 'object' && data !== null && 'value' in data) {
47
45
  return (data as { value: string }).value;
48
46
  }
49
47
  throw new Error('Invalid data');
50
48
  }
51
-
52
- // ✅ CORRECT - Using proper types
53
- interface Data {
54
- value: string;
55
- }
56
-
57
- function processData(data: Data) {
58
- return data.value;
59
- }
49
+ // Or: interface Data { value: string; } function processData(data: Data) { return data.value; }
60
50
  ```
61
51
 
62
52
  ### MUST: Use Discriminated Unions
@@ -64,18 +54,11 @@ function processData(data: Data) {
64
54
  **MUST use discriminated unions instead of boolean flags:**
65
55
 
66
56
  ```tsx
67
- // ❌ WRONG - Boolean flags
68
- interface User {
69
- isAdmin: boolean;
70
- isGuest: boolean;
71
- // Confusing: what if both are true?
72
- }
57
+ // ❌ WRONG: Boolean flags (confusing: what if both are true?)
58
+ interface User { isAdmin: boolean; isGuest: boolean; }
73
59
 
74
- // ✅ CORRECT - Discriminated union
75
- type User =
76
- | { type: 'admin'; permissions: Permission[] }
77
- | { type: 'guest'; limitedAccess: boolean }
78
- | { type: 'user'; role: UserRole };
60
+ // ✅ CORRECT: Discriminated union
61
+ type User = { type: 'admin'; permissions: Permission[] } | { type: 'guest'; limitedAccess: boolean } | { type: 'user'; role: UserRole };
79
62
  ```
80
63
 
81
64
  ### SHOULD: Use ReadonlyArray
@@ -148,20 +131,10 @@ npm run format
148
131
  **SHOULD use React.memo, useMemo, useCallback appropriately:**
149
132
 
150
133
  ```tsx
151
- // ✅ CORRECT - Memoize expensive computations
152
- const expensiveValue = useMemo(() => {
153
- return computeExpensiveValue(data);
154
- }, [data]);
155
-
156
- // ✅ CORRECT - Memoize callbacks
157
- const handleClick = useCallback(() => {
158
- doSomething(id);
159
- }, [id]);
160
-
161
- // ✅ CORRECT - Memoize components
162
- const ExpensiveComponent = React.memo(({ data }) => {
163
- return <div>{/* ... */}</div>;
164
- });
134
+ // ✅ CORRECT: Memoize expensive computations, callbacks, and components
135
+ const expensiveValue = useMemo(() => computeExpensiveValue(data), [data]);
136
+ const handleClick = useCallback(() => doSomething(id), [id]);
137
+ const ExpensiveComponent = React.memo(({ data }) => <div>{/* ... */}</div>);
165
138
  ```
166
139
 
167
140
  ### SHOULD: Avoid Unnecessary Re-renders
@@ -169,18 +142,12 @@ const ExpensiveComponent = React.memo(({ data }) => {
169
142
  **SHOULD avoid causing unnecessary re-renders:**
170
143
 
171
144
  ```tsx
172
- // ❌ WRONG - New object on every render
173
- function Component({ items }) {
174
- const config = { items, enabled: true }; // New object each render
175
- return <Child config={config} />;
176
- }
145
+ // ❌ WRONG: New object on every render (causes unnecessary re-renders)
146
+ function Component({ items }) { const config = { items, enabled: true }; return <Child config={config} />; }
177
147
 
178
- // ✅ CORRECT - Memoize object
148
+ // ✅ CORRECT: Memoize object
179
149
  function Component({ items }) {
180
- const config = useMemo(
181
- () => ({ items, enabled: true }),
182
- [items]
183
- );
150
+ const config = useMemo(() => ({ items, enabled: true }), [items]);
184
151
  return <Child config={config} />;
185
152
  }
186
153
  ```
@@ -190,17 +157,11 @@ function Component({ items }) {
190
157
  **SHOULD lazy load heavy components:**
191
158
 
192
159
  ```tsx
193
- // ✅ CORRECT - Lazy loading
160
+ // ✅ CORRECT: Lazy load heavy components
194
161
  import { lazy, Suspense } from 'react';
195
-
196
162
  const HeavyComponent = lazy(() => import('./HeavyComponent'));
197
-
198
163
  function App() {
199
- return (
200
- <Suspense fallback={<Loading />}>
201
- <HeavyComponent />
202
- </Suspense>
203
- );
164
+ return <Suspense fallback={<Loading />}><HeavyComponent /></Suspense>;
204
165
  }
205
166
  ```
206
167
 
@@ -211,11 +172,8 @@ function App() {
211
172
  **MUST use semantic HTML elements:**
212
173
 
213
174
  ```tsx
214
- // ❌ WRONG - Non-semantic
215
- <div onClick={handleClick}>Click me</div>
216
-
217
- // ✅ CORRECT - Semantic
218
- <button onClick={handleClick}>Click me</button>
175
+ // ❌ WRONG: Non-semantic (<div onClick={...}>)
176
+ // ✅ CORRECT: Semantic HTML (<button onClick={...}>)
219
177
  ```
220
178
 
221
179
  ### MUST: Provide ARIA Labels
@@ -223,7 +181,7 @@ function App() {
223
181
  **MUST provide ARIA labels for interactive elements:**
224
182
 
225
183
  ```tsx
226
- // ✅ CORRECT - ARIA labels
184
+ // ✅ CORRECT: Provide ARIA labels for interactive elements
227
185
  <button aria-label="Close dialog">×</button>
228
186
  <input aria-label="Search" type="search" />
229
187
  ```
@@ -233,17 +191,8 @@ function App() {
233
191
  **MUST ensure all interactive elements are keyboard accessible:**
234
192
 
235
193
  ```tsx
236
- // ✅ CORRECT - Keyboard accessible
237
- <button
238
- onClick={handleClick}
239
- onKeyDown={(e) => {
240
- if (e.key === 'Enter' || e.key === ' ') {
241
- handleClick();
242
- }
243
- }}
244
- >
245
- Click me
246
- </button>
194
+ // ✅ CORRECT: Ensure keyboard navigation (Enter or Space key)
195
+ <button onClick={handleClick} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') handleClick(); }}>Click me</button>
247
196
  ```
248
197
 
249
198
  ### MUST: Provide Focus Indicators
@@ -251,10 +200,8 @@ function App() {
251
200
  **MUST provide visible focus indicators:**
252
201
 
253
202
  ```tsx
254
- // ✅ CORRECT - Focus styles
255
- <button className="focus:outline-none focus:ring-2 focus:ring-main-500">
256
- Click me
257
- </button>
203
+ // ✅ CORRECT: Provide visible focus indicators
204
+ <button className="focus:outline-none focus:ring-2 focus:ring-main-500">Click me</button>
258
205
  ```
259
206
 
260
207
  ## Code Review Checklist
@@ -281,20 +228,12 @@ function App() {
281
228
  **Functions SHOULD be small and focused:**
282
229
 
283
230
  ```tsx
284
- // ❌ WRONG - Large function
285
- function processUserData(user) {
286
- // 100+ lines of logic
287
- }
288
-
289
- // ✅ CORRECT - Small, focused functions
290
- function validateUser(user: User): ValidationResult {
291
- // Validation logic
292
- }
293
-
294
- function transformUser(user: User): TransformedUser {
295
- // Transformation logic
296
- }
231
+ // ❌ WRONG: Large function (100+ lines, multiple responsibilities)
232
+ function processUserData(user) { /* 100+ lines of logic */ }
297
233
 
234
+ // ✅ CORRECT: Small, focused functions
235
+ function validateUser(user: User): ValidationResult { /* Validation logic */ }
236
+ function transformUser(user: User): TransformedUser { /* Transformation logic */ }
298
237
  function processUserData(user: User) {
299
238
  const validation = validateUser(user);
300
239
  if (!validation.valid) return validation;
@@ -307,24 +246,11 @@ function processUserData(user: User) {
307
246
  **Functions SHOULD have low cyclomatic complexity (< 10):**
308
247
 
309
248
  ```tsx
310
- // ❌ WRONG - High complexity
311
- function processData(data) {
312
- if (condition1) {
313
- if (condition2) {
314
- if (condition3) {
315
- // ... many nested conditions
316
- }
317
- }
318
- }
319
- }
249
+ // ❌ WRONG: High complexity (many nested conditions)
250
+ function processData(data) { if (condition1) { if (condition2) { if (condition3) { /* ... */ } } } }
320
251
 
321
- // ✅ CORRECT - Lower complexity
322
- function processData(data) {
323
- if (!condition1) return;
324
- if (!condition2) return;
325
- if (!condition3) return;
326
- // Process
327
- }
252
+ // ✅ CORRECT: Lower complexity (early returns)
253
+ function processData(data) { if (!condition1) return; if (!condition2) return; if (!condition3) return; /* Process */ }
328
254
  ```
329
255
 
330
256
  ## Error Handling
@@ -334,7 +260,7 @@ function processData(data) {
334
260
  **MUST handle errors and provide user feedback:**
335
261
 
336
262
  ```tsx
337
- // ✅ CORRECT - Error handling
263
+ // ✅ CORRECT: Handle errors gracefully with user feedback
338
264
  try {
339
265
  const data = await fetchData();
340
266
  setData(data);
@@ -349,24 +275,15 @@ try {
349
275
  **MUST use type-safe error handling:**
350
276
 
351
277
  ```tsx
352
- // ✅ CORRECT - Type-safe errors
278
+ // ✅ CORRECT: Type-safe error handling
353
279
  function isApiError(error: unknown): error is ApiError {
354
- return (
355
- typeof error === 'object' &&
356
- error !== null &&
357
- 'code' in error &&
358
- 'message' in error
359
- );
280
+ return typeof error === 'object' && error !== null && 'code' in error && 'message' in error;
360
281
  }
361
-
362
282
  try {
363
283
  await apiCall();
364
284
  } catch (error) {
365
- if (isApiError(error)) {
366
- handleApiError(error);
367
- } else {
368
- handleUnknownError(error);
369
- }
285
+ if (isApiError(error)) handleApiError(error);
286
+ else handleUnknownError(error);
370
287
  }
371
288
  ```
372
289
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Enforce tech stack compliance including Tailwind v4, React 19+, Supabase, and other required technologies
3
3
  globs: ["src/**/*.{ts,tsx,js,jsx,css}", "*.config.{ts,js}"]
4
- alwaysApply: true
4
+ alwaysApply: false
5
5
  paceCoreVersion: "0.6.x"
6
6
  rulesVersion: "2025-01-28"
7
7
  ---
@@ -16,19 +16,8 @@ This guide ensures consuming apps use the correct versions and patterns for all
16
16
  **MUST use Tailwind v4 CSS-first syntax, NOT v3 patterns:**
17
17
 
18
18
  ```css
19
- /* ✅ CORRECT - Tailwind v4 */
20
- @import 'tailwindcss';
21
-
22
- @theme {
23
- --color-main-*: oklch(...);
24
- --color-sec-*: oklch(...);
25
- --color-acc-*: oklch(...);
26
- }
27
-
28
- /* ❌ WRONG - Tailwind v3 */
29
- @tailwind base;
30
- @tailwind components;
31
- @tailwind utilities;
19
+ /* ✅ CORRECT: Tailwind v4 CSS-first (@import 'tailwindcss'; @theme { ... }) */
20
+ /* ❌ WRONG: Tailwind v3 (@tailwind base/components/utilities directives) */
32
21
  ```
33
22
 
34
23
  ### MUST NOT: Use Bracket Syntax
@@ -36,11 +25,8 @@ This guide ensures consuming apps use the correct versions and patterns for all
36
25
  **MUST NOT use bracket syntax like `bg-[oklch(...)]`. Map everything through theme variables:**
37
26
 
38
27
  ```tsx
39
- // ❌ WRONG - Bracket syntax
40
- <div className="bg-[oklch(0.5 0.2 200)]">
41
-
42
- // ✅ CORRECT - Theme variable
43
- <div className="bg-main-500">
28
+ // ❌ WRONG: Bracket syntax (bg-[oklch(...)])
29
+ // ✅ CORRECT: Theme variable (bg-main-500)
44
30
  ```
45
31
 
46
32
  ### MUST: Use Custom Color Namespaces
@@ -51,11 +37,8 @@ This guide ensures consuming apps use the correct versions and patterns for all
51
37
  - `acc-*` for accent colors (red, orange, amber, yellow, lime, pink, rose)
52
38
 
53
39
  ```tsx
54
- // ✅ CORRECT - Custom namespaces
55
- <div className="bg-main-500 text-sec-800 border-acc-300">
56
-
57
- // ❌ WRONG - Standard Tailwind colors
58
- <div className="bg-blue-500 text-gray-800 border-red-300">
40
+ // ✅ CORRECT: Custom namespaces (main-*, sec-*, acc-*)
41
+ // WRONG: Standard Tailwind colors (blue-*, gray-*, red-*)
59
42
  ```
60
43
 
61
44
  ### MUST: Use Semantic Classes
@@ -77,17 +60,11 @@ This guide ensures consuming apps use the correct versions and patterns for all
77
60
  **MUST use React 19+ patterns:**
78
61
 
79
62
  ```tsx
80
- // ✅ CORRECT - React 19 features
63
+ // ✅ CORRECT: React 19+ features (Suspense, useTransition, etc.)
81
64
  import { Suspense, useTransition } from 'react';
82
-
83
65
  function App() {
84
66
  const [isPending, startTransition] = useTransition();
85
-
86
- return (
87
- <Suspense fallback={<Loading />}>
88
- <Component />
89
- </Suspense>
90
- );
67
+ return <Suspense fallback={<Loading />}><Component /></Suspense>;
91
68
  }
92
69
  ```
93
70
 
@@ -96,16 +73,10 @@ function App() {
96
73
  **MUST use functional components with hooks exclusively:**
97
74
 
98
75
  ```tsx
99
- // ✅ CORRECT - Functional component
100
- function MyComponent() {
101
- const [state, setState] = useState();
102
- return <div>...</div>;
103
- }
76
+ // ✅ CORRECT: Functional components with hooks
77
+ function MyComponent() { const [state, setState] = useState(); return <div>...</div>; }
104
78
 
105
- // ❌ WRONG - Class component
106
- class MyComponent extends React.Component {
107
- // ...
108
- }
79
+ // ❌ WRONG: Class components
109
80
  ```
110
81
 
111
82
  ## Supabase
@@ -115,17 +86,8 @@ class MyComponent extends React.Component {
115
86
  **MUST use `useSecureSupabase()` for all database operations:**
116
87
 
117
88
  ```tsx
118
- // ✅ CORRECT - Secure client
119
- import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
120
-
121
- function Component() {
122
- const secureSupabase = useSecureSupabase();
123
- const { data } = await secureSupabase.from('table').select('*');
124
- }
125
-
126
- // ❌ WRONG - Base client
127
- import { createClient } from '@supabase/supabase-js';
128
- const supabase = createClient(...);
89
+ // ✅ CORRECT: useSecureSupabase() from '@jmruthers/pace-core/rbac'
90
+ // WRONG: createClient() from '@supabase/supabase-js' (base client)
129
91
  ```
130
92
 
131
93
  ### MUST: Enforce RLS
@@ -137,17 +99,10 @@ const supabase = createClient(...);
137
99
  **SHOULD use RPC functions for complex queries:**
138
100
 
139
101
  ```tsx
140
- // ✅ CORRECT - RPC function
141
- const { data } = await secureSupabase.rpc('data_events_list', {
142
- organisation_id: orgId
143
- });
144
-
145
- // ❌ AVOID - Complex client-side queries
146
- const { data } = await secureSupabase
147
- .from('events')
148
- .select('*, organisations(*), users(*)')
149
- .eq('organisation_id', orgId)
150
- // ... many joins
102
+ // ✅ CORRECT: RPC functions for complex queries
103
+ const { data } = await secureSupabase.rpc('data_events_list', { organisation_id: orgId });
104
+
105
+ // ❌ AVOID: Complex client-side queries with many joins
151
106
  ```
152
107
 
153
108
  ## TanStack Query
@@ -157,28 +112,11 @@ const { data } = await secureSupabase
157
112
  **MUST use TanStack Query for all server state management:**
158
113
 
159
114
  ```tsx
160
- // ✅ CORRECT - TanStack Query
115
+ // ✅ CORRECT: TanStack Query for server state
161
116
  import { useQuery, useMutation } from '@tanstack/react-query';
117
+ const { data, isLoading } = useQuery({ queryKey: ['events', orgId], queryFn: () => fetchEvents(orgId) });
162
118
 
163
- function Component() {
164
- const { data, isLoading } = useQuery({
165
- queryKey: ['events', orgId],
166
- queryFn: () => fetchEvents(orgId)
167
- });
168
-
169
- const mutation = useMutation({
170
- mutationFn: createEvent,
171
- onSuccess: () => {
172
- queryClient.invalidateQueries({ queryKey: ['events'] });
173
- }
174
- });
175
- }
176
-
177
- // ❌ WRONG - useState for server state
178
- const [data, setData] = useState();
179
- useEffect(() => {
180
- fetchEvents().then(setData);
181
- }, []);
119
+ // WRONG: useState + useEffect for server state
182
120
  ```
183
121
 
184
122
  ### SHOULD: Configure Query Client
@@ -186,16 +124,8 @@ useEffect(() => {
186
124
  **SHOULD configure QueryClient with appropriate defaults:**
187
125
 
188
126
  ```tsx
189
- // ✅ CORRECT - Configured QueryClient
190
- const queryClient = new QueryClient({
191
- defaultOptions: {
192
- queries: {
193
- staleTime: 5 * 60 * 1000, // 5 minutes
194
- cacheTime: 10 * 60 * 1000, // 10 minutes
195
- retry: 1,
196
- },
197
- },
198
- });
127
+ // ✅ CORRECT: Configure QueryClient with appropriate defaults (staleTime, cacheTime, retry)
128
+ const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000, cacheTime: 10 * 60 * 1000, retry: 1 } } });
199
129
  ```
200
130
 
201
131
  ## React Hook Form + Zod
@@ -205,23 +135,12 @@ const queryClient = new QueryClient({
205
135
  **MUST use React Hook Form with Zod for all forms:**
206
136
 
207
137
  ```tsx
208
- // ✅ CORRECT - React Hook Form + Zod
138
+ // ✅ CORRECT: React Hook Form + Zod (useZodForm from pace-core)
209
139
  import { useZodForm } from '@jmruthers/pace-core';
210
- import { z } from 'zod';
211
-
212
- const schema = z.object({
213
- email: z.string().email(),
214
- name: z.string().min(1),
215
- });
140
+ const schema = z.object({ email: z.string().email(), name: z.string().min(1) });
141
+ const form = useZodForm(schema);
216
142
 
217
- function Form() {
218
- const form = useZodForm(schema);
219
- return <Form {...form}>...</Form>;
220
- }
221
-
222
- // ❌ WRONG - Manual form handling
223
- const [email, setEmail] = useState('');
224
- const [errors, setErrors] = useState({});
143
+ // ❌ WRONG: Manual form handling (useState for form state)
225
144
  ```
226
145
 
227
146
  ## Vite
@@ -231,14 +150,10 @@ const [errors, setErrors] = useState({});
231
150
  **MUST use Vite for all build tooling:**
232
151
 
233
152
  ```typescript
234
- // vite.config.ts
153
+ // ✅ CORRECT: Vite for build tooling
235
154
  import { defineConfig } from 'vite';
236
155
  import react from '@vitejs/plugin-react';
237
-
238
- export default defineConfig({
239
- plugins: [react()],
240
- // ...
241
- });
156
+ export default defineConfig({ plugins: [react()] });
242
157
  ```
243
158
 
244
159
  ### MUST: Use Environment Variables Correctly
@@ -246,11 +161,8 @@ export default defineConfig({
246
161
  **MUST use `import.meta.env` for environment variables:**
247
162
 
248
163
  ```tsx
249
- // ✅ CORRECT - Vite env vars
250
- const apiUrl = import.meta.env.VITE_API_URL;
251
-
252
- // ❌ WRONG - Node.js env vars
253
- const apiUrl = process.env.VITE_API_URL;
164
+ // ✅ CORRECT: import.meta.env.VITE_API_URL (Vite env vars)
165
+ // WRONG: process.env.VITE_API_URL (Node.js env vars)
254
166
  ```
255
167
 
256
168
  ## TypeScript
@@ -260,15 +172,8 @@ const apiUrl = process.env.VITE_API_URL;
260
172
  **MUST use TypeScript 5+ with strict mode:**
261
173
 
262
174
  ```json
263
- // tsconfig.json
264
- {
265
- "compilerOptions": {
266
- "target": "ES2022",
267
- "module": "ESNext",
268
- "strict": true,
269
- // ...
270
- }
271
- }
175
+ // ✅ CORRECT: TypeScript 5+ with strict mode
176
+ { "compilerOptions": { "target": "ES2022", "module": "ESNext", "strict": true } }
272
177
  ```
273
178
 
274
179
  ## Version Requirements