@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
@@ -1,11 +1,13 @@
1
1
  ---
2
- lastUpdated: 2025-01-02T00:00:00+11:00
2
+ lastUpdated: 2025-01-28T00:00:00+11:00
3
3
  version: 0.5.182
4
4
  reviewedBy: rls-audit-and-fixes
5
5
  ---
6
6
 
7
7
  # RBAC and RLS Standard
8
8
 
9
+ **🤖 Cursor Rule**: See [09-rbac-compliance.mdc](../../cursor-rules/09-rbac-compliance.mdc) for AI-optimized directives that automatically enforce RBAC contract compliance (ESLint-enforced).
10
+
9
11
  ## Purpose
10
12
 
11
13
  Define standards for Row-Level Security (RLS) policies and Role-Based Access Control (RBAC) integration to ensure security, performance, and maintainability.
@@ -101,16 +103,36 @@ FOR SELECT USING (
101
103
  );
102
104
  ```
103
105
 
106
+ ## Helper Selection Quick Guide
107
+
108
+ | Scenario | Helper(s) to use | Notes |
109
+ |----------|------------------|-------|
110
+ | Organisation-scoped rows | `check_user_organisation_access(organisation_id)` | Always check `organisation_id IS NOT NULL` first. |
111
+ | Page-permission checks | `check_rbac_permission_with_context(..., get_app_id('APP'))` | Use the wrapper instead of inline `rbac_check_permission_simplified` + `auth.uid()`. |
112
+ | Event-scoped rows | `check_user_event_access(event_id)` | Combine with permission wrapper when pages require it. |
113
+ | Public rows | `check_public_event_access(event_id)` or `is_public = true` | Keep anonymous and authenticated policies separate. |
114
+ | User-owned rows | `get_effective_user_id() = user_id` | Use when `organisation_id IS NULL`. |
115
+ | Service role bypass | `is_service_role()` | Put first in OR chains; use sparingly. |
116
+
117
+ ## RLS Helper Requirements (enforced)
118
+
119
+ - Helper functions **must** be `STABLE`, `SECURITY DEFINER`, and `SET search_path TO public`.
120
+ - **Never** inline `auth.uid()`, `auth.role()`, or `current_setting()` inside policies.
121
+ - Use `get_app_id()` for app UUIDs (do not hardcode UUIDs or call legacy getters).
122
+ - Avoid subqueries inside policies; move lookups into helpers.
123
+
104
124
  ## Standard Helper Functions
105
125
 
106
126
  ### Core Helper Functions
107
127
 
108
128
  These functions are available for use in RLS policies:
109
129
 
110
- #### `is_super_admin()`
130
+ #### `is_super_admin(p_user_id UUID)`
111
131
  - **Returns**: `boolean`
112
- - **Purpose**: Checks if current user is a super admin
113
- - **Usage**: `is_super_admin()`
132
+ - **Purpose**: Checks if the specified user is a super admin
133
+ - **Usage**: `is_super_admin(safe_get_user_id_for_rls())`
134
+ - **⚠️ CRITICAL**: Always pass an explicit user ID parameter. Never call without parameters.
135
+ - **Security**: This function requires an explicit parameter to prevent fallback strategy vulnerabilities. Use `safe_get_user_id_for_rls()` to get the user ID in RLS policies.
114
136
 
115
137
  #### `check_user_organisation_access(p_organisation_id UUID)`
116
138
  - **Returns**: `boolean`
@@ -212,7 +234,7 @@ FOR SELECT TO authenticated
212
234
  USING (
213
235
  organisation_id IS NOT NULL
214
236
  AND (
215
- is_super_admin()
237
+ is_super_admin(safe_get_user_id_for_rls())
216
238
  OR check_user_organisation_access(organisation_id)
217
239
  )
218
240
  );
@@ -223,6 +245,7 @@ USING (
223
245
  **Notes:**
224
246
  - Always check `organisation_id IS NOT NULL` first
225
247
  - Super admin check comes before organisation access check
248
+ - **MUST** use `is_super_admin(safe_get_user_id_for_rls())` with explicit parameter
226
249
  - Use `check_user_organisation_access()` for basic membership checks
227
250
 
228
251
  ### RBAC Permission-Based Policy
@@ -236,7 +259,7 @@ FOR SELECT TO authenticated
236
259
  USING (
237
260
  organisation_id IS NOT NULL
238
261
  AND (
239
- is_super_admin()
262
+ is_super_admin(safe_get_user_id_for_rls())
240
263
  OR check_rbac_permission_with_context(
241
264
  'read:page.table_name',
242
265
  'table_name',
@@ -258,7 +281,7 @@ FOR SELECT TO authenticated
258
281
  USING (
259
282
  organisation_id IS NOT NULL
260
283
  AND (
261
- is_super_admin()
284
+ is_super_admin(safe_get_user_id_for_rls())
262
285
  OR check_rbac_permission_with_context(
263
286
  'read:page.table_name',
264
287
  'table_name',
@@ -275,7 +298,7 @@ FOR INSERT TO authenticated
275
298
  WITH CHECK (
276
299
  organisation_id IS NOT NULL
277
300
  AND (
278
- is_super_admin()
301
+ is_super_admin(safe_get_user_id_for_rls())
279
302
  OR check_rbac_permission_with_context(
280
303
  'create:page.table_name',
281
304
  'table_name',
@@ -292,7 +315,7 @@ FOR UPDATE TO authenticated
292
315
  USING (
293
316
  organisation_id IS NOT NULL
294
317
  AND (
295
- is_super_admin()
318
+ is_super_admin(safe_get_user_id_for_rls())
296
319
  OR check_rbac_permission_with_context(
297
320
  'update:page.table_name',
298
321
  'table_name',
@@ -305,7 +328,7 @@ USING (
305
328
  WITH CHECK (
306
329
  organisation_id IS NOT NULL
307
330
  AND (
308
- is_super_admin()
331
+ is_super_admin(safe_get_user_id_for_rls())
309
332
  OR check_rbac_permission_with_context(
310
333
  'update:page.table_name',
311
334
  'table_name',
@@ -322,7 +345,7 @@ FOR DELETE TO authenticated
322
345
  USING (
323
346
  organisation_id IS NOT NULL
324
347
  AND (
325
- is_super_admin()
348
+ is_super_admin(safe_get_user_id_for_rls())
326
349
  OR check_rbac_permission_with_context(
327
350
  'delete:page.table_name',
328
351
  'table_name',
@@ -351,7 +374,7 @@ FOR SELECT TO authenticated
351
374
  USING (
352
375
  organisation_id IS NOT NULL
353
376
  AND (
354
- is_super_admin()
377
+ is_super_admin(safe_get_user_id_for_rls())
355
378
  OR check_user_event_access(event_id)
356
379
  )
357
380
  );
@@ -387,7 +410,7 @@ USING (
387
410
  organisation_id IS NOT NULL
388
411
  AND is_authenticated_user()
389
412
  AND (
390
- is_super_admin()
413
+ is_super_admin(safe_get_user_id_for_rls())
391
414
  OR check_user_organisation_access(organisation_id)
392
415
  )
393
416
  )
@@ -542,7 +565,7 @@ USING (is_authenticated_user());
542
565
  ```sql
