@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
@@ -7,15 +7,41 @@ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # pace-core Compliance Guide
9
9
 
10
- **📚 Human-Readable Standard**: See [00-pace-core-compliance.md](../../packages/core/docs/standards/00-pace-core-compliance.md) for complete documentation.
10
+ **📚 Human-Readable Standard**: See [1-pace-core-compliance-standards.md](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) for complete documentation.
11
11
 
12
12
  This guide ensures consuming apps use pace-core components, hooks, and utilities correctly, preventing duplication and maintaining consistency across the PACE suite.
13
13
 
14
- This guide ensures consuming apps use pace-core components, hooks, and utilities correctly, preventing duplication and maintaining consistency across the PACE suite.
14
+ ## AI Agent Instructions
15
+
16
+ **When writing or modifying code, ALWAYS:**
17
+ 1. **Check pace-core first** - Before creating any component, hook, or utility, verify if pace-core provides it
18
+ 2. **Use pace-core components** - Never use native HTML elements (`<button>`, `<input>`) when pace-core provides components
19
+ 3. **Use pace-core hooks** - Never create custom hooks when pace-core provides equivalent functionality
20
+ 4. **Use secure Supabase client** - Always use `useSecureSupabase()`, never `createClient()` for queries
21
+ 5. **Read documentation** - Before using any pace-core component, check its documentation for required props and usage patterns
22
+ 6. **Follow provider nesting** - Always nest providers in the correct order (QueryClientProvider → BrowserRouter → UnifiedAuthProvider → OrganisationProvider)
23
+ 7. **Configure Vite correctly** - Always exclude `@jmruthers/pace-core` and `react-router-dom` from pre-bundling
24
+
25
+ **Decision Tree: Should I create this or use pace-core?**
26
+ ```
27
+ 1. What am I trying to create?
28
+ ├─ Component (Button, Input, Card, etc.) → Use pace-core
29
+ ├─ Hook (auth, permissions, debounce, etc.) → Use pace-core
30
+ ├─ Utility (formatDate, cn, validation, etc.) → Use pace-core
31
+ └─ App-specific domain logic → Create custom (but follow pace-core patterns)
32
+
33
+ 2. Does pace-core provide this?
34
+ ├─ YES → Use pace-core (import from '@jmruthers/pace-core')
35
+ └─ NO → Check if it should be added to pace-core (for shared use)
36
+
37
+ 3. Am I about to use native HTML?
38
+ ├─ YES → Check if pace-core has equivalent component
39
+ └─ NO → Continue
40
+ ```
15
41
 
16
42
  ## MUST: Use pace-core Instead of Custom Solutions
17
43
 
18
- **You MUST use pace-core components, hooks, and utilities when they exist.** Creating custom solutions duplicates functionality and breaks consistency.
44
+ **ALWAYS use pace-core components, hooks, and utilities when they exist.** Creating custom solutions duplicates functionality and breaks consistency.
19
45
 
20
46
  ### Components
21
47
 
@@ -33,10 +59,28 @@ This guide ensures consuming apps use pace-core components, hooks, and utilities
33
59
  - Import directly from `@radix-ui/*` - Use pace-core wrappers instead
34
60
  - Import directly from `lucide-react` - Import icons from `@jmruthers/pace-core/icons` instead
35
61
 
36
- **Example:**
62
+ **Examples:**
37
63
  ```tsx
38
- // ❌ WRONG: <button className="btn">Click me</button>
39
- // CORRECT: import { Button } from '@jmruthers/pace-core'; <Button>Click me</Button>
64
+ // ❌ WRONG: Native HTML button
65
+ <button className="btn-primary" onClick={handleClick}>
66
+ Click me
67
+ </button>
68
+
69
+ // ✅ CORRECT: pace-core Button component
70
+ import { Button } from '@jmruthers/pace-core';
71
+ <Button onClick={handleClick}>Click me</Button>
72
+
73
+ // ❌ WRONG: Native HTML input
74
+ <input
75
+ type="text"
76
+ className="form-input"
77
+ value={value}
78
+ onChange={handleChange}
79
+ />
80
+
81
+ // ✅ CORRECT: pace-core Input component
82
+ import { Input } from '@jmruthers/pace-core';
83
+ <Input type="text" value={value} onChange={handleChange} />
40
84
  ```
