@jmruthers/pace-core 0.6.10 → 0.6.11

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 (726) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/audit-tool/00-dependencies.cjs +46 -13
  3. package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
  4. package/audit-tool/audits/02-project-structure.cjs +13 -3
  5. package/audit-tool/audits/03-architecture.cjs +78 -4
  6. package/audit-tool/audits/04-code-quality.cjs +9 -2
  7. package/audit-tool/audits/05-styling.cjs +19 -7
  8. package/audit-tool/audits/06-security-rbac.cjs +105 -14
  9. package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
  10. package/audit-tool/audits/08-testing-documentation.cjs +11 -3
  11. package/audit-tool/audits/09-operations.cjs +19 -7
  12. package/audit-tool/index.cjs +22 -11
  13. package/audit-tool/utils/report-utils.cjs +4 -0
  14. package/cursor-rules/01-pace-core-compliance.mdc +1 -0
  15. package/cursor-rules/02-project-structure.mdc +1 -0
  16. package/cursor-rules/03-architecture.mdc +3 -1
  17. package/cursor-rules/04-code-quality.mdc +1 -0
  18. package/cursor-rules/05-styling.mdc +41 -7
  19. package/cursor-rules/06-security-rbac.mdc +2 -1
  20. package/cursor-rules/07-api-tech-stack.mdc +1 -0
  21. package/cursor-rules/08-testing-documentation.mdc +1 -0
  22. package/cursor-rules/09-operations.mdc +1 -0
  23. package/dist/{DataTable-SAXFG4XI.js → DataTable-EFYP2QLE.js} +10 -7
  24. package/dist/{InactivityServiceProvider-DHryoh6K.d.ts → InactivityServiceProvider-BbxwwDz1.d.ts} +10 -1
  25. package/dist/{UnifiedAuthProvider-CiBAl9-s.d.ts → UnifiedAuthProvider-Bkt_tzdS.d.ts} +56 -24
  26. package/dist/{api-F47QJ7FX.js → api-BZR2CYXL.js} +3 -2
  27. package/dist/api-result-USV1Czr-.d.ts +51 -0
  28. package/dist/{audit-Z6ZZBWLU.js → audit-HI2DHUVU.js} +2 -1
  29. package/dist/{auth-BZOJqrdd.d.ts → auth-JvdRVaud.d.ts} +1 -1
  30. package/dist/{chunk-KSNLMI7N.js → chunk-2DL2WSOE.js} +1 -155
  31. package/dist/{chunk-MPY44PWB.js → chunk-2OEVOGGR.js} +4648 -3560
  32. package/dist/chunk-44CNXN4P.js +15 -0
  33. package/dist/{chunk-Y4PF6HIM.js → chunk-4R3T5ENU.js} +867 -786
  34. package/dist/{chunk-LNHFAF4X.js → chunk-7A6IMHH2.js} +289 -247
  35. package/dist/chunk-CU2BU2MQ.js +2 -0
  36. package/dist/{chunk-JJEYZ3DX.js → chunk-D6BMFMQZ.js} +37 -2
  37. package/dist/{chunk-BCTXBU6U.js → chunk-ENLXB7GP.js} +88 -71
  38. package/dist/{chunk-FBZ7U3ID.js → chunk-J2KQK6DG.js} +937 -987
  39. package/dist/{chunk-TFIPNIPE.js → chunk-KJXRL3XE.js} +3300 -2245
  40. package/dist/{chunk-3GWSPISD.js → chunk-L5LFKKLJ.js} +1 -1
  41. package/dist/{chunk-X5EAU5G7.js → chunk-PCSHBLPB.js} +132 -114
  42. package/dist/{chunk-NIU6DPQV.js → chunk-QRYSEPHB.js} +2 -0
  43. package/dist/{chunk-KYURMOQM.js → chunk-V7FTM2LU.js} +423 -320
  44. package/dist/chunk-WY6Y7KC3.js +264 -0
  45. package/dist/{chunk-FN52B75D.js → chunk-XOJME5T7.js} +176 -15
  46. package/dist/{chunk-7YDC7LMU.js → chunk-XPFVT3GN.js} +71 -66
  47. package/dist/{chunk-66R6RLUZ.js → chunk-YFTFFJIV.js} +3 -3
  48. package/dist/{chunk-W46INAVW.js → chunk-YYTWKVHO.js} +688 -570
  49. package/dist/components.d.ts +8 -7
  50. package/dist/components.js +17 -15
  51. package/dist/{database.generated-DT8JTZiP.d.ts → database.generated-qkdoiVrJ.d.ts} +45 -10
  52. package/dist/eslint-rules/index.cjs +3 -0
  53. package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
  54. package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
  55. package/dist/{event-WTAQuGcq.d.ts → event-BfCox3N2.d.ts} +36 -10
  56. package/dist/{file-reference-BavO2eQj.d.ts → file-reference-DU1hcawx.d.ts} +29 -13
  57. package/dist/hooks.d.ts +22 -9
  58. package/dist/hooks.js +34 -25
  59. package/dist/icons/index.d.ts +1 -0
  60. package/dist/icons/index.js +1 -0
  61. package/dist/index.d.ts +66 -177
  62. package/dist/index.js +316 -340
  63. package/dist/pagination-BW1mqywp.d.ts +201 -0
  64. package/dist/providers.d.ts +6 -5
  65. package/dist/providers.js +5 -3
  66. package/dist/rbac/index.d.ts +123 -138
  67. package/dist/rbac/index.js +10 -8
  68. package/dist/theming/runtime.d.ts +19 -2
  69. package/dist/theming/runtime.js +1 -1
  70. package/dist/{timezone-K-ptz3HO.d.ts → timezone-BTWWXKVY.d.ts} +1 -1
  71. package/dist/types.d.ts +17 -10
  72. package/dist/types.js +1 -0
  73. package/dist/{usePublicPageContext-vxBlEHO9.d.ts → usePublicPageContext-B91dGYW1.d.ts} +433 -356
  74. package/dist/{usePublicRouteParams-G3Ks53mk.d.ts → usePublicRouteParams-BgV6VhMi.d.ts} +73 -4
  75. package/dist/utils.d.ts +163 -145
  76. package/dist/utils.js +42 -25
  77. package/docs/api/modules.md +782 -643
  78. package/docs/api-reference/rpc-functions.md +12 -3
  79. package/docs/core-concepts/rbac-system.md +8 -0
  80. package/docs/getting-started/cursor-rules.md +17 -20
  81. package/docs/getting-started/dependencies.md +1 -1
  82. package/docs/getting-started/setup.md +235 -0
  83. package/docs/implementation-guides/authentication.md +27 -0
  84. package/docs/implementation-guides/data-tables.md +176 -3
  85. package/docs/migration/ApiResult-migration.md +25 -0
  86. package/docs/rbac/api-reference.md +33 -31
  87. package/docs/standards/0-standards-overview.md +50 -15
  88. package/docs/standards/1-pace-core-compliance-standards.md +62 -57
  89. package/docs/standards/2-project-structure-standards.md +33 -16
  90. package/docs/standards/3-architecture-standards.md +41 -1
  91. package/docs/standards/4-code-quality-standards.md +26 -6
  92. package/docs/standards/5-styling-standards.md +35 -1
  93. package/docs/standards/6-security-rbac-standards.md +66 -0
  94. package/docs/standards/7-api-tech-stack-standards.md +25 -14
  95. package/docs/standards/8-testing-documentation-standards.md +31 -0
  96. package/docs/standards/9-operations-standards.md +19 -0
  97. package/docs/standards/README.md +20 -201
  98. package/docs/testing/test-setup-for-consumers.md +2 -0
  99. package/docs/troubleshooting/common-issues.md +17 -1
  100. package/docs/troubleshooting/organisation-context-setup.md +8 -0
  101. package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
  102. package/eslint-config-pace-core.cjs +20 -0
  103. package/package.json +14 -20
  104. package/scripts/{build-docs-incremental.js → build-docs.js} +3 -2
  105. package/scripts/setup.cjs +536 -0
  106. package/scripts/validate.cjs +480 -0
  107. package/src/__tests__/helpers/{__tests__/component-test-utils.test.tsx → component-test-utils.test.tsx} +3 -3
  108. package/src/__tests__/helpers/{__tests__/optimized-test-setup.test.ts → optimized-test-setup.test.ts} +2 -2
  109. package/src/__tests__/helpers/{__tests__/supabaseMock.test.ts → supabaseMock.test.ts} +2 -2
  110. package/src/__tests__/helpers/{__tests__/test-providers.test.tsx → test-providers.test.tsx} +1 -1
  111. package/src/__tests__/helpers/test-providers.tsx +37 -39
  112. package/src/__tests__/helpers/{__tests__/test-utils.test.tsx → test-utils.test.tsx} +4 -3
  113. package/src/__tests__/helpers/{__tests__/timer-utils.test.ts → timer-utils.test.ts} +2 -2
  114. package/src/assets/app-icons/index.test.ts +304 -0
  115. package/src/components/AddressField/AddressField.test.tsx +1 -1
  116. package/src/components/AddressField/AddressField.tsx +238 -212
  117. package/src/components/Button/Button.tsx +1 -1
  118. package/src/components/Card/Card.test.tsx +172 -17
  119. package/src/components/Card/Card.tsx +19 -10
  120. package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
  121. package/src/components/ContextSelector/{__tests__/ContextSelector.test.tsx → ContextSelector.test.tsx} +6 -6
  122. package/src/components/ContextSelector/ContextSelector.tsx +66 -280
  123. package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
  124. package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
  125. package/src/components/DataTable/AUDIT_REPORT.md +59 -44
  126. package/src/components/DataTable/{__tests__/DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx} +6 -6
  127. package/src/components/DataTable/{__tests__/DataTable.default-state.test.tsx → DataTable.default-state.test.tsx} +5 -5
  128. package/src/components/DataTable/{__tests__/DataTable.export.test.tsx → DataTable.export.test.tsx} +10 -10
  129. package/src/components/DataTable/{__tests__/DataTable.grouping-aggregation.test.tsx → DataTable.grouping-aggregation.test.tsx} +6 -6
  130. package/src/components/DataTable/{__tests__/DataTable.hooks.test.tsx → DataTable.hooks.test.tsx} +6 -6
  131. package/src/components/DataTable/{__tests__/DataTable.select-label-display.test.tsx → DataTable.select-label-display.test.tsx} +6 -6
  132. package/src/components/DataTable/DataTable.test.tsx +787 -416
  133. package/src/components/DataTable/DataTable.tsx +12 -12
  134. package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
  135. package/src/components/DataTable/{__tests__/DataTableCore.test-setup.ts → DataTableCore.test-setup.ts} +10 -9
  136. package/src/components/DataTable/{__tests__/DataTableCore.test.tsx → DataTableCore.test.tsx} +8 -8
  137. package/src/components/DataTable/{__tests__/README.md → README.md} +17 -7
  138. package/src/components/DataTable/TESTING.md +101 -0
  139. package/src/components/DataTable/{__tests__/a11y.basic.test.tsx → a11y.basic.test.tsx} +34 -34
  140. package/src/components/DataTable/components/DataTableCore.tsx +104 -864
  141. package/src/components/DataTable/components/{__tests__/GroupingDropdown.test.tsx → GroupingDropdown.test.tsx} +17 -8
  142. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +61 -559
  144. package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
  145. package/src/components/DataTable/context/{__tests__/DataTableContext.test.tsx → DataTableContext.test.tsx} +2 -2
  146. package/src/components/DataTable/context/DataTableContext.tsx +7 -6
  147. package/src/components/DataTable/core/{__tests__/ColumnFactory.test.ts → ColumnFactory.test.ts} +2 -2
  148. package/src/components/DataTable/hooks/{__tests__/useColumnOrderPersistence.test.ts → useColumnOrderPersistence.test.ts} +2 -2
  149. package/src/components/DataTable/hooks/{__tests__/useColumnVisibilityPersistence.test.ts → useColumnVisibilityPersistence.test.ts} +2 -2
  150. package/src/components/DataTable/hooks/{__tests__/useDataTableConfiguration.test.ts → useDataTableConfiguration.test.ts} +3 -3
  151. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
  152. package/src/components/DataTable/hooks/{__tests__/useDataTableDataPipeline.test.ts → useDataTableDataPipeline.test.ts} +6 -6
  153. package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
  154. package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
  155. package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
  156. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +238 -0
  157. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
  158. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
  159. package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
  160. package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
  161. package/src/components/DataTable/hooks/{__tests__/useDataTablePermissions.test.ts → useDataTablePermissions.test.ts} +11 -11
  162. package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
  163. package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
  164. package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
  165. package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
  166. package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
  167. package/src/components/DataTable/hooks/useDataTableScope.test.ts +110 -0
  168. package/src/components/DataTable/hooks/useDataTableScope.ts +123 -0
  169. package/src/components/DataTable/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +47 -5
  170. package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
  171. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
  172. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
  173. package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
  174. package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
  175. package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
  176. package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
  177. package/src/components/DataTable/hooks/{__tests__/useEffectiveColumnOrder.test.ts → useEffectiveColumnOrder.test.ts} +2 -2
  178. package/src/components/DataTable/hooks/{__tests__/useHierarchicalState.test.ts → useHierarchicalState.test.ts} +2 -2
  179. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.test.ts +3 -3
  180. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.ts +2 -2
  181. package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
  182. package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
  183. package/src/components/DataTable/hooks/{__tests__/useKeyboardNavigation.test.ts → useKeyboardNavigation.test.ts} +3 -3
  184. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
  185. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.test.ts +3 -3
  186. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.ts +3 -3
  187. package/src/components/DataTable/hooks/{__tests__/useServerSideDataEffect.test.ts → useServerSideDataEffect.test.ts} +2 -2
  188. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
  189. package/src/components/DataTable/hooks/{__tests__/useTableColumns.test.ts → useTableColumns.test.ts} +2 -2
  190. package/src/components/DataTable/hooks/{__tests__/useTableHandlers.test.ts → useTableHandlers.test.ts} +25 -4
  191. package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
  192. package/src/components/DataTable/index.ts +18 -17
  193. package/src/components/DataTable/{__tests__/keyboard.test.tsx → keyboard.test.tsx} +41 -63
  194. package/src/components/DataTable/{__tests__/mocks → mocks}/MockRBACProvider.tsx +1 -1
  195. package/src/components/DataTable/{__tests__/pagination.modes.test.tsx → pagination.modes.test.tsx} +6 -6
  196. package/src/components/DataTable/{__tests__/ssr.strict-mode.test.tsx → ssr.strict-mode.test.tsx} +2 -2
  197. package/src/components/DataTable/{__tests__/styles.test.ts → styles.test.ts} +1 -4
  198. package/src/components/DataTable/styles.ts +0 -1
  199. package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
  200. package/src/components/DataTable/{__tests__/test-utils → test-utils}/dataFactories.ts +2 -2
  201. package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
  202. package/src/components/DataTable/{__tests__/test-utils/sharedTestUtils.tsx → test-utils/sharedTestUtils.ts} +97 -66
  203. package/src/components/DataTable/{__tests__/test-utils.ts → test-utils.ts} +1 -1
  204. package/src/components/DataTable/types/actions.ts +71 -0
  205. package/src/components/DataTable/types/base.ts +39 -0
  206. package/src/components/DataTable/types/columns.ts +125 -0
  207. package/src/components/DataTable/types/export.ts +32 -0
  208. package/src/components/DataTable/types/features.ts +81 -0
  209. package/src/components/DataTable/types/hierarchical.ts +44 -0
  210. package/src/components/DataTable/types/index.ts +43 -0
  211. package/src/components/DataTable/types/pagination.ts +85 -0
  212. package/src/components/DataTable/types/performance.ts +47 -0
  213. package/src/components/DataTable/types/props.ts +62 -0
  214. package/src/components/DataTable/types/rbac.ts +45 -0
  215. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableCore.test.tsx +430 -28
  216. package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
  217. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableErrorBoundary.test.tsx +4 -4
  218. package/src/components/DataTable/{components → ui/layout}/DataTableErrorBoundary.tsx +7 -7
  219. package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
  220. package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
  221. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
  222. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
  223. package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
  224. package/src/components/DataTable/{components → ui/modals}/DataTableModals.tsx +36 -28
  225. package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
  226. package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
  227. package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
  228. package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
  229. package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
  230. package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
  231. package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
  232. package/src/components/DataTable/{components/__tests__ → ui/shared}/AccessDeniedPage.test.tsx +2 -2
  233. package/src/components/DataTable/{components → ui/shared}/AccessDeniedPage.tsx +2 -2
  234. package/src/components/DataTable/{components/__tests__ → ui/shared}/ActionButtons.test.tsx +6 -4
  235. package/src/components/DataTable/{components → ui/shared}/ActionButtons.tsx +4 -4
  236. package/src/components/DataTable/{components/__tests__ → ui/shared}/ColumnFilter.test.tsx +29 -16
  237. package/src/components/DataTable/{components → ui/shared}/ColumnFilter.tsx +4 -4
  238. package/src/components/DataTable/{components/__tests__ → ui/shared}/PaginationControls.test.tsx +38 -16
  239. package/src/components/DataTable/{components → ui/shared}/PaginationControls.tsx +21 -15
  240. package/src/components/DataTable/{components/__tests__ → ui/shared}/SortIndicator.test.tsx +2 -2
  241. package/src/components/DataTable/{components → ui/shared}/SortIndicator.tsx +1 -1
  242. package/src/components/DataTable/{components/__tests__ → ui/table}/EditFields.test.tsx +3 -3
  243. package/src/components/DataTable/{components → ui/table}/EditFields.tsx +138 -69
  244. package/src/components/DataTable/{components/__tests__ → ui/table}/EditableRow.test.tsx +36 -27
  245. package/src/components/DataTable/{components → ui/table}/EditableRow.tsx +86 -104
  246. package/src/components/DataTable/{components/__tests__ → ui/table}/EmptyState.test.tsx +2 -62
  247. package/src/components/DataTable/{components → ui/table}/EmptyState.tsx +7 -15
  248. package/src/components/DataTable/{components/__tests__ → ui/table}/FilterRow.test.tsx +5 -4
  249. package/src/components/DataTable/{components → ui/table}/FilterRow.tsx +3 -3
  250. package/src/components/DataTable/{components/__tests__ → ui/table}/LoadingState.test.tsx +6 -10
  251. package/src/components/DataTable/{components → ui/table}/LoadingState.tsx +4 -4
  252. package/src/components/DataTable/{components/__tests__ → ui/table}/RowComponent.test.tsx +412 -17
  253. package/src/components/DataTable/{components → ui/table}/RowComponent.tsx +183 -177
  254. package/src/components/DataTable/{components/__tests__ → ui/table}/UnifiedTableBody.test.tsx +425 -16
  255. package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
  256. package/src/components/DataTable/{components/__tests__ → ui/table}/cellValueUtils.test.ts +2 -2
  257. package/src/components/DataTable/{components → ui/table}/cellValueUtils.ts +1 -1
  258. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/BulkOperationsDropdown.test.tsx +12 -5
  259. package/src/components/DataTable/{components → ui/toolbar}/BulkOperationsDropdown.tsx +3 -3
  260. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/ColumnVisibilityDropdown.test.tsx +7 -4
  261. package/src/components/DataTable/{components → ui/toolbar}/ColumnVisibilityDropdown.tsx +7 -7
  262. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/DataTableToolbar.test.tsx +4 -4
  263. package/src/components/DataTable/{components → ui/toolbar}/DataTableToolbar.tsx +4 -4
  264. package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
  265. package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
  266. package/src/components/DataTable/utils/{__tests__/a11yUtils.test.ts → a11yUtils.test.ts} +2 -2
  267. package/src/components/DataTable/utils/{__tests__/aggregationUtils.test.ts → aggregationUtils.test.ts} +3 -3
  268. package/src/components/DataTable/utils/{__tests__/columnUtils.test.ts → columnUtils.test.ts} +2 -2
  269. package/src/components/DataTable/utils/csvParse.test.ts +74 -0
  270. package/src/components/DataTable/utils/csvParse.ts +65 -0
  271. package/src/components/DataTable/utils/{__tests__/errorHandling.test.ts → errorHandling.test.ts} +2 -2
  272. package/src/components/DataTable/utils/{__tests__/exportUtils.test.ts → exportUtils.test.ts} +3 -3
  273. package/src/components/DataTable/utils/{__tests__/flexibleImport.test.ts → flexibleImport.test.ts} +2 -2
  274. package/src/components/DataTable/utils/flexibleImport.ts +3 -186
  275. package/src/components/DataTable/utils/{__tests__/hierarchicalSorting.test.ts → hierarchicalSorting.test.ts} +3 -3
  276. package/src/components/DataTable/utils/{__tests__/hierarchicalUtils.test.ts → hierarchicalUtils.test.ts} +3 -3
  277. package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
  278. package/src/components/DataTable/utils/importDateParser.ts +114 -0
  279. package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
  280. package/src/components/DataTable/utils/importValueParser.ts +91 -0
  281. package/src/components/DataTable/utils/{__tests__/paginationUtils.test.ts → paginationUtils.test.ts} +2 -2
  282. package/src/components/DataTable/utils/paginationUtils.ts +6 -3
  283. package/src/components/DataTable/utils/{__tests__/performanceUtils.test.ts → performanceUtils.test.ts} +3 -3
  284. package/src/components/DataTable/utils/{__tests__/rowUtils.test.ts → rowUtils.test.ts} +3 -3
  285. package/src/components/DataTable/utils/{__tests__/selectFieldUtils.test.ts → selectFieldUtils.test.ts} +66 -3
  286. package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
  287. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
  288. package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
  289. package/src/components/Dialog/Dialog.test-utils.ts +49 -0
  290. package/src/components/Dialog/Dialog.test.tsx +896 -89
  291. package/src/components/Dialog/Dialog.tsx +174 -882
  292. package/src/components/Dialog/dialogLock.test.ts +238 -0
  293. package/src/components/Dialog/dialogLock.ts +98 -0
  294. package/src/components/Dialog/index.ts +2 -0
  295. package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
  296. package/src/components/Dialog/useDialogDimensions.ts +140 -0
  297. package/src/components/Dialog/useDialogLifecycle.test.ts +358 -0
  298. package/src/components/Dialog/useDialogLifecycle.ts +135 -0
  299. package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
  300. package/src/components/Dialog/useDialogPersistence.ts +357 -0
  301. package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
  302. package/src/components/FileDisplay/FileDisplay.tsx +24 -656
  303. package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
  304. package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
  305. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
  306. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
  307. package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
  308. package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
  309. package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
  310. package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
  311. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
  312. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
  313. package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
  314. package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
  315. package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
  316. package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
  317. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
  318. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
  319. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
  320. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
  321. package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
  322. package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
  323. package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
  324. package/src/components/FileDisplay/fallbackUtils.ts +44 -0
  325. package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
  326. package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
  327. package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
  328. package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
  329. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.test.ts +40 -42
  330. package/src/components/FileDisplay/useFileDisplay.ts +515 -0
  331. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.unit.test.ts +406 -77
  332. package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
  333. package/src/{hooks/public → components/FileDisplay}/usePublicFileDisplay.test.ts +94 -88
  334. package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
  335. package/src/components/FileUpload/FileUpload.test.tsx +16 -10
  336. package/src/components/FileUpload/FileUpload.tsx +107 -525
  337. package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
  338. package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
  339. package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
  340. package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
  341. package/src/components/FileUpload/useFileUploadManager.ts +454 -0
  342. package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
  343. package/src/components/FileUpload/useResolvedAppId.ts +77 -0
  344. package/src/components/Footer/Footer.test.tsx +6 -292
  345. package/src/components/Footer/Footer.tsx +8 -125
  346. package/src/components/Form/Form.test.tsx +44 -27
  347. package/src/components/Form/Form.tsx +64 -287
  348. package/src/components/Form/useFormPersistence.ts +257 -0
  349. package/src/components/Header/Header.test.tsx +17 -18
  350. package/src/components/Header/Header.tsx +10 -1
  351. package/src/components/Input/Input.tsx +1 -1
  352. package/src/components/Label/Label.test.tsx +1 -1
  353. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
  354. package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
  355. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
  356. package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
  357. package/src/components/NavigationMenu/index.ts +6 -1
  358. package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
  359. package/src/components/NavigationMenu/{__tests__/useNavigationFiltering.test.ts → useNavigationFiltering.test.ts} +68 -53
  360. package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
  361. package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
  362. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +77 -62
  363. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
  364. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
  365. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
  366. package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
  367. package/src/components/PaceAppLayout/useFilteredNavItems.ts +304 -0
  368. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +142 -0
  369. package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
  370. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
  371. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +79 -0
  372. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
  373. package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
  374. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
  376. package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
  377. package/src/components/Progress/Progress.tsx +1 -2
  378. package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
  379. package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
  380. package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
  381. package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
  382. package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
  383. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
  384. package/src/components/Select/Select.test.tsx +1 -1
  385. package/src/components/Select/Select.tsx +28 -18
  386. package/src/components/Select/{__tests__/context.test.tsx → context.test.tsx} +3 -3
  387. package/src/components/Select/{utils/__tests__/text.test.tsx → text.test.tsx} +2 -2
  388. package/src/components/Select/{utils/text.ts → text.ts} +1 -1
  389. package/src/components/Select/{hooks/__tests__/useSelectEvents.test.ts → useSelectEvents.test.ts} +5 -5
  390. package/src/components/Select/{hooks/useSelectEvents.ts → useSelectEvents.ts} +2 -2
  391. package/src/components/Select/{hooks/__tests__/useSelectSearch.test.tsx → useSelectSearch.test.tsx} +7 -7
  392. package/src/components/Select/{hooks/useSelectSearch.ts → useSelectSearch.ts} +2 -2
  393. package/src/components/Select/{hooks/__tests__/useSelectState.test.ts → useSelectState.test.ts} +16 -2
  394. package/src/components/Select/{hooks/useSelectState.ts → useSelectState.ts} +3 -3
  395. package/src/components/Table/Table.test.tsx +348 -0
  396. package/src/components/Tabs/Tabs.test.tsx +270 -0
  397. package/src/components/Tabs/Tabs.tsx +1 -1
  398. package/src/components/Toast/Toast.test.tsx +420 -0
  399. package/src/components/{__tests__/index.test.ts → index.test.ts} +2 -2
  400. package/src/constants/{__tests__/performance.test.ts → performance.test.ts} +2 -2
  401. package/src/hooks/{__tests__/ServiceHooks.test.tsx → ServiceHooks.test.tsx} +8 -8
  402. package/src/hooks/{__tests__/hooks.integration.test.tsx → hooks.integration.test.tsx} +11 -11
  403. package/src/hooks/index.ts +7 -4
  404. package/src/hooks/{__tests__/index.unit.test.ts → index.unit.test.ts} +2 -2
  405. package/src/hooks/public/usePublicEvent.test.ts +1 -1
  406. package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
  407. package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
  408. package/src/hooks/services/useAuth.ts +9 -7
  409. package/src/hooks/useAddressAutocomplete.test.ts +22 -22
  410. package/src/hooks/useAddressAutocomplete.ts +90 -75
  411. package/src/hooks/{__tests__/useAppConfig.unit.test.ts → useAppConfig.unit.test.ts} +328 -22
  412. package/src/hooks/{__tests__/useComponentPerformance.unit.test.tsx → useComponentPerformance.unit.test.tsx} +27 -41
  413. package/src/hooks/useDataTablePerformance.ts +100 -120
  414. package/src/hooks/{__tests__/useDataTablePerformance.unit.test.ts → useDataTablePerformance.unit.test.ts} +5 -5
  415. package/src/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +2 -2
  416. package/src/hooks/{__tests__/useDebounce.unit.test.ts → useDebounce.unit.test.ts} +2 -2
  417. package/src/hooks/useEventTheme.test.ts +4 -1
  418. package/src/hooks/useEventTheme.ts +49 -21
  419. package/src/hooks/useEvents.ts +41 -1
  420. package/src/hooks/{__tests__/useEvents.unit.test.ts → useEvents.unit.test.ts} +5 -5
  421. package/src/hooks/useFileReference.test.ts +44 -41
  422. package/src/hooks/useFileReference.ts +182 -173
  423. package/src/hooks/useFileUrl.ts +1 -1
  424. package/src/hooks/{__tests__/useFileUrl.unit.test.ts → useFileUrl.unit.test.ts} +26 -36
  425. package/src/hooks/{__tests__/useFileUrlCache.test.ts → useFileUrlCache.test.ts} +8 -8
  426. package/src/hooks/useFileUrlCache.ts +1 -1
  427. package/src/hooks/{__tests__/useFocusManagement.unit.test.ts → useFocusManagement.unit.test.ts} +2 -2
  428. package/src/hooks/{__tests__/useFocusTrap.unit.test.tsx → useFocusTrap.unit.test.tsx} +2 -2
  429. package/src/hooks/{__tests__/useFormDialog.test.ts → useFormDialog.test.ts} +2 -2
  430. package/src/hooks/useInactivityTracker.ts +138 -131
  431. package/src/hooks/{__tests__/useInactivityTracker.unit.test.ts → useInactivityTracker.unit.test.ts} +3 -3
  432. package/src/hooks/{__tests__/useIsMobile.unit.test.ts → useIsMobile.unit.test.ts} +2 -2
  433. package/src/hooks/useIsPrint.ts +62 -0
  434. package/src/hooks/useIsPrint.unit.test.ts +545 -0
  435. package/src/hooks/{__tests__/useKeyboardShortcuts.unit.test.ts → useKeyboardShortcuts.unit.test.ts} +2 -2
  436. package/src/hooks/{__tests__/useOrganisationPermissions.unit.test.tsx → useOrganisationPermissions.unit.test.tsx} +4 -4
  437. package/src/hooks/useOrganisationSecurity.test.ts +3 -3
  438. package/src/hooks/useOrganisationSecurity.ts +190 -201
  439. package/src/hooks/{__tests__/useOrganisationSecurity.unit.test.tsx → useOrganisationSecurity.unit.test.tsx} +61 -63
  440. package/src/hooks/{__tests__/useOrganisations.unit.test.ts → useOrganisations.unit.test.ts} +5 -5
  441. package/src/hooks/{__tests__/usePerformanceMonitor.unit.test.ts → usePerformanceMonitor.unit.test.ts} +13 -14
  442. package/src/hooks/{__tests__/usePermissionCache.test.ts → usePermissionCache.test.ts} +26 -27
  443. package/src/hooks/usePermissionCache.ts +276 -271
  444. package/src/hooks/{__tests__/usePreventTabReload.test.ts → usePreventTabReload.test.ts} +2 -2
  445. package/src/hooks/{__tests__/usePublicEvent.simple.test.ts → usePublicEvent.simple.test.ts} +4 -4
  446. package/src/hooks/{__tests__/usePublicEvent.test.ts → usePublicEvent.test.ts} +4 -4
  447. package/src/hooks/{__tests__/usePublicEvent.unit.test.ts → usePublicEvent.unit.test.ts} +4 -4
  448. package/src/hooks/{__tests__/usePublicFileDisplay.test.ts → usePublicFileDisplay.test.ts} +12 -12
  449. package/src/hooks/{__tests__/usePublicRouteParams.unit.test.ts → usePublicRouteParams.unit.test.ts} +3 -3
  450. package/src/hooks/{__tests__/useQueryCache.test.ts → useQueryCache.test.ts} +2 -2
  451. package/src/hooks/useQueryCache.ts +0 -2
  452. package/src/hooks/{__tests__/useRBAC.unit.test.ts → useRBAC.unit.test.ts} +55 -38
  453. package/src/hooks/{__tests__/useSessionDraft.test.ts → useSessionDraft.test.ts} +2 -2
  454. package/src/hooks/{__tests__/useSessionRestoration.unit.test.tsx → useSessionRestoration.unit.test.tsx} +10 -19
  455. package/src/hooks/useStorage.ts +21 -16
  456. package/src/hooks/{__tests__/useStorage.unit.test.ts → useStorage.unit.test.ts} +38 -75
  457. package/src/hooks/{__tests__/useToast.test.ts → useToast.test.ts} +2 -2
  458. package/src/hooks/{__tests__/useToast.unit.test.tsx → useToast.unit.test.tsx} +2 -2
  459. package/src/hooks/{__tests__/useZodForm.unit.test.tsx → useZodForm.unit.test.tsx} +2 -2
  460. package/src/icons/{__tests__/index.test.ts → index.test.ts} +2 -2
  461. package/src/icons/index.ts +2 -0
  462. package/src/{__tests__/index.test.ts → index.test.ts} +3 -7
  463. package/src/index.ts +15 -7
  464. package/src/providers/{__tests__/AuthProvider.test.tsx → AuthProvider.test.tsx} +3 -3
  465. package/src/providers/{__tests__/EventProvider.test.tsx → EventProvider.test.tsx} +3 -3
  466. package/src/providers/InactivityProvider.test-helper.tsx +40 -0
  467. package/src/providers/{__tests__/InactivityProvider.test.tsx → InactivityProvider.test.tsx} +14 -21
  468. package/src/providers/{__tests__/ProviderLifecycle.test.tsx → ProviderLifecycle.test.tsx} +4 -4
  469. package/src/providers/{__tests__/UnifiedAuthProvider.test.tsx → UnifiedAuthProvider.test.tsx} +1 -1
  470. package/src/providers/{__tests__/index.test.ts → index.test.ts} +2 -2
  471. package/src/providers/services/{__tests__/AuthServiceProvider.integration.test.tsx → AuthServiceProvider.integration.test.tsx} +4 -4
  472. package/src/providers/services/{__tests__/AuthServiceProvider.test.tsx → AuthServiceProvider.test.tsx} +7 -7
  473. package/src/providers/services/{__tests__/EventServiceProvider.test.tsx → EventServiceProvider.test.tsx} +7 -7
  474. package/src/providers/services/{__tests__/InactivityServiceProvider.test.tsx → InactivityServiceProvider.test.tsx} +5 -5
  475. package/src/providers/services/{__tests__/OrganisationServiceProvider.test.tsx → OrganisationServiceProvider.test.tsx} +6 -6
  476. package/src/providers/services/UnifiedAuthContext.ts +30 -27
  477. package/src/providers/services/{__tests__/UnifiedAuthProvider.advanced.test.tsx → UnifiedAuthProvider.advanced.test.tsx} +8 -9
  478. package/src/providers/services/{__tests__/UnifiedAuthProvider.appId.test.tsx → UnifiedAuthProvider.appId.test.tsx} +25 -25
  479. package/src/providers/services/{__tests__/UnifiedAuthProvider.integration.test.tsx → UnifiedAuthProvider.integration.test.tsx} +14 -11
  480. package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
  481. package/src/providers/services/{__tests__/contexts.test.tsx → contexts.test.tsx} +6 -6
  482. package/src/providers/services/{__tests__/useUnifiedAuth.test.tsx → useUnifiedAuth.test.tsx} +6 -6
  483. package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
  484. package/src/providers/useInactivity.test-helper.ts +27 -0
  485. package/src/rbac/{__tests__/adapters.comprehensive.test.tsx → adapters.comprehensive.test.tsx} +24 -24
  486. package/src/rbac/adapters.test.tsx +22 -22
  487. package/src/rbac/adapters.tsx +29 -29
  488. package/src/rbac/api.test.ts +973 -42
  489. package/src/rbac/api.ts +228 -253
  490. package/src/rbac/{__tests__/audit-batched.test.ts → audit-batched.test.ts} +6 -6
  491. package/src/rbac/audit.ts +4 -1
  492. package/src/rbac/{__tests__/auth-rbac-security.integration.test.tsx → auth-rbac-security.integration.test.tsx} +1 -1
  493. package/src/rbac/{__tests__/auth-rbac.e2e.test.tsx → auth-rbac.e2e.test.tsx} +27 -34
  494. package/src/rbac/cache-invalidation.test.ts +715 -0
  495. package/src/rbac/components/{__tests__/AccessDenied.test.tsx → AccessDenied.test.tsx} +3 -3
  496. package/src/rbac/components/{__tests__/NavigationGuard.test.tsx → NavigationGuard.test.tsx} +13 -11
  497. package/src/{__tests__/rbac/PagePermissionGuard.test.tsx → rbac/components/PagePermissionGuard.guard.test.tsx} +33 -19
  498. package/src/rbac/components/{__tests__/PagePermissionGuard.performance.test.tsx → PagePermissionGuard.performance.test.tsx} +30 -9
  499. package/src/rbac/components/{__tests__/PagePermissionGuard.race-condition.test.tsx → PagePermissionGuard.race-condition.test.tsx} +7 -7
  500. package/src/rbac/components/{__tests__/PagePermissionGuard.test.tsx → PagePermissionGuard.test.tsx} +10 -10
  501. package/src/rbac/components/PagePermissionGuard.tsx +177 -372
  502. package/src/rbac/components/{__tests__/PagePermissionGuard.verification.test.tsx → PagePermissionGuard.verification.test.tsx} +7 -7
  503. package/src/rbac/config.ts +58 -18
  504. package/src/rbac/{__tests__/engine.comprehensive.test.ts → engine.comprehensive.test.ts} +3 -3
  505. package/src/rbac/engine.test.ts +494 -0
  506. package/src/rbac/errors.ts +89 -55
  507. package/src/rbac/hooks/permissions/runPermissionCheck.ts +77 -0
  508. package/src/rbac/hooks/permissions/{__tests__/useAccessLevel.test.ts → useAccessLevel.test.ts} +40 -40
  509. package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
  510. package/src/rbac/hooks/permissions/{__tests__/useCan.test.ts → useCan.test.ts} +41 -41
  511. package/src/rbac/hooks/permissions/useCan.ts +170 -252
  512. package/src/rbac/hooks/permissions/{__tests__/useMultiplePermissions.test.ts → useMultiplePermissions.test.ts} +49 -49
  513. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +6 -2
  514. package/src/rbac/hooks/permissions/{__tests__/usePermissions.test.ts → usePermissions.test.ts} +10 -12
  515. package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
  516. package/src/rbac/hooks/useCan.test.ts +42 -42
  517. package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
  518. package/src/rbac/hooks/usePageGuardScope.ts +117 -0
  519. package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
  520. package/src/rbac/hooks/{__tests__/usePermissions.integration.test.ts → usePermissions.integration.test.ts} +9 -9
  521. package/src/{__tests__/hooks/usePermissions.test.ts → rbac/hooks/usePermissions.stability.test.ts} +18 -18
  522. package/src/rbac/hooks/usePermissions.test.ts +54 -54
  523. package/src/rbac/hooks/useRBAC.test.ts +313 -217
  524. package/src/rbac/hooks/useRBAC.ts +145 -81
  525. package/src/rbac/hooks/useResourcePermissions.test.ts +25 -25
  526. package/src/rbac/hooks/useResourcePermissions.ts +68 -134
  527. package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
  528. package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
  529. package/src/rbac/hooks/useRoleManagement.ts +153 -585
  530. package/src/rbac/hooks/{__tests__/useSecureSupabase.test.ts → useSecureSupabase.test.ts} +17 -17
  531. package/src/rbac/hooks/useSecureSupabase.ts +10 -2
  532. package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
  533. package/src/rbac/{__tests__/performance.test.ts → performance.test.ts} +1 -1
  534. package/src/rbac/{__tests__/rbac-core.test.tsx → rbac-core.test.tsx} +3 -3
  535. package/src/rbac/{__tests__/rbac-engine-core-logic.test.ts → rbac-engine-core-logic.test.ts} +2 -2
  536. package/src/rbac/{__tests__/rbac-engine-simplified.test.ts → rbac-engine-simplified.test.ts} +3 -3
  537. package/src/rbac/{__tests__/rbac-functions.test.ts → rbac-functions.test.ts} +57 -0
  538. package/src/rbac/{__tests__/rbac-role-isolation.test.ts → rbac-role-isolation.test.ts} +2 -2
  539. package/src/rbac/request-deduplication.test.ts +14 -9
  540. package/src/rbac/request-deduplication.ts +5 -4
  541. package/src/rbac/{__tests__/scenarios.user-role.test.tsx → scenarios.user-role.test.tsx} +23 -23
  542. package/src/rbac/secureClient.test.ts +514 -83
  543. package/src/rbac/secureClient.ts +8 -2
  544. package/src/rbac/security.test.ts +323 -0
  545. package/src/rbac/types/roleManagement.ts +66 -0
  546. package/src/rbac/utils/{__tests__/clientSecurity.test.ts → clientSecurity.test.ts} +4 -4
  547. package/src/rbac/utils/{__tests__/contextValidator.test.ts → contextValidator.test.ts} +4 -4
  548. package/src/rbac/utils/contextValidator.ts +5 -1
  549. package/src/rbac/utils/{__tests__/deep-equal.test.ts → deep-equal.test.ts} +1 -1
  550. package/src/rbac/utils/{__tests__/eventContext.test.ts → eventContext.test.ts} +36 -21
  551. package/src/rbac/utils/eventContext.ts +37 -33
  552. package/src/rbac/utils/fetchPermissionMap.ts +13 -0
  553. package/src/rbac/utils/permissionMapHelpers.ts +34 -0
  554. package/src/rbac/utils/roleManagementRpc.ts +303 -0
  555. package/src/services/{__tests__/AuthService.edge-cases.test.ts → AuthService.edge-cases.test.ts} +19 -19
  556. package/src/services/{__tests__/AuthService.restoreSession.test.ts → AuthService.restoreSession.test.ts} +2 -2
  557. package/src/services/{__tests__/AuthService.test.ts → AuthService.test.ts} +89 -55
  558. package/src/services/AuthService.ts +184 -205
  559. package/src/services/{__tests__/BaseService.edge-cases.test.ts → BaseService.edge-cases.test.ts} +3 -3
  560. package/src/services/{__tests__/BaseService.test.ts → BaseService.test.ts} +2 -2
  561. package/src/services/{__tests__/EventService.edge-cases.test.ts → EventService.edge-cases.test.ts} +27 -24
  562. package/src/services/{__tests__/EventService.eventColours.test.ts → EventService.eventColours.test.ts} +1 -1
  563. package/src/services/{__tests__/EventService.test.ts → EventService.test.ts} +256 -24
  564. package/src/services/EventService.ts +242 -312
  565. package/src/services/{__tests__/InactivityService.edge-cases.test.ts → InactivityService.edge-cases.test.ts} +3 -3
  566. package/src/services/{__tests__/InactivityService.lifecycle.test.ts → InactivityService.lifecycle.test.ts} +2 -2
  567. package/src/services/{__tests__/InactivityService.test.ts → InactivityService.test.ts} +179 -4
  568. package/src/services/InactivityService.ts +172 -213
  569. package/src/services/{__tests__/OrganisationService.edge-cases.test.ts → OrganisationService.edge-cases.test.ts} +5 -5
  570. package/src/services/{__tests__/OrganisationService.pagination.test.ts → OrganisationService.pagination.test.ts} +4 -4
  571. package/src/services/{__tests__/OrganisationService.test.ts → OrganisationService.test.ts} +410 -7
  572. package/src/services/OrganisationService.ts +184 -238
  573. package/src/services/base/BaseService.test.ts +1 -1
  574. package/src/services/interfaces/{__tests__/IAuthService.test.ts → IAuthService.test.ts} +21 -27
  575. package/src/services/interfaces/IAuthService.ts +10 -9
  576. package/src/services/interfaces/{__tests__/IEventService.test.ts → IEventService.test.ts} +4 -4
  577. package/src/services/interfaces/{__tests__/IInactivityService.test.ts → IInactivityService.test.ts} +3 -3
  578. package/src/services/interfaces/{__tests__/IOrganisationService.test.ts → IOrganisationService.test.ts} +3 -3
  579. package/src/styles/core.css +243 -12
  580. package/src/theming/{__tests__/parseEventColours.test.ts → parseEventColours.test.ts} +1 -1
  581. package/src/theming/{__tests__/runtime.test.ts → runtime.test.ts} +8 -17
  582. package/src/theming/runtime.ts +71 -2
  583. package/src/types/api-result.ts +53 -0
  584. package/src/types/{__tests__/core.test.ts → core.test.ts} +2 -2
  585. package/src/types/{__tests__/database-generated.test.ts → database-generated.test.ts} +3 -3
  586. package/src/types/database.generated.ts +45 -10
  587. package/src/types/event.ts +38 -18
  588. package/src/types/{__tests__/file-reference.test.ts → file-reference.test.ts} +13 -13
  589. package/src/types/file-reference.ts +37 -12
  590. package/src/types/{__tests__/guards.test.ts → guards.test.ts} +2 -2
  591. package/src/types/{__tests__/index.test.ts → index.test.ts} +2 -2
  592. package/src/types/index.ts +3 -0
  593. package/src/types/{__tests__/organisation.roles.test.ts → organisation.roles.test.ts} +1 -1
  594. package/src/types/{__tests__/organisation.test.ts → organisation.test.ts} +3 -31
  595. package/src/types/organisation.ts +15 -15
  596. package/src/types/supabase.ts +13 -4
  597. package/src/types/{__tests__/theme.test.ts → theme.test.ts} +1 -1
  598. package/src/types/{__tests__/type-validation.test.ts → type-validation.test.ts} +1 -1
  599. package/src/types/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  600. package/src/utils/app/appIdResolver.test.ts +98 -71
  601. package/src/utils/app/appIdResolver.ts +31 -20
  602. package/src/utils/{__tests__/appConfig.unit.test.ts → appConfig.unit.test.ts} +1 -1
  603. package/src/utils/{__tests__/audit.unit.test.ts → audit.unit.test.ts} +1 -1
  604. package/src/utils/{__tests__/auth-utils.unit.test.ts → auth-utils.unit.test.ts} +16 -17
  605. package/src/utils/{__tests__/bundleAnalysis.unit.test.ts → bundleAnalysis.unit.test.ts} +35 -35
  606. package/src/utils/{__tests__/cn.unit.test.ts → cn.unit.test.ts} +1 -1
  607. package/src/utils/context/organisationContext.test.ts +105 -91
  608. package/src/utils/context/organisationContext.ts +29 -40
  609. package/src/utils/core/{__tests__/cn.test.ts → cn.test.ts} +3 -3
  610. package/src/utils/core/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +2 -2
  611. package/src/utils/core/{__tests__/logger.test.ts → logger.test.ts} +2 -2
  612. package/src/utils/core/mergeRefs.ts +24 -0
  613. package/src/utils/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +1 -1
  614. package/src/utils/{__tests__/deviceFingerprint.unit.test.ts → deviceFingerprint.unit.test.ts} +1 -1
  615. package/src/utils/dynamic/createLazyComponent.tsx +9 -1
  616. package/src/utils/dynamic/{__tests__/dynamicUtils.test.ts → dynamicUtils.test.ts} +2 -2
  617. package/src/utils/dynamic/{__tests__/lazyLoad.test.tsx → lazyLoad.test.tsx} +2 -2
  618. package/src/utils/{__tests__/dynamicUtils.unit.test.ts → dynamicUtils.unit.test.ts} +1 -1
  619. package/src/utils/file-reference/{__tests__/file-reference.test.ts → file-reference.test.ts} +214 -289
  620. package/src/utils/file-reference/index.ts +330 -347
  621. package/src/utils/{__tests__/formatDate.unit.test.ts → formatDate.unit.test.ts} +2 -2
  622. package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
  623. package/src/utils/formatting/formatNumber.test.ts +1 -1
  624. package/src/utils/{__tests__/formatting.unit.test.ts → formatting.unit.test.ts} +1 -1
  625. package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
  626. package/src/utils/google-places/googlePlacesUtils.ts +67 -99
  627. package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
  628. package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
  629. package/src/utils/{__tests__/index.unit.test.ts → index.unit.test.ts} +1 -1
  630. package/src/utils/{__tests__/lazyLoad.unit.test.tsx → lazyLoad.unit.test.tsx} +13 -14
  631. package/src/utils/location/location.test.ts +1 -1
  632. package/src/utils/{__tests__/logger.unit.test.ts → logger.unit.test.ts} +1 -1
  633. package/src/utils/{__tests__/organisationContext.unit.test.ts → organisationContext.unit.test.ts} +37 -48
  634. package/src/utils/performance/{__tests__/bundleAnalysis.test.ts → bundleAnalysis.test.ts} +2 -2
  635. package/src/utils/performance/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  636. package/src/utils/performance/{__tests__/performanceBudgets.test.ts → performanceBudgets.test.ts} +2 -2
  637. package/src/utils/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  638. package/src/utils/{__tests__/performanceBudgets.unit.test.ts → performanceBudgets.unit.test.ts} +2 -2
  639. package/src/utils/{__tests__/permissionTypes.unit.test.ts → permissionTypes.unit.test.ts} +1 -1
  640. package/src/utils/{__tests__/permissionUtils.unit.test.ts → permissionUtils.unit.test.ts} +1 -1
  641. package/src/utils/permissions/{__tests__/permissionTypes.test.ts → permissionTypes.test.ts} +2 -2
  642. package/src/utils/persistence/{__tests__/keyDerivation.test.ts → keyDerivation.test.ts} +2 -2
  643. package/src/utils/persistence/{__tests__/sensitiveFieldDetection.test.ts → sensitiveFieldDetection.test.ts} +2 -2
  644. package/src/utils/{__tests__/request-deduplication.test.ts → request-deduplication.test.ts} +2 -2
  645. package/src/utils/{__tests__/sanitization.unit.test.ts → sanitization.unit.test.ts} +1 -1
  646. package/src/utils/{__tests__/schemaUtils.unit.test.ts → schemaUtils.unit.test.ts} +1 -1
  647. package/src/utils/{__tests__/secureDataAccess.unit.test.ts → secureDataAccess.unit.test.ts} +2 -2
  648. package/src/utils/{__tests__/secureErrors.unit.test.ts → secureErrors.unit.test.ts} +4 -4
  649. package/src/utils/{__tests__/secureStorage.unit.test.ts → secureStorage.unit.test.ts} +1 -1
  650. package/src/utils/security/auth-utils.ts +34 -23
  651. package/src/utils/security/secureDataAccess.ts +241 -281
  652. package/src/utils/security/secureErrors.test.ts +1 -1
  653. package/src/utils/security/secureStorage.test.ts +1 -1
  654. package/src/utils/security/security.test.ts +25 -17
  655. package/src/utils/security/security.ts +15 -18
  656. package/src/utils/security/securityMonitor.test.ts +1 -1
  657. package/src/utils/{__tests__/security.unit.test.ts → security.unit.test.ts} +21 -15
  658. package/src/utils/{__tests__/securityMonitor.unit.test.ts → securityMonitor.unit.test.ts} +1 -1
  659. package/src/utils/{__tests__/sessionTracking.unit.test.ts → sessionTracking.unit.test.ts} +12 -12
  660. package/src/utils/storage/{__tests__/config.unit.test.ts → config.unit.test.ts} +2 -2
  661. package/src/utils/storage/helpers.test.ts +88 -102
  662. package/src/utils/storage/helpers.ts +173 -251
  663. package/src/utils/storage/{__tests__/index.unit.test.ts → index.unit.test.ts} +3 -3
  664. package/src/utils/storage/types.ts +7 -0
  665. package/src/utils/supabase/createBaseClient.test.ts +1 -1
  666. package/src/utils/timezone/timezone.test.ts +1 -1
  667. package/src/utils/{__tests__/timezone.test.ts → timezone.test.ts} +2 -2
  668. package/src/utils/validation/{__tests__/common.test.ts → common.test.ts} +2 -2
  669. package/src/utils/validation/{__tests__/csrf.test.ts → csrf.test.ts} +56 -28
  670. package/src/utils/validation/csrf.ts +42 -41
  671. package/src/utils/validation/{__tests__/htmlSanitization.unit.test.ts → htmlSanitization.unit.test.ts} +2 -2
  672. package/src/utils/validation/{__tests__/passwordSchema.test.ts → passwordSchema.test.ts} +2 -2
  673. package/src/utils/validation/{__tests__/schema.test.ts → schema.test.ts} +2 -2
  674. package/src/utils/validation/{__tests__/sqlInjectionProtection.test.ts → sqlInjectionProtection.test.ts} +2 -2
  675. package/src/utils/validation/{__tests__/user.test.ts → user.test.ts} +2 -2
  676. package/src/utils/validation/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  677. package/src/utils/validation/{__tests__/validationUtils.test.ts → validationUtils.test.ts} +2 -2
  678. package/src/utils/{__tests__/validation.unit.test.ts → validation.unit.test.ts} +1 -1
  679. package/src/utils/{__tests__/validationUtils.unit.test.ts → validationUtils.unit.test.ts} +5 -2
  680. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
  681. package/dist/chunk-KPYQWGFQ.js +0 -183
  682. package/dist/types-D05dCGma.d.ts +0 -521
  683. package/scripts/eslint-audit.cjs +0 -222
  684. package/scripts/generate-docs.js +0 -157
  685. package/scripts/install-cursor-rules.cjs +0 -255
  686. package/scripts/install-eslint-config.cjs +0 -349
  687. package/scripts/setup-build-cache.js +0 -73
  688. package/scripts/validate-pre-publish.js +0 -145
  689. package/src/__tests__/integration/UserProfile.test.tsx +0 -124
  690. package/src/__tests__/public-recipe-view.test.ts +0 -228
  691. package/src/__tests__/rls-policies.test.ts +0 -472
  692. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
  693. package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
  694. package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
  695. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
  696. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
  697. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
  698. package/src/components/DataTable/core/ActionManager.ts +0 -235
  699. package/src/components/DataTable/core/ColumnManager.ts +0 -204
  700. package/src/components/DataTable/core/DataManager.ts +0 -190
  701. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
  702. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  703. package/src/components/DataTable/core/StateManager.ts +0 -312
  704. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
  705. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
  706. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
  707. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
  708. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
  709. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
  710. package/src/components/DataTable/core/interfaces.ts +0 -338
  711. package/src/components/DataTable/types.ts +0 -764
  712. package/src/hooks/public/usePublicFileDisplay.ts +0 -534
  713. package/src/hooks/useFileDisplay.ts +0 -748
  714. package/src/providers/OrganisationProvider.test.tsx +0 -40
  715. package/src/providers/OrganisationProvider.tsx +0 -92
  716. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
  717. package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
  718. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
  719. package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
  720. /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
  721. /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
  722. /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
  723. /package/src/providers/{__tests__/README.md → README.md} +0 -0
  724. /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
  725. /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
  726. /package/src/types/{__tests__/README.md → README.md} +0 -0
