@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
@@ -1,13 +1,43 @@
1
1
  ---
2
- description: Enforce SOLID architecture principles in consuming apps
2
+ description: Enforce SOLID architecture principles, component design, and API design patterns
3
3
  globs: ["src/**/*.{ts,tsx}"]
4
4
  alwaysApply: false
5
5
  paceCoreVersion: "0.6.x"
6
6
  rulesVersion: "2025-01-28"
7
7
  ---
8
- # SOLID Principles Guide
8
+ # Architecture Standards Guide
9
9
 
10
- This guide enforces SOLID architecture principles to ensure maintainable, extensible, and testable code.
10
+ **📚 Human-Readable Standard**: See [3-architecture-standards.md](../../packages/core/docs/standards/3-architecture-standards.md) for complete documentation.
11
+
12
+ This guide enforces SOLID architecture principles, component design patterns, and API design patterns to ensure maintainable, extensible, and testable code.
13
+
14
+ ## AI Agent Instructions
15
+
16
+ **When writing or modifying code, ALWAYS:**
17
+ 1. **Extract complex logic** - Move business logic out of components into hooks, services, or utilities
18
+ 2. **Use composition** - Extend functionality through composition, not modification of pace-core components
19
+ 3. **Keep components simple** - Components should only handle UI rendering, not data fetching or business logic
20
+ 4. **Use focused interfaces** - Create small, specific interfaces instead of large, generic ones
21
+ 5. **Depend on abstractions** - Use interfaces/types, not concrete implementations
22
+ 6. **Follow ApiResult pattern** - All RPCs must return ApiResult shape with proper error handling
23
+
24
+ **Decision Tree: Where should this logic live?**
25
+ ```
26
+ 1. What type of logic is this?
27
+ ├─ UI rendering → Component
28
+ ├─ Data fetching → Hook or service
29
+ ├─ Business logic → Hook, service, or utility
30
+ ├─ Formatting/transformation → Utility function
31
+ └─ Validation → Zod schema or utility
32
+
33
+ 2. Is this logic complex?
34
+ ├─ YES → Extract to hook/service/utility
35
+ └─ NO → Can stay in component if simple
36
+
37
+ 3. Does this modify pace-core behavior?
38
+ ├─ YES → Use composition (wrap pace-core component)
39
+ └─ NO → Continue
40
+ ```
11
41
 
12
42
  ## Single Responsibility Principle (SRP)
13
43
 
@@ -204,17 +234,103 @@ Before committing code, verify:
204
234
  - [ ] No god objects or bloated components
205
235
  - [ ] Code is testable and maintainable
206
236
 
207
- ## Anti-Patterns to Avoid
237
+ ## Common Mistakes to Avoid
238
+
239
+ **When writing code, NEVER:**
240
+ 1. **Create god objects** - Components/classes that do too much
241
+ ```tsx
242
+ // ❌ WRONG: Component does everything
243
+ function UserDashboard({ userId }) {
244
+ const [user, setUser] = useState(null);
245
+ const [events, setEvents] = useState([]);
246
+ const [organisations, setOrganisations] = useState([]);
247
+ // 200+ lines of logic...
248
+ }
249
+
250
+ // ✅ CORRECT: Separated concerns
251
+ function UserDashboard({ userId }) {
252
+ const user = useUser(userId);
253
+ const events = useUserEvents(userId);
254
+ const organisations = useUserOrganisations(userId);
255
+ return <DashboardContent user={user} events={events} organisations={organisations} />;
256
+ }
257
+ ```
258
+
259
+ 2. **Put business logic in components** - Extract to hooks/services
260
+ 3. **Create large interfaces** - Use focused, specific interfaces
261
+ 4. **Depend on concrete implementations** - Use abstractions (interfaces/types)
262
+ 5. **Modify pace-core components** - Use composition instead
263
+ 6. **Use boolean flags for states** - Use discriminated unions
264
+
265
+ ## API Design Patterns
266
+
267
+ ### MUST: Follow API Design Principles
268
+
269
+ **APIs MUST be:**
270
+ - Intuitive and consistent
271
+ - Extensible without breaking changes
272
+ - Clear about errors and edge cases
273
+
274
+ ### MUST: Use ApiResult Pattern
275
+
276
+ **All RPCs MUST return ApiResult shape:**
277
+
278
+ ```typescript
279
+ type ApiResult<T> = { ok: true; data: T } | { ok: false; error: ApiError };
280
+ type ApiError = { code: string; message: string; details?: object };
281
+ ```
282
+
283
+ ```tsx
284
+ // ✅ CORRECT: RPC returns ApiResult
285
+ const result = await supabase.rpc('app_events_create', { name, date });
286
+ if (!result.ok) {
287
+ // Handle error
288
+ return { ok: false, error: result.error };
289
+ }
290
+ return { ok: true, data: result.data };
291
+ ```
292
+
293
+ ### SHOULD: Make Write RPCs Idempotent
294
+
295
+ **Write RPCs SHOULD be idempotent when possible:**
296
+
297
+ ```sql
298
+ -- ✅ CORRECT: Idempotent create (ON CONFLICT DO NOTHING)
299
+ INSERT INTO events (id, name, date)
300
+ VALUES (p_event_id, p_name, p_date)
301
+ ON CONFLICT (id) DO NOTHING;
302
+ ```
303
+
304
+ ## Component Design Patterns
305
+
306
+ ### MUST: Follow Component Principles
208
307
 
