@jmruthers/pace-core 0.5.193 → 0.6.1

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 (191) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +372 -0
  4. package/cursor-rules/01-standards-compliance.mdc +275 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +341 -0
  7. package/cursor-rules/04-testing-standards.mdc +315 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +392 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +309 -0
  11. package/cursor-rules/CHANGELOG.md +101 -0
  12. package/cursor-rules/README.md +191 -0
  13. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-CH1U5Tpy.d.ts} +1 -1
  14. package/dist/{DataTable-5FU7IESH.js → DataTable-DQ7RSOHE.js} +6 -6
  15. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-ce4xlHYA.d.ts} +34 -155
  16. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-ATAP5UTR.js} +2 -2
  17. package/dist/{chunk-6C4YBBJM 5.js → chunk-3QRJFVBR.js} +1 -1
  18. package/dist/chunk-3QRJFVBR.js.map +1 -0
  19. package/dist/{chunk-IIELH4DL.js → chunk-3XTALGJF.js} +2 -2
  20. package/dist/{chunk-IIELH4DL.js.map → chunk-3XTALGJF.js.map} +1 -1
  21. package/dist/{chunk-HWIIPPNI.js → chunk-4N5C5XZU.js} +20 -20
  22. package/dist/chunk-4N5C5XZU.js.map +1 -0
  23. package/dist/{chunk-7EQTDTTJ.js → chunk-4ZC4GX36.js} +5 -5
  24. package/dist/{chunk-7EQTDTTJ.js 2.map → chunk-4ZC4GX36.js.map} +1 -1
  25. package/dist/{chunk-7FLMSG37.js → chunk-BYFSK72L.js} +22 -22
  26. package/dist/chunk-BYFSK72L.js.map +1 -0
  27. package/dist/{chunk-LFNCN2SP.js → chunk-EXUD6RNJ.js} +46 -7
  28. package/dist/chunk-EXUD6RNJ.js.map +1 -0
  29. package/dist/{chunk-NOAYCWCX 5.js → chunk-GLK6VM3F.js} +167 -169
  30. package/dist/chunk-GLK6VM3F.js.map +1 -0
  31. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  32. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  33. package/dist/{chunk-BC4IJKSL.js → chunk-JBKQ3SAO.js} +2 -2
  34. package/dist/{chunk-QWWZ5CAQ.js → chunk-LXQLPRQ2.js} +2 -2
  35. package/dist/{chunk-E3SPN4VZ 5.js → chunk-T33XF5ZC.js} +119 -114
  36. package/dist/chunk-T33XF5ZC.js.map +1 -0
  37. package/dist/{chunk-XNXXZ43G.js → chunk-XM25TVIE.js} +27 -4
  38. package/dist/chunk-XM25TVIE.js.map +1 -0
  39. package/dist/components.d.ts +3 -3
  40. package/dist/components.js +8 -8
  41. package/dist/hooks.d.ts +6 -6
  42. package/dist/hooks.js +17 -22
  43. package/dist/hooks.js.map +1 -1
  44. package/dist/index.d.ts +7 -7
  45. package/dist/index.js +15 -16
  46. package/dist/index.js.map +1 -1
  47. package/dist/providers.js +1 -1
  48. package/dist/rbac/index.d.ts +1 -1
  49. package/dist/rbac/index.js +5 -5
  50. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-BJAlWfuJ.d.ts} +3 -3
  51. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  52. package/dist/utils.d.ts +1 -1
  53. package/dist/utils.js +3 -3
  54. package/docs/getting-started/cursor-rules.md +262 -0
  55. package/docs/getting-started/installation-guide.md +6 -1
  56. package/docs/getting-started/quick-start.md +6 -1
  57. package/docs/migration/MIGRATION_GUIDE.md +4 -4
  58. package/docs/migration/REACT_19_MIGRATION.md +227 -0
  59. package/docs/standards/README.md +39 -0
  60. package/docs/troubleshooting/migration.md +4 -4
  61. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  62. package/package.json +11 -6
  63. package/scripts/audit-consuming-app.cjs +961 -0
  64. package/scripts/check-pace-core-compliance.cjs +34 -15
  65. package/scripts/install-cursor-rules.cjs +236 -0
  66. package/src/__tests__/helpers/test-providers.tsx +1 -1
  67. package/src/__tests__/helpers/test-utils.tsx +1 -1
  68. package/src/components/Badge/Badge.tsx +2 -4
  69. package/src/components/Button/Button.tsx +5 -4
  70. package/src/components/Calendar/Calendar.tsx +1 -1
  71. package/src/components/DataTable/DataTable.test.tsx +57 -93
  72. package/src/components/DataTable/DataTable.tsx +2 -2
  73. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +13 -5
  74. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  75. package/src/components/DataTable/components/AccessDeniedPage.tsx +1 -1
  76. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  77. package/src/components/DataTable/components/DataTableCore.tsx +4 -7
  78. package/src/components/DataTable/components/DataTableModals.tsx +1 -1
  79. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  80. package/src/components/DataTable/components/UnifiedTableBody.tsx +6 -8
  81. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  82. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  83. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  84. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  85. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  86. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  87. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  88. package/src/components/DataTable/hooks/useColumnReordering.ts +2 -2
  89. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  90. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  91. package/src/components/Dialog/Dialog.tsx +6 -5
  92. package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
  93. package/src/components/EventSelector/EventSelector.tsx +1 -1
  94. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  95. package/src/components/Footer/Footer.tsx +1 -1
  96. package/src/components/Form/Form.test.tsx +36 -15
  97. package/src/components/Form/Form.tsx +30 -26
  98. package/src/components/Header/Header.tsx +1 -1
  99. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  100. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  101. package/src/components/Input/Input.tsx +28 -30
  102. package/src/components/Label/Label.tsx +1 -1
  103. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  104. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  105. package/src/components/LoginForm/LoginForm.tsx +8 -8
  106. package/src/components/NavigationMenu/NavigationMenu.tsx +1 -1
  107. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  108. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +50 -50
  109. package/src/components/PaceAppLayout/PaceAppLayout.tsx +1 -1
  110. package/src/components/PaceAppLayout/README.md +1 -1
  111. package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -1
  112. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  113. package/src/components/PasswordChange/PasswordChangeForm.tsx +1 -1
  114. package/src/components/Progress/Progress.tsx +1 -1
  115. package/src/components/PublicLayout/PublicPageLayout.tsx +1 -1
  116. package/src/components/Select/Select.tsx +33 -22
  117. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +1 -1
  118. package/src/components/Table/Table.tsx +1 -1
  119. package/src/components/Textarea/Textarea.tsx +27 -29
  120. package/src/components/Toast/Toast.tsx +1 -1
  121. package/src/components/Tooltip/Tooltip.tsx +1 -1
  122. package/src/components/UserMenu/UserMenu.tsx +1 -1
  123. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  124. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  125. package/src/hooks/public/usePublicEvent.ts +1 -1
  126. package/src/hooks/public/usePublicEventLogo.ts +1 -1
  127. package/src/hooks/public/usePublicRouteParams.ts +1 -1
  128. package/src/hooks/useDataTableState.ts +8 -18
  129. package/src/hooks/useFocusManagement.ts +2 -2
  130. package/src/hooks/useFocusTrap.ts +4 -4
  131. package/src/hooks/useFormDialog.ts +8 -7
  132. package/src/hooks/useInactivityTracker.ts +1 -1
  133. package/src/hooks/usePermissionCache.ts +1 -1
  134. package/src/hooks/useSecureDataAccess.ts +19 -4
  135. package/src/hooks/useToast.ts +2 -2
  136. package/src/providers/__tests__/OrganisationProvider.test.tsx +57 -13
  137. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  138. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  139. package/src/providers/services/UnifiedAuthProvider.tsx +22 -22
  140. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +13 -3
  141. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +24 -24
  142. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  143. package/src/rbac/components/NavigationGuard.tsx +1 -1
  144. package/src/rbac/components/NavigationProvider.tsx +1 -1
  145. package/src/rbac/components/PagePermissionGuard.tsx +1 -1
  146. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  147. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  148. package/src/rbac/components/RoleBasedRouter.tsx +1 -1
  149. package/src/rbac/components/SecureDataProvider.tsx +1 -1
  150. package/src/rbac/secureClient.ts +12 -0
  151. package/src/utils/security/secureDataAccess.test.ts +31 -20
  152. package/src/utils/security/secureDataAccess.ts +4 -3
  153. package/dist/chunk-6C4YBBJM.js +0 -628
  154. package/dist/chunk-6C4YBBJM.js.map +0 -1
  155. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  156. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  157. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  158. package/dist/chunk-7FLMSG37.js.map +0 -1
  159. package/dist/chunk-E3SPN4VZ.js +0 -12917
  160. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  161. package/dist/chunk-E66EQZE6 5.js +0 -37
  162. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  163. package/dist/chunk-HWIIPPNI.js.map +0 -1
  164. package/dist/chunk-I7PSE6JW 5.js +0 -191
  165. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  166. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  167. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  168. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  169. package/dist/chunk-LFNCN2SP.js.map +0 -1
  170. package/dist/chunk-LMC26NLJ 2.js +0 -84
  171. package/dist/chunk-NOAYCWCX.js +0 -4993
  172. package/dist/chunk-NOAYCWCX.js.map +0 -1
  173. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  174. package/dist/chunk-QXHPKYJV 3.js +0 -113
  175. package/dist/chunk-R77UEZ4E 3.js +0 -68
  176. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  177. package/dist/chunk-XNXXZ43G.js.map +0 -1
  178. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  179. package/dist/components.js 5.map +0 -1
  180. package/dist/styles/index 2.js +0 -12
  181. package/dist/styles/index.js 5.map +0 -1
  182. package/dist/theming/runtime 5.js +0 -19
  183. package/dist/theming/runtime.js 5.map +0 -1
  184. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-DQ7RSOHE.js.map} +0 -0
  185. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-ATAP5UTR.js.map} +0 -0
  186. /package/dist/{chunk-BC4IJKSL.js.map → chunk-JBKQ3SAO.js.map} +0 -0
  187. /package/dist/{chunk-QWWZ5CAQ.js 3.map → chunk-LXQLPRQ2.js.map} +0 -0
  188. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  189. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  190. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  191. /package/examples/{rbac → RBAC}/index.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2025-01-28