@@ -514,41 +514,41 @@ SELECT revoke_global_role(
514
514
 
515
515
  ### Event-App Role Management
516
516
 
517
- #### grant_event_app_role()
517
+ #### rbac_role_grant (event-app)
518
518
 
519
- Grants an event-app specific role to a user.
519
+ Grants an event-app role to a user. Use the same RPC `rbac_role_grant` with `p_role_type = 'event_app'` and `p_context_id` in the form `'<event_id>:<app_id>'`.
520
+
521
+ **RPC name:** `rbac_role_grant`
520
522
 
521
523
  **Signature:**
522
524
  ```sql
523
- grant_event_app_role(
524
- p_user_id UUID,
525
- p_event_id UUID,
526
- p_app_id UUID,
527
- p_role TEXT,
528
- p_granted_by UUID DEFAULT auth.uid(),
529
- p_notes TEXT DEFAULT NULL
530
- ) RETURNS UUID
525
+ public.rbac_role_grant(
526
+ p_user_id uuid,
527
+ p_role_type text, -- 'event_app' for event-app roles
528
+ p_role_name text,
529
+ p_context_id text DEFAULT NULL::text, -- '<event_id>:<app_id>' for event_app
530
+ p_granted_by uuid DEFAULT auth.uid()
531
+ )
532
+ RETURNS TABLE(success boolean, message text, role_id uuid, error_code text)
531
533
  ```
532
534
 
533
- **Parameters:**
535
+ **Parameters (event-app):**
534
536
  - `p_user_id`: The user to grant the role to
535
- - `p_event_id`: The event context
536
- - `p_app_id`: The application context
537
- - `p_role`: Event-app role ('viewer', 'participant', 'planner', 'event_admin')
538
- - `p_granted_by`: User granting the role (defaults to current user)
539
- - `p_notes`: Optional notes about the role grant
537
+ - `p_role_type`: `'event_app'` for event-app roles
538
+ - `p_role_name`: Event-app role (`'viewer'`, `'participant'`, `'planner'`, `'event_admin'`)
539
+ - `p_context_id`: `'<event_id>:<app_id>'` (e.g. event code or UUID, then app UUID as text)
540
+ - `p_granted_by`: Optional; user granting the role (defaults to current user)
540
541
 
541
- **Example:**
542
- ```sql
543
- -- Grant event_admin role for specific event and app
544
- SELECT grant_event_app_role(
545
- 'user-123'::UUID,
546
- 'event-789'::UUID,
547
- 'app-101'::UUID,
548
- 'event_admin',
549
- 'admin-user-789'::UUID,
550
- 'Assigned as event administrator'
551
- );
542
+ **Example (application code):**
543
+ ```typescript
544
+ const { data, error } = await supabase.rpc('rbac_role_grant', {
545
+ p_user_id: userId,
546
+ p_role_type: 'event_app',
547
+ p_role_name: 'event_admin',
548
+ p_context_id: `${eventId}:${appId}`,
549
+ p_granted_by: grantedBy ?? undefined,
550
+ });
551
+ // data is array of { success, message, role_id, error_code }
552
552
  ```
553
553
 
554
554
  #### revoke_event_app_role()
@@ -622,13 +622,15 @@ import { createClient } from '@supabase/supabase-js';
622
622
 
623
623
  const supabase = createClient(url, key);
624
624
 
625
- // Grant organisation role
626
- const { data: roleId, error: grantError } = await supabase.rpc('rbac_role_grant', {
625
+ // Grant organisation role (organisation context)
626
+ const { data: grantData, error: grantError } = await supabase.rpc('rbac_role_grant', {
627
627
  p_user_id: 'user-123',
628
- p_organisation_id: 'org-456',
628
+ p_role_type: 'organisation',
629
629
  p_role_name: 'org_admin',
630
- p_notes: 'Promoted to administrator'
630
+ p_context_id: 'org-456', // organisation_id for organisation roles
631
+ p_granted_by: currentUserId,
631
632
  });
633
+ // Grant event-app role: use p_role_type: 'event_app', p_context_id: `${eventId}:${appId}`
632
634
 
633
635
  if (grantError) {
634
636
  console.error('Failed to grant role:', grantError);
@@ -42,6 +42,17 @@ They are intentionally overlapping in *coverage*, but **not duplicative in purpo
42
42
 
43
43
  Think of this as *defence in depth*, not redundancy.
44
44
 
45
+ ```mermaid
46
+ flowchart LR
47
+ Standards[Standards]
48
+ CursorRules[Cursor Rules]
49
+ ESLint[ESLint]
50
+ AuditTool[Audit Tool]
51
+ Standards -->|"Write time"| CursorRules
52
+ Standards -->|"Dev / CI"| ESLint
53
+ Standards -->|"Review / CI"| AuditTool
54
+ ```
55
+
45
56
  ### 1. Standards Documents (Source of Truth)
46
57
 
47
58
  **What they are**
@@ -64,6 +75,8 @@ Think of this as *defence in depth*, not redundancy.
64
75
 
65
76
  ### 2. Cursor Rules (Real-time Guidance)
66
77
 
78
+ Cursor rules live in the package under `cursor-rules/`. Consuming apps copy them into `.cursor/rules/` via `npm run setup` (see [pace-core Compliance](./1-pace-core-compliance-standards.md) for setup steps).
79
+
67
80
  **What they are**
68
81
  - AI-optimised interpretations of the standards
69
82
  - Applied while code is being written or modified
@@ -122,7 +135,7 @@ Think of this as *defence in depth*, not redundancy.
122
135
 
123
136
  ➡️ The audit tool answers: *"Is this system actually compliant?"*
124
137
 
125
- **Usage**: Run `npm run audit:pace-core` in your consuming app to generate a comprehensive audit report organized by standard.
138
+ **Usage:** In a consuming app (or from the repo root with pace-core available), run `npm run validate`. This runs type-check, lint, build, tests, and the pace-core audit. The pace-core audit report is written to `audit/<timestamp>-pace-core-audit.md`; ESLint output is written to `audit/<timestamp>-eslint-report.md` when the lint step runs.
126
139
 
127
140
  ---
128
141
 
@@ -135,9 +148,22 @@ Think of this as *defence in depth*, not redundancy.
135
148
  | ESLint | Fast mechanical enforcement | Dev / CI |
136
149
  | Audit tool | Deep architectural verification | Review / CI |
137
150
 
151
+ | Layer | Out of scope |
152
+ |--------------|--------------|
153
+ | Standards | Not executable; do not enforce by themselves |
154
+ | Cursor rules | Not a replacement for lint or audits |
155
+ | ESLint | Not system-level correctness; not complex business rules |
156
+ | Audit tool | Not stylistic issues; not file-level AST duplication |
157
+
138
158
  No single layer is sufficient on its own.
139
159
  Together, they create a **repeatable, scalable quality system** for both humans and AI.
140
160
 
161
+ ### Traceability
162
+
163
+ - **From audit report to standard:** Each audit section links to the corresponding standard doc (via the report; links are generated in the audit tool).
164
+ - **From ESLint rule to standard:** ESLint rules are grouped by standard (e.g. `01-pace-core-compliance`, `06-security-rbac`); rule names or plugin metadata map to the standard doc.
165
+ - **Principle:** When fixing a finding, open the referenced standard for intent and examples; fix the cause, do not silence the tool.
166
+
141
167
  ---
142
168
 
143
169
  ## Precedence Order
@@ -153,24 +179,31 @@ When standards conflict, apply this precedence order:
153
179
 
154
180
  **Example:** If a component pattern conflicts with a security requirement, security wins.
155
181
 
182
+ ### When tools disagree
183
+
184
+ - Treat the **standards document** as the arbiter. If the standard is clear, the tool that matches it is correct; fix the other or fix the code.
185
+ - If the standard is ambiguous, **update the standard first** (with rationale), then align the tool(s).
186
+ - Do not silence a tool to get a green build; fix the underlying issue or document an explicit, approved exception in the standard.
187
+ - **Remediation:** When the audit (or lint) fails in CI, use the generated report and the linked standard doc to fix issues, then re-run `npm run validate`.
188
+
156
189
  ---
157
190
 
158
191
  ## Standards File Mapping
159
192
 
160
- The standards are organized into 10 files, each covering a specific domain:
161
-
162
- | File | Standard | Cursor Rule | Purpose |
163
- |------|----------|------------|---------|
164
- | `0-standards-overview.md` | Overview | `00-standards-overview.mdc` | This file - entry point and system overview |
165
- | `1-pace-core-compliance-standards.md` | pace-core Compliance | `01-pace-core-compliance.mdc` | Enforce pace-core usage patterns |
166
- | `2-project-structure-standards.md` | Project Structure | `02-project-structure.mdc` | Define standard folder structure |
167
- | `3-architecture-standards.md` | Architecture | `03-architecture.mdc` | Enforce SOLID architecture principles |
168
- | `4-code-quality-standards.md` | Code Quality | `04-code-quality.mdc` | Enforce code quality standards |
169
- | `5-styling-standards.md` | Styling | `05-styling.mdc` | Enforce clean markup and styling standards |
170
- | `6-security-rbac-standards.md` | Security & RBAC | `06-security-rbac.mdc` | Enforce RBAC contract and security |
171
- | `7-api-tech-stack-standards.md` | API & Tech Stack | `07-api-tech-stack.mdc` | Enforce tech stack versions and API standards |
172
- | `8-testing-documentation-standards.md` | Testing & Documentation | `08-testing-documentation.mdc` | Enforce testing and documentation standards |
173
- | `9-operations-standards.md` | Operations | `09-operations.mdc` | Enforce error handling, performance, and CI/CD |
193
+ The standards are organized into 10 files, each covering a specific domain. ESLint rule files are prefixed by standard (e.g. `01-pace-core-compliance`, `06-security-rbac`).
194
+
195
+ | File | Standard | Cursor Rule | ESLint | Audit | Purpose |
196
+ |------|----------|------------|--------|-------|---------|
197
+ | `0-standards-overview.md` | Overview | `00-standards-overview.mdc` | — | — | This file - entry point and system overview |
198
+ | `1-pace-core-compliance-standards.md` | pace-core Compliance | `01-pace-core-compliance.mdc` | Yes | Yes | Enforce pace-core usage patterns |
199
+ | `2-project-structure-standards.md` | Project Structure | `02-project-structure.mdc` | — | Yes | Define standard folder structure |
200
+ | `3-architecture-standards.md` | Architecture | `03-architecture.mdc` | — | Yes | Enforce SOLID architecture principles |
201
+ | `4-code-quality-standards.md` | Code Quality | `04-code-quality.mdc` | Yes | Yes | Enforce code quality standards |
202
+ | `5-styling-standards.md` | Styling | `05-styling.mdc` | Yes | Yes | Enforce clean markup and styling standards |
203
+ | `6-security-rbac-standards.md` | Security & RBAC | `06-security-rbac.mdc` | Yes | Yes | Enforce RBAC contract and security |
204
+ | `7-api-tech-stack-standards.md` | API & Tech Stack | `07-api-tech-stack.mdc` | Yes | Yes | Enforce tech stack versions and API standards |
205
+ | `8-testing-documentation-standards.md` | Testing & Documentation | `08-testing-documentation.mdc` | Yes | Yes | Enforce testing and documentation standards |
206
+ | `9-operations-standards.md` | Operations | `09-operations.mdc` | — | Yes | Enforce error handling, performance, and CI/CD |
174
207
 
175
208
  ---
176
209
 
@@ -218,3 +251,5 @@ The standards are organized into 10 files, each covering a specific domain:
218
251
  **Last Updated:** 2025-01-28
219
252
  **Version:** 2.0.0
220
253
  **Applies to:** All pace-core and consuming apps
254
+
255
+ The standards version (e.g. 2.0.0) is updated when the standards system, precedence, or four-layer model changes; it is independent of the pace-core package version.
@@ -65,12 +65,12 @@ npm install @jmruthers/pace-core
65
65
 
66
66
  **Automated Setup (Easiest)**
67
67
 
68
- Use the installation script to set up ESLint:
68
+ Use the combined setup script to set up ESLint (and other pace-core tools):
69
69
 
70
70
  ```bash
71
- npm run setup:eslint
72
- # or
73
- node node_modules/@jmruthers/pace-core/scripts/install-eslint-config.cjs
71
+ npm run setup
72
+ # or to force update existing configs
73
+ npm run setup -- --force
74
74
  ```
75
75
 
76
76
  This script will:
@@ -147,12 +147,12 @@ export default tseslint.config(
147
147
 
148
148
  **Automated Setup (Easiest)**
149
149
 
150
- Use the installation script to set up Cursor rules:
150
+ Use the combined setup script to set up Cursor rules (and other pace-core tools):
151
151
 
152
152
  ```bash
153
- npm run setup:cursor-rules
154
- # or
155
- node node_modules/@jmruthers/pace-core/scripts/install-cursor-rules.cjs
153
+ npm run setup
154
+ # or to force update existing configs
155
+ npm run setup -- --force
156
156
  ```
157
157
 
158
158
  This script will:
@@ -233,6 +233,8 @@ Rules are organized in `packages/core/eslint-rules/rules/`:
233
233
  - `07-api-tech-stack.cjs` - RPC naming, React 19+, import.meta.env
234
234
  - `08-testing.cjs` - Test file naming
235
235
 
236
+ Rule IDs are under the plugin prefix `pace-core-compliance/` (e.g. `pace-core-compliance/prefer-pace-core-components`). Use this prefix when configuring overrides or looking up rules in IDE/CI output.
237
+
236
238
  ### Detailed Rule Descriptions
237
239
 
238
240
  #### Import Rules
@@ -565,43 +567,21 @@ function YourComponent() {
565
567
  }
566
568
  ```
567
569
 
568
- ## Static Analysis Script
569
-
570
- The static analysis script provides a comprehensive scan of your codebase and generates a detailed compliance report.
571
-
572
- ### Running the Script
573
-
574
- ```bash
575
- # From your consuming app root
576
- node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs
577
- ```
578
-
579
- Or add it to your `package.json`:
580
-
581
- ```json
582
- {
583
- "scripts": {
584
- "check:pace-core": "node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs"
585
- }
586
- }
587
- ```
588
-
589
- ### What It Checks
570
+ ## Compliance validation
590
571
 
591
- 1. **Restricted Imports** - Scans for direct imports of wrapped libraries
592
- 2. **Duplicate Components** - Finds local components matching pace-core names
593
- 3. **Duplicate Hooks** - Finds local hooks matching pace-core hooks
594
- 4. **Duplicate Utils** - Finds local utils matching pace-core utils
595
- 5. **Suggestions** - Recommends pace-core alternatives for native HTML elements
572
+ Compliance is validated by **ESLint** (during development) and the **pace-core Audit** step (when you run `npm run validate`).
596
573
 
597
- ### Report Output
574
+ **Run validation:** From the consuming app root (or repository root for pace-core development), run `npm run validate`. The pace-core audit report is written to `audit/<timestamp>-pace-core-audit.md`. For pace-core development, run `npm run validate` from the repository root; the audit runs against the current directory.
598
575
 
599
- The script generates a color-coded terminal report showing:
576
+ **What the Standard 1 audit checks:**
600
577
 
601
- - **Errors** - Critical violations that must be fixed
602
- - ⚠️ **Warnings** - Issues that should be addressed
603
- - 💡 **Suggestions** - Recommendations for improvement
604
- - **Summary** - Overall compliance status
578
+ - Provider nesting order in `main.tsx` (QueryClientProvider BrowserRouter → UnifiedAuthProvider → OrganisationProvider)
579
+ - Core styles import chain (app.css: tailwindcss, pace-core core.css, @source directives)
580
+ - RBAC setup (`setupRBAC()` called before rendering)
581
+ - Vite aliases (no aliases that bypass pace-core exports)
582
+ - Secure Supabase client location (`createClient()` only in main.tsx or lib/supabase.ts)
583
+ - Cursor rules present (`.cursor/rules/` with pace-core rules)
584
+ - ESLint config includes pace-core config
605
585
 
606
586
  ## Best Practices
607
587
 
@@ -707,6 +687,16 @@ createRoot(document.getElementById("root")!).render(
707
687
  - ❌ `UnifiedAuthProvider` wrapping `BrowserRouter` (causes context errors)
708
688
  - ❌ Missing `BrowserRouter` (causes `useNavigate` errors)
709
689
 
690
+ ## MUST: Auth routing
691
+
692
+ **MUST** protect routes with pace-core **ProtectedRoute**. Use a single public `/login` route and wrap all other routes in `<Route element={<ProtectedRoute />}>` (or `requireEvent={false}` variant for apps that do not require an event).
693
+
694
+ **MUST NOT** implement a global auth gate that wraps the entire route tree and redirects unauthenticated users to `/login` when `!isAuthenticated`. That pattern races with post-login context updates and can cause "login succeeds but redirect doesn't happen" or the login form to reset.
695
+
696
+ **SHOULD NOT** use React Router `BrowserRouter` `future` flags (e.g. `v7_startTransition`, `v7_relativeSplatPath`) unless login and logout have been verified with that configuration; use plain `<BrowserRouter>` by default.
697
+
698
+ See [Authentication implementation guide](../../implementation-guides/authentication.md#critical-auth-routing-pattern) for the full auth routing pattern and checklist.
699
+
710
700
  ## MUST: Vite Configuration
711
701
 
712
702
  **⚠️ CRITICAL: Vite configuration prevents React context mismatches!**
@@ -844,7 +834,7 @@ function useSecureSupabase(
844
834
 
845
835
  ### Acceptable Exceptions
846
836
 
847
- **The ONLY acceptable use of `createClient()` in consuming app code is:**
837
+ **The ONLY acceptable uses of `createClient()` in consuming app code are:**
848
838
 
849
839
  1. **Creating the base client for `UnifiedAuthProvider`** - This MUST be in one of these files:
850
840
  - `src/main.tsx` (or `main.jsx`)
@@ -862,13 +852,15 @@ function useSecureSupabase(
862
852
  const supabase = createClient(...);
863
853
  ```
864
854
 
855
+ 2. **PublicPageProvider (pace-core)** - `PublicPageProvider` may create a client for unauthenticated public pages only; that client must not be used for authenticated or organisation-scoped data.
856
+
865
857
  **NO OTHER EXCEPTIONS ARE PERMITTED** - All other uses of `createClient()` are security violations and MUST be fixed.
866
858
 
867
859
  ### Detection / Audit Tool
868
860
 
869
- The audit tool (`npm run audit:pace-core`) performs comprehensive system-level analysis organized by standards:
861
+ The pace-core Audit step (run via `npm run validate`) performs comprehensive system-level analysis organized by standards:
870
862
 
871
- - **Standard 1 (pace-core Compliance)**: Provider nesting, core styles import, RBAC setup, Vite aliases, secure Supabase client location, Cursor rules, ESLint config
863
+ - **Standard 1 (pace-core Compliance)**: Provider nesting, core styles import, RBAC setup, Vite aliases, secure Supabase client location, **auth routing (no global auth gate)**, Cursor rules, ESLint config
872
864
  - **Standard 2 (Project Structure)**: Directory structure, config files, import paths, test colocation, Supabase structure
873
865
  - **Standard 3 (Architecture)**: Component boundaries, ApiResult usage
874
866
  - **Standard 4 (Code Quality)**: TypeScript config, test coverage config
@@ -880,6 +872,26 @@ The audit tool (`npm run audit:pace-core`) performs comprehensive system-level a
880
872
 
881
873
  **Reference**: See [packages/core/audit-tool/](../../audit-tool/) for audit tool implementation.
882
874
 
875
+ ### How each layer enforces this standard
876
+
877
+ - **Standards (this doc):** Source of truth; defines MUST/SHOULD and exceptions.
878
+ - **Cursor rule:** `01-pace-core-compliance.mdc` — AI guidance when editing `src/**/*.{ts,tsx,js,jsx}`; points to this doc and ESLint.
879
+ - **ESLint:** Rules in `01-pace-core-compliance.cjs` (plugin prefix `pace-core-compliance/`): prefer-pace-core-components, prefer-pace-core-hooks, prefer-pace-core-utils, no-local-component-duplication, no-inline-styles, prefer-pace-core-form; plus no-restricted-imports and RBAC rules from Standard 6. Run via lint step in CI and locally.
880
+ - **Audit tool:** Standard 1 audit runs as part of `npm run validate`; checks provider nesting, core styles import, RBAC setup, Vite aliases, secure Supabase client location, **auth routing pattern (flags files that redirect to `/login` when `!isAuthenticated`, which indicates a global auth gate)**, Cursor rules presence, ESLint config. Report: `audit/<timestamp>-pace-core-audit.md`. ESLint does not currently enforce auth routing; use the audit and the [Authentication implementation guide](../../implementation-guides/authentication.md#critical-auth-routing-pattern) to avoid the global auth gate pattern.
881
+
882
+ ### Audit issue types and where to read
883
+
884
+ | Audit issue type | See section in this doc |
885
+ |------------------|--------------------------|
886
+ | providerNesting | MUST: Provider Nesting Order |
887
+ | coreStyles | (Styling standard) / app.css |
888
+ | rbacSetup | MUST: Setup RBAC Before Use (Cursor rule); Detection / Audit Tool |
889
+ | viteAlias | MUST: Vite Configuration |
890
+ | supabaseClient | MUST: Use Secure Supabase Client |
891
+ | authRouting | MUST: Auth routing (no global auth gate); [Authentication guide](../../implementation-guides/authentication.md#critical-auth-routing-pattern) |
892
+ | cursorRules | Step 3: Setup Cursor Rules |
893
+ | eslintConfig | Step 2: Setup ESLint |
894
+
883
895
  ### Detection / Audit (Legacy)
884
896
 
885
897
  - `rg "createClient\(" src` must return **exactly ONE match** in the file that creates the base client for `UnifiedAuthProvider`.
@@ -934,17 +946,19 @@ During audits, documented exceptions will be:
934
946
 
935
947
  **Invalid exceptions** (undocumented, unnecessary, or security-related) will be flagged as violations requiring remediation.
936
948
 
949
+ Documented exceptions are not yet detected automatically by the audit tool; they are tracked manually or via review. Future versions may report them as informational.
950
+
937
951
  ## Troubleshooting
938
952
 
939
953
  ### ESLint Setup Issues
940
954
 
941
955
  **Error: "Could not find 'no-restricted-imports' in plugin 'pace-core-compliance'"**
942
956
  - **Cause**: This rule was removed from the plugin (it's now handled by standard ESLint `no-restricted-imports`)
943
- - **Fix**: Update to the latest version of `@jmruthers/pace-core` and run `npm run setup:eslint --force`
957
+ - **Fix**: Update to the latest version of `@jmruthers/pace-core` and run `npm run setup -- --force`
944
958
 
945
959
  **Error: "TypeError: Unexpected array" when using `tseslint.config()`**
946
960
  - **Cause**: Incorrect spreading of `paceCoreConfig` in `tseslint.config()` wrapper
947
- - **Fix**: Run `npm run setup:eslint --force` to fix the config structure, or manually ensure `paceCoreConfig` is spread correctly:
961
+ - **Fix**: Run `npm run setup -- --force` to fix the config structure, or manually ensure `paceCoreConfig` is spread correctly:
948
962
  ```javascript
949
963
  import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
950
964
 
@@ -959,7 +973,7 @@ During audits, documented exceptions will be:
959
973
  - **Fix**:
960
974
  1. Ensure `@jmruthers/pace-core` is built: `npm run build` in pace-core
961
975
  2. Check that `node_modules/@jmruthers/pace-core/dist/eslint-rules/` exists
962
- 3. Run `npm run setup:eslint --force` to regenerate config
976
+ 3. Run `npm run setup -- --force` to regenerate config
963
977
 
964
978
  ### ESLint Rules Not Working
965
979
 
@@ -970,12 +984,6 @@ During audits, documented exceptions will be:
970
984
  5. **Verify rules are available**: Check that the rules file exists
971
985
  6. **Check rule count**: Verify all rules are loaded
972
986
 
973
- ### Static Analysis Script Errors
974
-
975
- 1. **Manifest not found**: Ensure `core-usage-manifest.json` exists in pace-core package
976
- 2. **No files scanned**: Check that you're running from the project root
977
- 3. **Permission errors**: Ensure script has read access to source files
978
-
979
987
  ### False Positives
980
988
 
981
989
  If you encounter false positives:
@@ -1004,10 +1012,7 @@ After setting up the ESLint config, verify it's working:
1004
1012
  ```
1005
1013
  Run ESLint and verify it reports the violation.
1006
1014
 
1007
- 3. **Run static analysis**: Use the compliance script to get a full report:
1008
- ```bash
1009
- npm run check:pace-core
1010
- ```
1015
+ 3. **Run full validation**: Run `npm run validate` and review `audit/<timestamp>-pace-core-audit.md` for Standard 1 issues.
1011
1016
 
1012
1017
  ## Related Documentation
1013
1018
 
@@ -25,6 +25,23 @@ This guide defines the standard project structure and file organization patterns
25
25
  9. [Migration from Existing Projects](#migration-from-existing-projects)
26
26
  10. [Structure Checklist](#structure-checklist)
27
27
 
28
+ ### How each layer enforces this standard
29
+
30
+ - **Standards (this doc):** Source of truth; defines MUST/SHOULD for structure, naming, imports, and config.
31
+ - **Cursor rule:** `02-project-structure.mdc` — AI guidance when creating or organizing files (`**/*.{ts,tsx,js,jsx,md}`, `src/**`); points to this doc.
32
+ - **ESLint:** No project-structure rules; structure is enforced by the Cursor rule and the audit tool only.
33
+ - **Audit tool:** Standard 2 audit runs as part of `npm run validate`; checks directory structure, config files, import paths (tsconfig), test colocation, feature-based organization (no type-based or domain-based). Report: `audit/<timestamp>-pace-core-audit.md`. For pace-core development, run `npm run validate` from the repository root.
34
+
35
+ ### Audit issue types and where to read
36
+
37
+ | Audit issue type | See section in this doc |
38
+ |---------------------|------------------------------------------------|
39
+ | directoryStructure | Standard Directory Structure |
40
+ | configFiles | Configuration Files |
41
+ | importPaths | Import Path Configuration |
42
+ | testColocation | Testing Structure (Test Colocation) |
43
+ | organizationPattern | Component Organization / File Organization Standard |
44
+
28
45
  ---
29
46
 
30
47
  ## Standard Directory Structure
@@ -95,7 +112,7 @@ your-app/
95
112
  │ └── audit-*.md
96
113
 
97
114
  ├── .gitignore
98
- ├── .eslintrc.js # ESLint config (or eslint.config.js)
115
+ ├── eslint.config.js # ESLint config (flat config; or .eslintrc.js / eslint.config.cjs)
99
116
  ├── package.json
100
117
  ├── tsconfig.json # TypeScript config
101
118
  ├── tsconfig.app.json # App-specific TS config (if needed)
@@ -409,7 +426,7 @@ describe('EventCard', () => {
409
426
 
410
427
  ### Migration Files
411
428
 
412
- **MUST** place all migrations in `supabase/migrations/`:
429
+ **If the app has app-owned migrations:** they **MUST** be in `supabase/migrations/` with the naming convention `YYYYMMDDHHMMSS_description.sql`:
413
430
 
414
431
  ```
415
432
  supabase/
@@ -419,7 +436,7 @@ supabase/
419
436
  └── 20250117150000_add_rls_policies.sql
420
437
  ```
421
438
 
422
- **MUST** follow naming convention: `YYYYMMDDHHMMSS_description.sql`
439
+ **If the app has no app-owned migrations** (e.g. shared DB managed elsewhere): **MUST** add `supabase/README.md` explaining where migrations/RLS are managed and whether the app will add migrations in the future.
423
440
 
424
441
  ### Edge Functions (if used)
425
442
 
@@ -436,20 +453,18 @@ supabase/
436
453
 
437
454
  ### Supabase Client Setup
438
455
 
439
- **MUST** place Supabase client in `src/lib/supabase.ts`:
456
+ **MUST** place the base Supabase client in `main.tsx`, `App.tsx`, or (if in a separate file) `src/lib/supabase.ts`. If in a separate file, the base client **MUST NOT** be exported for general use; it must only be passed to `UnifiedAuthProvider`. Components **MUST** use `useSecureSupabase()` from pace-core for queries. See [pace-core Compliance](./1-pace-core-compliance-standards.md) for security requirements.
440
457
 
441
458
  ```typescript
442
- // src/lib/supabase.ts
459
+ // src/lib/supabase.ts — base client for UnifiedAuthProvider only; DO NOT import elsewhere
443
460
  import { createClient } from '@supabase/supabase-js';
444
461
  import type { Database } from '@/types/database';
445
462
 
446
463
  const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
447
464
  const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
448
465
 
449
- export const supabaseClient = createClient<Database>(
450
- supabaseUrl,
451
- supabaseAnonKey
452
- );
466
+ // Used only by main.tsx/App.tsx for UnifiedAuthProvider; components use useSecureSupabase()
467
+ export const supabaseClient = createClient<Database>(supabaseUrl, supabaseAnonKey);
453
468
  ```
454
469
 
455
470
  ---
@@ -467,7 +482,7 @@ export const supabaseClient = createClient<Database>(
467
482
  | `vite.config.ts` | Vite build configuration | ✅ Yes |
468
483
  | `vitest.config.ts` | Vitest test configuration | ✅ Yes |
469
484
  | `.gitignore` | Git ignore patterns | ✅ Yes |
470
- | `.eslintrc.js` or `eslint.config.js` | ESLint configuration | ✅ Yes |
485
+ | `eslint.config.js` (or `.eslintrc.js` / `eslint.config.cjs`) | ESLint configuration | ✅ Yes |
471
486
 
472
487
  ### Root Directory Rules
473
488
 
@@ -704,9 +719,10 @@ your-app/
704
719
 
705
720
  1. **Remove Duplicate pace-core Components**
706
721
  ```bash
707
- # Check for pace-core duplicates
708
- node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs
722
+ # Run full validation (includes pace-core audit)
723
+ npm run validate
709
724
  ```
725
+ Review `audit/<timestamp>-pace-core-audit.md` for Standard 1 and project structure issues.
710
726
 
711
727
  2. **Remove Empty Directories**
712
728
  ```bash
@@ -719,16 +735,17 @@ your-app/
719
735
 
720
736
  #### Phase 5: Verification
721
737
 
722
- 1. **Install Cursor Rules**
738
+ 1. **Run Setup**
723
739
  ```bash
724
- node node_modules/@jmruthers/pace-core/scripts/install-cursor-rules.cjs
740
+ npm run setup
725
741
  ```
726
742
 
727
743
  2. **Run Compliance Checks**
728
744
  ```bash
729
- # Check pace-core compliance
730
- node node_modules/@jmruthers/pace-core/scripts/check-pace-core-compliance.cjs
745
+ # Run full validation (includes pace-core audit)
746
+ npm run validate
731
747
  ```
748
+ Review `audit/<timestamp>-pace-core-audit.md` for compliance and structure issues.
732
749
 
733
750
  3. **Verify Build**
734
751
  ```bash
@@ -6,6 +6,20 @@
6
6
 
7
7
  Define the core architectural principles and SOLID expectations for pace-core and consuming apps so components, APIs, and utilities evolve consistently and sustainably.
8
8
 
9
+ ### How each layer enforces this standard
10
+
11
+ - **Standards (this doc):** Source of truth; defines SOLID, component design, API design, and boundaries.
12
+ - **Cursor rule:** `03-architecture.mdc` — AI guidance when editing `src/**/*.{ts,tsx}`; points to this doc.
13
+ - **ESLint:** SRP proxies only: `max-lines-per-function`, `complexity`, `max-lines` (on `src/**` and, in the monorepo, `packages/core/src/**`). Other architecture enforcement is via the Cursor rule and the audit tool.
14
+ - **Audit tool:** Standard 3 audit runs as part of `npm run validate`; checks component boundaries (data fetching in components, complex business logic in components) and ApiResult shape usage. Report: `audit/<timestamp>-pace-core-audit.md`. For pace-core development, run `npm run validate` from the repository root.
15
+
16
+ ### Audit issue types and where to read
17
+
18
+ | Audit issue type | See section in this doc |
19
+ |--------------------|----------------------------------------------------------------|
20
+ | componentBoundary | Component Design Principles / SOLID (Single Responsibility) |
21
+ | apiResult | API Design Principles (Type-Safe Results) |
22
+
9
23
  ---
10
24
 
11
25
  ## Architectural Principles
@@ -164,6 +178,32 @@ const supabaseService: DataService = { /* ... */ };
164
178
  const mockService: DataService = { /* ... */ };
165
179
  ```
166
180
 
181
+ ### How we check SOLID
182
+
183
+ Each principle is enforced by one or more layers. The table below shows which layer(s) check what.
184
+
185
+ | Principle | Standards | Cursor rule | ESLint | Audit tool |
186
+ |-----------|-----------|-------------|--------|------------|
187
+ | **SRP** | Defined (this doc) | Guidance: extract logic to hooks/services | Proxies: `max-lines-per-function`, `max-lines` (1000), `complexity` (on `src/**`, `packages/core/src/**`) | componentBoundary: data fetching in components, complex business logic (no line or named-export checks; those are in ESLint) |
188
+ | **OCP** | Defined (this doc) | Guidance: composition over modification | — | — |
189
+ | **LSP** | Defined (this doc) | Guidance: maintain interface contracts | — | — |
190
+ | **ISP** | Defined (this doc) | Guidance: focused interfaces | — | Optional: large interface/props count heuristic |
191
+ | **DIP** | Defined (this doc) | Guidance: depend on abstractions | — | Partly covered by componentBoundary (data in components) |
192
+
193
+ **Limitations:** OCP, LSP, ISP, and DIP are enforced by standards and cursor rules only; there are no mechanical checks for them. SRP is partially checked: the audit flags component-boundary violations (data/business logic in components), and ESLint uses length/complexity as proxies for “single reason to change.” Full SRP adherence is not mechanically decidable.
194
+
195
+ ### Size limits (SRP proxies)
196
+
197
+ **Line-related limits** are enforced only by **ESLint** (single source; audit does not report line counts):
198
+
199
+ | What | Limit | Enforced by | Why |
200
+ |------|-------|--------------|-----|
201
+ | **Lines per function** | 400 | ESLint `max-lines-per-function` | Same. |
202
+ | **Lines per file** | 1000 | ESLint `max-lines` | Same. |
203
+ | **Named exports per file** | 10 | ESLint `pace-core-compliance/max-named-exports` | Same. |
204
+
205
+ All SRP size limits (lines and named exports) are enforced only by ESLint; the audit does not report them.
206
+
167
207
  ---
168
208
 
169
209
  ## Component Design Principles
@@ -194,7 +234,7 @@ function Counter() {
194
234
 
195
235
  ### Accessible by Default
196
236
 
197
- **Components must be accessible with correct roles, keyboard support, and visible focus.**
237
+ **Components must be accessible with correct roles, keyboard support, and visible focus.** Prefer pace-core `Button` when available; it provides built-in accessibility. This example illustrates accessibility attributes when building a custom primitive.
198
238
 
199
239
  ```tsx
200
240
  // ✅ CORRECT - Accessible component