@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
@@ -61,7 +61,7 @@
61
61
  * - Efficient error handling
62
62
  *
63
63
  * @dependencies
64
- * - React 18+ - Component framework
64
+ * - React 19+ - Component framework
65
65
  * - useCan hook - Permission checking
66
66
  * - useUnifiedAuth - Authentication context
67
67
  * - RBAC types - Type definitions
@@ -49,7 +49,7 @@
49
49
  * - Cached permission checks
50
50
  *
51
51
  * @dependencies
52
- * - React 18+ - Context and hooks
52
+ * - React 19+ - Context and hooks
53
53
  * - useUnifiedAuth - Authentication context
54
54
  * - RBAC types - Type definitions
55
55
  */
@@ -60,7 +60,7 @@
60
60
  * - Efficient error handling
61
61
  *
62
62
  * @dependencies
63
- * - React 18+ - Component framework
63
+ * - React 19+ - Component framework
64
64
  * - useCan hook - Permission checking
65
65
  * - useUnifiedAuth - Authentication context
66
66
  * - RBAC types - Type definitions
@@ -56,7 +56,7 @@
56
56
  * - Efficient route matching
57
57
  *
58
58
  * @dependencies
59
- * - React 18+ - Component framework
59
+ * - React 19+ - Component framework
60
60
  * - React Router - Routing functionality
61
61
  * - useCan hook - Permission checking
62
62
  * - useUnifiedAuth - Authentication context
@@ -50,7 +50,7 @@
50
50
  * - Cached permission checks
51
51
  *
52
52
  * @dependencies
53
- * - React 18+ - Context and hooks
53
+ * - React 19+ - Context and hooks
54
54
  * - useUnifiedAuth - Authentication context
55
55
  * - useSecureDataAccess - Secure data access hook
56
56
  * - RBAC types - Type definitions
@@ -223,6 +223,18 @@ export class SecureSupabaseClient {
223
223
  'rbac_apps', // App configuration table - no organisation scope
224
224
  'rbac_app_pages', // Page configuration table - scoped by app_id, not organisation_id
225
225
  'rbac_global_roles', // Global roles - no organisation scope
226
+ // Person-scoped tables (organisation_id was removed in person-scoped profiles migration)
227
+ 'core_person', // Person records - person-scoped, no organisation_id
228
+ 'core_member', // Member profiles - person-scoped, no organisation_id
229
+ 'core_contact', // Contact profiles - person-scoped, no organisation_id
230
+ 'core_consent', // Consent records - person-scoped, no organisation_id
231
+ 'core_identification', // Identification records - person-scoped, no organisation_id
232
+ 'core_qualification', // Qualification records - person-scoped, no organisation_id
233
+ 'medi_profile', // Medical profiles - person-scoped, no organisation_id
234
+ 'medi_condition', // Medical conditions - person-scoped via medi_profile, no organisation_id
235
+ 'medi_diet', // Medical diets - person-scoped via medi_profile, no organisation_id
236
+ 'medi_action_plan', // Medical action plans - person-scoped via medi_profile, no organisation_id
237
+ 'medi_profile_versions', // Medical profile versions - person-scoped via medi_profile, no organisation_id
226
238
  ];
227
239
 
228
240
  // Skip organisation filter for tables that don't have organisation_id column