11
+
12
+ ### Changed
13
+ - **BREAKING**: Upgraded from React 18.3.1 to React 19.2.3
14
+ - **BREAKING**: Updated peer dependencies to require React ^19.0.0
15
+ - **BREAKING**: Updated @types/react to ^19.2.7 and @types/react-dom to ^19.2.3
16
+ - **BREAKING**: Updated @vitejs/plugin-react to ^5.1.2
17
+ - Fixed TypeScript errors related to React 19's stricter type system in Button and Select components
18
+ - Updated vitest.config.ts to remove duplicate configuration keys
19
+
20
+ ### Added
21
+ - **React Compiler**: Added `babel-plugin-react-compiler` for automatic component optimizations
22
+ - **React Compiler Configuration**: Configured React Compiler in vite.config.ts and vitest.config.ts
23
+ - **Migration Guide**: Added React 19 migration guide at `docs/migration/REACT_19_MIGRATION.md`
24
+ - Updated documentation to reflect React 19 requirements
25
+
26
+ ### Technical Details
27
+ - React Compiler automatically optimizes components during development and in consuming apps
28
+ - TypeScript types updated to handle React 19's stricter `child.props` typing
29
+ - All error boundaries verified compatible with React 19 error handling changes
30
+ - All tests pass with React 19 and React Compiler enabled
31
+
32
+ ### Migration Notes
33
+ - Consuming apps must upgrade to React 19.2.3+
34
+ - Consuming apps should install and configure React Compiler for optimal performance
35
+ - See `docs/migration/REACT_19_MIGRATION.md` for complete migration instructions
36
+
37
+ ## [Unreleased]
38
+
10
39
  ### Added