41
85
 
42
86
  ### Hooks
@@ -81,8 +125,13 @@ This guide ensures consuming apps use pace-core components, hooks, and utilities
81
125
 
82
126
  ## MUST: Use Secure Supabase Client
83
127
 
84
- **All database operations MUST use `useSecureSupabase()` (or the contract-approved pace-core secure client wrapper).**
85
- Consuming apps **MUST NOT** use the base Supabase client directly for queries.
128
+ **ALWAYS use `useSecureSupabase()` for all database operations.** Never use the base Supabase client directly for queries.
129
+
130
+ **When writing database code:**
131
+ 1. Import: `import { useSecureSupabase } from '@jmruthers/pace-core/rbac'`
132
+ 2. Call hook: `const secureSupabase = useSecureSupabase()`
133
+ 3. Use for queries: `await secureSupabase.from('table').select('*')`
134
+ 4. Never use: `createClient()` for queries (only for provider setup)
86
135
 
87
136
  ### Hard Requirements
88
137
 
@@ -174,16 +223,11 @@ const { data } = await supabase.from('users').select('*'); // Bypasses RLS
174
223
 
175
224
  **NO OTHER EXCEPTIONS ARE PERMITTED** - All other uses of `createClient()` are security violations and MUST be fixed.
176
225
 
177
- ### Detection / Audit
178
-
179
- - `rg "createClient\(" src` must return **exactly ONE match** in the file that creates the base client for `UnifiedAuthProvider`.
180
- - That file MUST be one of: `main.tsx`, `App.tsx`, or `lib/supabase.ts` (or `.jsx`/`.js` equivalents).
181
- - No `.from(` / `.rpc(` calls may be performed on an insecure client reference.
182
- - All `useSecureSupabase()` calls should be without parameters.
226
+ **Note**: System-level validation of Supabase client usage is handled by the audit tool. See [1-pace-core-compliance-standards.md](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) for complete enforcement details.
183
227
 
184
228
  ## MUST: Setup RBAC Before Use
185
229
 
186
- **You MUST call `setupRBAC()` before any RBAC usage.** This is non-negotiable.
230
+ **ALWAYS call `setupRBAC()` before any RBAC usage.** This is non-negotiable.
187
231
 
188
232
  ```tsx
189
233
  // main.tsx - MUST be first
@@ -194,7 +238,7 @@ setupRBAC(supabase);
194
238
 
195
239
  ## MUST: Read Documentation Before Using Components
196
240
 
197
- **You MUST read pace-core component documentation before using any component.** Never guess about props, usage patterns, or behavior.
241
+ **ALWAYS read pace-core component documentation before using any component.** Never guess about props, usage patterns, or behavior.
198
242
 
199
243
  ### Where to Find Documentation
200
244
 
@@ -292,20 +336,97 @@ Before using any pace-core component:
292
336
  - Document why custom solution is needed
293
337
  - Follow pace-core patterns for consistency
294
338
 
295
- ## MUST: Use pace-core Providers
339
+ ## MUST: Provider Nesting Order
296
340
 
297
- **You MUST wrap your app with required providers:**
341
+ **⚠️ CRITICAL: Provider nesting order matters!** Incorrect nesting causes React context errors.
342
+
343
+ **MUST** nest providers in this exact order (outermost to innermost):
344
+
345
+ 1. `QueryClientProvider` (outermost)
346
+ 2. `BrowserRouter`
347
+ 3. `UnifiedAuthProvider`
348
+ 4. `OrganisationProvider`
349
+ 5. `App` (innermost)
298
350
 
299
351
  ```tsx