543
566
  CREATE POLICY "rbac_select_table_name" ON table_name
544
567
  FOR SELECT TO authenticated
545
- USING (is_super_admin());
568
+ USING (is_super_admin(safe_get_user_id_for_rls()));
546
569
  ```
547
570
 
548
571
  **Example:** `rbac_global_roles`, `rbac_policy_configs`
@@ -552,20 +575,20 @@ USING (is_super_admin());
552
575
  -- All operations restricted to super admin
553
576
  CREATE POLICY "rbac_select_table_name" ON table_name
554
577
  FOR SELECT TO authenticated
555
- USING (is_super_admin());
578
+ USING (is_super_admin(safe_get_user_id_for_rls()));
556
579
 
557
580
  CREATE POLICY "rbac_insert_table_name" ON table_name
558
581
  FOR INSERT TO authenticated
559
- WITH CHECK (is_super_admin());
582
+ WITH CHECK (is_super_admin(safe_get_user_id_for_rls()));
560
583
 
561
584
  CREATE POLICY "rbac_update_table_name" ON table_name
562
585
  FOR UPDATE TO authenticated
563
- USING (is_super_admin())
564
- WITH CHECK (is_super_admin());
586
+ USING (is_super_admin(safe_get_user_id_for_rls()))
587
+ WITH CHECK (is_super_admin(safe_get_user_id_for_rls()));
565
588
 
566
589
  CREATE POLICY "rbac_delete_table_name" ON table_name
567
590
  FOR DELETE TO authenticated
568
- USING (is_super_admin());
591
+ USING (is_super_admin(safe_get_user_id_for_rls()));
569
592
  ```