@@ -21,15 +21,25 @@ const mockSupabaseClient = {
21
21
  let mockQueryBuilder: any;
22
22
 
23
23
  const createMockQueryBuilder = (customData?: any, customError?: any) => {
24
+ // Create spy functions that return this for chaining
25
+ const selectSpy = vi.fn(function(this: any) { return this; });
26
+ const eqSpy = vi.fn(function(this: any) { return this; });
27
+ const orderSpy = vi.fn(function(this: any) { return this; });
28
+ const limitSpy = vi.fn(function(this: any) { return this; });
29
+ const rangeSpy = vi.fn(function(this: any) { return this; });
30
+ const insertSpy = vi.fn(function(this: any) { return this; });
31
+ const updateSpy = vi.fn(function(this: any) { return this; });
32
+ const deleteSpy = vi.fn(function(this: any) { return this; });
33
+
24
34
  const builder: any = {
25
- select: vi.fn(function(this: any) { return this; }),
26
- eq: vi.fn(function(this: any) { return this; }),
27
- order: vi.fn(function(this: any) { return this; }),
28
- limit: vi.fn(function(this: any) { return this; }),
29
- range: vi.fn(function(this: any) { return this; }),
30
- insert: vi.fn(function(this: any) { return this; }),
31
- update: vi.fn(function(this: any) { return this; }),
32
- delete: vi.fn(function(this: any) { return this; }),
35
+ select: selectSpy,
36
+ eq: eqSpy,
37
+ order: orderSpy,
38
+ limit: limitSpy,
39
+ range: rangeSpy,
40
+ insert: insertSpy,
41
+ update: updateSpy,
42
+ delete: deleteSpy,
33
43
  single: vi.fn().mockImplementation(() => {
34
44
  const data = customData !== undefined ? customData : { id: 'test-123' };
35
45
  const error = customError !== undefined ? customError : null;
@@ -56,7 +66,7 @@ const createMockQueryBuilder = (customData?: any, customError?: any) => {
56
66
  describe('secureDataAccess', () => {
57
67
  let secureDataAccess: ReturnType<typeof createSecureDataAccess>;
58
68
  const mockOrganisationId = 'org-123';
59
- const mockTable = 'pace_person'; // Use a table that has organisation_id column
69
+ const mockTable = 'core_events'; // Use a table that has organisation_id column (pace_person doesn't have it)
60
70
  const mockSelect = 'id, name, organisation_id';
61
71
 
62
72
  beforeEach(() => {
@@ -332,10 +342,10 @@ describe('secureDataAccess', () => {
332
342
  const mockFilters = { id: '1' };
333
343
  const mockResult = { id: '1', name: 'Updated Item', organisation_id: mockOrganisationId };
334
344
 
335
- mockQueryBuilder.update = vi.fn().mockReturnThis();
336
- mockQueryBuilder.eq = vi.fn().mockReturnThis();
337
- mockQueryBuilder.select = vi.fn().mockReturnThis();
345
+ // Create a fresh mock query builder with proper chaining
346
+ mockQueryBuilder = createMockQueryBuilder(mockResult);
338
347
  mockQueryBuilder.single = vi.fn().mockResolvedValue({ data: mockResult, error: null });
348
+ mockSupabaseClient.from = vi.fn().mockReturnValue(mockQueryBuilder);
339
349
 
340
350
  const result = await secureDataAccess.secureUpdate(mockTable, mockData, mockFilters, mockOrganisationId);
341
351
 
@@ -366,9 +376,13 @@ describe('secureDataAccess', () => {
366
376
  it('should delete data with organisation filter', async () => {
367
377
  const mockFilters = { id: '1' };
368
378
 
369
- mockQueryBuilder.delete = vi.fn().mockReturnThis();
370
- mockQueryBuilder.eq = vi.fn().mockReturnThis();
371
- mockQueryBuilder.single = vi.fn().mockResolvedValue({ data: null, error: null });
379
+ // Create a fresh mock query builder with proper chaining
380
+ mockQueryBuilder = createMockQueryBuilder();
381
+ // Make the query builder thenable and resolve successfully
382
+ mockQueryBuilder.then = function(resolve: any) {
383
+ return Promise.resolve({ data: null, error: null }).then(resolve);
384
+ };
385
+ mockSupabaseClient.from = vi.fn().mockReturnValue(mockQueryBuilder);
372
386
 
373
387
  const result = await secureDataAccess.secureDelete(mockTable, mockFilters, mockOrganisationId);
374
388
 
@@ -687,12 +701,9 @@ describe('secureDataAccess', () => {
687
701
  };
688
702
 
689
703
  const mockData = [{ id: '1', name: 'Test', organisation_id: mockOrganisationId }];
690
- // Create a new mock with the expected data
691
- mockQueryBuilder = createMockQueryBuilder(mockData);
692
- mockSupabaseClient.from = vi.fn().mockReturnValue(mockQueryBuilder);
693
704
  // Create a new mock with the expected data
694
- mockQueryBuilder = createMockQueryBuilder(mockData);
695
- mockSupabaseClient.from = vi.fn().mockReturnValue(mockQueryBuilder);
705
+ mockQueryBuilder = createMockQueryBuilder(mockData);
706
+ mockSupabaseClient.from = vi.fn().mockReturnValue(mockQueryBuilder);
696
707
 
697
708
  const options: SecureQueryOptions = {
698
709
  table: mockTable,
@@ -99,9 +99,10 @@ export const createSecureDataAccess = (
99
99
  // SECURITY: Phase 2 additions - complete organisation table mapping
100
100
  'organisation_audit_log', 'organisation_invitations', 'organisation_app_access',
101
101
  // SECURITY: Emergency additions for Phase 1 fixes
102
- 'cake_meal', 'cake_mealtype', 'core_person', 'pace_person',
103
- // NOTE: core_member, medi_profile, core_contact, core_consent, core_identification, core_qualification
104
- // are now person-scoped (not organisation-scoped) - removed from this list
102
+ 'cake_meal', 'cake_mealtype',
103
+ // NOTE: core_person, pace_person, core_member, medi_profile, core_contact, core_consent,
104
+ // core_identification, core_qualification are now person-scoped (not organisation-scoped)
105
+ // and do NOT have organisation_id columns - removed from this list
105
106
  // SECURITY: Phase 3A additions - medical and personal data
106
107
  // NOTE: medi_condition, medi_diet, medi_action_plan, medi_profile_versions are now person-scoped
107
108
  // (via medi_profile) - removed from this list