352
+ // ✅ CORRECT: main.tsx
353
+ import { BrowserRouter } from 'react-router-dom';
354
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
300
355
  import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
301
- <UnifiedAuthProvider supabaseClient={supabase} appName="Your App">
302
- <OrganisationProvider>{/* Your app */}</OrganisationProvider>
303
- </UnifiedAuthProvider>
356
+ import { createClient } from '@supabase/supabase-js';
357
+
358
+ const queryClient = new QueryClient();
359
+ const supabase = createClient(
360
+ import.meta.env.VITE_SUPABASE_URL,
361
+ import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
362
+ );
363
+
364
+ createRoot(document.getElementById("root")!).render(
365
+ <QueryClientProvider client={queryClient}>
366
+ <BrowserRouter>
367
+ <UnifiedAuthProvider supabaseClient={supabase} appName="YourApp">
368
+ <OrganisationProvider>
369
+ <App />
370
+ </OrganisationProvider>
371
+ </UnifiedAuthProvider>
372
+ </BrowserRouter>
373
+ </QueryClientProvider>
374
+ );
375
+ ```
376
+
377
+ **Common mistakes to avoid:**
378
+ - ❌ `BrowserRouter` inside `UnifiedAuthProvider` (causes Router context errors)
379
+ - ❌ `UnifiedAuthProvider` wrapping `BrowserRouter` (causes context errors)
380
+ - ❌ Missing `BrowserRouter` (causes `useNavigate` errors)
381
+
382
+ ## MUST: Vite Configuration
383
+
384
+ **⚠️ CRITICAL: Vite configuration prevents React context mismatches!**
385
+
386
+ **MUST** configure Vite to exclude `@jmruthers/pace-core` and `react-router-dom` from pre-bundling:
387
+
388
+ ```typescript
389
+ // vite.config.ts
390
+ import { defineConfig } from 'vite';
391
+ import react from '@vitejs/plugin-react';
392
+ import path from 'path';
393
+
394
+ export default defineConfig({
395
+ plugins: [react()],
396
+ resolve: {
397
+ alias: {
398
+ '@': path.resolve(__dirname, './src'),
399
+ },
400
+ // CRITICAL: Dedupe React dependencies
401
+ dedupe: ['react', 'react-dom', 'react-router-dom'],
402
+ },
403
+ optimizeDeps: {
404
+ include: [
405
+ 'react',
406
+ 'react-dom',
407
+ 'react/jsx-runtime',
408
+ ],
409
+ // CRITICAL: Exclude pace-core to prevent React context mismatches
410
+ exclude: ['@jmruthers/pace-core', 'react-router-dom'],
411
+ },
412
+ });
304
413
  ```
305
414
 
415
+ **Why this matters:**
416
+ - Pre-bundling `@jmruthers/pace-core` creates separate React instances
417
+ - This causes "useUnifiedAuth must be used within a UnifiedAuthProvider" errors
418
+ - Excluding it ensures pace-core uses the same React instance as your app
419
+ - `react-router-dom` must also be excluded and deduped to prevent Router context errors
420
+
421
+ **If you encounter context errors:**
422
+ 1. Verify `@jmruthers/pace-core` is in `optimizeDeps.exclude`
423
+ 2. Verify `react-router-dom` is in both `resolve.dedupe` and `optimizeDeps.exclude`
424
+ 3. Clear Vite cache: `rm -rf node_modules/.vite`
425
+ 4. Restart dev server
426
+
306
427
  ## MUST: Import Core Styles
307
428
 
308
- **You MUST import pace-core styles via app.css:**
429
+ **ALWAYS import pace-core styles via app.css:**
309
430
 
310
431
  The correct pattern is a two-file CSS architecture:
311
432
  1. `src/app.css` - Contains `@import "@jmruthers/pace-core/styles/core.css";` (CSS @import)
@@ -326,11 +447,11 @@ import './app.css'; // ✅ CORRECT - app.css imports core.css
326
447
  - Import `core.css` directly in `main.tsx` or `App.tsx` - This causes duplicate imports
327
448
  - Use JavaScript import for `core.css` - Use CSS `@import` in `app.css` instead
328
449
 
329
- **See [08-markup-quality.md](../../packages/core/docs/standards/08-markup-quality.md) for complete CSS setup instructions.**
450
+ **See [5-styling-standards.md](../../packages/core/docs/standards/5-styling-standards.md) for complete CSS setup instructions.**
330
451
 
331
452
  ## MUST NOT: Use Inline Styles
332
453
 
333
- **You MUST NOT use inline styles (`style={{...}}`).** All styling MUST come from pace-core components and Tailwind classes.
454
+ **NEVER use inline styles (`style={{...}}`).** All styling MUST come from pace-core components and Tailwind classes.
334
455
 
335
456
  ### Why No Inline Styles
336
457
 
@@ -392,14 +513,46 @@ Before adding any styling:
392
513
 
393
514
  ## Common Mistakes to Avoid
394
515
 
395
- 1. **Using inline styles** - Never use `style={{...}}`, use pace-core components and Tailwind classes
396
- 2. **Guessing component props** - Always read documentation first
397
- 3. **Creating duplicate components** - Always check pace-core first
398
- 4. **Using base Supabase client** - Always use `useSecureSupabase()`
399
- 5. **Missing RBAC setup** - Always call `setupRBAC()` first
400
- 6. **Missing providers** - Always wrap with required providers
401
- 7. **Missing styles** - Always import core.css
402
- 8. **Direct library imports** - Use pace-core wrappers instead
516
+ **When writing code, NEVER:**
517
+ 1. **Use native HTML when pace-core provides components** - Always check pace-core first
518
+ ```tsx
519
+ // WRONG
520
+ <button>Click</button>
521
+ <input type="text" />
522
+
523
+ // CORRECT
524
+ <Button>Click</Button>
525
+ <Input type="text" />
526
+ ```
527
+
528
+ 2. **Create wrapper functions around pace-core hooks** - Use hooks directly
529
+ ```tsx
530
+ // ❌ WRONG
531
+ function useMyAuth() {
532
+ const auth = useUnifiedAuth();
533
+ return { user: auth.user, isAdmin: auth.user?.role === 'admin' };
534
+ }
535
+
536
+ // ✅ CORRECT
537
+ const { user } = useUnifiedAuth();
538
+ const { canManage } = useCan(user?.id, scope, 'manage:users');
539
+ ```
540
+
541
+ 3. **Use createClient() for queries** - Always use `useSecureSupabase()`
542
+ ```tsx
543
+ // ❌ WRONG
544
+ const supabase = createClient(url, key);
545
+ const { data } = await supabase.from('users').select('*');
546
+
547
+ // ✅ CORRECT
548
+ const secureSupabase = useSecureSupabase();
549
+ const { data } = await secureSupabase.from('users').select('*');
550
+ ```
551
+
552
+ 4. **Guess component props** - Always read documentation first
553
+ 5. **Use inline styles** - Use pace-core components and Tailwind classes
554
+ 6. **Skip provider nesting** - Always nest in correct order
555
+ 7. **Skip Vite configuration** - Always exclude pace-core from pre-bundling
403
556
 
404
557
  ## Compliance Exceptions
405
558
 
@@ -424,8 +577,8 @@ If you encounter a situation where a rule seems to conflict with a legitimate re
424
577
 
425
578
  ## Reference
426
579
 
427
- - **pace-core Exports**: See `pace-core-exports.mdc` for complete export reference
428
- - **RBAC Implementation**: See `rbac-implementation.mdc` for RBAC patterns
580
+ - **pace-core Exports**: See [pace-core documentation](../../packages/core/docs/README.md) for complete export reference
581
+ - **RBAC Implementation**: See [6-security-rbac-standards.md](../../packages/core/docs/standards/6-security-rbac-standards.md) for RBAC patterns
429
582
  - **Component Documentation**:
430
583
  - API Reference: `node_modules/@jmruthers/pace-core/docs/api-reference/components.md`
431
584
  - Implementation Guides: `node_modules/@jmruthers/pace-core/docs/implementation-guides/`
@@ -7,10 +7,42 @@ rulesVersion: "2025-01-28"
7
7
  ---
8
8
  # Project Structure Standard
9
9
 
10
- **📚 Human-Readable Standard**: See [02-project-structure.md](../../packages/core/docs/standards/02-project-structure.md) for complete documentation including migration guides and detailed examples.
10
+ **📚 Human-Readable Standard**: See [2-project-structure-standards.md](../../packages/core/docs/standards/2-project-structure-standards.md) for complete documentation including migration guides and detailed examples.
11
11
 
12
12
  This guide defines the standard folder structure and file organization for consuming apps in the PACE suite.
13
13
 
14
+ ## AI Agent Instructions
15
+
16
+ **When creating or organizing files, ALWAYS:**
17
+ 1. **Organize by feature** - Group components, hooks, and utilities by feature/domain, not by type
18
+ 2. **Colocate tests** - Place test files next to source files (`Component.test.tsx` next to `Component.tsx`)
19
+ 3. **Follow naming conventions** - Components: `PascalCase.tsx`, Hooks: `use*.ts`, Utils: `camelCase.ts`
20
+ 4. **Use absolute imports** - Use `@/` path alias for imports, never relative imports for distant files
21
+ 5. **Keep root clean** - Only configuration files and documentation in root, never source files
22
+ 6. **Place migrations correctly** - All migrations in `supabase/migrations/` with timestamp format
23
+
24
+ **Decision Tree: File Organization**
25
+ ```
26
+ 1. Where should this file go?
27
+ ├─ Component → src/components/<feature>/ComponentName.tsx
28
+ ├─ Hook → src/hooks/useHookName.ts (or colocated with component)
29
+ ├─ Utility → src/utils/utilityName.ts
30
+ ├─ Type → src/types/typeName.ts (or colocated with feature)
31
+ ├─ Test → Next to source file (ComponentName.test.tsx)
32
+ └─ Migration → supabase/migrations/YYYYMMDDHHMMSS_description.sql
33
+
34
+ 2. How should I name it?
35
+ ├─ Component → PascalCase (EventCard.tsx)
36
+ ├─ Hook → camelCase with use prefix (useEventData.ts)
37
+ ├─ Utility → camelCase (formatEvent.ts)
38
+ └─ Test → Same as source + .test (EventCard.test.tsx)
39
+
40
+ 3. Should I use absolute or relative imports?
41
+ ├─ Same directory → Relative (./Component)
42
+ ├─ Different directory → Absolute (@/components/events/EventCard)
43
+ └─ pace-core → Package import (@jmruthers/pace-core)
44
+ ```
45
+
14
46
  ## MUST: Follow Standard Directory Structure
15
47
 
16
48
  **Consuming apps MUST follow this structure:**
@@ -42,7 +74,7 @@ your-app/
42
74
 
43
75
  ## MUST: Organize Components by Feature
44
76
 
45
- **Components SHOULD be organized by feature/domain, not by type:**
77
+ **ALWAYS organize components by feature/domain, not by type:**
46
78
 
47
79
  ```