570
593
 
571
594
  ### Common Patterns Summary
@@ -579,19 +602,121 @@ USING (is_super_admin());
579
602
  | Service Role | System operations | `is_service_role()` |
580
603
  | Public Access | Anonymous users | `check_public_event_access()` or `is_public` flag |
581
604
  | Read-Only Types | Reference tables | `is_authenticated_user()` |
582
- | Super Admin Only | Admin-only tables | `is_super_admin()` |
605
+ | Super Admin Only | Admin-only tables | `is_super_admin(safe_get_user_id_for_rls())` |
583
606
 
584
607
  ### Policy Best Practices
585
608
 
586
609
  1. **Always use helper functions** - Never inline `auth.uid()`, `auth.role()`, or `current_setting()`
587
610
  2. **Check NULL first** - Always check `organisation_id IS NOT NULL` before using it
588
- 3. **Super admin first** - Super admin checks should come before other checks in OR conditions
611
+ 3. **Super admin first** - Super admin checks should come before other checks in OR conditions. **MUST** use `is_super_admin(safe_get_user_id_for_rls())` with explicit parameter - never call without parameters.
589
612
  4. **Service role first** - Service role checks should be the first condition in multi-condition policies
590
613
  5. **Consistent naming** - Follow the naming convention: `rbac_{operation}_{table}_{scope}`
591
614
  6. **Document exceptions** - If a policy deviates from standard patterns, add a comment explaining why
592
615
  7. **Test thoroughly** - Test with different user roles (super_admin, org_admin, member, anon)
593
616
  8. **Avoid `true OR ...`** - Never use `true OR ...` conditions as they bypass all security checks
594
617
 
618
+ ## Edge Functions and Serverless Functions
619
+
620
+ **Edge Functions (Deno serverless functions) MUST use pace-core's `isPermitted()` API function.** Edge Functions cannot use React hooks, but pace-core provides programmatic APIs that work outside React.
621
+
622
+ ### ✅ CORRECT - Edge Function Pattern
623
+
624
+ ```typescript
625
+ // supabase/functions/my-function/index.ts
626
+ import { createClient } from 'jsr:@supabase/supabase-js@2';
627
+ import { setupRBAC, isPermitted } from 'npm:@jmruthers/pace-core@^0.6.0/rbac';
628
+
629
+ Deno.serve(async (req: Request) => {
630
+ // 1. Create Supabase client from request headers
631
+ const authHeader = req.headers.get('Authorization');
632
+ if (!authHeader) {
633
+ return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 });
634
+ }
635
+
636
+ const supabase = createClient(
637
+ Deno.env.get('SUPABASE_URL') ?? '',
638
+ Deno.env.get('SUPABASE_ANON_KEY') ?? '',
639
+ {
640
+ global: {
641
+ headers: { Authorization: authHeader },
642
+ },
643
+ }
644
+ );
645
+
646
+ // 2. Get user from session
647
+ const { data: { user } } = await supabase.auth.getUser();
648
+ if (!user) {
649
+ return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 });
650
+ }
651
+
652
+ // 3. Setup RBAC (required before using isPermitted)
653
+ setupRBAC(supabase);
654
+
655
+ // 4. Extract organisation context from request
656
+ const organisationId = req.headers.get('x-organisation-id') ||
657
+ (await req.json()).organisationId;
658
+
659
+ if (!organisationId) {
660
+ return new Response(JSON.stringify({ error: 'Organisation context required' }), { status: 400 });
661
+ }
662
+
663
+ // 5. Check permission using pace-core API
664
+ const hasPermission = await isPermitted({
665
+ userId: user.id,
666
+ scope: { organisationId },
667
+ permission: 'read:dashboard',
668
+ pageId: 'dashboard'
669
+ });
670
+
671
+ if (!hasPermission) {
672
+ return new Response(JSON.stringify({ error: 'Permission denied' }), { status: 403 });
673
+ }
674
+
675
+ // 6. Proceed with function logic
676
+ return new Response(JSON.stringify({ success: true }));
677
+ });
678
+ ```
679
+
680
+ ### ❌ FORBIDDEN - Custom RBAC Helper in Edge Functions
681
+
682
+ **Creating custom RBAC helper functions in Edge Functions is FORBIDDEN.** pace-core provides all necessary APIs.
683
+
684
+ ```typescript
685
+ // ❌ FORBIDDEN - Custom RBAC helper
686
+ // supabase/functions/_shared/rbac.ts
687
+ export async function checkPermission(userId: string, permission: string) {
688
+ // Custom logic that bypasses pace-core
689
+ const { data } = await supabase.rpc('rbac_check_permission_simplified', {
690
+ p_user_id: userId,
691
+ p_permission: permission
692
+ });
693
+ return data;
694
+ }
695
+ ```
696
+
697
+ ### Why No Exceptions
698
+
699
+ - pace-core provides `isPermitted()` API that works outside React
700
+ - `setupRBAC()` initializes the engine with a Supabase client
701
+ - No custom helpers needed - use pace-core APIs directly
702
+ - Custom helpers bypass security validation, caching, and audit logging
703
+
704
+ ### Edge Function Requirements
705
+
706
+ 1. **MUST** call `setupRBAC(supabase)` before using `isPermitted()`
707
+ 2. **MUST** extract `userId` from Supabase auth session
708
+ 3. **MUST** extract `organisationId` from request (headers, body, or query params)
709
+ 4. **MUST** use `isPermitted()` with complete `PermissionCheck` input
710
+ 5. **MUST NOT** create custom RBAC helper functions
711
+ 6. **MUST NOT** call `rbac_check_permission_simplified` RPC directly
712
+
713
+ ## Security Baseline (aligns with Security Standard)
714
+ - Never bypass RLS; validate all inputs and sanitize logs (no tokens/PII).
715
+ - Use safe, user-friendly error messaging.
716
+ - Prefer pace-core security helpers and secure clients (`useSecureSupabase`, RBAC helpers) over custom implementations.
717
+ - Monitor RLS performance (avoid subqueries/InitPlan); keep helpers `STABLE SECURITY DEFINER` with `SET search_path TO public`.
718
+ - **Edge Functions MUST use pace-core `isPermitted()` API - no exceptions allowed.**
719
+
595
720
  ### Common Pitfalls to Avoid