209
- 1. **God Objects** - Classes/components that do too much
210
- 2. **Feature Envy** - Functions that use more of another object than their own
211
- 3. **Data Clumps** - Groups of data that should be objects
212
- 4. **Long Parameter Lists** - Use objects/interfaces instead
213
- 5. **Divergent Change** - One class changed for multiple reasons
214
- 6. **Shotgun Surgery** - One change requires many class modifications
308
+ **Components MUST:**
309
+ - Be stateless when possible
310
+ - Use composable structure
311
+ - Be accessible by default
312
+ - Be fully typed
313
+ - Have small surface area
314
+
315
+ ### MUST NOT: Add Domain Logic to Components
316
+
317
+ **Components MUST NOT:**
318
+ - Include domain-specific logic
319
+ - Fetch data directly (use hooks/services)
320
+ - Include business workflows
321
+
322
+ ### MUST: Ensure Accessibility
323
+
324
+ **Components MUST:**
325
+ - Be keyboard operable
326
+ - Have correct ARIA roles
327
+ - Have visible focus states
328
+ - Avoid inaccessible interactions
215
329
 
216
330
  ## Reference
217
331
 
332
+ **Note**: RLS policy validation is handled by the audit tool. See [3-architecture-standards.md](../../packages/core/docs/standards/3-architecture-standards.md) for complete enforcement details.
333
+
218
334
  - Single Responsibility: Each module has one reason to change
219
335
  - Open/Closed: Open for extension, closed for modification
220
336
  - Liskov Substitution: Subtypes must be substitutable