48
80
  src/
@@ -64,7 +96,7 @@ src/
64
96
 
65
97
  ## MUST: Colocate Tests
66
98
 
67
- **Tests MUST be colocated with source files:**
99
+ **ALWAYS colocate tests with source files:**
68
100
 
69
101
  ```
70
102
  src/
@@ -143,7 +175,7 @@ src/
143
175
 
144
176
  ## MUST: Use Consistent Import Paths
145
177
 
146
- **MUST use consistent import patterns:**
178
+ **ALWAYS use consistent import patterns:**
147
179
 
148
180
  ```tsx
149
181
  // ✅ CORRECT - Absolute imports from src
@@ -203,4 +235,4 @@ Before committing, verify:
203
235
 
204
236
  ## Reference
205
237
 
206
- See `project-structure.mdc` in pace-core for detailed structure patterns.
238
+ **Note**: File structure validation is handled by the audit tool. See [2-project-structure-standards.md](../../packages/core/docs/standards/2-project-structure-standards.md) for complete enforcement details.
@@ -1,15 +1,43 @@
1
1
  ---
2
- description: Enforce SOLID architecture principles in consuming apps
2
+ description: Enforce SOLID architecture principles, component design, and API design patterns
3
3
  globs: ["src/**/*.{ts,tsx}"]
