@jmruthers/pace-core 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/{scripts/audit/audit-dependencies.cjs → audit-tool/00-dependencies.cjs} +12 -13
  2. package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
  3. package/audit-tool/audits/02-project-structure.cjs +255 -0
  4. package/audit-tool/audits/03-architecture.cjs +196 -0
  5. package/audit-tool/audits/04-code-quality.cjs +149 -0
  6. package/audit-tool/audits/05-styling.cjs +224 -0
  7. package/audit-tool/audits/06-security-rbac.cjs +544 -0
  8. package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
  9. package/audit-tool/audits/08-testing-documentation.cjs +202 -0
  10. package/audit-tool/audits/09-operations.cjs +208 -0
  11. package/audit-tool/index.cjs +291 -0
  12. package/audit-tool/utils/code-utils.cjs +218 -0
  13. package/audit-tool/utils/file-utils.cjs +230 -0
  14. package/audit-tool/utils/report-utils.cjs +241 -0
  15. package/cursor-rules/00-standards-overview.mdc +156 -0
  16. package/cursor-rules/{00-pace-core-compliance.mdc → 01-pace-core-compliance.mdc} +187 -34
  17. package/cursor-rules/02-project-structure.mdc +37 -5
  18. package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +125 -11
  19. package/cursor-rules/04-code-quality.mdc +419 -0
  20. package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +55 -10
  21. package/cursor-rules/{09-rbac-compliance.mdc → 06-security-rbac.mdc} +62 -6
  22. package/cursor-rules/07-api-tech-stack.mdc +377 -0
  23. package/cursor-rules/08-testing-documentation.mdc +324 -0
  24. package/cursor-rules/09-operations.mdc +365 -0
  25. package/dist/DataTable-7PMH7XN7.js +15 -0
  26. package/dist/{DataTable-2N_tqbfq.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
  27. package/dist/{PublicPageProvider-BBH6Vqg7.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +26 -16
  28. package/dist/{chunk-FENMYN2U.js → chunk-5X4QLXRG.js} +1 -3
  29. package/dist/{chunk-4T7OBVTU.js → chunk-6F3IILHI.js} +1 -1
  30. package/dist/{chunk-SD6WQY43.js → chunk-7ILTDCL2.js} +9 -1
  31. package/dist/{chunk-3QC3KRHK.js → chunk-A3W6LW53.js} +16 -1
  32. package/dist/{chunk-7TYHROIV.js → chunk-BM4CQ5P3.js} +50 -8
  33. package/dist/{chunk-2HGJFNAH.js → chunk-FEJLJNWA.js} +1 -15
  34. package/dist/{chunk-OHIK3MIO.js → chunk-GHYHJTYV.js} +2 -2
  35. package/dist/{chunk-UIYSCEV7.js → chunk-IUBRCBSY.js} +1 -1
  36. package/dist/{chunk-LAZMKTTF.js → chunk-JGWDVX64.js} +281 -347
  37. package/dist/{chunk-MAGBIDNS.js → chunk-L4XMVJKY.js} +2 -2
  38. package/dist/{chunk-A55DK444.js → chunk-OJ4SKRSV.js} +1 -7
  39. package/dist/{chunk-ZS5VO5JB.js → chunk-Q7Q7V5NV.js} +406 -451
  40. package/dist/{chunk-3O3WHILE.js → chunk-VBCS3DUA.js} +236 -60
  41. package/dist/{chunk-BVP2BCJF.js → chunk-ZKAWKYT4.js} +8 -8
  42. package/dist/components.d.ts +5 -4
  43. package/dist/components.js +27 -32
  44. package/dist/eslint-rules/index.cjs +22 -9
  45. package/{src/eslint-rules/rules/compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +184 -23
  46. package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
  47. package/dist/eslint-rules/rules/05-styling.cjs +61 -0
  48. package/dist/eslint-rules/rules/{rbac.cjs → 06-security-rbac.cjs} +26 -10
  49. package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
  50. package/dist/eslint-rules/rules/08-testing.cjs +94 -0
  51. package/dist/hooks.d.ts +5 -5
  52. package/dist/hooks.js +6 -6
  53. package/dist/index.d.ts +6 -6
  54. package/dist/index.js +18 -17
  55. package/dist/rbac/index.js +6 -6
  56. package/dist/theming/runtime.d.ts +14 -1
  57. package/dist/theming/runtime.js +1 -1
  58. package/dist/{types-B-K_5VnO.d.ts → types-DXstZpNI.d.ts} +0 -17
  59. package/dist/{usePublicRouteParams-COZ28Mvq.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +19 -19
  60. package/dist/utils.d.ts +2 -2
  61. package/dist/utils.js +8 -8
  62. package/docs/README.md +1 -1
  63. package/docs/api/modules.md +47 -31
  64. package/docs/api-reference/components.md +18 -20
  65. package/docs/api-reference/hooks.md +80 -80
  66. package/docs/api-reference/types.md +1 -1
  67. package/docs/api-reference/utilities.md +1 -1
  68. package/docs/architecture/README.md +1 -1
  69. package/docs/core-concepts/events.md +3 -3
  70. package/docs/core-concepts/organisations.md +6 -6
  71. package/docs/core-concepts/permissions.md +6 -6
  72. package/docs/documentation-index.md +12 -18
  73. package/docs/getting-started/documentation-index.md +1 -1
  74. package/docs/getting-started/examples/README.md +4 -4
  75. package/docs/getting-started/examples/full-featured-app.md +1 -1
  76. package/docs/getting-started/faq.md +2 -2
  77. package/docs/getting-started/quick-reference.md +4 -4
  78. package/docs/implementation-guides/authentication.md +15 -15
  79. package/docs/implementation-guides/component-styling.md +1 -1
  80. package/docs/implementation-guides/data-tables.md +126 -33
  81. package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
  82. package/docs/implementation-guides/dynamic-colors.md +3 -3
  83. package/docs/implementation-guides/file-upload-storage.md +2 -2
  84. package/docs/implementation-guides/hierarchical-datatable.md +40 -60
  85. package/docs/implementation-guides/inactivity-tracking.md +3 -3
  86. package/docs/implementation-guides/large-datasets.md +3 -2
  87. package/docs/implementation-guides/organisation-security.md +2 -2
  88. package/docs/implementation-guides/performance.md +2 -2
  89. package/docs/implementation-guides/permission-enforcement.md +1 -1
  90. package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
  91. package/docs/migration/V0.4.0_rbac-migration.md +6 -6
  92. package/docs/rbac/README.md +5 -5
  93. package/docs/rbac/advanced-patterns.md +6 -6
  94. package/docs/rbac/api-reference.md +20 -20
  95. package/docs/rbac/event-based-apps.md +3 -3
  96. package/docs/rbac/examples.md +41 -41
  97. package/docs/rbac/getting-started.md +37 -37
  98. package/docs/rbac/performance.md +1 -1
  99. package/docs/rbac/quick-start.md +52 -52
  100. package/docs/rbac/secure-client-protection.md +1 -1
  101. package/docs/rbac/troubleshooting.md +1 -1
  102. package/docs/security/README.md +5 -5
  103. package/docs/standards/0-standards-overview.md +220 -0
  104. package/docs/standards/{00-pace-core-compliance.md → 1-pace-core-compliance-standards.md} +204 -185
  105. package/docs/standards/{02-project-structure.md → 2-project-structure-standards.md} +11 -47
  106. package/docs/standards/3-architecture-standards.md +606 -0
  107. package/docs/standards/4-code-quality-standards.md +728 -0
  108. package/docs/standards/{08-markup-quality.md → 5-styling-standards.md} +12 -9
  109. package/docs/standards/{09-rbac-compliance.md → 6-security-rbac-standards.md} +126 -18
  110. package/docs/standards/7-api-tech-stack-standards.md +662 -0
  111. package/docs/standards/8-testing-documentation-standards.md +401 -0
  112. package/docs/standards/9-operations-standards.md +1102 -0
  113. package/docs/standards/README.md +203 -104
  114. package/docs/troubleshooting/README.md +4 -4
  115. package/docs/troubleshooting/common-issues.md +2 -2
  116. package/docs/troubleshooting/debugging.md +9 -9
  117. package/docs/troubleshooting/migration.md +4 -4
  118. package/eslint-config-pace-core.cjs +21 -10
  119. package/package.json +6 -5
  120. package/scripts/install-cursor-rules.cjs +11 -243
  121. package/scripts/install-eslint-config.cjs +284 -0
  122. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +2 -2
  123. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
  124. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +10 -10
  125. package/src/__tests__/integration/UserProfile.test.tsx +14 -14
  126. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
  127. package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
  128. package/src/__tests__/templates/component.test.template.tsx +18 -15
  129. package/src/components/Calendar/Calendar.tsx +201 -47
  130. package/src/components/ContextSelector/ContextSelector.tsx +137 -153
  131. package/src/components/DataTable/AUDIT_REPORT.md +293 -0
  132. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
  133. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
  134. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
  135. package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
  136. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
  137. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
  138. package/src/components/DataTable/components/DataTableLayout.tsx +5 -16
  139. package/src/components/DataTable/components/EditableRow.tsx +5 -7
  140. package/src/components/DataTable/components/EmptyState.tsx +10 -9
  141. package/src/components/DataTable/components/FilterRow.tsx +2 -4
  142. package/src/components/DataTable/components/ImportModal.tsx +124 -126
  143. package/src/components/DataTable/components/LoadingState.tsx +5 -6
  144. package/src/components/DataTable/components/SortIndicator.tsx +50 -0
  145. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
  146. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
  147. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
  148. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
  149. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
  150. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
  151. package/src/components/DataTable/components/index.ts +2 -1
  152. package/src/components/DataTable/types.ts +0 -18
  153. package/src/components/DataTable/utils/a11yUtils.ts +17 -0
  154. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
  155. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
  156. package/src/components/DateTimeField/DateTimeField.tsx +7 -8
  157. package/src/components/Dialog/Dialog.test.tsx +1 -0
  158. package/src/components/Dialog/Dialog.tsx +25 -8
  159. package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
  160. package/src/components/FileUpload/FileUpload.test.tsx +52 -14
  161. package/src/components/FileUpload/FileUpload.tsx +112 -130
  162. package/src/components/Progress/Progress.tsx +2 -4
  163. package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
  164. package/src/components/Select/Select.tsx +86 -77
  165. package/src/components/Select/types.ts +3 -0
  166. package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
  167. package/src/hooks/__tests__/hooks.integration.test.tsx +49 -49
  168. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
  169. package/src/hooks/public/usePublicEvent.ts +5 -5
  170. package/src/hooks/public/usePublicEventLogo.ts +5 -5
  171. package/src/hooks/public/usePublicFileDisplay.ts +2 -2
  172. package/src/hooks/public/usePublicRouteParams.ts +5 -5
  173. package/src/hooks/useAppConfig.ts +2 -2
  174. package/src/hooks/useEventTheme.test.ts +7 -7
  175. package/src/hooks/useEventTheme.ts +1 -4
  176. package/src/hooks/useFileDisplay.ts +2 -2
  177. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
  178. package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
  179. package/src/providers/__tests__/EventProvider.test.tsx +61 -61
  180. package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
  181. package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
  182. package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
  183. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
  184. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
  185. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +10 -10
  186. package/src/styles/core.css +7 -0
  187. package/src/theming/__tests__/parseEventColours.test.ts +9 -3
  188. package/src/theming/parseEventColours.ts +22 -10
  189. package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
  190. package/src/utils/storage/README.md +1 -1
  191. package/cursor-rules/01-standards-compliance.mdc +0 -285
  192. package/cursor-rules/04-testing-standards.mdc +0 -270
  193. package/cursor-rules/05-bug-reports-and-features.mdc +0 -248
  194. package/cursor-rules/06-code-quality.mdc +0 -311
  195. package/cursor-rules/07-tech-stack-compliance.mdc +0 -216
  196. package/cursor-rules/10-error-handling-patterns.mdc +0 -179
  197. package/cursor-rules/11-performance-optimization.mdc +0 -169
  198. package/cursor-rules/12-ci-cd-integration.mdc +0 -150
  199. package/dist/DataTable-LRJL4IRV.js +0 -15
  200. package/dist/eslint-rules/rules/compliance.cjs +0 -348
  201. package/dist/eslint-rules/rules/components.cjs +0 -113
  202. package/dist/eslint-rules/rules/imports.cjs +0 -102
  203. package/docs/best-practices/README.md +0 -472
  204. package/docs/best-practices/accessibility.md +0 -604
  205. package/docs/best-practices/common-patterns.md +0 -516
  206. package/docs/best-practices/deployment.md +0 -1103
  207. package/docs/best-practices/performance.md +0 -1328
  208. package/docs/best-practices/security.md +0 -940
  209. package/docs/best-practices/testing.md +0 -1034
  210. package/docs/rbac/compliance/compliance-guide.md +0 -544
  211. package/docs/standards/01-standards-compliance.md +0 -188
  212. package/docs/standards/03-solid-principles.md +0 -39
  213. package/docs/standards/04-testing-standards.md +0 -36
  214. package/docs/standards/05-bug-reports-and-features.md +0 -27
  215. package/docs/standards/06-code-quality.md +0 -34
  216. package/docs/standards/07-tech-stack-compliance.md +0 -30
  217. package/docs/standards/10-error-handling-patterns.md +0 -401
  218. package/docs/standards/11-performance-optimization.md +0 -348
  219. package/docs/standards/12-ci-cd-integration.md +0 -370
  220. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +0 -192
  221. package/scripts/audit/audit-compliance.cjs +0 -1295
  222. package/scripts/audit/audit-components.cjs +0 -260
  223. package/scripts/audit/audit-rbac.cjs +0 -954
  224. package/scripts/audit/audit-standards.cjs +0 -1268
  225. package/scripts/audit/index.cjs +0 -1927
  226. package/src/components/DataTable/components/DataTableBody.tsx +0 -478
  227. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
  228. package/src/components/DataTable/components/ExpandButton.tsx +0 -113
  229. package/src/components/DataTable/components/GroupHeader.tsx +0 -54
  230. package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
  231. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
  232. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
  233. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
  234. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
  235. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
  236. package/src/components/DataTable/core/DataTableContext.tsx +0 -216
  237. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
  238. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
  239. package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
  240. package/src/components/DataTable/utils/debugTools.ts +0 -514
  241. package/src/eslint-rules/index.cjs +0 -22
  242. package/src/eslint-rules/rules/components.cjs +0 -113
  243. package/src/eslint-rules/rules/imports.cjs +0 -102
  244. package/src/eslint-rules/rules/rbac.cjs +0 -790
  245. package/src/eslint-rules/utils/helpers.cjs +0 -42
  246. package/src/eslint-rules/utils/manifest-loader.cjs +0 -75
@@ -0,0 +1,230 @@
1
+ /**
2
+ * File System Utilities for Audit Tool
3
+ * @package @jmruthers/pace-core
4
+ * @module Audit/utils/file-utils
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ /**
11
+ * Recursively find all source files matching extensions
12
+ * @param {string} dir - Directory to search
13
+ * @param {string[]} extensions - File extensions to match (e.g., ['.ts', '.tsx', '.js', '.jsx'])
14
+ * @param {string[]} fileList - Accumulator for found files
15
+ * @returns {string[]} - Array of file paths
16
+ */
17
+ function findSourceFiles(dir, extensions = ['.ts', '.tsx', '.js', '.jsx'], fileList = []) {
18
+ if (!fs.existsSync(dir)) {
19
+ return fileList;
20
+ }
21
+
22
+ const files = fs.readdirSync(dir);
23
+
24
+ files.forEach(file => {
25
+ const filePath = path.join(dir, file);
26
+ const stat = fs.statSync(filePath);
27
+
28
+ if (stat.isDirectory()) {
29
+ // Skip common build/dependency directories
30
+ if (!['node_modules', 'dist', 'build', '.git', '.next', '.vite', 'coverage', '.turbo', '.cursor'].includes(file)) {
31
+ findSourceFiles(filePath, extensions, fileList);
32
+ }
33
+ } else {
34
+ const ext = path.extname(file);
35
+ if (extensions.includes(ext)) {
36
+ fileList.push(filePath);
37
+ }
38
+ }
39
+ });
40
+
41
+ return fileList;
42
+ }
43
+
44
+ /**
45
+ * Recursively find all SQL files in a directory
46
+ * @param {string} dir - Directory to search
47
+ * @param {string[]} fileList - Accumulator for found files
48
+ * @returns {string[]} - Array of SQL file paths
49
+ */
50
+ function findSQLFiles(dir, fileList = []) {
51
+ if (!fs.existsSync(dir)) {
52
+ return fileList;
53
+ }
54
+
55
+ const files = fs.readdirSync(dir);
56
+
57
+ files.forEach(file => {
58
+ const filePath = path.join(dir, file);
59
+ const stat = fs.statSync(filePath);
60
+
61
+ if (stat.isDirectory()) {
62
+ // Skip common build/dependency directories
63
+ if (!['node_modules', 'dist', 'build', '.git', '.next', '.vite', 'coverage', '.turbo'].includes(file)) {
64
+ findSQLFiles(filePath, fileList);
65
+ }
66
+ } else if (/\.sql$/.test(file)) {
67
+ fileList.push(filePath);
68
+ }
69
+ });
70
+
71
+ return fileList;
72
+ }
73
+
74
+ /**
75
+ * Find configuration files by name
76
+ * @param {string} dir - Directory to search
77
+ * @param {string[]} configNames - Array of config file names to find
78
+ * @returns {Object} - Object mapping config names to paths (or null if not found)
79
+ */
80
+ function findConfigFiles(dir, configNames) {
81
+ const results = {};
82
+
83
+ for (const configName of configNames) {
84
+ const possiblePaths = [
85
+ path.join(dir, configName),
86
+ path.join(dir, `.${configName}`),
87
+ ];
88
+
89
+ // Also check common variations
90
+ if (configName.includes('.')) {
91
+ const [base, ext] = configName.split('.');
92
+ possiblePaths.push(
93
+ path.join(dir, `${base}.js`),
94
+ path.join(dir, `${base}.ts`),
95
+ path.join(dir, `${base}.cjs`),
96
+ path.join(dir, `${base}.mjs`),
97
+ path.join(dir, `.${base}.js`),
98
+ path.join(dir, `.${base}.ts`),
99
+ path.join(dir, `.${base}.cjs`),
100
+ path.join(dir, `.${base}.mjs`)
101
+ );
102
+ }
103
+
104
+ let found = null;
105
+ for (const configPath of possiblePaths) {
106
+ if (fs.existsSync(configPath)) {
107
+ found = configPath;
108
+ break;
109
+ }
110
+ }
111
+
112
+ results[configName] = found;
113
+ }
114
+
115
+ return results;
116
+ }
117
+
118
+ /**
119
+ * Safely read a file with error handling
120
+ * @param {string} filePath - Path to file
121
+ * @returns {string|null} - File content or null if error
122
+ */
123
+ function readFileSafe(filePath) {
124
+ try {
125
+ if (!fs.existsSync(filePath)) {
126
+ return null;
127
+ }
128
+ return fs.readFileSync(filePath, 'utf8');
129
+ } catch (error) {
130
+ return null;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Get relative path from base path
136
+ * @param {string} filePath - Absolute file path
137
+ * @param {string} basePath - Base path to make relative to
138
+ * @returns {string} - Relative path
139
+ */
140
+ function getRelativePath(filePath, basePath) {
141
+ try {
142
+ return path.relative(basePath, filePath);
143
+ } catch (error) {
144
+ return filePath;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Find pace-core package.json
150
+ * @param {string} consumingAppPath - Path to consuming app
151
+ * @returns {string|null} - Path to pace-core package.json or null
152
+ */
153
+ function findPaceCorePackageJson(consumingAppPath) {
154
+ const possiblePaths = [
155
+ path.resolve(__dirname, '../../package.json'), // From packages/core/audit-tool/utils
156
+ path.resolve(__dirname, '../../../package.json'), // Alternative location (from root)
157
+ path.join(consumingAppPath, 'node_modules', '@jmruthers', 'pace-core', 'package.json'),
158
+ ];
159
+
160
+ for (const packagePath of possiblePaths) {
161
+ if (fs.existsSync(packagePath)) {
162
+ return packagePath;
163
+ }
164
+ }
165
+
166
+ return null;
167
+ }
168
+
169
+ /**
170
+ * Load core-usage-manifest.json
171
+ * @param {string} consumingAppPath - Path to consuming app
172
+ * @returns {Object|null} - Manifest object or null
173
+ */
174
+ function loadManifest(consumingAppPath) {
175
+ const possiblePaths = [
176
+ path.resolve(__dirname, '../../../core-usage-manifest.json'),
177
+ path.resolve(__dirname, '../../../../core-usage-manifest.json'),
178
+ path.join(consumingAppPath, 'node_modules', '@jmruthers', 'pace-core', 'core-usage-manifest.json'),
179
+ ];
180
+
181
+ for (const manifestPath of possiblePaths) {
182
+ if (fs.existsSync(manifestPath)) {
183
+ try {
184
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
185
+ } catch (e) {
186
+ // Continue to next path
187
+ }
188
+ }
189
+ }
190
+
191
+ return null;
192
+ }
193
+
194
+ /**
195
+ * Check if a directory exists
196
+ * @param {string} dirPath - Directory path
197
+ * @returns {boolean} - True if directory exists
198
+ */
199
+ function directoryExists(dirPath) {
200
+ try {
201
+ return fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();
202
+ } catch (error) {
203
+ return false;
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Check if a file exists
209
+ * @param {string} filePath - File path
210
+ * @returns {boolean} - True if file exists
211
+ */
212
+ function fileExists(filePath) {
213
+ try {
214
+ return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
215
+ } catch (error) {
216
+ return false;
217
+ }
218
+ }
219
+
220
+ module.exports = {
221
+ findSourceFiles,
222
+ findSQLFiles,
223
+ findConfigFiles,
224
+ readFileSafe,
225
+ getRelativePath,
226
+ findPaceCorePackageJson,
227
+ loadManifest,
228
+ directoryExists,
229
+ fileExists,
230
+ };
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Report Generation Utilities for Audit Tool
3
+ * @package @jmruthers/pace-core
4
+ * @module Audit/utils/report-utils
5
+ */
6
+
7
+ const path = require('path');
8
+
9
+ /**
10
+ * Format a single issue for markdown report
11
+ * @param {Object} issue - Issue object
12
+ * @param {string} standard - Standard name (e.g., '01-pace-core-compliance')
13
+ * @returns {string} - Formatted markdown
14
+ */
15
+ function formatIssue(issue, standard) {
16
+ const severity = issue.severity || 'error';
17
+ const severityIcon = severity === 'error' ? '❌' : severity === 'warning' ? '⚠️' : 'ℹ️';
18
+
19
+ let formatted = `\n#### ${severityIcon} ${issue.type || 'Issue'}\n\n`;
20
+
21
+ if (issue.file) {
22
+ formatted += `**File:** \`${issue.file}\`\n\n`;
23
+ }
24
+
25
+ if (issue.line) {
26
+ formatted += `**Line:** ${issue.line}\n\n`;
27
+ }
28
+
29
+ if (issue.message) {
30
+ formatted += `**Message:** ${issue.message}\n\n`;
31
+ }
32
+
33
+ if (issue.code) {
34
+ formatted += `**Code:**\n\`\`\`\n${issue.code}\n\`\`\`\n\n`;
35
+ }
36
+
37
+ if (issue.fix) {
38
+ formatted += `**Fix:** ${issue.fix}\n\n`;
39
+ }
40
+
41
+ if (issue.details) {
42
+ formatted += `**Details:** ${issue.details}\n\n`;
43
+ }
44
+
45
+ return formatted;
46
+ }
47
+
48
+ /**
49
+ * Format a standard section in the report
50
+ * @param {string} standard - Standard number and name (e.g., '01-pace-core-compliance')
51
+ * @param {string} standardName - Human-readable standard name
52
+ * @param {Array} issues - Array of issues
53
+ * @param {string} standardDocPath - Path to standards documentation
54
+ * @returns {string} - Formatted markdown section
55
+ */
56
+ function formatStandardSection(standard, standardName, issues, standardDocPath) {
57
+ if (issues.length === 0) {
58
+ return `\n### ✅ Standard ${standard}: ${standardName}\n\nNo issues found.\n`;
59
+ }
60
+
61
+ let section = `\n### ❌ Standard ${standard}: ${standardName}\n\n`;
62
+ section += `**Reference:** [${standardName}](https://github.com/jmruthers/pace-core/blob/main/packages/core/docs/standards/${standardDocPath})\n\n`;
63
+ section += `**Issues Found:** ${issues.length}\n\n`;
64
+
65
+ // Group issues by type
66
+ const issuesByType = {};
67
+ issues.forEach(issue => {
68
+ const type = issue.type || 'other';
69
+ if (!issuesByType[type]) {
70
+ issuesByType[type] = [];
71
+ }
72
+ issuesByType[type].push(issue);
73
+ });
74
+
75
+ // Format each type group
76
+ Object.entries(issuesByType).forEach(([type, typeIssues]) => {
77
+ section += `\n#### ${type} (${typeIssues.length} issue${typeIssues.length > 1 ? 's' : ''})\n`;
78
+ typeIssues.forEach(issue => {
79
+ section += formatIssue(issue, standard);
80
+ });
81
+ });
82
+
83
+ return section;
84
+ }
85
+
86
+ /**
87
+ * Generate markdown report from audit results
88
+ * @param {Object} results - Audit results object
89
+ * @param {string} consumingAppPath - Path to consuming app
90
+ * @returns {string} - Complete markdown report
91
+ */
92
+ function generateMarkdownReport(results, consumingAppPath) {
93
+ const now = new Date();
94
+ const timestamp = now.toISOString();
95
+
96
+ let report = `# pace-core Audit Report\n\n`;
97
+ report += `**Generated:** ${timestamp}\n`;
98
+ report += `**App Path:** ${consumingAppPath}\n\n`;
99
+ report += `---\n\n`;
100
+ report += `## Summary\n\n`;
101
+
102
+ // Calculate totals
103
+ const standardNames = {
104
+ '01-pace-core-compliance': 'pace-core Compliance',
105
+ '02-project-structure': 'Project Structure',
106
+ '03-architecture': 'Architecture',
107
+ '04-code-quality': 'Code Quality',
108
+ '05-styling': 'Styling',
109
+ '06-security-rbac': 'Security & RBAC',
110
+ '07-api-tech-stack': 'API & Tech Stack',
111
+ '08-testing-documentation': 'Testing & Documentation',
112
+ '09-operations': 'Operations',
113
+ };
114
+
115
+ const standardDocPaths = {
116
+ '01-pace-core-compliance': '1-pace-core-compliance-standards.md',
117
+ '02-project-structure': '2-project-structure-standards.md',
118
+ '03-architecture': '3-architecture-standards.md',
119
+ '04-code-quality': '4-code-quality-standards.md',
120
+ '05-styling': '5-styling-standards.md',
121
+ '06-security-rbac': '6-security-rbac-standards.md',
122
+ '07-api-tech-stack': '7-api-tech-stack-standards.md',
123
+ '08-testing-documentation': '8-testing-documentation-standards.md',
124
+ '09-operations': '9-operations-standards.md',
125
+ };
126
+
127
+ let totalIssues = 0;
128
+ const standardCounts = {};
129
+
130
+ // Count issues per standard
131
+ Object.keys(standardNames).forEach(standard => {
132
+ const standardResult = results[standard];
133
+ if (standardResult && standardResult.issues) {
134
+ const count = Array.isArray(standardResult.issues)
135
+ ? standardResult.issues.length
136
+ : Object.values(standardResult.issues).flat().length;
137
+ standardCounts[standard] = count;
138
+ totalIssues += count;
139
+ } else {
140
+ standardCounts[standard] = 0;
141
+ }
142
+ });
143
+
144
+ report += `**Total Issues:** ${totalIssues}\n\n`;
145
+ report += `| Standard | Issues |\n`;
146
+ report += `|----------|--------|\n`;
147
+
148
+ Object.entries(standardCounts).forEach(([standard, count]) => {
149
+ const icon = count === 0 ? '✅' : '❌';
150
+ report += `| ${icon} ${standardNames[standard]} | ${count} |\n`;
151
+ });
152
+
153
+ report += `\n---\n\n`;
154
+ report += `## Detailed Results\n\n`;
155
+
156
+ // Generate sections for each standard
157
+ Object.keys(standardNames).forEach(standard => {
158
+ const standardResult = results[standard];
159
+ if (standardResult) {
160
+ const issues = Array.isArray(standardResult.issues)
161
+ ? standardResult.issues
162
+ : Object.values(standardResult.issues || {}).flat();
163
+
164
+ report += formatStandardSection(
165
+ standard,
166
+ standardNames[standard],
167
+ issues,
168
+ standardDocPaths[standard]
169
+ );
170
+ }
171
+ });
172
+
173
+ report += `\n---\n\n`;
174
+ report += `## Next Steps\n\n`;
175
+
176
+ if (totalIssues === 0) {
177
+ report += `✅ All audits passed! Your app is compliant with pace-core standards.\n\n`;
178
+ } else {
179
+ report += `Please review the issues above and address them according to the referenced standards.\n\n`;
180
+ report += `For more information, see the [pace-core Standards Documentation](https://github.com/jmruthers/pace-core/blob/main/packages/core/docs/standards/README.md).\n\n`;
181
+ }
182
+
183
+ return report;
184
+ }
185
+
186
+ /**
187
+ * Generate summary statistics
188
+ * @param {Object} results - Audit results object
189
+ * @returns {Object} - Summary object with counts
190
+ */
191
+ function generateSummary(results) {
192
+ const standardNames = {
193
+ '01-pace-core-compliance': 'pace-core Compliance',
194
+ '02-project-structure': 'Project Structure',
195
+ '03-architecture': 'Architecture',
196
+ '04-code-quality': 'Code Quality',
197
+ '05-styling': 'Styling',
198
+ '06-security-rbac': 'Security & RBAC',
199
+ '07-api-tech-stack': 'API & Tech Stack',
200
+ '08-testing-documentation': 'Testing & Documentation',
201
+ '09-operations': 'Operations',
202
+ };
203
+
204
+ const summary = {
205
+ total: 0,
206
+ byStandard: {},
207
+ bySeverity: { error: 0, warning: 0, info: 0 },
208
+ };
209
+
210
+ Object.keys(standardNames).forEach(standard => {
211
+ const standardResult = results[standard];
212
+ if (standardResult && standardResult.issues) {
213
+ const issues = Array.isArray(standardResult.issues)
214
+ ? standardResult.issues
215
+ : Object.values(standardResult.issues || {}).flat();
216
+
217
+ const count = issues.length;
218
+ summary.byStandard[standard] = count;
219
+ summary.total += count;
220
+
221
+ // Count by severity
222
+ issues.forEach(issue => {
223
+ const severity = issue.severity || 'error';
224
+ if (summary.bySeverity[severity] !== undefined) {
225
+ summary.bySeverity[severity]++;
226
+ }
227
+ });
228
+ } else {
229
+ summary.byStandard[standard] = 0;
230
+ }
231
+ });
232
+
233
+ return summary;
234
+ }
235
+
236
+ module.exports = {
237
+ formatIssue,
238
+ formatStandardSection,
239
+ generateMarkdownReport,
240
+ generateSummary,
241
+ };
@@ -0,0 +1,156 @@
1
+ ---
2
+ description: Overview of the pace-core standards system and the four layers of quality enforcement
3
+ globs: ["**/*.{ts,tsx,js,jsx,md,mdx}"]
4
+ alwaysApply: true
5
+ paceCoreVersion: "0.6.x"
6
+ rulesVersion: "2025-01-28"
7
+ ---
8
+ # Standards Overview
9
+
10
+ **📚 Human-Readable Standard**: See [0-standards-overview.md](../../packages/core/docs/standards/0-standards-overview.md) for complete documentation.
11
+
12
+ This is the entry point to the pace-core standards system. It explains how the four layers of quality enforcement work together and how cursor rules fit into the system.
13
+
14
+ ## AI Agent Instructions
15
+
16
+ **When writing or modifying code, ALWAYS:**
17
+ 1. **Start here** - Read this overview to understand the system
18
+ 2. **Use the right rule** - Check the Quick Reference below to find the relevant rule(s)
19
+ 3. **Follow decision trees** - Each rule includes decision trees to guide your choices
20
+ 4. **Check examples** - Every rule includes ❌ WRONG / ✅ CORRECT examples
21
+ 5. **Reference standards** - When in doubt, check the linked standards document
22
+ 6. **Focus on patterns** - These rules guide patterns, not mechanical checks (ESLint handles those)
23
+
24
+ ## The Four Layers of Quality Enforcement
25
+
26
+ The pace-suite uses **four complementary quality layers**, each with a distinct responsibility:
27
+
28
+ ### 1. Standards Documents (Source of Truth)
29
+ - Human-readable `.md` documents
30
+ - Define *what "good" looks like*
31
+ - **If there is a conflict, the standards win.**
32
+
33
+ ### 2. Cursor Rules (Real-time Guidance) ← **You are here**
34
+ - AI-optimised interpretations of the standards
35
+ - Applied while code is being written or modified
36
+ - Prevent mistakes *before* they land
37
+ - **Translate standards into behaviour**, but do not redefine them
38
+
39
+ ### 3. ESLint (Fast, Local Static Analysis)
40
+ - Deterministic, file-level static analysis
41
+ - Catches obvious issues early (types, hooks, imports, patterns)
42
+ - Enforces *how code is written*, not *whether the system is correct*
43
+
44
+ ### 4. Audit Tool (Deep, System-Level Analysis)
45
+ - Operates across files, folders, and systems
46
+ - Validates architectural compliance (RBAC, data access, boundaries)
47
+ - Answers: *"Is this system actually compliant?"*
48
+
49
+ ## How the Layers Work Together
50
+
51
+ | Layer | Strength | Timing |
52
+ |--------------|----------------------------------|-----------------|
53
+ | Standards | Intent & clarity | Design time |
54
+ | Cursor rules | Preventive guidance | Write time |
55
+ | ESLint | Fast mechanical enforcement | Dev / CI |
56
+ | Audit tool | Deep architectural verification | Review / CI |
57
+
58
+ **No single layer is sufficient on its own.** Together, they create a repeatable, scalable quality system.
59
+
60
+ ## Standards File Mapping
61
+
62
+ The standards are organized into 10 files, each with a corresponding cursor rule:
63
+
64
+ | File | Standard | Cursor Rule | Purpose |
65
+ |------|----------|------------|---------|
66
+ | `0-standards-overview.md` | Overview | `00-standards-overview.mdc` | This file - entry point and system overview |
67
+ | `1-pace-core-compliance-standards.md` | pace-core Compliance | `01-pace-core-compliance.mdc` | Enforce pace-core usage patterns |
68
+ | `2-project-structure-standards.md` | Project Structure | `02-project-structure.mdc` | Define standard folder structure |
69
+ | `3-architecture-standards.md` | Architecture | `03-architecture.mdc` | Enforce SOLID architecture principles |
70
+ | `4-code-quality-standards.md` | Code Quality | `04-code-quality.mdc` | Enforce code quality standards |
71
+ | `5-styling-standards.md` | Styling | `05-styling.mdc` | Enforce clean markup and styling standards |
72
+ | `6-security-rbac-standards.md` | Security & RBAC | `06-security-rbac.mdc` | Enforce RBAC contract and security |
73
+ | `7-api-tech-stack-standards.md` | API & Tech Stack | `07-api-tech-stack.mdc` | Enforce tech stack versions and API standards |
74
+ | `8-testing-documentation-standards.md` | Testing & Documentation | `08-testing-documentation.mdc` | Enforce testing and documentation standards |
75
+ | `9-operations-standards.md` | Operations | `09-operations.mdc` | Enforce error handling, performance, and CI/CD |
76
+
77
+ ## Precedence Order
78
+
79
+ When standards conflict, apply this precedence order:
80
+
81
+ 1. **Security** - Security and RBAC standards take highest priority
82
+ 2. **API/RPC** - API contracts and RPC standards
83
+ 3. **Components & Markup** - Component usage and markup quality
84
+ 4. **Code Quality/Style** - TypeScript, naming, code style
85
+ 5. **Testing & Documentation** - Testing and documentation requirements
86
+ 6. **Consuming App Structure** - Project structure and organization
87
+
88
+ **Example:** If a component pattern conflicts with a security requirement, security wins.
89
+
90
+ ## Quick Reference Guide
91
+
92
+ **New to pace-core?** Start here:
93
+ 1. Read [Standards Overview](../../packages/core/docs/standards/0-standards-overview.md) (this file) - Understand the system
94
+ 2. Read [Styling Standards](../../packages/core/docs/standards/5-styling-standards.md) - **CRITICAL:** Required CSS setup
95
+ 3. Read [pace-core Compliance](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) - How to use pace-core
96
+ 4. Read [Project Structure](../../packages/core/docs/standards/2-project-structure-standards.md) - Organize your code
97
+
98
+ **Common Tasks:**
99
+ - **Setting up a new app?** → [Project Structure](../../packages/core/docs/standards/2-project-structure-standards.md) + [Styling Standards](../../packages/core/docs/standards/5-styling-standards.md)
100
+ - **Writing components?** → [Architecture](../../packages/core/docs/standards/3-architecture-standards.md) + [Code Quality](../../packages/core/docs/standards/4-code-quality-standards.md)
101
+ - **Working with RBAC?** → [Security & RBAC](../../packages/core/docs/standards/6-security-rbac-standards.md)
102
+ - **Creating APIs/RPCs?** → [API & Tech Stack](../../packages/core/docs/standards/7-api-tech-stack-standards.md)
103
+ - **Handling errors?** → [Operations](../../packages/core/docs/standards/9-operations-standards.md)
104
+ - **Writing tests?** → [Testing & Documentation](../../packages/core/docs/standards/8-testing-documentation-standards.md)
105
+
106
+ ## Key Principles
107
+
108
+ - **Do not silence tools** — fix the underlying issue
109
+ - **Do not duplicate rules** — each layer has a purpose
110
+ - **Do not diverge silently** — document exceptions explicitly
111
+ - **Standards always win** — tools must align to them
112
+
113
+ ## What Cursor Rules Do
114
+
115
+ Cursor rules provide **real-time guidance** during code writing:
116
+
117
+ ✅ **DO:**
118
+ - Steer AI agents toward correct patterns
119
+ - Enforce architectural intent during development
120
+ - Reduce rework later in linting or audits
121
+ - Translate standards into actionable behavior
122
+
123
+ ❌ **DON'T:**
124
+ - Replace lint or audits
125
+ - Invent new standards
126
+ - Silence problems "to move on"
127
+ - Enforce mechanical checks (ESLint handles this)
128
+ - Validate system-level compliance (audit tool handles this)
129
+
130
+ ## Quick Reference: Which Rule to Use?
131
+
132
+ **When writing code, use these rules:**
133
+
134
+ - **Creating components?** → `01-pace-core-compliance.mdc` + `03-architecture.mdc` + `05-styling.mdc`
135
+ - **Writing hooks or utilities?** → `01-pace-core-compliance.mdc` + `03-architecture.mdc` + `04-code-quality.mdc`
136
+ - **Setting up providers or auth?** → `01-pace-core-compliance.mdc` + `06-security-rbac.mdc`
137
+ - **Creating RPCs or APIs?** → `07-api-tech-stack.mdc` + `06-security-rbac.mdc`
138
+ - **Writing tests?** → `08-testing-documentation.mdc`
139
+ - **Handling errors?** → `09-operations.mdc`
140
+ - **Optimizing performance?** → `09-operations.mdc` + `04-code-quality.mdc`
141
+ - **Organizing files?** → `02-project-structure.mdc`
142
+ - **Styling components?** → `05-styling.mdc` (ALWAYS APPLIED)
143
+ - **Working with RBAC?** → `06-security-rbac.mdc`
144
+
145
+ ## Related Documentation
146
+
147
+ - [Standards Overview](../../packages/core/docs/standards/0-standards-overview.md) - Complete standards system documentation
148
+ - [pace-core Compliance](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) - pace-core usage patterns
149
+ - [Project Structure](../../packages/core/docs/standards/2-project-structure-standards.md) - Project structure and organization
150
+ - [Architecture](../../packages/core/docs/standards/3-architecture-standards.md) - SOLID architecture principles
151
+ - [Code Quality](../../packages/core/docs/standards/4-code-quality-standards.md) - Code quality and TypeScript standards
152
+ - [Styling](../../packages/core/docs/standards/5-styling-standards.md) - Markup and styling standards
153
+ - [Security & RBAC](../../packages/core/docs/standards/6-security-rbac-standards.md) - RBAC and RLS standards
154
+ - [API & Tech Stack](../../packages/core/docs/standards/7-api-tech-stack-standards.md) - Tech stack and API/RPC standards
155
+ - [Testing & Documentation](../../packages/core/docs/standards/8-testing-documentation-standards.md) - Testing and documentation standards
156
+ - [Operations](../../packages/core/docs/standards/9-operations-standards.md) - Error handling, performance, and CI/CD