11
40
  - **useFormDialog Hook**: Generic React hook for managing form dialog state (open/close, form data, reset behavior). Supports both controlled and uncontrolled usage patterns with type-safe form data management.
12
41
  - **DateTimeField Component**: Form input component for datetime values with automatic UTC ↔ timezone conversion
package/README.md CHANGED
@@ -80,6 +80,7 @@ import React from 'react';
80
80
  import ReactDOM from 'react-dom/client';
81
81
  import App from './App';
82
82
 
83
+ // React 19+ with createRoot
83
84
  const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
84
85
  root.render(
85
86
  <React.StrictMode>
@@ -104,7 +105,12 @@ import path from 'path'
104
105
 
105
106
  export default defineConfig({
106
107
  plugins: [
107
- react(),
108
+ react({
109
+ // React Compiler for automatic optimizations (React 19+)
110
+ babel: {
111
+ plugins: ['babel-plugin-react-compiler'],
112
+ },
113
+ }),
108
114
  tailwindcss({
109
115
  // Only need to scan your app's source files
110
116
  // pace-core source files are automatically scanned via @source directives
@@ -0,0 +1,372 @@
1
+ ---
2
+ description: Enforce pace-core usage patterns and prevent custom solutions when pace-core provides functionality
3
+ globs: ["src/**/*.{ts,tsx,js,jsx}"]
4
+ alwaysApply: true
5
+ paceCoreVersion: "0.5.x"
6
+ rulesVersion: "2025-01-15"
7
+ ---
8
+ # pace-core Compliance Guide
9
+
10
+ This guide ensures consuming apps use pace-core components, hooks, and utilities correctly, preventing duplication and maintaining consistency across the PACE suite.
11
+
12
+ ## MUST: Use pace-core Instead of Custom Solutions
13
+
14
+ **You MUST use pace-core components, hooks, and utilities when they exist.** Creating custom solutions duplicates functionality and breaks consistency.
15
+
16
+ ### Components
17
+
18
+ **MUST use pace-core components:**
19
+ - `Button`, `Card`, `Input`, `Label`, `Textarea` - Basic UI components
20
+ - `Dialog`, `Select`, `Tabs`, `Calendar`, `Toast`, `Tooltip` - Advanced UI components
21
+ - `DataTable` - Complex data tables with RBAC integration
22
+ - `Form`, `FormField`, `LoginForm` - Form components
23
+ - `Header`, `Footer`, `PaceAppLayout` - Layout components
24
+ - `FileUpload`, `FileDisplay` - Storage components
25
+
26
+ **MUST NOT:**
27
+ - Create custom button components when `Button` from pace-core exists
28
+ - Use native HTML elements (`<button>`, `<input>`) when pace-core provides components
29
+ - Import directly from `@radix-ui/*` - Use pace-core wrappers instead
30
+ - Import directly from `lucide-react` - Use pace-core components that include icons
31
+
32
+ **Example:**
33
+ ```tsx
34
+ // ❌ WRONG - Custom button
35
+ function CustomButton() {
36
+ return <button className="btn">Click me</button>;
37
+ }
38
+
39
+ // ✅ CORRECT - Use pace-core
40
+ import { Button } from '@jmruthers/pace-core';
41
+ function MyComponent() {
42
+ return <Button>Click me</Button>;
43
+ }
44
+ ```
45
+
46
+ ### Hooks
47
+
48
+ **MUST use pace-core hooks:**
49
+ - `useUnifiedAuth`, `useEvents`, `useOrganisations` - Authentication and data
50
+ - `usePermissions`, `useCan`, `useSecureSupabase` - RBAC hooks
51
+ - `useToast`, `useDebounce`, `useZodForm` - Utility hooks
52
+ - `useFileReference`, `useFileUpload` - File management hooks
53
+
54
+ **MUST NOT:**
55
+ - Create custom `useAuth` when `useUnifiedAuth` exists
56
+ - Create custom `useToast` when pace-core provides it
57
+ - Create custom `useDebounce` when pace-core provides it
58
+ - Create custom form hooks when `useZodForm` exists
59
+
60
+ **Example:**
61
+ ```tsx
62
+ // ❌ WRONG - Custom debounce hook
63
+ function useCustomDebounce(value: string, delay: number) {
64
+ const [debounced, setDebounced] = useState(value);
65
+ useEffect(() => {
66
+ const timer = setTimeout(() => setDebounced(value), delay);
67
+ return () => clearTimeout(timer);
68
+ }, [value, delay]);
69
+ return debounced;
70
+ }
71
+
72
+ // ✅ CORRECT - Use pace-core
73
+ import { useDebounce } from '@jmruthers/pace-core';
74
+ const debouncedValue = useDebounce(value, 500);
75
+ ```
76
+
77
+ ### Utilities
78
+
79
+ **MUST use pace-core utilities:**
80
+ - `cn` - Class name utility (replaces clsx/tailwind-merge)
81
+ - `formatDate`, `formatTime`, `formatDateTime` - Date formatting
82
+ - `formatCurrency`, `formatNumber`, `formatPercent` - Number formatting
83
+ - `emailSchema`, `nameSchema`, `passwordSchema` - Validation schemas
84
+ - `validateUserInput`, `sanitizeUserInput` - Input validation
85
+
86
+ **MUST NOT:**
87
+ - Create custom `formatDate` when pace-core provides it
88
+ - Use `clsx` directly - Use `cn` from pace-core
89
+ - Create custom validation when pace-core schemas exist
90
+
91
+ **Example:**
92
+ ```tsx
93
+ // ❌ WRONG - Custom date formatting
94
+ function formatDateCustom(date: Date): string {
95
+ return new Intl.DateTimeFormat('en-US').format(date);
96
+ }
97
+
98
+ // ✅ CORRECT - Use pace-core
99
+ import { formatDate } from '@jmruthers/pace-core';
100
+ const formatted = formatDate(date);
101
+ ```
102
+
103
+ ## MUST: Use Secure Supabase Client
104
+
105
+ **You MUST use `useSecureSupabase()` for all database operations.** Never use the base Supabase client directly.
106
+
107
+ ```tsx
108
+ // ❌ WRONG - Direct Supabase client
109
+ import { createClient } from '@supabase/supabase-js';
110
+ const supabase = createClient(...);
111
+ await supabase.from('users').select('*');
112
+
113
+ // ✅ CORRECT - Use secure client
114
+ import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
115
+ const secureSupabase = useSecureSupabase();
116
+ await secureSupabase.from('users').select('*');
117
+ ```
118
+
119
+ ## MUST: Setup RBAC Before Use
120
+
121
+ **You MUST call `setupRBAC()` before any RBAC usage.** This is non-negotiable.
122
+
123
+ ```tsx
124
+ // main.tsx - MUST be first
125
+ import { setupRBAC } from '@jmruthers/pace-core/rbac';
126
+ setupRBAC(supabase);
127
+
128
+ // Then render app
129
+ ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
130
+ ```
131
+
132
+ ## MUST: Read Documentation Before Using Components
133
+
134
+ **You MUST read pace-core component documentation before using any component.** Never guess about props, usage patterns, or behavior.
135
+
136
+ ### Where to Find Documentation
137
+
138
+ **Component API Reference:**
139
+ - Location: `node_modules/@jmruthers/pace-core/docs/api-reference/components.md`
140
+ - Or: Check pace-core repository `packages/core/docs/api-reference/components.md`
141
+ - Contains: Complete prop definitions, type information, usage examples
142
+
143
+ **Implementation Guides:**
144
+ - Location: `node_modules/@jmruthers/pace-core/docs/implementation-guides/`
145
+ - Contains: Detailed guides for complex components like DataTable, Forms, etc.
146
+ - Examples:
147
+ - `data-tables.md` - DataTable component guide
148
+ - `forms.md` - Form components guide
149
+ - `file-upload-storage.md` - FileUpload/FileDisplay guide
150
+
151
+ **Detailed API Documentation:**
152
+ - Location: `node_modules/@jmruthers/pace-core/docs/api/`
153
+ - Contains: In-depth API documentation for all exports
154
+
155
+ **Quick Reference:**
156
+ - Location: `node_modules/@jmruthers/pace-core/docs/getting-started/quick-reference.md`
157
+ - Contains: Quick lookup for common patterns
158
+
159
+ ### How to Find Component-Specific Docs
160
+
161
+ 1. **Check API Reference First:**
162
+ ```bash
163
+ # In your consuming app
164
+ cat node_modules/@jmruthers/pace-core/docs/api-reference/components.md
165
+ ```
166
+
167
+ 2. **Search Implementation Guides:**
168
+ - Look for component name in `implementation-guides/` directory
169
+ - Complex components have dedicated guides
170
+
171
+ 3. **Check Type Definitions:**
172
+ ```tsx
173
+ // Import and check TypeScript types
174
+ import type { DataTableProps } from '@jmruthers/pace-core';
175
+ // Hover over type to see prop definitions
176
+ ```
177
+
178
+ 4. **Use IDE IntelliSense:**
179
+ - TypeScript types provide inline documentation
180
+ - Hover over component name to see prop types
181
+ - Use autocomplete to discover available props
182
+
183
+ ### MUST NOT: Guess About Props or Usage
184
+
185
+ **❌ WRONG - Guessing props:**
186
+ ```tsx
187
+ // Don't guess - this might not work!
188
+ <DataTable
189
+ data={data}
190
+ columns={columns}
191
+ // Missing required rbac prop - will error!
192
+ />
193
+ ```
194
+
195
+ **✅ CORRECT - Read documentation first:**
196
+ ```tsx
197
+ // 1. Read DataTable docs in implementation-guides/data-tables.md
198
+ // 2. Understand required props (rbac is mandatory)
199
+ // 3. Use correct props
200
+ import { DataTable } from '@jmruthers/pace-core';
201
+
202
+ <DataTable
203
+ data={data}
204
+ columns={columns}
205
+ rbac={{ pageName: 'users' }} // Required - found in docs
206
+ features={{ search: true, pagination: true }}
207
+ />
208
+ ```
209
+
210
+ ### Documentation Checklist
211
+
212
+ Before using any pace-core component:
213
+ - [ ] Read component API reference
214
+ - [ ] Check for implementation guide if component is complex
215
+ - [ ] Review TypeScript types for prop definitions
216
+ - [ ] Check examples in documentation
217
+ - [ ] Verify required vs optional props
218
+ - [ ] Understand component behavior and limitations
219
+
220
+ ### Common Documentation Locations
221
+
222
+ | Component Type | Documentation Location |
223
+ |----------------|----------------------|
224
+ | Basic UI (Button, Card, etc.) | `api-reference/components.md` |
225
+ | DataTable | `implementation-guides/data-tables.md` |
226
+ | Forms | `implementation-guides/forms.md` |
227
+ | RBAC Components | `rbac/getting-started.md` |
228
+ | File Upload/Display | `implementation-guides/file-upload-storage.md` |
229
+ | Hooks | `api-reference/hooks.md` |
230
+ | Utilities | `api-reference/utilities.md` |
231
+
232
+ ## SHOULD: Check pace-core Before Creating New Components
233
+
234
+ **Before creating a new component, hook, or utility:**
235
+
236
+ 1. Check pace-core exports: `@jmruthers/pace-core`
237
+ 2. Review pace-core documentation
238
+ 3. Check `core-usage-manifest.json` for available exports
239
+ 4. Search pace-core source if needed
240
+
241
+ **If pace-core doesn't provide what you need:**
242
+ - Consider if it should be added to pace-core (for shared use)
243
+ - Document why custom solution is needed
244
+ - Follow pace-core patterns for consistency
245
+
246
+ ## MUST: Use pace-core Providers
247
+
248
+ **You MUST wrap your app with required providers:**
249
+
250
+ ```tsx
251
+ import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
252
+
253
+ function App() {
254
+ return (
255
+ <UnifiedAuthProvider supabaseClient={supabase} appName="Your App">
256
+ <OrganisationProvider>
257
+ {/* Your app */}
258
+ </OrganisationProvider>
259
+ </UnifiedAuthProvider>
260
+ );
261
+ }
262
+ ```
263
+
264
+ ## MUST: Import Core Styles
265
+
266
+ **You MUST import pace-core styles:**
267
+
268
+ ```tsx
269
+ // main.tsx or App.tsx
270
+ import '@jmruthers/pace-core/styles/core.css';
271
+ ```
272
+
273
+ ## MUST NOT: Use Inline Styles
274
+
275
+ **You MUST NOT use inline styles (`style={{...}}`).** All styling MUST come from pace-core components and Tailwind classes.
276
+
277
+ ### Why No Inline Styles
278
+
279
+ - Inline styles override pace-core component styles
280
+ - Inline styles break consistency across the PACE suite
281
+ - Inline styles are harder to maintain and update
282
+ - Inline styles don't benefit from theme variables and design system
283
+
284
+ ### Use pace-core Components for Styling
285
+
286
+ **All styling MUST come from:**
287
+ 1. **pace-core components** - Components already have correct styling
288
+ 2. **Tailwind utility classes** - Use Tailwind classes for layout and spacing
289
+ 3. **Semantic classes** - Use semantic classes from pace-core (e.g., `bg-background`, `text-foreground`)
290
+
291
+ **MUST NOT:**
292
+ - Use `style={{...}}` prop
293
+ - Use inline CSS strings
294
+ - Override component styles with inline styles
295
+ - Create custom CSS for styling that pace-core provides
296
+
297
+ **Example:**
298
+ ```tsx
299
+ // ❌ WRONG - Inline styles
300
+ <div style={{ backgroundColor: 'blue', padding: '10px', color: 'white' }}>
301
+ Content
302
+ </div>
303
+
304
+ // ❌ WRONG - Inline styles on pace-core component
305
+ <Button style={{ backgroundColor: 'red' }}>Click me</Button>
306
+
307
+ // ✅ CORRECT - Use pace-core component with Tailwind classes
308
+ <Card className="bg-main-500 p-4 text-white">
309
+ <CardContent>Content</CardContent>
310
+ </Card>
311
+
312
+ // ✅ CORRECT - Use pace-core component as-is (already styled)
313
+ <Button variant="default">Click me</Button>
314
+
315
+ // ✅ CORRECT - Use Tailwind for layout/spacing only
316
+ <div className="flex items-center gap-4 p-4">
317
+ <Button>Action</Button>
318
+ </div>
319
+ ```
320
+
321
+ ### When Tailwind Classes Are Acceptable
322
+
323
+ **Tailwind classes are acceptable for:**
324
+ - Layout (flex, grid, positioning)
325
+ - Spacing (margin, padding, gap)
326
+ - Responsive design (breakpoints)
327
+ - Layout-specific styling not provided by pace-core components
328
+
329
+ **Tailwind classes MUST NOT:**
330
+ - Override pace-core component internal styles
331
+ - Duplicate styling that pace-core components already provide
332
+ - Use standard Tailwind colors (use `main-*`, `sec-*`, `acc-*` namespaces)
333
+
334
+ ### Styling Checklist
335
+
336
+ Before adding any styling:
337
+ - [ ] Check if pace-core component provides the styling you need
338
+ - [ ] Use pace-core component variants/props for styling
339
+ - [ ] Use Tailwind classes only for layout/spacing
340
+ - [ ] Never use inline `style={{...}}` prop
341
+ - [ ] Never override component styles with inline styles
342
+ - [ ] Use semantic classes (`bg-background`, `text-foreground`) when available
343
+
344
+ ## SHOULD: Use pace-core Patterns
345
+
346
+ **Follow pace-core patterns for consistency:**
347
+ - Component structure and composition
348
+ - Error handling patterns
349
+ - Loading state patterns
350
+ - Form validation patterns
351
+ - RBAC permission checking patterns
352
+
353
+ ## Common Mistakes to Avoid
354
+
355
+ 1. **Using inline styles** - Never use `style={{...}}`, use pace-core components and Tailwind classes
356
+ 2. **Guessing component props** - Always read documentation first
357
+ 3. **Creating duplicate components** - Always check pace-core first
358
+ 4. **Using base Supabase client** - Always use `useSecureSupabase()`
359
+ 5. **Missing RBAC setup** - Always call `setupRBAC()` first
360
+ 6. **Missing providers** - Always wrap with required providers
361
+ 7. **Missing styles** - Always import core.css
362
+ 8. **Direct library imports** - Use pace-core wrappers instead
363
+
364
+ ## Reference
365
+
366
+ - **pace-core Exports**: See `pace-core-exports.mdc` for complete export reference
367
+ - **RBAC Implementation**: See `rbac-implementation.mdc` for RBAC patterns
368
+ - **Component Documentation**:
369
+ - API Reference: `node_modules/@jmruthers/pace-core/docs/api-reference/components.md`
370
+ - Implementation Guides: `node_modules/@jmruthers/pace-core/docs/implementation-guides/`
371
+ - Detailed API: `node_modules/@jmruthers/pace-core/docs/api/`
372
+ - **Always read documentation before using components** - Never guess about props or usage
@@ -0,0 +1,275 @@
1
+ ---
2
+ description: Enforce compliance with all pace-core standards across architecture, API, components, code style, security, testing, and RBAC/RLS
3
+ globs: ["src/**/*.{ts,tsx,js,jsx}", "supabase/migrations/**/*.sql"]
4
+ alwaysApply: true
5
+ paceCoreVersion: "0.5.x"
6
+ rulesVersion: "2025-01-15"
7
+ ---
8
+ # Standards Compliance Guide
9
+
10
+ This guide ensures consuming apps comply with all pace-core standards. Follow these standards to maintain quality, security, and consistency.
11
+
12
+ ## Architecture Standard
13
+
14
+ ### MUST: Follow Architecture Principles
15
+
16
+ **MUST adhere to:**
17
+ - Composition over complexity
18
+ - Separation of concerns
19
+ - Domain-agnostic design
20
+ - Extensible, stable APIs
21
+ - Secure by default
22
+ - Performance-conscious
23
+
24
+ ### MUST: Use Helper Functions in RLS Policies
25
+
26
+ **RLS policies MUST use helper functions, NEVER subqueries.**
27
+
28
+ ```sql
29
+ -- ❌ WRONG - Subquery in RLS policy (causes N+1 queries)
30
+ CREATE POLICY rbac_select_users ON users
31
+ FOR SELECT USING (
32
+ organisation_id IN (
33
+ SELECT organisation_id FROM organisation_memberships
34
+ WHERE user_id = auth.uid()
35
+ )
36
+ );
37
+
38
+ -- ✅ CORRECT - Helper function
39
+ CREATE OR REPLACE FUNCTION get_user_organisation_ids()
40
+ RETURNS uuid[]
41
+ LANGUAGE plpgsql
42
+ STABLE
43
+ SECURITY DEFINER
44
+ SET search_path TO public
45
+ AS $$
46
+ BEGIN
47
+ RETURN ARRAY(
48
+ SELECT organisation_id
49
+ FROM organisation_memberships
50
+ WHERE user_id = get_effective_user_id()
51
+ );
52
+ END;
53
+ $$;
54
+
55
+ CREATE POLICY rbac_select_users ON users
56
+ FOR SELECT USING (organisation_id = ANY(get_user_organisation_ids()));
57
+ ```
58
+
59
+ ### MUST: Test Database Migrations
60
+
61
+ **MUST verify migrations don't cause query timeouts or performance degradation.**
62
+
63
+ ## API & RPC Standard
64
+
65
+ ### MUST: Follow RPC Naming Convention
66
+
67
+ **RPCs MUST follow pattern: `<family>_<domain>_<verb>`**
68
+
69
+ - `data_*` prefix for read operations: `data_cake_dishes_list`, `data_file_reference_list`
70
+ - `app_*` prefix for write operations: `app_cake_dish_create`, `app_cake_dish_update`
71
+ - CRUD verbs only: `create`, `read`, `update`, `delete`, `list`, `get`
72
+ - Bulk operations: `_bulk` suffix (e.g., `app_cake_dish_create_bulk`)
73
+
74
+ ```sql
75
+ -- ✅ CORRECT
76
+ CREATE FUNCTION data_cake_dishes_list(...)
77
+ CREATE FUNCTION app_cake_dish_create(...)
78
+ CREATE FUNCTION app_cake_dish_create_bulk(...)
79
+
80
+ -- ❌ WRONG
81
+ CREATE FUNCTION getDishes(...)
82
+ CREATE FUNCTION create_dish(...)
83
+ ```
84
+
85
+ ### MUST: Use ApiResult Shape
86
+
87
+ **All RPCs MUST return ApiResult shape:**
88
+
89
+ ```typescript
90
+ type ApiResult<T> =
91
+ | { ok: true; data: T }
92
+ | { ok: false; error: ApiError };
93
+
94
+ type ApiError = {
95
+ code: string;
96
+ message: string;
97
+ details?: object;
98
+ };
99
+ ```
100
+
101
+ ### MUST: Enforce RLS in RPCs
102
+
103
+ **RPCs MUST enforce RLS and tenant boundaries.** Never bypass RLS.
104
+
105
+ ### SHOULD: Make Write RPCs Idempotent
106
+
107
+ **Write RPCs SHOULD be idempotent when possible.**
108
+
109
+ ## Component Standard
110
+
111
+ ### MUST: Follow Component Principles
112
+
113
+ **Components MUST:**
114
+ - Be stateless when possible
115
+ - Use composable structure
116
+ - Be accessible by default
117
+ - Be fully typed
118
+ - Have small surface area
119
+
120
+ ### MUST NOT: Add Domain Logic to Components
121
+
122
+ **Components MUST NOT:**
123
+ - Include domain-specific logic
124
+ - Fetch data directly (use hooks/services)
125
+ - Include business workflows
126
+
127
+ ### MUST: Ensure Accessibility
128
+
129
+ **Components MUST:**
130
+ - Be keyboard operable
131
+ - Have correct ARIA roles
132
+ - Have visible focus states
133
+ - Avoid inaccessible interactions
134
+
135
+ ## Code Style Standard
136
+
137
+ ### MUST: Follow TypeScript Rules
138
+
139
+ **MUST:**
140
+ - Use strict mode (`strict: true` in tsconfig)
141
+ - Prefer discriminated unions
142
+ - Use ReadonlyArray where possible
143
+ - Avoid boolean mode flags (use unions instead)
144
+
145
+ **MUST NOT:**
146
+ - Use `any` (use `unknown` if type is truly unknown)
147
+ - Use implicit any
148
+ - Use unnecessary type assertions
149
+
150
+ ### MUST: Follow Naming Conventions
151
+
152
+ - Hooks: `useSomething`
153
+ - Providers: `SomethingProvider`
154
+ - Utilities: `camelCase`
155
+ - Components: `PascalCase`
156
+
157
+ ### SHOULD: Use Preferred Patterns
158
+
159
+ **SHOULD:**
160
+ - Use pure functions
161
+ - Prefer composition over inheritance
162
+ - Use early returns
163
+ - Extract large functions into small helpers
164
+
165
+ ## Security Standard
166
+
167
+ ### MUST: Never Bypass RLS
168
+
169
+ **MUST enforce RLS on all tables.** Never bypass RLS policies.
170
+
171
+ ### MUST: Validate All Inputs
172
+
173
+ **MUST validate all inputs using Zod schemas or similar.**
174
+
175
+ ### MUST: Sanitize Logs
176
+
177
+ **MUST NOT log:**
178
+ - Passwords
179
+ - Tokens
180
+ - Sensitive data (PII)
181
+
182
+ **MAY log:**
183
+ - IDs
184
+ - Non-PII metadata
185
+
186
+ ### MUST: Use Safe Error Messaging
187
+
188
+ **MUST NOT expose internal details in error messages.**
189
+
190
+ ### MUST: Use Helper Functions in RLS
191
+
192
+ **RLS policies MUST use STABLE SECURITY DEFINER helper functions:**
193
+ - `STABLE` - Results consistent within transaction
194
+ - `SECURITY DEFINER` - Bypass RLS to avoid recursion
195
+ - `SET search_path TO 'public'` - Prevent search path injection
196
+
197
+ ## Testing Standard
198
+
199
+ ### MUST: Meet Coverage Requirements
200
+
201
+ **MUST achieve:**
202
+ - ≥90% coverage for utils & hooks
203
+ - ≥70% coverage for components
204
+
205
+ ### MUST: Use React Testing Library
206
+
207
+ **MUST use React Testing Library + userEvent for component tests.**
208
+
209
+ ### SHOULD: Colocate Tests
210
+
211
+ **Tests SHOULD be colocated: `*.test.ts` or `*.test.tsx`**
212
+
213
+ ### SHOULD: Test Critical Paths
214
+
215
+ **SHOULD test:**
216
+ - Key user interactions
217
+ - Error handling
218
+ - Edge cases
219
+ - Critical business logic
220
+
221
+ ## RBAC & RLS Standard
222
+
223
+ ### MUST: Use Helper Functions
224
+
225
+ **All RLS policies MUST use helper functions with:**
226
+ - `STABLE` attribute
227
+ - `SECURITY DEFINER` attribute
228
+ - `SET search_path TO 'public'`
229
+
230
+ ### MUST: Follow Policy Naming
231
+
232
+ **RLS policies MUST follow pattern: `rbac_{operation}_{table_name}_{scope}`**
233
+
234
+ Example: `rbac_select_users_organisation`
235
+
236
+ ### MUST: Include Organisation Context
237
+
238
+ **RLS policies MUST include `organisation_id` for multi-tenant isolation.**
239
+
240
+ ### MUST: Include Super Admin Checks
241
+
242
+ **RLS policies SHOULD include super admin checks where appropriate.**
243
+
244
+ ## Standards Precedence
245
+
246
+ When standards conflict, follow this order:
247
+ 1. Security Standard (highest priority)
248
+ 2. API & RPC Standard
249
+ 3. Component Standard
250
+ 4. Code Style Standard
251
+ 5. Testing Standard
252
+ 6. Documentation Standard
253
+
254
+ ## Compliance Checklist
255
+
256
+ Before committing code, verify:
257
+ - [ ] RLS policies use helper functions (no subqueries)
258
+ - [ ] RPCs follow naming convention
259
+ - [ ] Components are accessible and typed
260
+ - [ ] No `any` types used
261
+ - [ ] Inputs are validated
262
+ - [ ] Tests meet coverage requirements
263
+ - [ ] No sensitive data in logs
264
+ - [ ] Error messages are safe
265
+
266
+ ## Reference
267
+
268
+ See `packages/core/docs/standards/` for complete standards documentation:
269
+ - 01-architecture-standard.md
270
+ - 02-api-and-rpc-standard.md
271
+ - 03-component-standard.md
272
+ - 04-code-style-standard.md
273
+ - 05-security-standard.md
274
+ - 06-testing-and-docs-standard.md
275
+ - 07-rbac-and-rls-standard.md