4
4
  alwaysApply: false
5
5
  paceCoreVersion: "0.6.x"
6
6
  rulesVersion: "2025-01-28"
7
7
  ---
8
- # SOLID Principles Guide
8
+ # Architecture Standards Guide
9
9
 
10
- **📚 Human-Readable Standard**: See [03-solid-principles.md](../../packages/core/docs/standards/03-solid-principles.md) for complete documentation.
10
+ **📚 Human-Readable Standard**: See [3-architecture-standards.md](../../packages/core/docs/standards/3-architecture-standards.md) for complete documentation.
11
11
 
12
- This guide enforces SOLID architecture principles to ensure maintainable, extensible, and testable code.
12
+ This guide enforces SOLID architecture principles, component design patterns, and API design patterns to ensure maintainable, extensible, and testable code.
13
+
14
+ ## AI Agent Instructions
15
+
16
+ **When writing or modifying code, ALWAYS:**
17
+ 1. **Extract complex logic** - Move business logic out of components into hooks, services, or utilities
18
+ 2. **Use composition** - Extend functionality through composition, not modification of pace-core components
19
+ 3. **Keep components simple** - Components should only handle UI rendering, not data fetching or business logic
20
+ 4. **Use focused interfaces** - Create small, specific interfaces instead of large, generic ones
21
+ 5. **Depend on abstractions** - Use interfaces/types, not concrete implementations
22
+ 6. **Follow ApiResult pattern** - All RPCs must return ApiResult shape with proper error handling
23
+
24
+ **Decision Tree: Where should this logic live?**
25
+ ```
26
+ 1. What type of logic is this?
27
+ ├─ UI rendering → Component
28
+ ├─ Data fetching → Hook or service
29
+ ├─ Business logic → Hook, service, or utility
30
+ ├─ Formatting/transformation → Utility function
31
+ └─ Validation → Zod schema or utility
32
+
33
+ 2. Is this logic complex?
34
+ ├─ YES → Extract to hook/service/utility
35
+ └─ NO → Can stay in component if simple
36
+
37
+ 3. Does this modify pace-core behavior?
38
+ ├─ YES → Use composition (wrap pace-core component)
39
+ └─ NO → Continue
40
+ ```
13
41
 