@@ -0,0 +1,419 @@
1
+ ---
2
+ description: Enforce code quality standards including TypeScript, ESLint, formatting, performance, and accessibility
3
+ globs: ["src/**/*.{ts,tsx,js,jsx}"]
4
+ alwaysApply: false
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
+ ---
8
+ # Code Quality Guide
9
+
10
+ **📚 Human-Readable Standard**: See [4-code-quality-standards.md](../../packages/core/docs/standards/4-code-quality-standards.md) for complete documentation.
11
+
12
+ This guide enforces code quality standards to ensure maintainable, performant, and accessible code.
13
+
14
+ ## AI Agent Instructions
15
+
16
+ **When writing or modifying code, ALWAYS:**
17
+ 1. **Use strict TypeScript** - Never use `any`, always use proper types or `unknown` with type guards
18
+ 2. **Use discriminated unions** - Replace boolean flags with discriminated unions for better type safety
19
+ 3. **Use ReadonlyArray** - Use `ReadonlyArray` for immutable arrays
20
+ 4. **Ensure accessibility** - All components must be keyboard accessible, have ARIA labels, and visible focus states
21
+ 5. **Use semantic HTML** - Use semantic elements (`<main>`, `<section>`, `<article>`, etc.) instead of `<div>` wrappers
22
+ 6. **Memoize appropriately** - Use `useMemo` and `useCallback` for expensive computations and stable references
23
+ 7. **Early returns** - Use early returns to reduce nesting and improve readability
24
+
25
+ **Decision Tree: Type Safety**
26
+ ```
27
+ 1. What type should I use?
28
+ ├─ Known structure → Interface or type
29
+ ├─ Truly unknown → unknown (with type guard)
30
+ └─ Multiple variants → Discriminated union (not boolean flags)
31
+
32
+ 2. Is this an array that shouldn't be mutated?
33
+ ├─ YES → ReadonlyArray<T>
34
+ └─ NO → Array<T> or T[]
35
+
36
+ 3. Do I need multiple states?
37
+ ├─ YES → Discriminated union (type: 'loading' | 'success' | 'error')
38
+ └─ NO → Single type
39
+ ```
40
+
41
+ ## TypeScript Standards
42
+
43
+ ### MUST: Use Strict Mode
44
+
45
+ **TypeScript MUST use strict mode:**
46
+
47
+ ```json
48
+ // tsconfig.json
49
+ {
50
+ "compilerOptions": {
51
+ "strict": true,
52
+ "noImplicitAny": true,
53
+ "strictNullChecks": true,
54
+ "strictFunctionTypes": true,
55
+ "strictBindCallApply": true,
56
+ "strictPropertyInitialization": true,
57
+ "noImplicitThis": true,
58
+ "alwaysStrict": true
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### MUST NOT: Use `any`
64
+
65
+ **MUST NOT use `any` type. Use `unknown` if type is truly unknown:**
66
+
67
+ ```tsx
68
+ // ❌ WRONG: Using any
69
+ function processData(data: any) { return data.value; }
70
+
71
+ // ✅ CORRECT: Using unknown with type guard or proper types
72
+ function processData(data: unknown) {
73
+ if (typeof data === 'object' && data !== null && 'value' in data) {
74
+ return (data as { value: string }).value;
75
+ }
76
+ throw new Error('Invalid data');
77
+ }
78
+ // Or: interface Data { value: string; } function processData(data: Data) { return data.value; }
79
+ ```
80
+
81
+ ### MUST: Use Discriminated Unions
82
+
83
+ **MUST use discriminated unions instead of boolean flags:**
84
+
85
+ ```tsx
86
+ // ❌ WRONG: Boolean flags (confusing: what if both are true?)
87
+ interface User { isAdmin: boolean; isGuest: boolean; }
88
+
89
+ // ✅ CORRECT: Discriminated union
90
+ type User = { type: 'admin'; permissions: Permission[] } | { type: 'guest'; limitedAccess: boolean } | { type: 'user'; role: UserRole };
91
+ ```
92
+
93
+ ### SHOULD: Use ReadonlyArray
94
+
95
+ **SHOULD use ReadonlyArray for immutable arrays:**
96
+
97
+ ```tsx
98
+ // ✅ CORRECT - ReadonlyArray
99
+ function processItems(items: ReadonlyArray<Item>) {
100
+ // Can't mutate items
101
+ return items.map(item => transform(item));
102
+ }
103
+ ```
104
+
105
+ ## ESLint Configuration
106
+
107
+ **Note**: ESLint configuration and enforcement is handled by ESLint (Layer 3). See [4-code-quality-standards.md](../../packages/core/docs/standards/4-code-quality-standards.md) for complete ESLint setup instructions.
108
+
109
+ **MUST:**
110
+ - Use pace-core ESLint config
111
+ - Fix all ESLint errors before committing
112
+ - Run `npm run lint` before committing
113
+
114
+ ## Code Formatting
115
+
116
+ ### MUST: Use Consistent Formatting
117
+
118
+ **MUST use Prettier or equivalent for consistent formatting:**
119
+
120
+ ```json
121
+ // .prettierrc
122
+ {
123
+ "semi": true,
124
+ "singleQuote": true,
125
+ "tabWidth": 2,
126
+ "trailingComma": "es5",
127
+ "printWidth": 100
128
+ }
129
+ ```
130
+
131
+ ### MUST: Format Before Committing
132
+
133
+ **MUST format code before committing:**
134
+
135
+ ```bash
136
+ npm run format
137
+ # Or use pre-commit hook
138
+ ```
139
+
140
+ ## Performance Considerations
141
+
142
+ ### SHOULD: Optimize Re-renders
143
+
144
+ **SHOULD use React.memo, useMemo, useCallback appropriately:**
145
+
146
+ ```tsx
147
+ // ✅ CORRECT: Memoize expensive computations, callbacks, and components
148
+ const expensiveValue = useMemo(() => computeExpensiveValue(data), [data]);
149
+ const handleClick = useCallback(() => doSomething(id), [id]);
150
+ const ExpensiveComponent = React.memo(({ data }) => <div>{/* ... */}</div>);
151
+ ```
152
+
153
+ ### SHOULD: Avoid Unnecessary Re-renders
154
+
155
+ **SHOULD avoid causing unnecessary re-renders:**
156
+
157
+ ```tsx
158
+ // ❌ WRONG: New object on every render (causes unnecessary re-renders)
159
+ function Component({ items }) { const config = { items, enabled: true }; return <Child config={config} />; }
160
+
161
+ // ✅ CORRECT: Memoize object
162
+ function Component({ items }) {
163
+ const config = useMemo(() => ({ items, enabled: true }), [items]);
164
+ return <Child config={config} />;
165
+ }
166
+ ```
167
+
168
+ ### SHOULD: Lazy Load Heavy Components
169
+
170
+ **SHOULD lazy load heavy components:**
171
+
172
+ ```tsx
173
+ // ✅ CORRECT: Lazy load heavy components
174
+ import { lazy, Suspense } from 'react';
175
+ const HeavyComponent = lazy(() => import('./HeavyComponent'));
176
+ function App() {
177
+ return <Suspense fallback={<Loading />}><HeavyComponent /></Suspense>;
178
+ }
179
+ ```
180
+
181
+ ## Accessibility Requirements
182
+
183
+ **MUST** ensure all components and pages meet WCAG 2.1 Level AA standards.
184
+
185
+ ### Core Principles
186
+
187
+ 1. **Semantic HTML** - Use semantic elements (`<main>`, `<section>`, `<article>`, `<nav>`, etc.) instead of `<div>` wrappers
188
+ 2. **Keyboard Navigation** - All interactive elements must be accessible via keyboard
189
+ 3. **ARIA Labels** - Provide clear labels for screen readers when visible text isn't sufficient
190
+ 4. **Focus Management** - Visible focus indicators on all interactive elements
191
+ 5. **Color Contrast** - Text must meet 4.5:1 contrast ratio (WCAG AA)
192
+
193
+ ### Implementation Requirements
194
+
195
+ ```tsx
196
+ // ✅ CORRECT - Semantic HTML with ARIA
197
+ <main>
198
+ <h1>Page Title</h1>
199
+ <section aria-labelledby="section-title">
200
+ <h2 id="section-title">Section Title</h2>
201
+ <Button
202
+ aria-label="Delete user"
203
+ aria-describedby="delete-help"
204
+ >
205
+ Delete
206
+ </Button>
207
+ <span id="delete-help" className="sr-only">
208
+ Permanently removes the user account
209
+ </span>
210
+ </section>
211
+ </main>
212
+
213
+ // ❌ WRONG - Non-semantic structure
214
+ <div>
215
+ <div className="title">Page Title</div>
216
+ <div>
217
+ <button>Delete</button>
218
+ </div>
219
+ </div>
220
+ ```
221
+
222
+ ### Keyboard Navigation
223
+
224
+ **MUST** ensure all interactive elements are keyboard accessible:
225
+
226
+ ```tsx
227
+ // ✅ CORRECT - pace-core components handle keyboard navigation automatically
228
+ import { Button, DataTable } from '@jmruthers/pace-core';
229
+
230
+ <Button onClick={handleClick}>Click me</Button>
231
+ <DataTable data={data} columns={columns} />
232
+ ```
233
+
234
+ ### Screen Reader Support
235
+
236
+ **MUST** provide appropriate ARIA attributes:
237
+
238
+ ```tsx
239
+ // ✅ CORRECT - ARIA labels for icons
240
+ <Button aria-label="Close dialog">
241
+ <Icon name="x" aria-hidden="true" />
242
+ </Button>
243
+
244
+ // ✅ CORRECT - Error messages with role="alert"
245
+ {error && (
246
+ <div role="alert" aria-live="polite">
247
+ {error.message}
248
+ </div>
249
+ )}
250
+
251
+ // ✅ CORRECT - Loading states
252
+ <div role="status" aria-live="polite" aria-busy={loading}>
253
+ {loading && <span className="sr-only">Loading data...</span>}
254
+ {loading ? <Spinner /> : <Content />}
255
+ </div>
256
+ ```
257
+
258
+ ### Testing Accessibility
259
+
260
+ **MUST** test with:
261
+ - Keyboard navigation (Tab, Enter, Space, Arrow keys)
262
+ - Screen readers (NVDA, JAWS, VoiceOver)
263
+ - Automated tools (axe DevTools, WAVE, Lighthouse)
264
+
265
+ **Accessibility Checklist:**
266
+ - [ ] All interactive elements keyboard accessible
267
+ - [ ] Visible focus indicators on all interactive elements
268
+ - [ ] ARIA labels provided for icons and images
269
+ - [ ] Semantic HTML used appropriately
270
+ - [ ] Error messages properly associated with form fields
271
+ - [ ] Color contrast meets WCAG AA (4.5:1 for text)
272
+ - [ ] Screen reader announcements work correctly
273
+ - [ ] Focus management in modals and dynamic content
274
+
275
+ ## Code Review Checklist
276
+
277
+ **Before submitting code for review, verify:**
278
+
279
+ - [ ] TypeScript strict mode enabled
280
+ - [ ] No `any` types used
281
+ - [ ] ESLint passes with no errors
282
+ - [ ] Code is formatted consistently
283
+ - [ ] Performance optimizations applied where needed
284
+ - [ ] Accessibility requirements met
285
+ - [ ] Semantic HTML used
286
+ - [ ] ARIA labels provided
287
+ - [ ] Keyboard navigation works
288
+ - [ ] Focus indicators visible
289
+ - [ ] Code is readable and maintainable
290
+ - [ ] Comments explain "why", not "what"
291
+
292
+ ## Code Complexity
293
+
294
+ ### SHOULD: Keep Functions Small
295
+
296
+ **Functions SHOULD be small and focused:**
297
+
298
+ ```tsx
299
+ // ❌ WRONG: Large function (100+ lines, multiple responsibilities)
300
+ function processUserData(user) { /* 100+ lines of logic */ }
301
+
302
+ // ✅ CORRECT: Small, focused functions
303
+ function validateUser(user: User): ValidationResult { /* Validation logic */ }
304
+ function transformUser(user: User): TransformedUser { /* Transformation logic */ }
305
+ function processUserData(user: User) {
306
+ const validation = validateUser(user);
307
+ if (!validation.valid) return validation;
308
+ return transformUser(user);
309
+ }
310
+ ```
311
+
312
+ ### SHOULD: Limit Cyclomatic Complexity
313
+
314
+ **Functions SHOULD have low cyclomatic complexity (< 10):**
315
+
316
+ ```tsx
317
+ // ❌ WRONG: High complexity (many nested conditions)
318
+ function processData(data) { if (condition1) { if (condition2) { if (condition3) { /* ... */ } } } }
319
+
320
+ // ✅ CORRECT: Lower complexity (early returns)
321
+ function processData(data) { if (!condition1) return; if (!condition2) return; if (!condition3) return; /* Process */ }
322
+ ```
323
+
324
+ ## Error Handling
325
+
326
+ ### MUST: Handle Errors Gracefully
327
+
328
+ **MUST handle errors and provide user feedback:**
329
+
330
+ ```tsx
331
+ // ✅ CORRECT: Handle errors gracefully with user feedback
332
+ try {
333
+ const data = await fetchData();
334
+ setData(data);
335
+ } catch (error) {
336
+ logger.error('Failed to fetch data', error);
337
+ toast.error('Failed to load data. Please try again.');
338
+ }
339
+ ```
340
+
341
+ ### MUST: Use Type-Safe Error Handling
342
+
343
+ **MUST use type-safe error handling:**
344
+
345
+ ```tsx
346
+ // ✅ CORRECT: Type-safe error handling
347
+ function isApiError(error: unknown): error is ApiError {
348
+ return typeof error === 'object' && error !== null && 'code' in error && 'message' in error;
349
+ }
350
+ try {
351
+ await apiCall();
352
+ } catch (error) {
353
+ if (isApiError(error)) handleApiError(error);
354
+ else handleUnknownError(error);
355
+ }
356
+ ```
357
+
358
+ ## Common Mistakes to Avoid
359
+
360
+ **When writing code, NEVER:**
361
+ 1. **Use `any` type** - Always use proper types or `unknown` with type guards
362
+ ```tsx
363
+ // ❌ WRONG
364
+ function process(data: any) {
365
+ return data.value;
366
+ }
367
+
368
+ // ✅ CORRECT
369
+ function process(data: unknown) {
370
+ if (typeof data === 'object' && data !== null && 'value' in data) {
371
+ return (data as { value: string }).value;
372
+ }
373
+ throw new Error('Invalid data');
374
+ }
375
+ ```
376
+
377
+ 2. **Use boolean flags for multiple states** - Use discriminated unions
378
+ ```tsx
379
+ // ❌ WRONG
380
+ interface User { isAdmin: boolean; isGuest: boolean; }
381
+
382
+ // ✅ CORRECT
383
+ type User =
384
+ | { type: 'admin'; permissions: Permission[] }
385
+ | { type: 'guest'; limitedAccess: boolean }
386
+ | { type: 'user'; role: UserRole };
387
+ ```
388
+
389
+ 3. **Forget accessibility** - Always ensure keyboard navigation, ARIA labels, and semantic HTML
390
+ 4. **Create mutable arrays when they shouldn't change** - Use `ReadonlyArray`
391
+ 5. **Skip memoization for expensive operations** - Use `useMemo` and `useCallback` appropriately
392
+
393
+ ## Code Quality Checklist
394
+
395
+ Before committing, verify:
396
+ - [ ] TypeScript strict mode enabled
397
+ - [ ] No `any` types (use `unknown` with type guards)
398
+ - [ ] Discriminated unions used instead of boolean flags
399
+ - [ ] `ReadonlyArray` used for immutable arrays
400
+ - [ ] Naming conventions followed (hooks: `use*`, providers: `*Provider`, etc.)
401
+ - [ ] Pure functions preferred (no side effects)
402
+ - [ ] Early returns used to reduce nesting
403
+ - [ ] Complex logic extracted to helpers
404
+ - [ ] Components are small and focused
405
+ - [ ] Functional components only (no class components)
406
+ - [ ] Hook dependencies are complete
407
+ - [ ] Memoization used when appropriate
408
+ - [ ] Accessibility requirements met (WCAG 2.1 AA)
409
+ - [ ] Keyboard navigation supported
410
+ - [ ] ARIA labels provided where needed
411
+ - [ ] Semantic HTML used appropriately
412
+
413
+ ## Reference
414
+
415
+ **Note**: ESLint configuration details and mechanical type checking are handled by ESLint (Layer 3). See [4-code-quality-standards.md](../../packages/core/docs/standards/4-code-quality-standards.md) for complete enforcement details.
416
+
417
+ - TypeScript Handbook: https://www.typescriptlang.org/docs/
418
+ - React Performance: https://react.dev/learn/render-and-commit
419
+ - Web Accessibility: https://www.w3.org/WAI/