@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
@@ -449,7 +449,7 @@ function AuthenticatedApp() {
449
449
 
450
450
  // Don't track inactivity if not authenticated
451
451
  if (loading || !user) {
452
- return <div>Loading...</div>;
452
+ return <p>Loading...</p>;
453
453
  }
454
454
 
455
455
  return (
@@ -831,5 +831,5 @@ When user extends session during warning:
831
831
 
832
832
  - **[Authentication Integration](./permission-enforcement.md)** - Security patterns
833
833
  - **[Performance Optimization](./performance.md)** - Large application considerations
834
- - **[Accessibility Guidelines](../best-practices/accessibility.md)** - Accessibility best practices
835
- - **[Security Best Practices](../best-practices/security.md)** - Security considerations
834
+ - **[Accessibility Requirements](../standards/4-code-quality-standards.md#accessibility-requirements)** - Accessibility requirements
835
+ - **[Security & RBAC Standards](../standards/6-security-rbac-standards.md)** - Security considerations
@@ -10,11 +10,12 @@ This guide addresses the common issues when working with large datasets (9,000+
10
10
 
11
11
  **Problem**: Header and body columns were misaligned in virtualized mode due to separate table layouts.
12
12
 
13
- **Solution**: Enhanced `VirtualizedDataTable` component with:
13
+ **Solution**: `UnifiedTableBody` component automatically handles virtualization with:
14
14
  - Synchronized column sizing between header and body tables
15
15
  - `table-fixed` layout for consistent column widths
16
16
  - Dynamic column width calculation and synchronization
17
- - Proper `useLayoutEffect` for measuring actual column widths
17
+ - Automatic virtualization when data exceeds 1000 records
18
+ - Proper virtualization handling for optimal performance
18
19
 
19
20
  ```tsx
20
21
  // ✅ Now properly aligned
@@ -819,5 +819,5 @@ When invalid organisation IDs are provided:
819
819
 
820
820
  - **[RBAC System](../rbac/README.md)** - Role-based access control
821
821
  - **[Permission Enforcement](./permission-enforcement.md)** - UI permission patterns
822
- - **[Security Best Practices](../best-practices/security.md)** - Security guidelines
823
- - **[Audit Logging](../best-practices/audit-logging.md)** - Comprehensive audit patterns
822
+ - **[Security & RBAC Standards](../standards/6-security-rbac-standards.md)** - Security guidelines
823
+ - **[Operations Standards](../standards/9-operations-standards.md)** - Error handling and monitoring
@@ -299,9 +299,9 @@ EnhancedDataTable
299
299
  │ ├── SearchIndex
300
300
  │ ├── PerformanceMonitor
301
301
  │ └── VisibilityTracker
302
- ├── VirtualizedDataTable (when enabled)
302
+ ├── UnifiedTableBody (with automatic virtualization)
303
303
  │ ├── MemoizedRow
304
- │ └── MemoizedCell
304
+ │ └── Virtualized rows (when data > 1000 records)
305
305
  └── EnhancedPaginationControls
306
306
  ├── Performance metrics display
307
307
  ├── Jump to page functionality
@@ -701,7 +701,7 @@ useEffect(() => {
701
701
  ```tsx
702
702
  const { selectedOrganisationId } = useUnifiedAuth();
703
703
  if (!selectedOrganisationId) {
704
- return <div>Please select an organisation first</div>;
704
+ return <p>Please select an organisation first</p>;
705
705
  }
706
706
  ```
707
707
 
@@ -60,7 +60,7 @@ function OrganisationContextGuard({ children }) {
60
60
  }, [selectedOrganisation, supabase]);
61
61
 
62
62
  if (!contextReady) {
63
- return <div>Setting up organisation context...</div>;
63
+ return <p>Setting up organisation context...</p>;
64
64
  }
65
65
 
66
66
  return <>{children}</>;
@@ -239,7 +239,7 @@ function UserActions() {
239
239
  'delete:users'
240
240
  );
241
241
 
242
- if (isLoadingEdit || isLoadingDelete) return <div>Loading permissions...</div>;
242
+ if (isLoadingEdit || isLoadingDelete) return <p>Loading permissions...</p>;
243
243
 
244
244
  return (
245
245
  <div>
@@ -375,7 +375,7 @@ const { can: canEdit, isLoading } = useCan(
375
375
  'update:users'
376
376
  );
377
377
 
378
- if (isLoading) return <div>Loading...</div>;
378
+ if (isLoading) return <p>Loading...</p>;
379
379
  return canEdit ? <EditButton /> : null;
380
380
  ```
381
381
 
@@ -406,7 +406,7 @@ const canCreate = hasPermission('create:users');
406
406
  const canUpdate = hasPermission('update:users');
407
407
  const canDelete = hasPermission('delete:users');
408
408
 
409
- if (isLoading) return <div>Loading permissions...</div>;
409
+ if (isLoading) return <p>Loading permissions...</p>;
410
410
  ```
411
411
 
412
412
  ### Pattern 3: Component Guards
@@ -504,8 +504,8 @@ function UserActions({ userId, scope }) {
504
504
  checkPermission();
505
505
  }, [hasPermission, isLoading, userId, scope]);
506
506
 
507
- if (error) return <div>Error checking permissions</div>;
508
- if (isLoading) return <div>Loading...</div>;
507
+ if (error) return <p>Error checking permissions</p>;
508
+ if (isLoading) return <p>Loading...</p>;
509
509
 
510
510
  return (
511
511
  <div>
@@ -595,7 +595,7 @@ const canEdit = await hasPermission('update:users', { userId, scope });
595
595
  ```tsx
596
596
  const { hasPermission, isLoading } = useCan();
597
597
 
598
- if (isLoading) return <div>Loading permissions...</div>;
598
+ if (isLoading) return <p>Loading permissions...</p>;
599
599
  ```
600
600
 
601
601
  ### Getting Help
@@ -56,7 +56,7 @@ function MyComponent() {
56
56
  <PagePermissionGuard
57
57
  pageName="users"
58
58
  operation="read"
59
- fallback={<div>Access Denied</div>}
59
+ fallback={<p>Access Denied</p>}
60
60
  >
61
61
  <UserList />
62
62
  </PagePermissionGuard>
@@ -232,9 +232,9 @@ function UsersPage() {
232
232
  <PagePermissionGuard
233
233
  pageName="users"
234
234
  operation="read"
235
- fallback={<div>You don't have permission to view this page</div>}
235
+ fallback={<p>You don't have permission to view this page</p>}
236
236
  >
237
- <div>
237
+ <section>
238
238
  <h1>User Management</h1>
239
239
 
240
240
  {/* Multiple operations on same page */}
@@ -261,7 +261,7 @@ function UsersPage() {
261
261
  >
262
262
  <DeleteUserButtons />
263
263
  </PagePermissionGuard>
264
- </div>
264
+ </section>
265
265
  </PagePermissionGuard>
266
266
  );
267
267
  }
@@ -282,7 +282,7 @@ function AdminPanel() {
282
282
  <PagePermissionGuard
283
283
  pageName="admin"
284
284
  operation="read"
285
- fallback={<div>Access denied</div>}
285
+ fallback={<p>Access denied</p>}
286
286
  >
287
287
  <UserManagement />
288
288
  </PagePermissionGuard>
@@ -379,7 +379,7 @@ export function withPermission(permission: string, fallback?: React.ComponentTyp
379
379
 
380
380
  // Usage
381
381
  const ProtectedUserList = withPermission('read:users', () => (
382
- <div>Access denied to user list</div>
382
+ <p>Access denied to user list</p>
383
383
  ))(UserList);
384
384
 
385
385
  // In component
@@ -436,16 +436,16 @@ export const useOrganisationPermissions = createPermissionHook('organisations');
436
436
  function UserManagement({ userId, scope }) {
437
437
  const { permissions, isLoading } = useUserPermissions(userId, scope);
438
438
 
439
- if (isLoading) return <div>Loading permissions...</div>;
439
+ if (isLoading) return <p>Loading permissions...</p>;
440
440
 
441
441
  return (
442
- <div>
442
+ <section>
443
443
  {permissions.read && <UserList />}
444
444
  {permissions.create && <CreateUserButton />}
445
445
  {permissions.update && <EditUserButton />}
446
446
  {permissions.delete && <DeleteUserButton />}
447
447
  {permissions.manage && <UserManagementPanel />}
448
- </div>
448
+ </section>
449
449
  );
450
450
  }
451
451
  ```
@@ -647,7 +647,7 @@ import { withPermission } from './permission-decorators';
647
647
 
648
648
  // Mock component
649
649
  const TestComponent = ({ data }: { data: string }) => (
650
- <div>Test Component: {data}</div>
650
+ <p>Test Component: {data}</p>
651
651
  );
652
652
 
653
653
  describe('Permission Decorators', () => {
@@ -684,7 +684,7 @@ describe('Permission Decorators', () => {
684
684
  })
685
685
  }));
686
686
 
687
- const FallbackComponent = () => <div>Access Denied</div>;
687
+ const FallbackComponent = () => <p>Access Denied</p>;
688
688
  const ProtectedComponent = withPermission('read:users', FallbackComponent)(TestComponent);
689
689
 
690
690
  render(
@@ -44,13 +44,13 @@ function UserActions() {
44
44
  undefined // No pageId for event-app permissions
45
45
  );
46
46
 
47
- if (error) return <div>Error: {error.message}</div>;
48
- if (isLoading) return <div>Checking permissions...</div>;
47
+ if (error) return <p>Error: {error.message}</p>;
48
+ if (isLoading) return <p>Checking permissions...</p>;
49
49
 
50
50
  return (
51
- <div>
51
+ <section>
52
52
  {can && <EventActions />}
53
- </div>
53
+ </section>
54
54
  );
55
55
  }
56
56
  ```
@@ -87,19 +87,19 @@ function PermissionDisplay() {
87
87
  }
88
88
  );
89
89
 
90
- if (isLoading) return <div>Loading permissions...</div>;
91
- if (error) return <div>Error: {error.message}</div>;
90
+ if (isLoading) return <p>Loading permissions...</p>;
91
+ if (error) return <p>Error: {error.message}</p>;
92
92
 
93
93
  return (
94
- <div>
94
+ <section>
95
95
  <h3>User Permissions</h3>
96
96
  {Object.entries(permissions).map(([pageId, operations]) => (
97
- <div key={pageId}>
97
+ <p key={pageId}>
98
98
  <strong>{pageId}:</strong> {operations.join(', ')}
99
- </div>
99
+ </p>
100
100
  ))}
101
101
  <button onClick={refetch}>Refresh</button>
102
- </div>
102
+ </section>
103
103
  );
104
104
  }
105
105
  ```
@@ -128,13 +128,13 @@ function AccessLevelDisplay({ userId, scope }) {
128
128
  scope
129
129
  });
130
130
 
131
- if (isLoading) return <div>Loading access level...</div>;
132
- if (error) return <div>Error: {error.message}</div>;
131
+ if (isLoading) return <p>Loading access level...</p>;
132
+ if (error) return <p>Error: {error.message}</p>;
133
133
 
134
134
  return (
135
- <div>
135
+ <section>
136
136
  <p>Access Level: {accessLevel || 'None'}</p>
137
- </div>
137
+ </section>
138
138
  );
139
139
  }
140
140
  ```
@@ -183,12 +183,12 @@ function UserManagement({ userId, scope }) {
183
183
  }, [checkMultiple, isLoading, userId, scope]);
184
184
 
185
185
  return (
186
- <div>
186
+ <section>
187
187
  {permissions['read:users'] && <UserList />}
188
188
  {permissions['create:users'] && <CreateUserButton />}
189
189
  {permissions['update:users'] && <EditUserButton />}
190
190
  {permissions['delete:users'] && <DeleteUserButton />}
191
- </div>
191
+ </section>
192
192
  );
193
193
  }
194
194
  ```
@@ -221,12 +221,12 @@ import { PermissionEnforcer } from '@jmruthers/pace-core/rbac';
221
221
 
222
222
  function UserActions() {
223
223
  return (
224
- <div>
224
+ <section>
225
225
  {/* Pattern 1: PermissionEnforcer - automatic scope resolution */}
226
226
  <PermissionEnforcer
227
227
  permissions={['read:users']}
228
228
  operation="user-management"
229
- fallback={<div>Access Denied</div>}
229
+ fallback={<p>Access Denied</p>}
230
230
  >
231
231
  <UserList />
232
232
  </PermissionEnforcer>
@@ -236,11 +236,11 @@ function UserActions() {
236
236
  permissions={['create:users', 'update:users']}
237
237
  operation="user-crud"
238
238
  requireAll={true} // User needs ALL permissions
239
- fallback={<div>You need create and update permissions</div>}
239
+ fallback={<p>You need create and update permissions</p>}
240
240
  >
241
241
  <UserManagementPanel />
242
242
  </PermissionEnforcer>
243
- </div>
243
+ </section>
244
244
  );
245
245
  }
246
246
  ```
@@ -491,7 +491,7 @@ export function Dashboard() {
491
491
  const { user, selectedEventId, selectedOrganisationId } = useUnifiedAuth()
492
492
 
493
493
  if (!user) {
494
- return <div>Please log in</div>
494
+ return <p>Please log in</p>
495
495
  }
496
496
 
497
497
  return (
@@ -580,7 +580,7 @@ export function Participants() {
580
580
  const { user, selectedEventId, selectedOrganisationId } = useUnifiedAuth()
581
581
 
582
582
  if (!user) {
583
- return <div>Please log in</div>
583
+ return <p>Please log in</p>
584
584
  }
585
585
 
586
586
  return (
@@ -748,7 +748,7 @@ setupRBAC(supabase) // Must be called BEFORE rendering app
748
748
  setSelectedEventId('your-event-id');
749
749
  }, []);
750
750
 
751
- return <div>...</div>;
751
+ return <p>...</p>;
752
752
  }
753
753
  ```
754
754
 
@@ -17,7 +17,7 @@ import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
17
17
 
18
18
  function UserProfile() {
19
19
  return (
20
- <div>
20
+ <section>
21
21
  <h1>User Profile</h1>
22
22
  <PagePermissionGuard
23
23
  pageName="profile"
@@ -26,7 +26,7 @@ function UserProfile() {
26
26
  >
27
27
  <EditButton />
28
28
  </PagePermissionGuard>
29
- </div>
29
+ </section>
30
30
  );
31
31
  }
32
32
  ```
@@ -86,7 +86,7 @@ import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
86
86
 
87
87
  function AdminPanel() {
88
88
  return (
89
- <div>
89
+ <section>
90
90
  <h1>Admin Panel</h1>
91
91
 
92
92
  <PagePermissionGuard
@@ -100,11 +100,11 @@ function AdminPanel() {
100
100
  <PagePermissionGuard
101
101
  pageName="system"
102
102
  operation="manage"
103
- fallback={<div>System management access required</div>}
103
+ fallback={<p>System management access required</p>}
104
104
  >
105
105
  <SystemSettings />
106
106
  </PagePermissionGuard>
107
- </div>
107
+ </section>
108
108
  );
109
109
  }
110
110
  ```
@@ -116,14 +116,14 @@ import { AccessLevelGuard } from '@jmruthers/pace-core/rbac';
116
116
 
117
117
  function EventManagement({ userId, scope }) {
118
118
  return (
119
- <div>
119
+ <section>
120
120
  <h1>Event Management</h1>
121
121
 
122
122
  <AccessLevelGuard
123
123
  userId={userId}
124
124
  scope={scope}
125
125
  requiredLevel="planner"
126
- fallback={<div>Planner access required</div>}
126
+ fallback={<p>Planner access required</p>}
127
127
  >
128
128
  <EventPlanning />
129
129
  </AccessLevelGuard>
@@ -132,11 +132,11 @@ function EventManagement({ userId, scope }) {
132
132
  userId={userId}
133
133
  scope={scope}
134
134
  requiredLevel="admin"
135
- fallback={<div>Admin access required</div>}
135
+ fallback={<p>Admin access required</p>}
136
136
  >
137
137
  <EventAdminPanel />
138
138
  </AccessLevelGuard>
139
- </div>
139
+ </section>
140
140
  );
141
141
  }
142
142
  ```
@@ -185,7 +185,7 @@ function UsersTable({ users, userId, scope }) {
185
185
  id: 'actions',
186
186
  header: 'Actions',
187
187
  cell: ({ row }) => (
188
- <div className="flex space-x-2">
188
+ <section className="flex space-x-2">
189
189
  {permissions.canEdit && (
190
190
  <button onClick={() => editUser(row.original.id)}>
191
191
  Edit
@@ -196,7 +196,7 @@ function UsersTable({ users, userId, scope }) {
196
196
  Delete
197
197
  </button>
198
198
  )}
199
- </div>
199
+ </section>
200
200
  ),
201
201
  },
202
202
  ];
@@ -246,31 +246,31 @@ function UserForm({ userId, scope, userData }) {
246
246
 
247
247
  return (
248
248
  <form>
249
- <div>
249
+ <section>
250
250
  <label>Name</label>
251
251
  <input defaultValue={userData.name} />
252
- </div>
252
+ </section>
253
253
 
254
- <div>
254
+ <section>
255
255
  <label>Email</label>
256
256
  <input defaultValue={userData.email} />
257
- </div>
257
+ </section>
258
258
 
259
259
  {permissions.canEditRole && (
260
- <div>
260
+ <section>
261
261
  <label>Role</label>
262
262
  <select defaultValue={userData.role}>
263
263
  <option value="user">User</option>
264
264
  <option value="admin">Admin</option>
265
265
  </select>
266
- </div>
266
+ </section>
267
267
  )}
268
268
 
269
269
  {permissions.canEditPermissions && (
270
- <div>
270
+ <section>
271
271
  <label>Permissions</label>
272
272
  <PermissionSelector defaultValue={userData.permissions} />
273
- </div>
273
+ </section>
274
274
  )}
275
275
 
276
276
  <button type="submit">Save</button>
@@ -318,7 +318,7 @@ function Navigation({ userId, scope }) {
318
318
  checkNavigationPermissions();
319
319
  }, [hasPermission, isLoading, userId, scope]);
320
320
 
321
- if (isLoading) return <div>Loading navigation...</div>;
321
+ if (isLoading) return <p>Loading navigation...</p>;
322
322
 
323
323
  return (
324
324
  <nav>
@@ -449,12 +449,12 @@ function OptimizedUserList({ userId, scope }) {
449
449
  }, [hasPermission, isLoading, userId, scope]);
450
450
 
451
451
  return (
452
- <div>
452
+ <section>
453
453
  {permissions.canRead && <UserList />}
454
454
  {permissions.canCreate && <CreateUserButton />}
455
455
  {permissions.canUpdate && <EditUserButton />}
456
456
  {permissions.canDelete && <DeleteUserButton />}
457
- </div>
457
+ </section>
458
458
  );
459
459
  }
460
460
  ```
@@ -477,11 +477,11 @@ function UserActions({ userId, scope }) {
477
477
  };
478
478
 
479
479
  return (
480
- <div>
480
+ <section>
481
481
  <button onClick={() => handleUserUpdate(userData)}>
482
482
  Update User
483
483
  </button>
484
- </div>
484
+ </section>
485
485
  );
486
486
  }
487
487
  ```
@@ -525,18 +525,18 @@ function UserManagement({ userId, scope }) {
525
525
  }, [hasPermission, isLoading, userId, scope]);
526
526
 
527
527
  if (error) {
528
- return <div>Error: {error.message}</div>;
528
+ return <p>Error: {error.message}</p>;
529
529
  }
530
530
 
531
531
  if (isLoading) {
532
- return <div>Checking permissions...</div>;
532
+ return <p>Checking permissions...</p>;
533
533
  }
534
534
 
535
535
  return (
536
- <div>
537
- {errorMessage && <div className="error">{errorMessage}</div>}
536
+ <section>
537
+ {errorMessage && <p className="error">{errorMessage}</p>}
538
538
  {canEdit && <EditUserButton />}
539
- </div>
539
+ </section>
540
540
  );
541
541
  }
542
542
  ```
@@ -571,9 +571,9 @@ function CustomUserActions({ userId, scope, user }) {
571
571
  }, [hasPermission, userId, scope, user]);
572
572
 
573
573
  return (
574
- <div>
574
+ <section>
575
575
  {canEdit && <EditUserButton userId={user.id} />}
576
- </div>
576
+ </section>
577
577
  );
578
578
  }
579
579
  ```
@@ -610,11 +610,11 @@ function ProtectedRoute({ children, requiredPermission, userId, scope }) {
610
610
  }, [hasPermission, isLoading, requiredPermission, userId, scope, navigate]);
611
611
 
612
612
  if (isLoading) {
613
- return <div>Checking access...</div>;
613
+ return <p>Checking access...</p>;
614
614
  }
615
615
 
616
616
  if (!hasAccess) {
617
- return <div>Access denied</div>;
617
+ return <p>Access denied</p>;
618
618
  }
619
619
 
620
620
  return children;
@@ -679,9 +679,9 @@ test('renders fallback when user lacks permission', () => {
679
679
  userId="user-123"
680
680
  scope={{ organisationId: "org-456" }}
681
681
  permission="read:users"
682
- fallback={<div>Access Denied</div>}
682
+ fallback={<p>Access Denied</p>}
683
683
  >
684
- <div>User List</div>
684
+ <section>User List</section>
685
685
  </PermissionGuard>
686
686
  );
687
687
 
@@ -739,7 +739,7 @@ function UserManagement() {
739
739
  >
740
740
  <CreateUserButton />
741
741
  </PermissionEnforcer>
742
- </div>
742
+ </section>
743
743
  );
744
744
  }
745
745
  ```
@@ -771,7 +771,7 @@ function EventDashboard() {
771
771
  >
772
772
  <ParticipantManagement />
773
773
  </PermissionEnforcer>
774
- </div>
774
+ </section>
775
775
  );
776
776
  }
777
777
  ```
@@ -795,7 +795,7 @@ function AdaptiveComponent({ appId }) {
795
795
  loadAppConfig();
796
796
  }, [appId]);
797
797
 
798
- if (!appConfig) return <div>Loading app configuration...</div>;
798
+ if (!appConfig) return <p>Loading app configuration...</p>;
799
799
 
800
800
  // Determine required context based on app type
801
801
  const scope = appConfig.requires_event
@@ -858,15 +858,15 @@ function ContextAwareComponent({ appId }) {
858
858
  getAppConfig(appId).then(setAppConfig);
859
859
  }, [appId]);
860
860
 
861
- if (!appConfig) return <div>Loading...</div>;
861
+ if (!appConfig) return <p>Loading...</p>;
862
862
 
863
863
  const getContextError = () => {
864
864
  if (appConfig.requires_event) {
865
865
  return (
866
- <div>
866
+ <section>
867
867
  <p>Access denied</p>
868
868
  <p>This app requires event context</p>
869
- </div>
869
+ </section>
870
870
  );
871
871
  } else {
872
872
  return (