14
42
  ## Single Responsibility Principle (SRP)
15
43
 
@@ -206,17 +234,103 @@ Before committing code, verify:
206
234
  - [ ] No god objects or bloated components
207
235
  - [ ] Code is testable and maintainable
208
236
 
209
- ## Anti-Patterns to Avoid
237
+ ## Common Mistakes to Avoid
238
+
239
+ **When writing code, NEVER:**
240
+ 1. **Create god objects** - Components/classes that do too much
241
+ ```tsx
242
+ // ❌ WRONG: Component does everything
243
+ function UserDashboard({ userId }) {
244
+ const [user, setUser] = useState(null);
245
+ const [events, setEvents] = useState([]);
246
+ const [organisations, setOrganisations] = useState([]);
247
+ // 200+ lines of logic...
248
+ }
249
+
250
+ // ✅ CORRECT: Separated concerns
251
+ function UserDashboard({ userId }) {
252
+ const user = useUser(userId);
253
+ const events = useUserEvents(userId);
254
+ const organisations = useUserOrganisations(userId);
255
+ return <DashboardContent user={user} events={events} organisations={organisations} />;
256
+ }
257
+ ```
258
+
259
+ 2. **Put business logic in components** - Extract to hooks/services
260
+ 3. **Create large interfaces** - Use focused, specific interfaces
261
+ 4. **Depend on concrete implementations** - Use abstractions (interfaces/types)
262
+ 5. **Modify pace-core components** - Use composition instead
263
+ 6. **Use boolean flags for states** - Use discriminated unions
264
+
265
+ ## API Design Patterns
266
+
267
+ ### MUST: Follow API Design Principles
268
+
269
+ **APIs MUST be:**
270
+ - Intuitive and consistent
271
+ - Extensible without breaking changes
272
+ - Clear about errors and edge cases
273
+
274
+ ### MUST: Use ApiResult Pattern
275
+
276
+ **All RPCs MUST return ApiResult shape:**
277
+
278
+ ```typescript
279
+ type ApiResult<T> = { ok: true; data: T } | { ok: false; error: ApiError };
280
+ type ApiError = { code: string; message: string; details?: object };
281
+ ```
282
+
283
+ ```tsx
284
+ // ✅ CORRECT: RPC returns ApiResult
285
+ const result = await supabase.rpc('app_events_create', { name, date });
286
+ if (!result.ok) {
287
+ // Handle error
288
+ return { ok: false, error: result.error };
289
+ }
290
+ return { ok: true, data: result.data };
291
+ ```
292
+
293
+ ### SHOULD: Make Write RPCs Idempotent
210
294
 
