@jmruthers/pace-core 0.6.4 → 0.6.6

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 (387) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/core-usage-manifest.json +93 -0
  4. package/cursor-rules/00-pace-core-compliance.mdc +128 -26
  5. package/cursor-rules/01-standards-compliance.mdc +49 -8
  6. package/cursor-rules/02-project-structure.mdc +6 -0
  7. package/cursor-rules/03-solid-principles.mdc +2 -0
  8. package/cursor-rules/04-testing-standards.mdc +2 -0
  9. package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
  10. package/cursor-rules/06-code-quality.mdc +2 -0
  11. package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
  12. package/cursor-rules/08-markup-quality.mdc +52 -27
  13. package/cursor-rules/09-rbac-compliance.mdc +462 -0
  14. package/cursor-rules/10-error-handling-patterns.mdc +179 -0
  15. package/cursor-rules/11-performance-optimization.mdc +169 -0
  16. package/cursor-rules/12-ci-cd-integration.mdc +150 -0
  17. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  18. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
  19. package/dist/DataTable-LRJL4IRV.js +15 -0
  20. package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
  21. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  22. package/dist/api-Y4MQWOFW.js +4 -0
  23. package/dist/audit-MYQXYZFU.js +3 -0
  24. package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
  25. package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
  26. package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
  27. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  28. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  29. package/dist/chunk-4T7OBVTU.js +62 -0
  30. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  31. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  32. package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
  33. package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
  34. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  35. package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
  36. package/dist/chunk-C7NSAPTL.js +1 -0
  37. package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
  38. package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
  39. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  40. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  41. package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
  42. package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
  43. package/dist/chunk-MBADTM7L.js +64 -0
  44. package/dist/chunk-OHIK3MIO.js +994 -0
  45. package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
  46. package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
  47. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  48. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  49. package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
  50. package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
  51. package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
  52. package/dist/components.d.ts +6 -6
  53. package/dist/components.js +57 -267
  54. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  55. package/dist/eslint-rules/index.cjs +22 -0
  56. package/dist/eslint-rules/rules/compliance.cjs +348 -0
  57. package/dist/eslint-rules/rules/components.cjs +113 -0
  58. package/dist/eslint-rules/rules/imports.cjs +102 -0
  59. package/dist/eslint-rules/rules/rbac.cjs +790 -0
  60. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  61. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  62. package/dist/hooks.d.ts +5 -5
  63. package/dist/hooks.js +62 -270
  64. package/dist/icons/index.d.ts +1 -0
  65. package/dist/icons/index.js +1 -0
  66. package/dist/index.d.ts +36 -26
  67. package/dist/index.js +87 -690
  68. package/dist/providers.d.ts +2 -2
  69. package/dist/providers.js +8 -35
  70. package/dist/rbac/eslint-rules.d.ts +46 -44
  71. package/dist/rbac/eslint-rules.js +7 -4
  72. package/dist/rbac/index.d.ts +124 -594
  73. package/dist/rbac/index.js +14 -207
  74. package/dist/styles/index.js +2 -12
  75. package/dist/theming/runtime.js +3 -19
  76. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  77. package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
  78. package/dist/types-t9H8qKRw.d.ts +55 -0
  79. package/dist/types.d.ts +1 -1
  80. package/dist/types.js +7 -94
  81. package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
  82. package/dist/utils.d.ts +24 -117
  83. package/dist/utils.js +54 -392
  84. package/docs/README.md +16 -6
  85. package/docs/api/README.md +4 -402
  86. package/docs/api/modules.md +454 -930
  87. package/docs/api-reference/components.md +3 -1
  88. package/docs/api-reference/deprecated.md +31 -6
  89. package/docs/api-reference/rpc-functions.md +78 -3
  90. package/docs/best-practices/accessibility.md +6 -3
  91. package/docs/getting-started/cursor-rules.md +3 -23
  92. package/docs/getting-started/dependencies.md +650 -0
  93. package/docs/getting-started/installation-guide.md +20 -7
  94. package/docs/getting-started/quick-start.md +23 -12
  95. package/docs/implementation-guides/permission-enforcement.md +4 -0
  96. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  97. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  98. package/docs/rbac/README.md +12 -3
  99. package/docs/rbac/edge-functions-guide.md +376 -0
  100. package/docs/rbac/secure-client-protection.md +0 -34
  101. package/docs/standards/00-pace-core-compliance.md +967 -0
  102. package/docs/standards/01-standards-compliance.md +188 -0
  103. package/docs/standards/02-project-structure.md +985 -0
  104. package/docs/standards/03-solid-principles.md +39 -0
  105. package/docs/standards/04-testing-standards.md +36 -0
  106. package/docs/standards/05-bug-reports-and-features.md +27 -0
  107. package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
  108. package/docs/standards/07-tech-stack-compliance.md +30 -0
  109. package/docs/standards/08-markup-quality.md +345 -0
  110. package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
  111. package/docs/standards/10-error-handling-patterns.md +401 -0
  112. package/docs/standards/11-performance-optimization.md +348 -0
  113. package/docs/standards/12-ci-cd-integration.md +370 -0
  114. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
  115. package/docs/standards/README.md +62 -33
  116. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  117. package/eslint-config-pace-core.cjs +20 -4
  118. package/package.json +31 -21
  119. package/scripts/audit/audit-compliance.cjs +1295 -0
  120. package/scripts/audit/audit-components.cjs +260 -0
  121. package/scripts/audit/audit-dependencies.cjs +395 -0
  122. package/scripts/audit/audit-rbac.cjs +954 -0
  123. package/scripts/audit/audit-standards.cjs +1268 -0
  124. package/scripts/audit/index.cjs +1898 -194
  125. package/scripts/install-cursor-rules.cjs +259 -8
  126. package/scripts/validate-master.js +1 -1
  127. package/src/__tests__/fixtures/supabase.ts +1 -1
  128. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
  129. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  130. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  131. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
  132. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  133. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  134. package/src/__tests__/public-recipe-view.test.ts +38 -9
  135. package/src/components/Button/Button.tsx +5 -1
  136. package/src/components/ContextSelector/ContextSelector.tsx +42 -39
  137. package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
  138. package/src/components/DataTable/components/DataTableBody.tsx +55 -31
  139. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  140. package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
  141. package/src/components/DataTable/components/EditFields.tsx +23 -3
  142. package/src/components/DataTable/components/EditableRow.tsx +7 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +4 -6
  144. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  145. package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
  146. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
  147. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
  148. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  149. package/src/components/DataTable/core/DataTableContext.tsx +1 -1
  150. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  151. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  152. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  153. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  154. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  155. package/src/components/DataTable/types.ts +5 -0
  156. package/src/components/DateTimeField/DateTimeField.tsx +20 -20
  157. package/src/components/DateTimeField/README.md +5 -2
  158. package/src/components/Dialog/Dialog.test.tsx +361 -318
  159. package/src/components/Dialog/Dialog.tsx +1154 -323
  160. package/src/components/Dialog/index.ts +3 -3
  161. package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
  162. package/src/components/FileDisplay/FileDisplay.tsx +28 -22
  163. package/src/components/Form/Form.test.tsx +9 -10
  164. package/src/components/Form/Form.tsx +369 -9
  165. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
  166. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
  167. package/src/components/LoginForm/LoginForm.tsx +2 -2
  168. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  169. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
  170. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  171. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  172. package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
  173. package/src/components/PaceAppLayout/README.md +10 -9
  174. package/src/components/PaceAppLayout/test-setup.tsx +40 -31
  175. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  176. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  177. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
  178. package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
  179. package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
  180. package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
  181. package/src/components/Select/Select.tsx +23 -21
  182. package/src/components/Select/types.ts +1 -1
  183. package/src/components/UserMenu/UserMenu.test.tsx +38 -6
  184. package/src/components/UserMenu/UserMenu.tsx +39 -34
  185. package/src/components/index.ts +3 -4
  186. package/src/eslint-rules/index.cjs +22 -0
  187. package/src/eslint-rules/rules/compliance.cjs +348 -0
  188. package/src/eslint-rules/rules/components.cjs +113 -0
  189. package/src/eslint-rules/rules/imports.cjs +102 -0
  190. package/src/eslint-rules/rules/rbac.cjs +790 -0
  191. package/src/eslint-rules/utils/helpers.cjs +42 -0
  192. package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
  193. package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
  194. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  195. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  196. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  197. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  198. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  199. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  200. package/src/hooks/public/usePublicEvent.ts +62 -190
  201. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  202. package/src/hooks/public/usePublicEventLogo.ts +19 -9
  203. package/src/hooks/useAppConfig.ts +26 -24
  204. package/src/hooks/useEventTheme.test.ts +211 -233
  205. package/src/hooks/useEventTheme.ts +19 -28
  206. package/src/hooks/useEvents.ts +11 -7
  207. package/src/hooks/useKeyboardShortcuts.ts +1 -1
  208. package/src/hooks/useOrganisationPermissions.ts +9 -11
  209. package/src/hooks/useOrganisations.ts +13 -7
  210. package/src/hooks/useQueryCache.ts +0 -1
  211. package/src/hooks/useSessionDraft.ts +380 -0
  212. package/src/hooks/useSessionRestoration.ts +3 -1
  213. package/src/icons/index.ts +27 -0
  214. package/src/index.ts +16 -1
  215. package/src/providers/OrganisationProvider.tsx +23 -14
  216. package/src/providers/services/EventServiceProvider.tsx +1 -24
  217. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  218. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
  219. package/src/rbac/README.md +20 -20
  220. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  221. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  222. package/src/rbac/adapters.tsx +7 -295
  223. package/src/rbac/api.test.ts +44 -56
  224. package/src/rbac/api.ts +10 -17
  225. package/src/rbac/cache-invalidation.ts +0 -1
  226. package/src/rbac/compliance/index.ts +10 -0
  227. package/src/rbac/compliance/pattern-detector.ts +553 -0
  228. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  229. package/src/rbac/components/AccessDenied.tsx +150 -0
  230. package/src/rbac/components/NavigationGuard.tsx +12 -20
  231. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  232. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  233. package/src/rbac/components/index.ts +3 -41
  234. package/src/rbac/eslint-rules.js +1 -1
  235. package/src/rbac/hooks/index.ts +0 -3
  236. package/src/rbac/hooks/permissions/index.ts +0 -3
  237. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  238. package/src/rbac/hooks/usePermissions.ts +0 -3
  239. package/src/rbac/hooks/useRBAC.test.ts +21 -3
  240. package/src/rbac/hooks/useRBAC.ts +4 -3
  241. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  242. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  243. package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
  244. package/src/rbac/hooks/useResourcePermissions.ts +182 -63
  245. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  246. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  247. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  248. package/src/rbac/index.ts +7 -9
  249. package/src/rbac/permissions.ts +17 -17
  250. package/src/rbac/utils/contextValidator.ts +45 -7
  251. package/src/services/AuthService.ts +132 -23
  252. package/src/services/EventService.ts +4 -97
  253. package/src/services/InactivityService.ts +155 -58
  254. package/src/services/OrganisationService.ts +7 -44
  255. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  256. package/src/services/base/BaseService.ts +0 -3
  257. package/src/styles/core.css +4 -0
  258. package/src/types/database.generated.ts +4733 -3809
  259. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  260. package/src/utils/context/organisationContext.test.ts +13 -28
  261. package/src/utils/context/organisationContext.ts +21 -52
  262. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  263. package/src/utils/file-reference/index.ts +39 -15
  264. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  265. package/src/utils/formatting/formatTime.test.ts +3 -2
  266. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  267. package/src/utils/index.ts +4 -1
  268. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  269. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  270. package/src/utils/persistence/keyDerivation.ts +304 -0
  271. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  272. package/src/utils/security/secureStorage.ts +5 -5
  273. package/src/utils/storage/helpers.ts +3 -3
  274. package/src/utils/supabase/createBaseClient.ts +147 -0
  275. package/src/utils/timezone/timezone.test.ts +1 -2
  276. package/src/utils/timezone/timezone.ts +1 -1
  277. package/src/utils/validation/csrf.ts +4 -4
  278. package/cursor-rules/CHANGELOG.md +0 -119
  279. package/cursor-rules/README.md +0 -192
  280. package/dist/DataTable-E7YQZD7D.js +0 -175
  281. package/dist/DataTable-E7YQZD7D.js.map +0 -1
  282. package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
  283. package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
  284. package/dist/api-6LVZTHDS.js +0 -52
  285. package/dist/api-6LVZTHDS.js.map +0 -1
  286. package/dist/audit-V53FV5AG.js +0 -17
  287. package/dist/audit-V53FV5AG.js.map +0 -1
  288. package/dist/chunk-36LVWXB2.js +0 -227
  289. package/dist/chunk-36LVWXB2.js.map +0 -1
  290. package/dist/chunk-3LPHPB62.js.map +0 -1
  291. package/dist/chunk-5DRSZLL2.js.map +0 -1
  292. package/dist/chunk-5EC5MEWX.js.map +0 -1
  293. package/dist/chunk-63FOKYGO.js.map +0 -1
  294. package/dist/chunk-6SOIHG6Z.js.map +0 -1
  295. package/dist/chunk-7JPAB3T5.js.map +0 -1
  296. package/dist/chunk-ATKZM7RX.js +0 -2053
  297. package/dist/chunk-ATKZM7RX.js.map +0 -1
  298. package/dist/chunk-AVMLPIM7.js.map +0 -1
  299. package/dist/chunk-DGUM43GV.js.map +0 -1
  300. package/dist/chunk-E66EQZE6.js.map +0 -1
  301. package/dist/chunk-FFQEQTNW.js.map +0 -1
  302. package/dist/chunk-FMUCXFII.js.map +0 -1
  303. package/dist/chunk-G37KK66H.js.map +0 -1
  304. package/dist/chunk-I6DAQMWX.js.map +0 -1
  305. package/dist/chunk-J36DSWQK.js.map +0 -1
  306. package/dist/chunk-KQCRWDSA.js +0 -1
  307. package/dist/chunk-KQCRWDSA.js.map +0 -1
  308. package/dist/chunk-L4OXEN46.js.map +0 -1
  309. package/dist/chunk-LMC26NLJ.js +0 -84
  310. package/dist/chunk-LMC26NLJ.js.map +0 -1
  311. package/dist/chunk-M43Y4SSO.js.map +0 -1
  312. package/dist/chunk-M7MPQISP.js.map +0 -1
  313. package/dist/chunk-NN6WWZ5U.js.map +0 -1
  314. package/dist/chunk-OEWDTMG7.js.map +0 -1
  315. package/dist/chunk-PWLANIRT.js.map +0 -1
  316. package/dist/chunk-QXHPKYJV.js.map +0 -1
  317. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  318. package/dist/chunk-YKRAFF5K.js.map +0 -1
  319. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  320. package/dist/components.js.map +0 -1
  321. package/dist/contextValidator-OOPCLPZW.js +0 -9
  322. package/dist/contextValidator-OOPCLPZW.js.map +0 -1
  323. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  324. package/dist/hooks.js.map +0 -1
  325. package/dist/index.js.map +0 -1
  326. package/dist/providers.js.map +0 -1
  327. package/dist/rbac/eslint-rules.js.map +0 -1
  328. package/dist/rbac/index.js.map +0 -1
  329. package/dist/styles/index.js.map +0 -1
  330. package/dist/theming/runtime.js.map +0 -1
  331. package/dist/types.js.map +0 -1
  332. package/dist/utils.js.map +0 -1
  333. package/docs/standards/01-architecture-standard.md +0 -44
  334. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  335. package/docs/standards/03-component-standard.md +0 -32
  336. package/docs/standards/05-security-standard.md +0 -44
  337. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  338. package/docs/standards/pace-core-compliance.md +0 -432
  339. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  340. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  341. package/scripts/audit/core/checks/bundle.cjs +0 -142
  342. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  343. package/scripts/audit/core/checks/config.cjs +0 -54
  344. package/scripts/audit/core/checks/coverage.cjs +0 -84
  345. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  346. package/scripts/audit/core/checks/documentation.cjs +0 -268
  347. package/scripts/audit/core/checks/environment.cjs +0 -116
  348. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  349. package/scripts/audit/core/checks/forms.cjs +0 -172
  350. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  351. package/scripts/audit/core/checks/hooks.cjs +0 -334
  352. package/scripts/audit/core/checks/imports.cjs +0 -244
  353. package/scripts/audit/core/checks/performance.cjs +0 -325
  354. package/scripts/audit/core/checks/routes.cjs +0 -117
  355. package/scripts/audit/core/checks/state.cjs +0 -130
  356. package/scripts/audit/core/checks/structure.cjs +0 -65
  357. package/scripts/audit/core/checks/style.cjs +0 -584
  358. package/scripts/audit/core/checks/testing.cjs +0 -122
  359. package/scripts/audit/core/checks/typescript.cjs +0 -61
  360. package/scripts/audit/core/scanner.cjs +0 -199
  361. package/scripts/audit/core/utils.cjs +0 -137
  362. package/scripts/audit/reporters/console.cjs +0 -151
  363. package/scripts/audit/reporters/json.cjs +0 -54
  364. package/scripts/audit/reporters/markdown.cjs +0 -124
  365. package/scripts/audit-consuming-app.cjs +0 -86
  366. package/src/eslint-rules/pace-core-compliance.cjs +0 -510
  367. package/src/eslint-rules/pace-core-compliance.js +0 -638
  368. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  369. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  370. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  371. package/src/rbac/components/NavigationProvider.tsx +0 -345
  372. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  373. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  374. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  375. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  376. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  377. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  378. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  379. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  380. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  381. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  382. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  383. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  384. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  385. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  386. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  387. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -0,0 +1,348 @@