596
721
 
597
722
  **❌ DON'T:**
@@ -648,13 +773,7 @@ Tables are assigned to specific apps for RBAC permission checking:
648
773
 
649
774
  ### Before Merging RLS Changes
650
775
 
651
- 1. **Run RLS Compliance Audit**:
652
- ```bash
653
- npm run audit:rls
654
- ```
655
- This checks for violations and should pass with zero violations.
656
-
657
- 2. **Run Supabase Advisors**:
776
+ 1. **Run Supabase Advisors**:
658
777
  ```bash
659
778
  supabase advisors performance
660
779
  supabase advisors security
@@ -686,32 +805,9 @@ Tables are assigned to specific apps for RBAC permission checking:
686
805
 
687
806
  ### Ongoing RLS Compliance Monitoring
688
807
 
689
- **Run RLS audit regularly** to catch any rogue policies that violate standards:
808
+ **Run Supabase advisors regularly** to catch any rogue policies that violate standards:
690
809
 
691
810
  ```bash
692
- # Quick audit (recommended before merging PRs)
693
- npm run audit:rls
694
-
695
- # Or use test database
696
- npm run audit:rls:test
697
-
698
- # For CI/CD (fails on violations)
699
- npm run audit:rls:ci
700
- ```
701
-
702
- The audit checks for:
703
- - Tables with RLS enabled but no policies
704
- - Policies using inline `auth.uid()` calls
705
- - Policies using `current_setting()` directly
706
- - Helper functions missing STABLE/SECURITY DEFINER
707
-
708
- ### Weekly Health Checks
709
-
710
- Run weekly:
711
- ```bash
712
- # RLS compliance audit
713
- npm run audit:rls
714
-
715
811
  # Performance advisors
716
812
  supabase advisors performance
717
813
 
@@ -772,8 +868,7 @@ date +"%Y%m%d%H%M%S"
772
868
 
773
869
  ## Related Documentation
774
870
 
775
- - [Security Standard](./05-security-standard.md)
871
+ - Security baseline (see section above)
776
872
  - [RLS Policy Remediation Plan](../troubleshooting/rls-policy-remediation-plan-combined.md)
777
873
  - [Database Unhealthiness Diagnosis](../troubleshooting/database-unhealthiness-diagnosis.md)
778
874
  - [RBAC-RLS Integration Guide](../rbac/rbac-rls-integration.md)
779
-