211
- 1. **God Objects** - Classes/components that do too much
212
- 2. **Feature Envy** - Functions that use more of another object than their own
213
- 3. **Data Clumps** - Groups of data that should be objects
214
- 4. **Long Parameter Lists** - Use objects/interfaces instead
215
- 5. **Divergent Change** - One class changed for multiple reasons
216
- 6. **Shotgun Surgery** - One change requires many class modifications
295
+ **Write RPCs SHOULD be idempotent when possible:**
296
+
297
+ ```sql
298
+ -- CORRECT: Idempotent create (ON CONFLICT DO NOTHING)
299
+ INSERT INTO events (id, name, date)
300
+ VALUES (p_event_id, p_name, p_date)
301
+ ON CONFLICT (id) DO NOTHING;
302
+ ```
303
+
304
+ ## Component Design Patterns
305
+
306
+ ### MUST: Follow Component Principles
307
+
308
+ **Components MUST:**
309
+ - Be stateless when possible
310
+ - Use composable structure
311
+ - Be accessible by default
312
+ - Be fully typed
313
+ - Have small surface area
314
+
315
+ ### MUST NOT: Add Domain Logic to Components
316
+
317
+ **Components MUST NOT:**
318
+ - Include domain-specific logic
319
+ - Fetch data directly (use hooks/services)
320
+ - Include business workflows
321
+
322
+ ### MUST: Ensure Accessibility
323
+
324
+ **Components MUST:**
325
+ - Be keyboard operable
326
+ - Have correct ARIA roles
327
+ - Have visible focus states
328
+ - Avoid inaccessible interactions
217
329
 
218
330
  ## Reference
219
331
 
332
+ **Note**: RLS policy validation is handled by the audit tool. See [3-architecture-standards.md](../../packages/core/docs/standards/3-architecture-standards.md) for complete enforcement details.
333
+
220
334
  - Single Responsibility: Each module has one reason to change
221
335
  - Open/Closed: Open for extension, closed for modification
222
336
  - Liskov Substitution: Subtypes must be substitutable