1
+ # Performance Optimization Guide
2
+
3
+ **🤖 Cursor Rule**: See [11-performance-optimization.mdc](../../cursor-rules/11-performance-optimization.mdc) for AI-optimized directives that automatically enforce performance best practices.
4
+
5
+ ## Purpose
6
+
7
+ This standard defines performance optimization patterns and best practices to ensure:
8
+ - **Fast page loads** and responsive user interfaces
9
+ - **Efficient database queries** with proper RLS optimization
10
+ - **Optimized React rendering** with proper memoization
11
+ - **Effective caching strategies** for server state
12
+ - **Minimal bundle sizes** and code splitting
13
+
14
+ ## Principles
15
+
16
+ 1. **Measure before optimizing** - Profile and identify bottlenecks
17
+ 2. **Optimize critical paths first** - Focus on user-facing performance
18
+ 3. **Use appropriate caching** - Balance freshness with performance
19
+ 4. **Minimize re-renders** - Use React optimization techniques
20
+ 5. **Optimize database queries** - Use helper functions, avoid N+1 queries
21
+
22
+ ## React Performance
23
+
24
+ ### Memoization
25
+
26
+ **Use `useMemo` for expensive computations:**
27
+
28
+ ```tsx
29
+ // ✅ CORRECT - Memoize expensive computation
30
+ const expensiveValue = useMemo(() => {
31
+ return computeExpensiveValue(data);
32
+ }, [data]);
33
+
34
+ // ❌ WRONG - Recomputes on every render
35
+ const expensiveValue = computeExpensiveValue(data);
36
+ ```
37
+
38
+ **Use `useCallback` for stable function references:**
39
+
40
+ ```tsx
41
+ // ✅ CORRECT - Stable callback reference
42
+ const handleClick = useCallback(() => {
43
+ doSomething(id);
44
+ }, [id]);
45
+
46
+ // ❌ WRONG - New function on every render
47
+ const handleClick = () => {
48
+ doSomething(id);
49
+ };
50
+ ```
51
+
52
+ **Use `React.memo` for expensive components:**
53
+
54
+ ```tsx
55
+ // ✅ CORRECT - Memoize component
56
+ const ExpensiveComponent = React.memo(({ data }) => {
57
+ return <div>{/* expensive rendering */}</div>;
58
+ });
59
+
60
+ // ❌ WRONG - Re-renders unnecessarily
61
+ function ExpensiveComponent({ data }) {
62
+ return <div>{/* expensive rendering */}</div>;
63
+ }
64
+ ```
65
+
66
+ ### Avoiding Unnecessary Re-renders
67
+
68
+ **Don't create new objects/arrays in render:**
69
+
70
+ ```tsx
71
+ // ❌ WRONG - New object on every render
72
+ function Component({ items }) {
73
+ const config = { items, enabled: true };
74
+ return <Child config={config} />;
75
+ }
76
+
77
+ // ✅ CORRECT - Memoize object
78
+ function Component({ items }) {
79
+ const config = useMemo(() => ({ items, enabled: true }), [items]);
80
+ return <Child config={config} />;
81
+ }
82
+ ```
83
+
84
+ ### Code Splitting
85
+
86
+ **Lazy load heavy components:**
87
+
88
+ ```tsx
89
+ // ✅ CORRECT - Lazy load
90
+ import { lazy, Suspense } from 'react';
91
+ const HeavyComponent = lazy(() => import('./HeavyComponent'));
92
+
93
+ function App() {
94
+ return (
95
+ <Suspense fallback={<Loading />}>
96
+ <HeavyComponent />
97
+ </Suspense>
98
+ );
99
+ }
100
+ ```
101
+
102
+ ## Database Performance
103
+
104
+ ### RLS Policy Optimization
105
+
106
+ **MUST use helper functions (STABLE SECURITY DEFINER):**
107
+
108
+ ```sql
109
+ -- ✅ CORRECT - Helper function (evaluated once)
110
+ CREATE POLICY "rbac_select_users" ON users FOR SELECT USING (
111
+ check_user_organisation_access(organisation_id)
112
+ );
113
+
114
+ -- ❌ WRONG - Subquery (evaluated per row)
115
+ CREATE POLICY "rbac_select_users" ON users FOR SELECT USING (
116
+ organisation_id IN (SELECT organisation_id FROM organisation_memberships WHERE user_id = auth.uid())
117
+ );
118
+ ```
119
+
120
+ **MUST avoid InitPlan nodes:**
121
+
122
+ ```sql
123
+ -- ❌ WRONG - Causes InitPlan (severe performance degradation)
124
+ CREATE POLICY "bad_policy" ON table_name FOR SELECT USING (
125
+ user_id = auth.uid() -- Called for every row!
126
+ );
127
+
128
+ -- ✅ CORRECT - Helper function
129
+ CREATE POLICY "good_policy" ON table_name FOR SELECT USING (
130
+ get_effective_user_id() = user_id -- Evaluated once
131
+ );
132
+ ```
133
+
134
+ ### Query Optimization
135
+
136
+ **Use indexes for frequently queried columns:**
137
+
138
+ ```sql
139
+ -- ✅ CORRECT - Index on frequently queried column
140
+ CREATE INDEX idx_users_organisation_id ON users(organisation_id);
141
+ CREATE INDEX idx_events_organisation_id_event_id ON events(organisation_id, event_id);
142
+ ```
143
+
144
+ **Avoid N+1 queries:**
145
+
146
+ ```tsx
147
+ // ❌ WRONG - N+1 queries
148
+ const events = await fetchEvents();
149
+ for (const event of events) {
150
+ const users = await fetchEventUsers(event.id); // N queries!
151
+ }
152
+
153
+ // ✅ CORRECT - Single query with join
154
+ const eventsWithUsers = await fetchEventsWithUsers(); // 1 query
155
+ ```
156
+
157
+ **Use RPC functions for complex queries:**
158
+
159
+ ```tsx
160
+ // ✅ CORRECT - RPC for complex query
161
+ const { data } = await supabase.rpc('data_events_list', {
162
+ organisation_id: orgId
163
+ });
164
+
165
+ // ❌ AVOID - Complex client-side query
166
+ const { data } = await supabase
167
+ .from('events')
168
+ .select('*, users(*), organisations(*)')
169
+ .eq('organisation_id', orgId);
170
+ ```
171
+
172
+ ## Caching Strategies
173
+
174
+ ### TanStack Query Configuration
175
+
176
+ **Configure appropriate cache times:**
177
+
178
+ ```tsx
179
+ // ✅ CORRECT - Configure cache
180
+ const queryClient = new QueryClient({
181
+ defaultOptions: {
182
+ queries: {
183
+ staleTime: 5 * 60 * 1000, // 5 minutes
184
+ cacheTime: 10 * 60 * 1000, // 10 minutes
185
+ retry: 1,
186
+ refetchOnWindowFocus: false, // Prevent unnecessary refetches
187
+ },
188
+ },
189
+ });
190
+ ```
191
+
192
+ **Use query keys effectively:**
193
+
194
+ ```tsx
195
+ // ✅ CORRECT - Specific query keys
196
+ const { data } = useQuery({
197
+ queryKey: ['events', organisationId, eventId],
198
+ queryFn: () => fetchEvent(organisationId, eventId),
199
+ });
200
+
201
+ // ❌ WRONG - Too generic
202
+ const { data } = useQuery({
203
+ queryKey: ['events'],
204
+ queryFn: () => fetchEvent(organisationId, eventId),
205
+ });
206
+ ```
207
+
208
+ ### React Query Optimizations
209
+
210
+ **Use `keepPreviousData` for pagination:**
211
+
212
+ ```tsx
213
+ // ✅ CORRECT - Keep previous data during pagination
214
+ const { data } = useQuery({
215
+ queryKey: ['events', page],
216
+ queryFn: () => fetchEvents(page),
217
+ keepPreviousData: true,
218
+ });
219
+ ```
220
+
221
+ **Use `select` to transform data efficiently:**
222
+
223
+ ```tsx
224
+ // ✅ CORRECT - Transform in select (only runs when data changes)
225
+ const { data: eventCount } = useQuery({
226
+ queryKey: ['events'],
227
+ queryFn: fetchEvents,
228
+ select: (data) => data.length,
229
+ });
230
+ ```
231
+
232
+ ## Bundle Size Optimization
233
+
234
+ ### Tree Shaking
235
+
236
+ **Use named imports:**
237
+
238
+ ```tsx
239
+ // ✅ CORRECT - Tree-shakeable
240
+ import { Button, Card } from '@jmruthers/pace-core';
241
+
242
+ // ❌ WRONG - Imports entire library
243
+ import * as PaceCore from '@jmruthers/pace-core';
244
+ ```
245
+
246
+ ### Dynamic Imports
247
+
248
+ **Lazy load heavy dependencies:**
249
+
250
+ ```tsx
251
+ // ✅ CORRECT - Dynamic import
252
+ const HeavyLibrary = lazy(() => import('heavy-library'));
253
+
254
+ // ❌ WRONG - Eager import
255
+ import HeavyLibrary from 'heavy-library';
256
+ ```
257
+
258
+ ## Performance Monitoring
259
+
260
+ ### Measuring Performance
261
+
262
+ **Use React DevTools Profiler:**
263
+
264
+ 1. Open React DevTools
265
+ 2. Go to Profiler tab
266
+ 3. Record a session
267
+ 4. Identify slow components
268
+ 5. Optimize based on findings
269
+
270
+ **Use browser DevTools:**
271
+
272
+ 1. Open Performance tab
273
+ 2. Record page load
274
+ 3. Identify bottlenecks
275
+ 4. Optimize critical rendering path
276
+
277
+ ### Performance Metrics
278
+
279
+ **Track these metrics:**
280
+
281
+ - **Time to First Byte (TTFB)** - < 200ms
282
+ - **First Contentful Paint (FCP)** - < 1.8s
283
+ - **Largest Contentful Paint (LCP)** - < 2.5s
284
+ - **Time to Interactive (TTI)** - < 3.8s
285
+ - **Cumulative Layout Shift (CLS)** - < 0.1
286
+
287
+ ## Performance Checklist
288
+
289
+ Before committing performance-sensitive code, verify:
290
+
291
+ - [ ] Expensive computations memoized with `useMemo`
292
+ - [ ] Callbacks stable with `useCallback`
293
+ - [ ] Components memoized with `React.memo` when appropriate
294
+ - [ ] No new objects/arrays created in render
295
+ - [ ] Heavy components lazy loaded
296
+ - [ ] RLS policies use helper functions (no subqueries)
297
+ - [ ] Queries use indexes appropriately
298
+ - [ ] No N+1 query patterns
299
+ - [ ] TanStack Query configured with appropriate cache times
300
+ - [ ] Bundle size optimized (tree shaking, code splitting)
301
+ - [ ] Performance metrics measured and acceptable
302
+
303
+ ## Common Performance Pitfalls
304
+
305
+ ### ❌ Don't: Create New Objects in Render
306
+
307
+ ```tsx
308
+ // ❌ WRONG
309
+ function Component({ items }) {
310
+ return <Child config={{ items, enabled: true }} />; // New object every render
311
+ }
312
+ ```
313
+
314
+ ### ❌ Don't: Use Inline Functions
315
+
316
+ ```tsx
317
+ // ❌ WRONG
318
+ <Button onClick={() => handleClick(id)}>Click</Button> // New function every render
319
+ ```
320
+
321
+ ### ❌ Don't: Over-Memoize
322
+
323
+ ```tsx
324
+ // ❌ WRONG - Memoizing simple computation
325
+ const simpleValue = useMemo(() => items.length, [items]); // Unnecessary
326
+ ```
327
+
328
+ ### ❌ Don't: Use Subqueries in RLS
329
+
330
+ ```sql
331
+ -- ❌ WRONG - N+1 performance issue
332
+ CREATE POLICY "bad" ON table FOR SELECT USING (
333
+ organisation_id IN (SELECT ... FROM ... WHERE user_id = auth.uid())
334
+ );
335
+ ```
336
+
337
+ ## Related Documentation
338
+
339
+ - [RLS Standard](./09-rbac-compliance.md) - RLS performance requirements
340
+ - [Code Quality Standard](./06-code-quality.md) - React performance patterns
341
+ - [Tech Stack Standard](./07-tech-stack-compliance.md) - TanStack Query configuration
342
+
343
+ ---
344
+
345
+ **Last Updated:** 2025-01-28
346
+ **Version:** 1.0.0
347
+ **Applies to:** All pace-core and consuming apps
348
+
@@ -0,0 +1,370 @@
1
+ # CI/CD Integration Guide
2
+
3
+ **🤖 Cursor Rule**: See [12-ci-cd-integration.mdc](../../cursor-rules/12-ci-cd-integration.mdc) for AI-optimized directives that automatically enforce CI/CD best practices.
4
+
5
+ ## Purpose
6
+
7
+ This standard defines CI/CD integration patterns and best practices to ensure:
8
+ - **Automated quality checks** on every commit
9
+ - **Consistent deployment processes** across environments
10
+ - **Proper testing** before deployment
11
+ - **Security scanning** and compliance checks
12
+ - **Efficient build and deployment** pipelines
13
+
14
+ ## Principles
15
+
16
+ 1. **Automate everything** - Manual steps are error-prone
17
+ 2. **Fail fast** - Catch issues early in the pipeline
18
+ 3. **Test before deploy** - Never deploy untested code
19
+ 4. **Security first** - Scan for vulnerabilities
20
+ 5. **Consistent environments** - Dev, staging, production parity
21
+
22
+ ## CI/CD Pipeline Structure
23
+
24
+ ### Standard Pipeline Stages
25
+
26
+ ```
27
+ 1. Lint & Format Check
28
+ 2. Type Check
29
+ 3. Unit Tests
30
+ 4. Integration Tests
31
+ 5. Build
32
+ 6. Security Scan
33
+ 7. Deploy (staging/production)
34
+ ```
35
+
36
+ ## GitHub Actions Example
37
+
38
+ ### Basic Workflow
39
+
40
+ ```yaml
41
+ # .github/workflows/ci.yml
42
+ name: CI
43
+
44
+ on:
45
+ push:
46
+ branches: [main, develop]
47
+ pull_request:
48
+ branches: [main, develop]
49
+
50
+ jobs:
51
+ quality-checks:
52
+ runs-on: ubuntu-latest
53
+ steps:
54
+ - uses: actions/checkout@v4
55
+
56
+ - name: Setup Node.js
57
+ uses: actions/setup-node@v4
58
+ with:
59
+ node-version: '20'
60
+ cache: 'npm'
61
+
62
+ - name: Install dependencies
63
+ run: npm ci
64
+
65
+ - name: Lint
66
+ run: npm run lint
67
+
68
+ - name: Type check
69
+ run: npm run type-check
70
+
71
+ - name: Format check
72
+ run: npm run format:check
73
+
74
+ - name: Run tests
75
+ run: npm run test
76
+
77
+ - name: Build
78
+ run: npm run build
79
+
80
+ - name: Security scan
81
+ run: npm audit --audit-level=moderate
82
+ ```
83
+
84
+ ### Advanced Workflow with Deployment
85
+
86
+ ```yaml
87
+ # .github/workflows/deploy.yml
88
+ name: Deploy
89
+
90
+ on:
91
+ push:
92
+ branches: [main]
93
+ workflow_dispatch:
94
+
95
+ jobs:
96
+ test:
97
+ runs-on: ubuntu-latest
98
+ steps:
99
+ - uses: actions/checkout@v4
100
+ - uses: actions/setup-node@v4
101
+ with:
102
+ node-version: '20'
103
+ cache: 'npm'
104
+ - run: npm ci
105
+ - run: npm run test
106
+ - run: npm run build
107
+
108
+ deploy-staging:
109
+ needs: test
110
+ runs-on: ubuntu-latest
111
+ environment: staging
112
+ steps:
113
+ - uses: actions/checkout@v4
114
+ - uses: actions/setup-node@v4
115
+ with:
116
+ node-version: '20'
117
+ - run: npm ci
118
+ - run: npm run build
119
+ - name: Deploy to Staging
120
+ run: |
121
+ # Your deployment script
122
+ echo "Deploying to staging..."
123
+
124
+ deploy-production:
125
+ needs: test
126
+ runs-on: ubuntu-latest
127
+ environment: production
128
+ if: github.ref == 'refs/heads/main'
129
+ steps:
130
+ - uses: actions/checkout@v4
131
+ - uses: actions/setup-node@v4
132
+ with:
133
+ node-version: '20'
134
+ - run: npm ci
135
+ - run: npm run build
136
+ - name: Deploy to Production
137
+ run: |
138
+ # Your deployment script
139
+ echo "Deploying to production..."
140
+ ```
141
+
142
+ ## Required CI Checks
143
+
144
+ ### MUST: Run These Checks
145
+
146
+ **Every CI pipeline MUST include:**
147
+
148
+ 1. **Linting** - ESLint with pace-core rules
149
+ ```yaml
150
+ - name: Lint
151
+ run: npm run lint
152
+ ```
153
+
154
+ 2. **Type Checking** - TypeScript compilation
155
+ ```yaml
156
+ - name: Type check
157
+ run: npx tsc --noEmit
158
+ ```
159
+
160
+ 3. **Testing** - Unit and integration tests
161
+ ```yaml
162
+ - name: Run tests
163
+ run: npm run test
164
+ ```
165
+
166
+ 4. **Build** - Verify build succeeds
167
+ ```yaml
168
+ - name: Build
169
+ run: npm run build
170
+ ```
171
+
172
+
173
+ ### SHOULD: Run These Checks
174
+
175
+ **Recommended additional checks:**
176
+
177
+ 1. **Format Check** - Prettier or similar
178
+ ```yaml
179
+ - name: Format check
180
+ run: npm run format:check
181
+ ```
182
+
183
+ 2. **Security Scan** - npm audit or Snyk
184
+ ```yaml
185
+ - name: Security scan
186
+ run: npm audit --audit-level=moderate
187
+ ```
188
+
189
+ 3. **Coverage Check** - Test coverage thresholds
190
+ ```yaml
191
+ - name: Coverage check
192
+ run: npm run test:coverage
193
+ ```
194
+
195
+ ## Package.json Scripts
196
+
197
+ ### Required Scripts
198
+
199
+ **MUST have these scripts in `package.json`:**
200
+
201
+ ```json
202
+ {
203
+ "scripts": {
204
+ "lint": "eslint .",
205
+ "lint:fix": "eslint . --fix",
206
+ "type-check": "tsc --noEmit",
207
+ "test": "vitest run",
208
+ "test:watch": "vitest",
209
+ "test:coverage": "vitest run --coverage",
210
+ "build": "vite build",
211
+ "format": "prettier --write .",
212
+ "format:check": "prettier --check ."
213
+ }
214
+ }
215
+ ```
216
+
217
+ ## Environment Variables
218
+
219
+ ### CI/CD Secrets
220
+
221
+ **Store sensitive values as secrets:**
222
+
223
+ ```yaml
224
+ # .github/workflows/deploy.yml
225
+ env:
226
+ SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
227
+ SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
228
+ VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
229
+ VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
230
+ ```
231
+
232
+ **Never commit secrets to repository:**
233
+ - Use GitHub Secrets
234
+ - Use environment-specific config files
235
+ - Use `.env.example` for documentation
236
+
237
+ ## Database Migrations in CI/CD
238
+
239
+ ### Migration Strategy
240
+
241
+ **For Supabase migrations:**
242
+
243
+ ```yaml
244
+ - name: Run migrations
245
+ run: |
246
+ npx supabase db push
247
+ # Or use Supabase CLI
248
+ supabase migration up
249
+ ```
250
+
251
+ **Best Practices:**
252
+ - Run migrations in staging first
253
+ - Test migrations in CI
254
+ - Never run destructive migrations automatically
255
+ - Use migration review process
256
+
257
+ ## Deployment Strategies
258
+
259
+ ### Staging Deployment
260
+
261
+ **Deploy to staging on every merge to `develop`:**
262
+
263
+ ```yaml
264
+ deploy-staging:
265
+ if: github.ref == 'refs/heads/develop'
266
+ environment: staging
267
+ steps:
268
+ - name: Deploy to Staging
269
+ run: |
270
+ # Deploy to staging environment
271
+ ```
272
+
273
+ ### Production Deployment
274
+
275
+ **Deploy to production only from `main` branch:**
276
+
277
+ ```yaml
278
+ deploy-production:
279
+ if: github.ref == 'refs/heads/main'
280
+ environment: production
281
+ steps:
282
+ - name: Deploy to Production
283
+ run: |
284
+ # Deploy to production environment
285
+ ```
286
+
287
+ ### Manual Deployment
288
+
289
+ **Allow manual deployment via workflow_dispatch:**
290
+
291
+ ```yaml
292
+ on:
293
+ workflow_dispatch:
294
+ inputs:
295
+ environment:
296
+ description: 'Environment to deploy to'
297
+ required: true
298
+ type: choice
299
+ options:
300
+ - staging
301
+ - production
302
+ ```
303
+
304
+ ## CI/CD Checklist
305
+
306
+ Before setting up CI/CD, verify:
307
+
308
+ - [ ] Lint check configured
309
+ - [ ] Type check configured
310
+ - [ ] Tests run in CI
311
+ - [ ] Build succeeds in CI
312
+ - [ ] Security scan configured
313
+ - [ ] Environment variables set as secrets
314
+ - [ ] Staging deployment configured
315
+ - [ ] Production deployment configured
316
+ - [ ] Migration strategy defined
317
+ - [ ] Rollback plan documented
318
+
319
+ ## Common CI/CD Issues
320
+
321
+ ### Issue: Tests Fail in CI but Pass Locally
322
+
323
+ **Causes:**
324
+ - Environment differences
325
+ - Missing environment variables
326
+ - Timezone issues
327
+ - File path differences
328
+
329
+ **Solutions:**
330
+ - Use same Node.js version
331
+ - Set all required environment variables
332
+ - Use consistent timezone (UTC)
333
+ - Use absolute paths or path aliases
334
+
335
+ ### Issue: Build Fails in CI
336
+
337
+ **Causes:**
338
+ - Missing dependencies
339
+ - Different Node.js version
340
+ - Platform-specific code
341
+
342
+ **Solutions:**
343
+ - Use `npm ci` (not `npm install`)
344
+ - Pin Node.js version
345
+ - Test on same platform as CI
346
+
347
+ ### Issue: Slow CI Pipeline
348
+
349
+ **Causes:**
350
+ - Running unnecessary checks
351
+ - Not caching dependencies
352
+ - Sequential jobs
353
+
354
+ **Solutions:**
355
+ - Cache node_modules
356
+ - Run jobs in parallel
357
+ - Only run necessary checks per branch
358
+
359
+ ## Related Documentation
360
+
361
+ - [Testing Standard](./04-testing-standards.md) - Test configuration
362
+ - [Code Quality Standard](./06-code-quality.md) - Linting and formatting
363
+ - [pace-core Compliance](./00-pace-core-compliance.md) - Compliance checks
364
+
365
+ ---
366
+
367
+ **Last Updated:** 2025-01-28
368
+ **Version:** 1.0.0
369
+ **Applies to:** All consuming apps using `@jmruthers/pace-core`
370
+