@jmruthers/pace-core 0.6.5 → 0.6.7

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 (473) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/audit-tool/00-dependencies.cjs +394 -0
  4. package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
  5. package/audit-tool/audits/02-project-structure.cjs +255 -0
  6. package/audit-tool/audits/03-architecture.cjs +196 -0
  7. package/audit-tool/audits/04-code-quality.cjs +149 -0
  8. package/audit-tool/audits/05-styling.cjs +224 -0
  9. package/audit-tool/audits/06-security-rbac.cjs +544 -0
  10. package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
  11. package/audit-tool/audits/08-testing-documentation.cjs +202 -0
  12. package/audit-tool/audits/09-operations.cjs +208 -0
  13. package/audit-tool/index.cjs +291 -0
  14. package/audit-tool/utils/code-utils.cjs +218 -0
  15. package/audit-tool/utils/file-utils.cjs +230 -0
  16. package/audit-tool/utils/report-utils.cjs +241 -0
  17. package/core-usage-manifest.json +93 -0
  18. package/cursor-rules/00-standards-overview.mdc +156 -0
  19. package/cursor-rules/01-pace-core-compliance.mdc +586 -0
  20. package/cursor-rules/02-project-structure.mdc +42 -4
  21. package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +126 -10
  22. package/cursor-rules/04-code-quality.mdc +419 -0
  23. package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +104 -34
  24. package/cursor-rules/06-security-rbac.mdc +518 -0
  25. package/cursor-rules/07-api-tech-stack.mdc +377 -0
  26. package/cursor-rules/08-testing-documentation.mdc +324 -0
  27. package/cursor-rules/09-operations.mdc +365 -0
  28. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  29. package/dist/DataTable-7PMH7XN7.js +15 -0
  30. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
  31. package/dist/{PublicPageProvider-QTFVrL-Z.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +33 -72
  32. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  33. package/dist/api-Y4MQWOFW.js +4 -0
  34. package/dist/audit-MYQXYZFU.js +3 -0
  35. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  36. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  37. package/dist/{chunk-UPPMRMYG.js → chunk-5X4QLXRG.js} +73 -151
  38. package/dist/chunk-6F3IILHI.js +62 -0
  39. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  40. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  41. package/dist/{chunk-FMUCXFII.js → chunk-7ILTDCL2.js} +9 -5
  42. package/dist/{chunk-M43Y4SSO.js → chunk-A3W6LW53.js} +15 -13
  43. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  44. package/dist/{chunk-HU2C6SSC.js → chunk-BM4CQ5P3.js} +606 -559
  45. package/dist/chunk-C7NSAPTL.js +1 -0
  46. package/dist/{chunk-J36DSWQK.js → chunk-FEJLJNWA.js} +7 -41
  47. package/dist/{chunk-IHB5DR3H.js → chunk-FTCRZOG2.js} +188 -387
  48. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  49. package/dist/chunk-GHYHJTYV.js +994 -0
  50. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  51. package/dist/{chunk-FFQEQTNW.js → chunk-IUBRCBSY.js} +134 -45
  52. package/dist/{chunk-6COVEUS7.js → chunk-JGWDVX64.js} +983 -1034
  53. package/dist/{chunk-RGAWHO7N.js → chunk-L4XMVJKY.js} +77 -222
  54. package/dist/chunk-MBADTM7L.js +64 -0
  55. package/dist/{chunk-M7MPQISP.js → chunk-OJ4SKRSV.js} +3 -16
  56. package/dist/{chunk-IVOFDYWT.js → chunk-Q7Q7V5NV.js} +2109 -1604
  57. package/dist/{chunk-JGRYX5UX.js → chunk-S7DKJPLT.js} +29 -58
  58. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  59. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  60. package/dist/{chunk-NTM7ZSB6.js → chunk-VBCS3DUA.js} +261 -168
  61. package/dist/{chunk-EFN2EIMK.js → chunk-ZFYPMX46.js} +271 -87
  62. package/dist/{chunk-L4OXEN46.js → chunk-ZKAWKYT4.js} +10 -24
  63. package/dist/components.d.ts +7 -5
  64. package/dist/components.js +46 -257
  65. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  66. package/dist/eslint-rules/index.cjs +35 -0
  67. package/{src/eslint-rules/pace-core-compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +234 -235
  68. package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
  69. package/dist/eslint-rules/rules/05-styling.cjs +61 -0
  70. package/dist/eslint-rules/rules/06-security-rbac.cjs +806 -0
  71. package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
  72. package/dist/eslint-rules/rules/08-testing.cjs +94 -0
  73. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  74. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  75. package/dist/hooks.d.ts +6 -6
  76. package/dist/hooks.js +62 -172
  77. package/dist/icons/index.d.ts +1 -0
  78. package/dist/icons/index.js +1 -0
  79. package/dist/index.d.ts +12 -11
  80. package/dist/index.js +67 -660
  81. package/dist/providers.d.ts +2 -2
  82. package/dist/providers.js +8 -35
  83. package/dist/rbac/eslint-rules.d.ts +46 -44
  84. package/dist/rbac/eslint-rules.js +7 -4
  85. package/dist/rbac/index.d.ts +109 -586
  86. package/dist/rbac/index.js +14 -207
  87. package/dist/styles/index.js +2 -12
  88. package/dist/theming/runtime.d.ts +14 -1
  89. package/dist/theming/runtime.js +3 -19
  90. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  91. package/dist/{types-CkbwOr4Y.d.ts → types-DXstZpNI.d.ts} +4 -17
  92. package/dist/types-t9H8qKRw.d.ts +55 -0
  93. package/dist/types.d.ts +1 -1
  94. package/dist/types.js +7 -94
  95. package/dist/{usePublicRouteParams-ClnV4tnv.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +20 -20
  96. package/dist/utils.d.ts +24 -117
  97. package/dist/utils.js +54 -392
  98. package/docs/README.md +17 -7
  99. package/docs/api/README.md +4 -402
  100. package/docs/api/modules.md +301 -871
  101. package/docs/api-reference/components.md +21 -21
  102. package/docs/api-reference/deprecated.md +31 -6
  103. package/docs/api-reference/hooks.md +80 -80
  104. package/docs/api-reference/rpc-functions.md +78 -3
  105. package/docs/api-reference/types.md +1 -1
  106. package/docs/api-reference/utilities.md +1 -1
  107. package/docs/architecture/README.md +1 -1
  108. package/docs/core-concepts/events.md +3 -3
  109. package/docs/core-concepts/organisations.md +6 -6
  110. package/docs/core-concepts/permissions.md +6 -6
  111. package/docs/documentation-index.md +12 -18
  112. package/docs/getting-started/cursor-rules.md +3 -23
  113. package/docs/getting-started/dependencies.md +650 -0
  114. package/docs/getting-started/documentation-index.md +1 -1
  115. package/docs/getting-started/examples/README.md +4 -4
  116. package/docs/getting-started/examples/full-featured-app.md +1 -1
  117. package/docs/getting-started/faq.md +2 -2
  118. package/docs/getting-started/installation-guide.md +20 -7
  119. package/docs/getting-started/quick-reference.md +4 -4
  120. package/docs/getting-started/quick-start.md +23 -12
  121. package/docs/implementation-guides/authentication.md +15 -15
  122. package/docs/implementation-guides/component-styling.md +1 -1
  123. package/docs/implementation-guides/data-tables.md +126 -33
  124. package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
  125. package/docs/implementation-guides/dynamic-colors.md +3 -3
  126. package/docs/implementation-guides/file-upload-storage.md +2 -2
  127. package/docs/implementation-guides/hierarchical-datatable.md +40 -60
  128. package/docs/implementation-guides/inactivity-tracking.md +3 -3
  129. package/docs/implementation-guides/large-datasets.md +3 -2
  130. package/docs/implementation-guides/organisation-security.md +2 -2
  131. package/docs/implementation-guides/performance.md +2 -2
  132. package/docs/implementation-guides/permission-enforcement.md +5 -1
  133. package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
  134. package/docs/migration/V0.4.0_rbac-migration.md +6 -6
  135. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  136. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  137. package/docs/rbac/README.md +17 -8
  138. package/docs/rbac/advanced-patterns.md +6 -6
  139. package/docs/rbac/api-reference.md +20 -20
  140. package/docs/rbac/edge-functions-guide.md +376 -0
  141. package/docs/rbac/event-based-apps.md +3 -3
  142. package/docs/rbac/examples.md +41 -41
  143. package/docs/rbac/getting-started.md +37 -37
  144. package/docs/rbac/performance.md +1 -1
  145. package/docs/rbac/quick-start.md +52 -52
  146. package/docs/rbac/secure-client-protection.md +1 -35
  147. package/docs/rbac/troubleshooting.md +1 -1
  148. package/docs/security/README.md +5 -5
  149. package/docs/standards/0-standards-overview.md +220 -0
  150. package/docs/standards/1-pace-core-compliance-standards.md +986 -0
  151. package/docs/standards/2-project-structure-standards.md +949 -0
  152. package/docs/standards/3-architecture-standards.md +606 -0
  153. package/docs/standards/4-code-quality-standards.md +728 -0
  154. package/docs/standards/5-styling-standards.md +348 -0
  155. package/docs/standards/{07-rbac-and-rls-standard.md → 6-security-rbac-standards.md} +269 -66
  156. package/docs/standards/7-api-tech-stack-standards.md +662 -0
  157. package/docs/standards/8-testing-documentation-standards.md +401 -0
  158. package/docs/standards/9-operations-standards.md +1102 -0
  159. package/docs/standards/README.md +185 -57
  160. package/docs/troubleshooting/README.md +4 -4
  161. package/docs/troubleshooting/common-issues.md +2 -2
  162. package/docs/troubleshooting/debugging.md +9 -9
  163. package/docs/troubleshooting/migration.md +4 -4
  164. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  165. package/eslint-config-pace-core.cjs +33 -6
  166. package/package.json +35 -23
  167. package/scripts/install-cursor-rules.cjs +25 -6
  168. package/scripts/install-eslint-config.cjs +284 -0
  169. package/src/__tests__/fixtures/supabase.ts +1 -1
  170. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +3 -3
  171. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  172. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  173. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
  174. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +13 -13
  175. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  176. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  177. package/src/__tests__/integration/UserProfile.test.tsx +14 -14
  178. package/src/__tests__/public-recipe-view.test.ts +38 -9
  179. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
  180. package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
  181. package/src/__tests__/templates/component.test.template.tsx +18 -15
  182. package/src/components/Button/Button.tsx +5 -1
  183. package/src/components/Calendar/Calendar.tsx +201 -47
  184. package/src/components/ContextSelector/ContextSelector.tsx +106 -119
  185. package/src/components/DataTable/AUDIT_REPORT.md +293 -0
  186. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
  187. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
  188. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
  189. package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
  190. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
  191. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  192. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
  193. package/src/components/DataTable/components/DataTableLayout.tsx +35 -21
  194. package/src/components/DataTable/components/EditFields.tsx +23 -3
  195. package/src/components/DataTable/components/EditableRow.tsx +12 -9
  196. package/src/components/DataTable/components/EmptyState.tsx +10 -9
  197. package/src/components/DataTable/components/FilterRow.tsx +2 -4
  198. package/src/components/DataTable/components/ImportModal.tsx +124 -126
  199. package/src/components/DataTable/components/LoadingState.tsx +5 -6
  200. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  201. package/src/components/DataTable/components/SortIndicator.tsx +50 -0
  202. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
  203. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
  204. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
  205. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
  206. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
  207. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
  208. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  209. package/src/components/DataTable/components/index.ts +2 -1
  210. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  211. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  212. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  213. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  214. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  215. package/src/components/DataTable/types.ts +5 -18
  216. package/src/components/DataTable/utils/a11yUtils.ts +17 -0
  217. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
  218. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
  219. package/src/components/DateTimeField/DateTimeField.tsx +10 -9
  220. package/src/components/Dialog/Dialog.test.tsx +128 -104
  221. package/src/components/Dialog/Dialog.tsx +742 -24
  222. package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
  223. package/src/components/FileDisplay/FileDisplay.test.tsx +4 -2
  224. package/src/components/FileDisplay/FileDisplay.tsx +23 -17
  225. package/src/components/FileUpload/FileUpload.test.tsx +52 -14
  226. package/src/components/FileUpload/FileUpload.tsx +112 -130
  227. package/src/components/Form/Form.test.tsx +6 -8
  228. package/src/components/Form/Form.tsx +365 -4
  229. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  230. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  231. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  232. package/src/components/PaceAppLayout/PaceAppLayout.tsx +11 -15
  233. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  234. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  235. package/src/components/Progress/Progress.tsx +2 -4
  236. package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
  237. package/src/components/Select/Select.tsx +109 -98
  238. package/src/components/Select/types.ts +4 -1
  239. package/src/components/UserMenu/UserMenu.tsx +9 -6
  240. package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
  241. package/src/hooks/__tests__/hooks.integration.test.tsx +55 -57
  242. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  243. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
  244. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  245. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  246. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  247. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  248. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  249. package/src/hooks/public/usePublicEvent.ts +67 -195
  250. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  251. package/src/hooks/public/usePublicEventLogo.ts +24 -14
  252. package/src/hooks/public/usePublicFileDisplay.ts +2 -2
  253. package/src/hooks/public/usePublicRouteParams.ts +5 -5
  254. package/src/hooks/useAppConfig.ts +28 -26
  255. package/src/hooks/useEventTheme.test.ts +217 -239
  256. package/src/hooks/useEventTheme.ts +16 -28
  257. package/src/hooks/useFileDisplay.ts +2 -2
  258. package/src/hooks/useOrganisationPermissions.ts +5 -7
  259. package/src/hooks/useQueryCache.ts +0 -1
  260. package/src/hooks/useSessionDraft.ts +380 -0
  261. package/src/hooks/useSessionRestoration.ts +3 -1
  262. package/src/icons/index.ts +27 -0
  263. package/src/index.ts +5 -0
  264. package/src/providers/OrganisationProvider.tsx +23 -14
  265. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
  266. package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
  267. package/src/providers/__tests__/EventProvider.test.tsx +61 -61
  268. package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
  269. package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
  270. package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
  271. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
  272. package/src/providers/services/EventServiceProvider.tsx +1 -24
  273. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  274. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
  275. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +13 -10
  276. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  277. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  278. package/src/rbac/adapters.tsx +7 -295
  279. package/src/rbac/api.test.ts +44 -56
  280. package/src/rbac/api.ts +10 -17
  281. package/src/rbac/cache-invalidation.ts +0 -1
  282. package/src/rbac/compliance/index.ts +10 -0
  283. package/src/rbac/compliance/pattern-detector.ts +553 -0
  284. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  285. package/src/rbac/components/AccessDenied.tsx +150 -0
  286. package/src/rbac/components/NavigationGuard.tsx +12 -20
  287. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  288. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  289. package/src/rbac/components/index.ts +3 -41
  290. package/src/rbac/eslint-rules.js +1 -1
  291. package/src/rbac/hooks/index.ts +0 -3
  292. package/src/rbac/hooks/permissions/index.ts +0 -3
  293. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  294. package/src/rbac/hooks/usePermissions.ts +0 -3
  295. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  296. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  297. package/src/rbac/hooks/useResourcePermissions.test.ts +124 -38
  298. package/src/rbac/hooks/useResourcePermissions.ts +139 -48
  299. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  300. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  301. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  302. package/src/rbac/index.ts +7 -9
  303. package/src/rbac/utils/contextValidator.ts +9 -7
  304. package/src/services/AuthService.ts +130 -18
  305. package/src/services/EventService.ts +4 -97
  306. package/src/services/InactivityService.ts +16 -0
  307. package/src/services/OrganisationService.ts +7 -44
  308. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  309. package/src/services/base/BaseService.ts +0 -3
  310. package/src/styles/core.css +7 -0
  311. package/src/theming/__tests__/parseEventColours.test.ts +9 -3
  312. package/src/theming/parseEventColours.ts +22 -10
  313. package/src/types/database.generated.ts +4733 -3809
  314. package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
  315. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  316. package/src/utils/context/organisationContext.test.ts +13 -28
  317. package/src/utils/context/organisationContext.ts +21 -52
  318. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  319. package/src/utils/file-reference/index.ts +39 -15
  320. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  321. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  322. package/src/utils/index.ts +4 -1
  323. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  324. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  325. package/src/utils/persistence/keyDerivation.ts +304 -0
  326. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  327. package/src/utils/security/secureStorage.ts +5 -5
  328. package/src/utils/storage/README.md +1 -1
  329. package/src/utils/storage/helpers.ts +3 -3
  330. package/src/utils/supabase/createBaseClient.ts +147 -0
  331. package/src/utils/timezone/timezone.test.ts +1 -2
  332. package/src/utils/timezone/timezone.ts +1 -1
  333. package/src/utils/validation/csrf.ts +4 -4
  334. package/cursor-rules/00-pace-core-compliance.mdc +0 -331
  335. package/cursor-rules/01-standards-compliance.mdc +0 -244
  336. package/cursor-rules/04-testing-standards.mdc +0 -268
  337. package/cursor-rules/05-bug-reports-and-features.mdc +0 -246
  338. package/cursor-rules/06-code-quality.mdc +0 -309
  339. package/cursor-rules/07-tech-stack-compliance.mdc +0 -214
  340. package/cursor-rules/CHANGELOG.md +0 -119
  341. package/cursor-rules/README.md +0 -192
  342. package/dist/DataTable-AOVNCPTX.js +0 -175
  343. package/dist/DataTable-AOVNCPTX.js.map +0 -1
  344. package/dist/UnifiedAuthProvider-4SBX4LU5.js +0 -18
  345. package/dist/UnifiedAuthProvider-4SBX4LU5.js.map +0 -1
  346. package/dist/api-O6HTBX5Y.js +0 -52
  347. package/dist/api-O6HTBX5Y.js.map +0 -1
  348. package/dist/audit-V53FV5AG.js +0 -17
  349. package/dist/audit-V53FV5AG.js.map +0 -1
  350. package/dist/chunk-5DRSZLL2.js.map +0 -1
  351. package/dist/chunk-63FOKYGO.js.map +0 -1
  352. package/dist/chunk-6COVEUS7.js.map +0 -1
  353. package/dist/chunk-AFVQODI2.js +0 -263
  354. package/dist/chunk-AFVQODI2.js.map +0 -1
  355. package/dist/chunk-DGUM43GV.js.map +0 -1
  356. package/dist/chunk-E66EQZE6.js.map +0 -1
  357. package/dist/chunk-EFN2EIMK.js.map +0 -1
  358. package/dist/chunk-FFQEQTNW.js.map +0 -1
  359. package/dist/chunk-FMUCXFII.js.map +0 -1
  360. package/dist/chunk-G37KK66H.js.map +0 -1
  361. package/dist/chunk-G7QEZTYQ.js +0 -2053
  362. package/dist/chunk-G7QEZTYQ.js.map +0 -1
  363. package/dist/chunk-HU2C6SSC.js.map +0 -1
  364. package/dist/chunk-IHB5DR3H.js.map +0 -1
  365. package/dist/chunk-IVOFDYWT.js.map +0 -1
  366. package/dist/chunk-J36DSWQK.js.map +0 -1
  367. package/dist/chunk-JGRYX5UX.js.map +0 -1
  368. package/dist/chunk-KQCRWDSA.js +0 -1
  369. package/dist/chunk-KQCRWDSA.js.map +0 -1
  370. package/dist/chunk-L4OXEN46.js.map +0 -1
  371. package/dist/chunk-LMC26NLJ.js +0 -84
  372. package/dist/chunk-LMC26NLJ.js.map +0 -1
  373. package/dist/chunk-M43Y4SSO.js.map +0 -1
  374. package/dist/chunk-M7MPQISP.js.map +0 -1
  375. package/dist/chunk-NTM7ZSB6.js.map +0 -1
  376. package/dist/chunk-PWLANIRT.js.map +0 -1
  377. package/dist/chunk-QXHPKYJV.js.map +0 -1
  378. package/dist/chunk-RGAWHO7N.js.map +0 -1
  379. package/dist/chunk-UPPMRMYG.js.map +0 -1
  380. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  381. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  382. package/dist/components.js.map +0 -1
  383. package/dist/contextValidator-5OGXSPKS.js +0 -9
  384. package/dist/contextValidator-5OGXSPKS.js.map +0 -1
  385. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  386. package/dist/hooks.js.map +0 -1
  387. package/dist/index.js.map +0 -1
  388. package/dist/providers.js.map +0 -1
  389. package/dist/rbac/eslint-rules.js.map +0 -1
  390. package/dist/rbac/index.js.map +0 -1
  391. package/dist/styles/index.js.map +0 -1
  392. package/dist/theming/runtime.js.map +0 -1
  393. package/dist/types.js.map +0 -1
  394. package/dist/utils.js.map +0 -1
  395. package/docs/best-practices/README.md +0 -472
  396. package/docs/best-practices/accessibility.md +0 -601
  397. package/docs/best-practices/common-patterns.md +0 -516
  398. package/docs/best-practices/deployment.md +0 -1103
  399. package/docs/best-practices/performance.md +0 -1328
  400. package/docs/best-practices/security.md +0 -940
  401. package/docs/best-practices/testing.md +0 -1034
  402. package/docs/rbac/compliance/compliance-guide.md +0 -544
  403. package/docs/standards/01-architecture-standard.md +0 -44
  404. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  405. package/docs/standards/03-component-standard.md +0 -32
  406. package/docs/standards/04-code-style-standard.md +0 -32
  407. package/docs/standards/05-security-standard.md +0 -44
  408. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  409. package/docs/standards/pace-core-compliance.md +0 -432
  410. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  411. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  412. package/scripts/audit/core/checks/bundle.cjs +0 -142
  413. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  414. package/scripts/audit/core/checks/config.cjs +0 -54
  415. package/scripts/audit/core/checks/coverage.cjs +0 -84
  416. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  417. package/scripts/audit/core/checks/documentation.cjs +0 -268
  418. package/scripts/audit/core/checks/environment.cjs +0 -116
  419. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  420. package/scripts/audit/core/checks/forms.cjs +0 -172
  421. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  422. package/scripts/audit/core/checks/hooks.cjs +0 -334
  423. package/scripts/audit/core/checks/imports.cjs +0 -244
  424. package/scripts/audit/core/checks/performance.cjs +0 -325
  425. package/scripts/audit/core/checks/routes.cjs +0 -117
  426. package/scripts/audit/core/checks/state.cjs +0 -130
  427. package/scripts/audit/core/checks/structure.cjs +0 -65
  428. package/scripts/audit/core/checks/style.cjs +0 -584
  429. package/scripts/audit/core/checks/testing.cjs +0 -122
  430. package/scripts/audit/core/checks/typescript.cjs +0 -61
  431. package/scripts/audit/core/scanner.cjs +0 -199
  432. package/scripts/audit/core/utils.cjs +0 -137
  433. package/scripts/audit/index.cjs +0 -223
  434. package/scripts/audit/reporters/console.cjs +0 -151
  435. package/scripts/audit/reporters/json.cjs +0 -54
  436. package/scripts/audit/reporters/markdown.cjs +0 -124
  437. package/scripts/audit-consuming-app.cjs +0 -86
  438. package/src/components/DataTable/components/DataTableBody.tsx +0 -454
  439. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
  440. package/src/components/DataTable/components/ExpandButton.tsx +0 -113
  441. package/src/components/DataTable/components/GroupHeader.tsx +0 -54
  442. package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
  443. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
  444. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
  445. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
  446. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
  447. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
  448. package/src/components/DataTable/core/DataTableContext.tsx +0 -216
  449. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
  450. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
  451. package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
  452. package/src/components/DataTable/utils/debugTools.ts +0 -514
  453. package/src/eslint-rules/pace-core-compliance.js +0 -638
  454. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  455. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  456. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  457. package/src/rbac/components/NavigationProvider.tsx +0 -345
  458. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  459. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  460. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  461. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  462. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  463. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  464. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  465. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  466. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  467. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  468. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  469. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  470. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  471. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  472. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  473. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -0,0 +1,986 @@
1
+ # pace-core Compliance Standards
2
+
3
+ **🤖 Cursor Rule**: See [01-pace-core-compliance.mdc](../../cursor-rules/01-pace-core-compliance.mdc) for AI-optimized directives that automatically enforce these standards.
4
+
5
+ This guide explains how to enforce pace-core usage patterns in consuming apps to ensure consistent design, reduce duplication, and maintain high code quality.
6
+
7
+ ## Overview
8
+
9
+ pace-core provides a comprehensive enforcement system that includes:
10
+
11
+ 1. **ESLint Rules** - Real-time linting during development (organized by standards: 01, 04, 05, 06, 07, 08)
12
+ 2. **Audit Tool** - Comprehensive system-level analysis organized by standards (01-09)
13
+ 3. **ESLint Config Preset** - Easy setup for consuming apps
14
+ 4. **Cursor Rules Integration** - AI-assisted enforcement via Cursor IDE
15
+
16
+ ### ESLint vs Audit Scripts
17
+
18
+ **ESLint Rules** (Real-time, AST-based):
19
+ - ✅ Run automatically in your IDE
20
+ - ✅ Provide immediate feedback during development
21
+ - ✅ Check single files using AST analysis
22
+ - ✅ Can be auto-fixed in many cases
23
+ - ✅ Integrated with your development workflow
24
+
25
+ **Audit Scripts** (Comprehensive, file-system based):
26
+ - ✅ Scan entire codebase
27
+ - ✅ Check file structure and configuration
28
+ - ✅ Cross-file analysis (e.g., provider nesting)
29
+ - ✅ Generate detailed reports
30
+ - ✅ Check setup files (main.tsx, app.css, etc.)
31
+
32
+ **What's in ESLint vs Audit Scripts**:
33
+
34
+ | Check | ESLint | Audit Script |
35
+ |-------|--------|--------------|
36
+ | Restricted imports | ✅ | ✅ (reference) |
37
+ | Native HTML elements | ✅ | ✅ (reference) |
38
+ | Custom hooks/utils | ✅ | ✅ (reference) |
39
+ | Inline styles | ✅ | ✅ (reference) |
40
+ | Plain form tags | ✅ | ✅ (reference) |
41
+ | Direct Supabase client | ✅ | ✅ (file location) |
42
+ | RBAC permission loading | ✅ | ✅ (reference) |
43
+ | Direct RBAC RPC/table | ✅ | ✅ (reference) |
44
+ | Hardcoded role checks | ✅ | ✅ (reference) |
45
+ | RESOURCE_NAMES constants | ✅ | ✅ (reference) |
46
+ | RBAC wrapper components | ✅ | ✅ (reference) |
47
+ | RBAC wrapper functions | ✅ | ✅ (reference) |
48
+ | RBAC setup (main.tsx) | ❌ | ✅ |
49
+ | Provider nesting | ❌ | ✅ |
50
+ | Core styles import chain | ❌ | ✅ |
51
+ | PagePermissionGuard coverage | ❌ | ✅ |
52
+ | Edge Functions RBAC | ❌ | ✅ |
53
+
54
+ **Note**: Many checks have been migrated from audit scripts to ESLint for real-time feedback. The audit scripts now focus on file-system and configuration checks that require cross-file analysis.
55
+
56
+ ## Quick Start
57
+
58
+ ### Step 1: Install pace-core
59
+
60
+ ```bash
61
+ npm install @jmruthers/pace-core
62
+ ```
63
+
64
+ ### Step 2: Setup ESLint (Recommended)
65
+
66
+ **Automated Setup (Easiest)**
67
+
68
+ Use the installation script to set up ESLint:
69
+
70
+ ```bash
71
+ npm run setup:eslint
72
+ # or
73
+ node node_modules/@jmruthers/pace-core/scripts/install-eslint-config.cjs
74
+ ```
75
+
76
+ This script will:
77
+ - ✅ Configure ESLint to use pace-core rules
78
+ - ✅ Create `eslint.config.js` if it doesn't exist
79
+ - ✅ Add pace-core config to existing ESLint config
80
+ - ✅ Create backups before modifying files
81
+
82
+ **Options:**
83
+ - `--force` - Force update even if already configured
84
+
85
+ **Option B: Manual Setup**
86
+
87
+ The easiest way to enable compliance checking is to use the shareable ESLint config. The config is CommonJS but works with both ES module and CommonJS ESLint configs:
88
+
89
+ **For ES Module ESLint Config (eslint.config.js):**
90
+ ```javascript
91
+ // eslint.config.js (ES modules)
92
+ import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
93
+
94
+ export default [
95
+ ...paceCoreConfig,
96
+ // your other config
97
+ ];
98
+ ```
99
+
100
+ **For CommonJS ESLint Config (.eslintrc.js or eslint.config.cjs):**
101
+ ```javascript
102
+ // eslint.config.cjs (CommonJS)
103
+ const paceCoreConfig = require('@jmruthers/pace-core/eslint-config');
104
+
105
+ module.exports = [
106
+ ...paceCoreConfig,
107
+ // your other config
108
+ ];
109
+ ```
110
+
111
+ **Complete Example (ESLint 9 flat config):**
112
+ ```javascript
113
+ // eslint.config.js
114
+ import js from '@eslint/js';
115
+ import reactHooks from 'eslint-plugin-react-hooks';
116
+ import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
117
+
118
+ export default [
119
+ js.configs.recommended,
120
+ ...paceCoreConfig, // pace-core rules
121
+ {
122
+ files: ['**/*.{ts,tsx}'],
123
+ plugins: {
124
+ 'react-hooks': reactHooks,
125
+ },
126
+ rules: {
127
+ ...reactHooks.configs.recommended.rules,
128
+ // Your other rules
129
+ },
130
+ },
131
+ ];
132
+ ```
133
+
134
+ ### Step 3: Setup Cursor Rules (Optional but Recommended)
135
+
136
+ **Automated Setup (Easiest)**
137
+
138
+ Use the installation script to set up Cursor rules:
139
+
140
+ ```bash
141
+ npm run setup:cursor-rules
142
+ # or
143
+ node node_modules/@jmruthers/pace-core/scripts/install-cursor-rules.cjs
144
+ ```
145
+
146
+ This script will:
147
+ - ✅ Install Cursor rules to `.cursor/rules/`
148
+ - ✅ Create backups before updating existing rules
149
+ - ✅ Automatically update pace-core rules when they change
150
+
151
+ **Options:**
152
+ - `--force` - Force update even if already configured
153
+
154
+ **Manual Setup (Alternative)**
155
+
156
+ To manually enable AI-assisted enforcement in Cursor IDE, copy the pace-core cursor rules to your project:
157
+
158
+ ```bash
159
+ # Create .cursor/rules directory if it doesn't exist
160
+ mkdir -p .cursor/rules
161
+
162
+ # Copy pace-core cursor rules
163
+ cp node_modules/@jmruthers/pace-core/cursor-rules/*.mdc .cursor/rules/
164
+ ```
165
+
166
+ Or manually create `.cursor/rules/01-pace-core-compliance.mdc` and reference the pace-core rules:
167
+
168
+ ```markdown
169
+ ---
170
+ description: Enforce pace-core usage patterns
171
+ globs: ["src/**/*.{ts,tsx,js,jsx}"]
172
+ alwaysApply: false
173
+ ---
174
+
175
+ # pace-core Compliance
176
+
177
+ **📚 Full Documentation**: See [pace-core compliance docs](node_modules/@jmruthers/pace-core/docs/standards/1-pace-core-compliance-standards.md)
178
+
179
+ **🔧 ESLint Setup**: Ensure ESLint is configured with `@jmruthers/pace-core/eslint-config`
180
+
181
+ This rule enforces pace-core usage patterns. ESLint provides real-time feedback, while this Cursor rule provides AI-assisted guidance.
182
+
183
+ ## Key Requirements
184
+
185
+ - Use pace-core components instead of native HTML or custom implementations
186
+ - Use pace-core hooks instead of custom hooks
187
+ - Use pace-core utilities instead of custom utilities
188
+ - Use `useSecureSupabase()` instead of direct Supabase client creation
189
+ - Follow RBAC patterns from pace-core
190
+ - Use RESOURCE_NAMES constants instead of string literals
191
+
192
+ See the full documentation for complete rules and examples.
193
+ ```
194
+
195
+ **Benefits of Cursor Rules Integration**:
196
+ - AI assistant (like me!) will automatically suggest pace-core alternatives
197
+ - Context-aware suggestions during code writing
198
+ - Works alongside ESLint for comprehensive enforcement
199
+ - Provides explanations and examples in real-time
200
+
201
+ ## ESLint Rules
202
+
203
+ pace-core provides ESLint rules organized by standards (01, 04, 05, 06, 07, 08). Rules are organized to match the 10-file standards structure:
204
+
205
+ - **Standard 1 (pace-core Compliance)**: 6 rules
206
+ - **Standard 4 (Code Quality)**: 3 rules
207
+ - **Standard 5 (Styling)**: 1 rule
208
+ - **Standard 6 (Security & RBAC)**: 8 rules
209
+ - **Standard 7 (API & Tech Stack)**: 3 rules
210
+ - **Standard 8 (Testing)**: 1 rule
211
+
212
+ **Total: 22 rules** organized across 6 standards files.
213
+
214
+ ### Rule Organization
215
+
216
+ Rules are organized in `packages/core/eslint-rules/rules/`:
217
+ - `01-pace-core-compliance.cjs` - pace-core usage patterns
218
+ - `04-code-quality.cjs` - Naming conventions, component/type naming
219
+ - `05-styling.cjs` - Inline styles
220
+ - `06-security-rbac.cjs` - Security and RBAC patterns
221
+ - `07-api-tech-stack.cjs` - RPC naming, React 19+, import.meta.env
222
+ - `08-testing.cjs` - Test file naming
223
+
224
+ ### Detailed Rule Descriptions
225
+
226
+ #### Import Rules
227
+
228
+ #### no-restricted-imports
229
+
230
+ **Severity**: Error
231
+
232
+ Blocks direct imports of libraries that pace-core wraps and standardizes.
233
+
234
+ **Restricted Libraries**:
235
+ - `@radix-ui/*` - All Radix UI packages (use pace-core components instead)
236
+ - `lucide-react` - Icons (import from `@jmruthers/pace-core/icons` instead)
237
+ - `react-day-picker` - Use `Calendar` from pace-core
238
+ - `@tanstack/react-table` - Use `DataTable` from pace-core
239
+ - `react-hook-form` - Use `Form` and `useZodForm` from pace-core
240
+ - `zod` - Use validation utilities from pace-core
241
+
242
+ **Example Violation**:
243
+ ```typescript
244
+ // ❌ Bad
245
+ import { Dialog } from '@radix-ui/react-dialog';
246
+ import { ChevronDown, Edit, Trash } from 'lucide-react';
247
+
248
+ // ✅ Good
249
+ import { Dialog } from '@jmruthers/pace-core';
250
+ import { ChevronDown, Edit, Trash } from '@jmruthers/pace-core/icons';
251
+ ```
252
+
253
+ ### Compliance Rules
254
+
255
+ #### prefer-pace-core-components
256
+
257
+ **Severity**: Warning
258
+
259
+ Suggests using pace-core components instead of native HTML elements.
260
+
261
+ **Detected Patterns**:
262
+ - `<button>` → Use `Button` from pace-core
263
+ - `<input>` → Use `Input` from pace-core
264
+ - `<textarea>` → Use `Textarea` from pace-core
265
+ - `<label>` → Use `Label` from pace-core
266
+
267
+ **Example**:
268
+ ```tsx
269
+ // ⚠️ Warning
270
+ <button onClick={handleClick}>Click me</button>
271
+
272
+ // ✅ Recommended
273
+ import { Button } from '@jmruthers/pace-core';
274
+ <Button onClick={handleClick}>Click me</Button>
275
+ ```
276
+
277
+ #### prefer-pace-core-hooks
278
+
279
+ **Severity**: Warning
280
+
281
+ Detects custom hooks that duplicate pace-core functionality.
282
+
283
+ **Common Patterns Detected**:
284
+ - `useToast`, `useNotification` → Use `useToast` from pace-core
285
+ - `useDebounce`, `useDebounced` → Use `useDebounce` from pace-core
286
+ - `useAuth`, `useAuthentication` → Use `useUnifiedAuth` from pace-core
287
+ - `useForm`, `useZodForm` → Use `useZodForm` from pace-core
288
+
289
+ **Example**:
290
+ ```typescript
291
+ // ⚠️ Warning
292
+ function useToast() {
293
+ // custom implementation
294
+ }
295
+
296
+ // ✅ Recommended
297
+ import { useToast } from '@jmruthers/pace-core';
298
+ ```
299
+
300
+ #### prefer-pace-core-utils
301
+
302
+ **Severity**: Warning
303
+
304
+ Detects utility functions that duplicate pace-core functionality.
305
+
306
+ **Common Patterns Detected**:
307
+ - `formatDate`, `dateFormat` → Use `formatDate` from pace-core
308
+ - `formatCurrency`, `formatMoney` → Use `formatCurrency` from pace-core
309
+ - `cn`, `classNames`, `clsx` → Use `cn` from pace-core
310
+ - `validate`, `validateInput` → Use `validateUserInput` from pace-core
311
+
312
+ **Example**:
313
+ ```typescript
314
+ // ⚠️ Warning
315
+ function formatDate(date: Date): string {
316
+ // custom implementation
317
+ }
318
+
319
+ // ✅ Recommended
320
+ import { formatDate } from '@jmruthers/pace-core';
321
+ ```
322
+
323
+ #### no-local-component-duplication
324
+
325
+ **Severity**: Error
326
+
327
+ Prevents creating local components with names matching pace-core components.
328
+
329
+ **Example Violation**:
330
+ ```
331
+ // ❌ Error: components/Button.tsx
332
+ export function Button() { ... }
333
+
334
+ // pace-core already provides Button component
335
+ ```
336
+
337
+ **Fix**: Remove the local component and import from pace-core:
338
+ ```typescript
339
+ import { Button } from '@jmruthers/pace-core';
340
+ ```
341
+
342
+ #### no-inline-styles
343
+
344
+ **Severity**: Error
345
+
346
+ Disallows inline styles. Use pace-core components or Tailwind classes instead.
347
+
348
+ **Example Violation**:
349
+ ```tsx
350
+ // ❌ Error
351
+ <div style={{ color: 'red', padding: '10px' }}>Content</div>
352
+
353
+ // ✅ Good
354
+ <div className="text-acc-500 p-4">Content</div>
355
+ // Or use pace-core components with built-in styling
356
+ ```
357
+
358
+ ### Component Rules
359
+
360
+ #### prefer-pace-core-form
361
+
362
+ **Severity**: Error
363
+
364
+ Disallows plain `<form>` tags and direct `react-hook-form` imports. Use pace-core `Form` component instead.
365
+
366
+ **Detected Patterns**:
367
+ - Plain `<form>` tags
368
+ - Direct imports from `react-hook-form` (except `useFormContext` when using pace-core `Form`)
369
+
370
+ **Example Violation**:
371
+ ```tsx
372
+ // ❌ Error
373
+ import { useForm, FormProvider } from 'react-hook-form';
374
+ <form onSubmit={handleSubmit}>...</form>
375
+
376
+ // ✅ Good
377
+ import { Form, useZodForm } from '@jmruthers/pace-core';
378
+ <Form form={form} onSubmit={handleSubmit}>...</Form>
379
+ ```
380
+
381
+ **Exception**: `useFormContext` is allowed when `Form` is imported from pace-core:
382
+ ```tsx
383
+ // ✅ Allowed
384
+ import { Form } from '@jmruthers/pace-core';
385
+ import { useFormContext } from 'react-hook-form'; // OK when using pace-core Form
386
+ ```
387
+
388
+ ### RBAC Rules
389
+
390
+ #### no-direct-supabase-client
391
+
392
+ **Severity**: Error
393
+
394
+ Disallows direct `createClient()` calls from `@supabase/supabase-js`. Use `useSecureSupabase()` from pace-core instead.
395
+
396
+ **Why**: Direct client creation bypasses organisation context and RLS policies, leading to security vulnerabilities.
397
+
398
+ **Example Violation**:
399
+ ```typescript
400
+ // ❌ Error
401
+ import { createClient } from '@supabase/supabase-js';
402
+ const supabase = createClient(url, key);
403
+
404
+ // ✅ Good
405
+ import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
406
+ const secureSupabase = useSecureSupabase();
407
+ ```
408
+
409
+ **Exception**: Creating the base client for `UnifiedAuthProvider` in `main.tsx` or `App.tsx` is allowed.
410
+
411
+ #### rbac-permission-loading
412
+
413
+ **Severity**: Error
414
+
415
+ Requires `isLoading` extraction from `useResourcePermissions` and checking it before permission calls in mutations.
416
+
417
+ **Why**: Permission checks may fail if scope resolution is still in progress.
418
+
419
+ **Example Violation**:
420
+ ```typescript
421
+ // ❌ Error
422
+ const { canCreate, canUpdate } = useResourcePermissions(RESOURCE_NAMES.EVENTS);
423
+ // Missing isLoading extraction
424
+
425
+ // In mutation:
426
+ if (canCreate(event)) { ... } // May fail if permissions still loading
427
+
428
+ // ✅ Good
429
+ const { canCreate, canUpdate, isLoading: permissionsLoading } = useResourcePermissions(RESOURCE_NAMES.EVENTS);
430
+
431
+ // In mutation:
432
+ if (permissionsLoading) {
433
+ throw new Error('Permission check in progress. Please wait...');
434
+ }
435
+ if (!canCreate(event)) {
436
+ throw new Error('Insufficient permissions');
437
+ }
438
+ ```
439
+
440
+ #### no-direct-rbac-rpc
441
+
442
+ **Severity**: Error
443
+
444
+ Disallows direct RPC calls to RBAC functions (e.g., `rbac_check_permission_simplified`). Use pace-core RBAC hooks instead.
445
+
446
+ **Example Violation**:
447
+ ```typescript
448
+ // ❌ Error
449
+ const { data } = await supabase.rpc('rbac_check_permission_simplified', {...});
450
+
451
+ // ✅ Good
452
+ import { isPermitted } from '@jmruthers/pace-core/rbac';
453
+ const hasPermission = await isPermitted({...});
454
+ ```
455
+
456
+ #### no-direct-rbac-table
457
+
458
+ **Severity**: Error
459
+
460
+ Disallows direct queries to RBAC tables. Use `useSecureSupabase()` hook or pace-core RBAC API functions instead.
461
+
462
+ **RBAC Tables**:
463
+ - `rbac_organisation_roles`
464
+ - `rbac_event_app_roles`
465
+ - `rbac_global_roles`
466
+ - `rbac_apps`
467
+ - `rbac_app_pages`
468
+ - `rbac_page_permissions`
469
+ - `rbac_user_profiles`
470
+
471
+ **Example Violation**:
472
+ ```typescript
473
+ // ❌ Error
474
+ const { data } = await supabase.from('rbac_organisation_roles').select('*');
475
+
476
+ // ✅ Good
477
+ import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
478
+ const secureSupabase = useSecureSupabase();
479
+ const { data } = await secureSupabase.from('rbac_organisation_roles').select('*');
480
+ ```
481
+
482
+ #### no-hardcoded-role-checks
483
+
484
+ **Severity**: Error
485
+
486
+ Disallows hardcoded role checks. Use `useAccessLevel` hook or `getRoleContext` API from pace-core instead.
487
+
488
+ **Example Violation**:
489
+ ```typescript
490
+ // ❌ Error
491
+ if (user.role === 'admin') { ... }
492
+ if (currentRole === 'org_admin') { ... }
493
+
494
+ // ✅ Good
495
+ import { useAccessLevel } from '@jmruthers/pace-core/rbac';
496
+ const { accessLevel } = useAccessLevel();
497
+ if (accessLevel === 'admin') { ... }
498
+ ```
499
+
500
+ #### rbac-use-resource-names-constants
501
+
502
+ **Severity**: Error
503
+
504
+ Requires `RESOURCE_NAMES` constants instead of string literals in `useResourcePermissions` calls.
505
+
506
+ **Example Violation**:
507
+ ```typescript
508
+ // ❌ Error
509
+ const permissions = useResourcePermissions('organisations');
510
+
511
+ // ✅ Good
512
+ import { RESOURCE_NAMES } from '@/config/resource-names';
513
+ const permissions = useResourcePermissions(RESOURCE_NAMES.ORGANISATIONS);
514
+ ```
515
+
516
+ #### no-rbac-wrapper-components
517
+
518
+ **Severity**: Error
519
+
520
+ Disallows wrapper components around `PagePermissionGuard`. Use `PagePermissionGuard` directly.
521
+
522
+ **Example Violation**:
523
+ ```tsx
524
+ // ❌ Error
525
+ function ProtectedPage({ pageName, children }) {
526
+ return <PagePermissionGuard pageName={pageName}>{children}</PagePermissionGuard>;
527
+ }
528
+
529
+ // ✅ Good
530
+ <PagePermissionGuard pageName="events" operation="read">
531
+ <YourPageContent />
532
+ </PagePermissionGuard>
533
+ ```
534
+
535
+ #### no-rbac-wrapper-functions
536
+
537
+ **Severity**: Error
538
+
539
+ Disallows wrapper functions around pace-core permission hooks. Use hooks directly in components.
540
+
541
+ **Example Violation**:
542
+ ```typescript
543
+ // ❌ Error
544
+ function canEditEvent(eventId: string) {
545
+ const { canUpdate } = useResourcePermissions(RESOURCE_NAMES.EVENTS);
546
+ return canUpdate(eventId) && someOtherCondition;
547
+ }
548
+
549
+ // ✅ Good
550
+ function YourComponent() {
551
+ const { canUpdate } = useResourcePermissions(RESOURCE_NAMES.EVENTS);
552
+ // Use canUpdate directly in component logic
553
+ }
554
+ ```
555
+
556
+ ## Static Analysis Script
557
+
558
+ The static analysis script provides a comprehensive scan of your codebase and generates a detailed compliance report.
559
+
560
+ ### Running the Script
561
+
562
+ ```bash
563
+ # From your consuming app root
564
+ node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs
565
+ ```
566
+
567
+ Or add it to your `package.json`:
568
+
569
+ ```json
570
+ {
571
+ "scripts": {
572
+ "check:pace-core": "node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs"
573
+ }
574
+ }
575
+ ```
576
+
577
+ ### What It Checks
578
+
579
+ 1. **Restricted Imports** - Scans for direct imports of wrapped libraries
580
+ 2. **Duplicate Components** - Finds local components matching pace-core names
581
+ 3. **Duplicate Hooks** - Finds local hooks matching pace-core hooks
582
+ 4. **Duplicate Utils** - Finds local utils matching pace-core utils
583
+ 5. **Suggestions** - Recommends pace-core alternatives for native HTML elements
584
+
585
+ ### Report Output
586
+
587
+ The script generates a color-coded terminal report showing:
588
+
589
+ - ❌ **Errors** - Critical violations that must be fixed
590
+ - ⚠️ **Warnings** - Issues that should be addressed
591
+ - 💡 **Suggestions** - Recommendations for improvement
592
+ - ✅ **Summary** - Overall compliance status
593
+
594
+ ## Best Practices
595
+
596
+ ### 1. Always Import from pace-core
597
+
598
+ ```typescript
599
+ // ✅ Good
600
+ import { Button, Card, Dialog } from '@jmruthers/pace-core';
601
+ import { useToast, useDebounce } from '@jmruthers/pace-core';
602
+ import { formatDate, formatCurrency } from '@jmruthers/pace-core';
603
+ ```
604
+
605
+ ### 2. Use pace-core Components for UI
606
+
607
+ Avoid native HTML elements when pace-core provides a component:
608
+
609
+ ```tsx
610
+ // ❌ Avoid
611
+ <button className="btn">Click</button>
612
+
613
+ // ✅ Use pace-core
614
+ <Button>Click</Button>
615
+ ```
616
+
617
+ ### 3. Leverage pace-core Hooks
618
+
619
+ Don't recreate hooks that pace-core already provides:
620
+
621
+ ```typescript
622
+ // ❌ Avoid
623
+ const [debouncedValue, setDebouncedValue] = useState(value);
624
+ useEffect(() => {
625
+ const timer = setTimeout(() => setDebouncedValue(value), 500);
626
+ return () => clearTimeout(timer);
627
+ }, [value]);
628
+
629
+ // ✅ Use pace-core
630
+ import { useDebounce } from '@jmruthers/pace-core';
631
+ const debouncedValue = useDebounce(value, 500);
632
+ ```
633
+
634
+ ### 4. Use pace-core Utilities
635
+
636
+ Leverage formatting, validation, and other utilities from pace-core:
637
+
638
+ ```typescript
639
+ // ❌ Avoid
640
+ const formatted = new Intl.DateTimeFormat('en-US').format(date);
641
+
642
+ // ✅ Use pace-core
643
+ import { formatDate } from '@jmruthers/pace-core';
644
+ const formatted = formatDate(date);
645
+ ```
646
+
647
+ ### 5. Check Before Creating New Components
648
+
649
+ Before creating a new component, check if pace-core already provides it:
650
+
651
+ 1. Review the [pace-core documentation](https://github.com/your-org/pace-core)
652
+ 2. Check `core-usage-manifest.json` for available components
653
+ 3. Search pace-core exports
654
+
655
+ ## MUST: Provider Nesting Order
656
+
657
+ **⚠️ CRITICAL: Provider nesting order matters!** Incorrect nesting causes React context errors.
658
+
659
+ **MUST** nest providers in this exact order (outermost to innermost):
660
+
661
+ 1. `QueryClientProvider` (outermost)
662
+ 2. `BrowserRouter`
663
+ 3. `UnifiedAuthProvider`
664
+ 4. `OrganisationProvider`
665
+ 5. `App` (innermost)
666
+
667
+ ```tsx
668
+ // ✅ CORRECT: main.tsx
669
+ import { BrowserRouter } from 'react-router-dom';
670
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
671
+ import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
672
+ import { createClient } from '@supabase/supabase-js';
673
+
674
+ const queryClient = new QueryClient();
675
+ const supabase = createClient(
676
+ import.meta.env.VITE_SUPABASE_URL,
677
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
678
+ );
679
+
680
+ createRoot(document.getElementById("root")!).render(
681
+ <QueryClientProvider client={queryClient}>
682
+ <BrowserRouter>
683
+ <UnifiedAuthProvider supabaseClient={supabase} appName="YourApp">
684
+ <OrganisationProvider>
685
+ <App />
686
+ </OrganisationProvider>
687
+ </UnifiedAuthProvider>
688
+ </BrowserRouter>
689
+ </QueryClientProvider>
690
+ );
691
+ ```
692
+
693
+ **Common mistakes to avoid:**
694
+ - ❌ `BrowserRouter` inside `UnifiedAuthProvider` (causes Router context errors)
695
+ - ❌ `UnifiedAuthProvider` wrapping `BrowserRouter` (causes context errors)
696
+ - ❌ Missing `BrowserRouter` (causes `useNavigate` errors)
697
+
698
+ ## MUST: Vite Configuration
699
+
700
+ **⚠️ CRITICAL: Vite configuration prevents React context mismatches!**
701
+
702
+ **MUST** configure Vite to exclude `@jmruthers/pace-core` and `react-router-dom` from pre-bundling:
703
+
704
+ ```typescript
705
+ // vite.config.ts
706
+ import { defineConfig } from 'vite';
707
+ import react from '@vitejs/plugin-react';
708
+ import path from 'path';
709
+
710
+ export default defineConfig({
711
+ plugins: [react()],
712
+ resolve: {
713
+ alias: {
714
+ '@': path.resolve(__dirname, './src'),
715
+ },
716
+ // CRITICAL: Dedupe React dependencies
717
+ dedupe: ['react', 'react-dom', 'react-router-dom'],
718
+ },
719
+ optimizeDeps: {
720
+ include: [
721
+ 'react',
722
+ 'react-dom',
723
+ 'react/jsx-runtime',
724
+ ],
725
+ // CRITICAL: Exclude pace-core to prevent React context mismatches
726
+ exclude: ['@jmruthers/pace-core', 'react-router-dom'],
727
+ },
728
+ });
729
+ ```
730
+
731
+ **Why this matters:**
732
+ - Pre-bundling `@jmruthers/pace-core` creates separate React instances
733
+ - This causes "useUnifiedAuth must be used within a UnifiedAuthProvider" errors
734
+ - Excluding it ensures pace-core uses the same React instance as your app
735
+ - `react-router-dom` must also be excluded and deduped to prevent Router context errors
736
+
737
+ **If you encounter context errors:**
738
+ 1. Verify `@jmruthers/pace-core` is in `optimizeDeps.exclude`
739
+ 2. Verify `react-router-dom` is in both `resolve.dedupe` and `optimizeDeps.exclude`
740
+ 3. Clear Vite cache: `rm -rf node_modules/.vite`
741
+ 4. Restart dev server
742
+
743
+ ## MUST: Use Secure Supabase Client
744
+
745
+ **All database operations MUST use `useSecureSupabase()` (or the contract-approved pace-core secure client wrapper).**
746
+ Consuming apps **MUST NOT** use the base Supabase client directly for queries.
747
+
748
+ ### Hard Requirements
749
+
750
+ - **MUST NOT** import or call `createClient()` from `@supabase/supabase-js` in consuming app code **except** for creating the base client passed to `UnifiedAuthProvider`.
751
+ - **MUST NOT** export, pass, or store an insecure Supabase client instance for general use.
752
+ - **MUST** perform all `.from(...)`, `.rpc(...)`, `.auth.*`, and storage operations via the secure client returned by `useSecureSupabase()` (or the approved pace-core equivalent).
753
+ - **MUST** create the base Supabase client ONCE and pass it to `UnifiedAuthProvider` as `supabaseClient` prop.
754
+ - **MUST** call `useSecureSupabase()` without parameters - it automatically uses the base client from `useUnifiedAuth()` provider layer.
755
+ - **MUST NOT** pass a base client directly to `useSecureSupabase()` - the hook gets it from the provider automatically.
756
+
757
+ ### Why this is critical
758
+
759
+ Using `createClient()` directly for queries can bypass organisation context enforcement and RLS policies, leading to:
760
+ - Cross-organisation data access
761
+ - Security vulnerabilities
762
+ - Data leakage between organisations
763
+
764
+ ### Correct Pattern
765
+
766
+ ```tsx
767
+ // ✅ CORRECT: Create base client ONCE for UnifiedAuthProvider
768
+ // main.tsx or App.tsx
769
+ import { createClient } from '@supabase/supabase-js';
770
+ import { UnifiedAuthProvider } from '@jmruthers/pace-core';
771
+
772
+ const supabase = createClient(
773
+ import.meta.env.VITE_SUPABASE_URL,
774
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
775
+ );
776
+
777
+ function App() {
778
+ return (
779
+ <UnifiedAuthProvider
780
+ supabaseClient={supabase} // Pass base client to provider
781
+ appName="YourApp"
782
+ // ... other props
783
+ >
784
+ <YourApp />
785
+ </UnifiedAuthProvider>
786
+ );
787
+ }
788
+
789
+ // ✅ CORRECT: Use secure client in components (no parameters needed)
790
+ // YourComponent.tsx
791
+ import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
792
+
793
+ function YourComponent() {
794
+ const secureSupabase = useSecureSupabase(); // Gets client from provider automatically
795
+
796
+ if (!secureSupabase) {
797
+ return <div>Loading...</div>;
798
+ }
799
+
800
+ // Use secureSupabase for all queries
801
+ const { data } = await secureSupabase.from('users').select('*');
802
+ }
803
+ ```
804
+
805
+ ### Incorrect Patterns
806
+
807
+ ```tsx
808
+ // ❌ FORBIDDEN: Creating client in component or service
809
+ import { createClient } from '@supabase/supabase-js';
810
+ const supabase = createClient(url, key); // Don't do this for queries
811
+
812
+ // ❌ FORBIDDEN: Passing base client to useSecureSupabase
813
+ import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
814
+ import { supabase } from './supabase'; // Don't export base client
815
+ const secureSupabase = useSecureSupabase(supabase); // Don't pass it
816
+
817
+ // ❌ FORBIDDEN: Using base client directly for queries
818
+ const { data } = await supabase.from('users').select('*'); // Bypasses RLS
819
+ ```
820
+
821
+ ### Hook Signature
822
+
823
+ The `useSecureSupabase()` hook signature is:
824
+
825
+ ```typescript
826
+ function useSecureSupabase(
827
+ baseClient?: SupabaseClient<Database> | null
828
+ ): SupabaseClient<Database> | null
829
+ ```
830
+
831
+ **Important**: The `baseClient` parameter is **optional**. The hook automatically gets the base client from `useUnifiedAuth()` provider layer. You should **NOT** pass a base client parameter - call `useSecureSupabase()` without arguments.
832
+
833
+ ### Acceptable Exceptions
834
+
835
+ **The ONLY acceptable use of `createClient()` in consuming app code is:**
836
+
837
+ 1. **Creating the base client for `UnifiedAuthProvider`** - This MUST be in one of these files:
838
+ - `src/main.tsx` (or `main.jsx`)
839
+ - `src/App.tsx` (or `App.jsx`)
840
+ - `src/lib/supabase.ts` (or `supabase.js`) - ONLY if this file is ONLY used to create the base client for the provider
841
+
842
+ **The file containing the base client creation MUST:**
843
+ - Be clearly named (e.g., `supabase.ts`, `main.tsx`)
844
+ - Only create the client once
845
+ - Pass it directly to `UnifiedAuthProvider` (not export it for general use)
846
+ - Include a comment explaining it's the base client for the provider:
847
+ ```tsx
848
+ // Base Supabase client for UnifiedAuthProvider only
849
+ // DO NOT use this client directly - use useSecureSupabase() instead
850
+ const supabase = createClient(...);
851
+ ```
852
+
853
+ **NO OTHER EXCEPTIONS ARE PERMITTED** - All other uses of `createClient()` are security violations and MUST be fixed.
854
+
855
+ ### Detection / Audit Tool
856
+
857
+ The audit tool (`npm run audit:pace-core`) performs comprehensive system-level analysis organized by standards:
858
+
859
+ - **Standard 1 (pace-core Compliance)**: Provider nesting, core styles import, RBAC setup, Vite aliases, secure Supabase client location, Cursor rules, ESLint config
860
+ - **Standard 2 (Project Structure)**: Directory structure, config files, import paths, test colocation, Supabase structure
861
+ - **Standard 3 (Architecture)**: Component boundaries, ApiResult usage
862
+ - **Standard 4 (Code Quality)**: TypeScript config, test coverage config
863
+ - **Standard 5 (Styling)**: app.css structure, Tailwind v4 config
864
+ - **Standard 6 (Security & RBAC)**: RLS policies, PagePermissionGuard coverage, Edge Functions RBAC
865
+ - **Standard 7 (API & Tech Stack)**: RPC naming in SQL, tech stack versions, Vite config
866
+ - **Standard 8 (Testing & Documentation)**: Test timeout config, testing tools, test structure
867
+ - **Standard 9 (Operations)**: Error handling patterns, CI/CD config, error boundaries
868
+
869
+ **Reference**: See [packages/core/audit-tool/](../../audit-tool/) for audit tool implementation.
870
+
871
+ ### Detection / Audit (Legacy)
872
+
873
+ - `rg "createClient\(" src` must return **exactly ONE match** in the file that creates the base client for `UnifiedAuthProvider`.
874
+ - That file MUST be one of: `main.tsx`, `App.tsx`, or `lib/supabase.ts` (or `.jsx`/`.js` equivalents).
875
+ - No `.from(` / `.rpc(` calls may be performed on an insecure client reference.
876
+ - All `useSecureSupabase()` calls should be without parameters.
877
+
878
+ ## Compliance Exceptions
879
+
880
+ **In general, pace-core compliance rules do NOT allow exceptions.** The rules are designed to ensure security, consistency, and maintainability across the PACE suite.
881
+
882
+ ### When Exceptions Are NOT Allowed
883
+
884
+ - **Security rules** (e.g., `createClient()` usage) - NO exceptions except the one documented above
885
+ - **RBAC rules** - NO exceptions
886
+ - **Component usage** - NO exceptions (use pace-core components)
887
+ - **Hook usage** - NO exceptions (use pace-core hooks)
888
+
889
+ ### Documenting Legitimate Edge Cases
890
+
891
+ If you encounter a situation where a rule seems to conflict with a legitimate requirement:
892
+
893
+ 1. **First**: Verify that pace-core doesn't provide a solution
894
+ 2. **Second**: Check if the requirement should be added to pace-core
895
+ 3. **Third**: If truly unavoidable, document the case clearly:
896
+ - Add a comment explaining why the exception is necessary
897
+ - Include a reference to this standard
898
+ - Consider opening an issue to add the missing functionality to pace-core
899
+
900
+ **Example of proper documentation:**
901
+ ```tsx
902
+ // @pace-core-compliance-exception: Legacy integration requires direct Supabase client
903
+ // Reason: Third-party service requires unauthenticated client for initial handshake
904
+ // Migration plan: Migrate to useSecureSupabase() when legacy system is updated (Q2 2025)
905
+ // Tracking issue: https://github.com/your-org/pace-core/issues/123
906
+ // Expected removal date: Q2 2025
907
+ const legacyClient = createClient(...);
908
+ ```
909
+
910
+ **Note**: Even with documentation, exceptions should be:
911
+ - Temporary (with a plan to remove them)
912
+ - Rare (only when absolutely necessary)
913
+ - Reviewed and approved by the team
914
+ - Tracked for eventual removal
915
+
916
+ ### Audit Handling of Exceptions
917
+
918
+ During audits, documented exceptions will be:
919
+ - **Verified** - Confirmed that the exception is legitimate and properly documented
920
+ - **Categorized** - Marked as "Acceptable Exception" if valid, or flagged for remediation if not
921
+ - **Tracked** - Included in the audit report with a recommendation to remove when possible
922
+
923
+ **Invalid exceptions** (undocumented, unnecessary, or security-related) will be flagged as violations requiring remediation.
924
+
925
+ ## Troubleshooting
926
+
927
+ ### ESLint Rules Not Working
928
+
929
+ 1. **Verify plugin is loaded**: Check that the config is imported correctly
930
+ 2. **Check rule names**: Rules must be prefixed with `pace-core-compliance/`
931
+ 3. **Verify manifest exists**: Rules load from `core-usage-manifest.json` in the pace-core package
932
+ 4. **CommonJS/ES Module issues**: If you're using ES modules and rules aren't loading, ensure you're using the config preset which handles this automatically
933
+ 5. **Verify rules are available**: Check that the rules file exists
934
+ 6. **Check rule count**: Verify all 15 rules are loaded
935
+
936
+ ### Static Analysis Script Errors
937
+
938
+ 1. **Manifest not found**: Ensure `core-usage-manifest.json` exists in pace-core package
939
+ 2. **No files scanned**: Check that you're running from the project root
940
+ 3. **Permission errors**: Ensure script has read access to source files
941
+
942
+ ### False Positives
943
+
944
+ If you encounter false positives:
945
+
946
+ 1. **Component name conflicts**: If you have a legitimate reason to create a local component with a pace-core name, consider:
947
+ - Renaming your component
948
+ - Using a namespace/prefix
949
+ - Documenting why pace-core doesn't meet your needs
950
+
951
+ 2. **Hook/Util patterns**: The pattern matching may flag similar names. Review the suggestion and decide if migration makes sense.
952
+
953
+ ## Verification
954
+
955
+ After setting up the ESLint config, verify it's working:
956
+
957
+ 1. **Check ESLint can load the config**:
958
+ ```bash
959
+ npx eslint --print-config src/App.tsx
960
+ ```
961
+ Look for `pace-core-compliance` in the plugins section.
962
+
963
+ 2. **Test with a violation**: Create a test file that imports a restricted library:
964
+ ```typescript
965
+ // test-violation.ts
966
+ import { Dialog } from '@radix-ui/react-dialog'; // Should trigger error
967
+ ```
968
+ Run ESLint and verify it reports the violation.
969
+
970
+ 3. **Run static analysis**: Use the compliance script to get a full report:
971
+ ```bash
972
+ npm run check:pace-core
973
+ ```
974
+
975
+ ## Related Documentation
976
+
977
+ - [Standards Overview](./0-standards-overview.md) - Standards system overview
978
+ - [Project Structure](./2-project-structure-standards.md) - Project structure and organization
979
+ - [Security & RBAC](./6-security-rbac-standards.md) - RBAC and security standards
980
+ - [API & Tech Stack](./7-api-tech-stack-standards.md) - API and tech stack standards
981
+
982
+ ---
983
+
984
+ **Last Updated:** 2025-01-28
985
+ **Version:** 2.0.0
986
+ **Applies to:** All consuming apps using `@jmruthers/pace-core`