@jmruthers/pace-core 0.6.5 → 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.
- package/CHANGELOG.md +104 -0
- package/README.md +5 -403
- package/audit-tool/00-dependencies.cjs +394 -0
- package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
- package/audit-tool/audits/02-project-structure.cjs +255 -0
- package/audit-tool/audits/03-architecture.cjs +196 -0
- package/audit-tool/audits/04-code-quality.cjs +149 -0
- package/audit-tool/audits/05-styling.cjs +224 -0
- package/audit-tool/audits/06-security-rbac.cjs +544 -0
- package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
- package/audit-tool/audits/08-testing-documentation.cjs +202 -0
- package/audit-tool/audits/09-operations.cjs +208 -0
- package/audit-tool/index.cjs +291 -0
- package/audit-tool/utils/code-utils.cjs +218 -0
- package/audit-tool/utils/file-utils.cjs +230 -0
- package/audit-tool/utils/report-utils.cjs +241 -0
- package/core-usage-manifest.json +93 -0
- package/cursor-rules/00-standards-overview.mdc +156 -0
- package/cursor-rules/01-pace-core-compliance.mdc +586 -0
- package/cursor-rules/02-project-structure.mdc +42 -4
- package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +126 -10
- package/cursor-rules/04-code-quality.mdc +419 -0
- package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +104 -34
- package/cursor-rules/06-security-rbac.mdc +518 -0
- package/cursor-rules/07-api-tech-stack.mdc +377 -0
- package/cursor-rules/08-testing-documentation.mdc +324 -0
- package/cursor-rules/09-operations.mdc +365 -0
- package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
- package/dist/DataTable-7PMH7XN7.js +15 -0
- package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
- package/dist/{PublicPageProvider-QTFVrL-Z.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +33 -72
- package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
- package/dist/api-Y4MQWOFW.js +4 -0
- package/dist/audit-MYQXYZFU.js +3 -0
- package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
- package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
- package/dist/{chunk-UPPMRMYG.js → chunk-5X4QLXRG.js} +73 -151
- package/dist/chunk-6F3IILHI.js +62 -0
- package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
- package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
- package/dist/{chunk-FMUCXFII.js → chunk-7ILTDCL2.js} +9 -5
- package/dist/{chunk-M43Y4SSO.js → chunk-A3W6LW53.js} +15 -13
- package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
- package/dist/{chunk-HU2C6SSC.js → chunk-BM4CQ5P3.js} +606 -559
- package/dist/chunk-C7NSAPTL.js +1 -0
- package/dist/{chunk-J36DSWQK.js → chunk-FEJLJNWA.js} +7 -41
- package/dist/{chunk-IHB5DR3H.js → chunk-FTCRZOG2.js} +188 -387
- package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
- package/dist/chunk-GHYHJTYV.js +994 -0
- package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
- package/dist/{chunk-FFQEQTNW.js → chunk-IUBRCBSY.js} +134 -45
- package/dist/{chunk-6COVEUS7.js → chunk-JGWDVX64.js} +983 -1034
- package/dist/{chunk-RGAWHO7N.js → chunk-L4XMVJKY.js} +77 -222
- package/dist/chunk-MBADTM7L.js +64 -0
- package/dist/{chunk-M7MPQISP.js → chunk-OJ4SKRSV.js} +3 -16
- package/dist/{chunk-IVOFDYWT.js → chunk-Q7Q7V5NV.js} +2109 -1604
- package/dist/{chunk-JGRYX5UX.js → chunk-S7DKJPLT.js} +29 -58
- package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
- package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
- package/dist/{chunk-NTM7ZSB6.js → chunk-VBCS3DUA.js} +261 -168
- package/dist/{chunk-EFN2EIMK.js → chunk-ZFYPMX46.js} +271 -87
- package/dist/{chunk-L4OXEN46.js → chunk-ZKAWKYT4.js} +10 -24
- package/dist/components.d.ts +7 -5
- package/dist/components.js +46 -257
- package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
- package/dist/eslint-rules/index.cjs +35 -0
- package/{src/eslint-rules/pace-core-compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +234 -235
- package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
- package/dist/eslint-rules/rules/05-styling.cjs +61 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +806 -0
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
- package/dist/eslint-rules/rules/08-testing.cjs +94 -0
- package/dist/eslint-rules/utils/helpers.cjs +42 -0
- package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +62 -172
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +67 -660
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +8 -35
- package/dist/rbac/eslint-rules.d.ts +46 -44
- package/dist/rbac/eslint-rules.js +7 -4
- package/dist/rbac/index.d.ts +109 -586
- package/dist/rbac/index.js +14 -207
- package/dist/styles/index.js +2 -12
- package/dist/theming/runtime.d.ts +14 -1
- package/dist/theming/runtime.js +3 -19
- package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
- package/dist/{types-CkbwOr4Y.d.ts → types-DXstZpNI.d.ts} +4 -17
- package/dist/types-t9H8qKRw.d.ts +55 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +7 -94
- package/dist/{usePublicRouteParams-ClnV4tnv.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +20 -20
- package/dist/utils.d.ts +24 -117
- package/dist/utils.js +54 -392
- package/docs/README.md +17 -7
- package/docs/api/README.md +4 -402
- package/docs/api/modules.md +301 -871
- package/docs/api-reference/components.md +21 -21
- package/docs/api-reference/deprecated.md +31 -6
- package/docs/api-reference/hooks.md +80 -80
- package/docs/api-reference/rpc-functions.md +78 -3
- package/docs/api-reference/types.md +1 -1
- package/docs/api-reference/utilities.md +1 -1
- package/docs/architecture/README.md +1 -1
- package/docs/core-concepts/events.md +3 -3
- package/docs/core-concepts/organisations.md +6 -6
- package/docs/core-concepts/permissions.md +6 -6
- package/docs/documentation-index.md +12 -18
- package/docs/getting-started/cursor-rules.md +3 -23
- package/docs/getting-started/dependencies.md +650 -0
- package/docs/getting-started/documentation-index.md +1 -1
- package/docs/getting-started/examples/README.md +4 -4
- package/docs/getting-started/examples/full-featured-app.md +1 -1
- package/docs/getting-started/faq.md +2 -2
- package/docs/getting-started/installation-guide.md +20 -7
- package/docs/getting-started/quick-reference.md +4 -4
- package/docs/getting-started/quick-start.md +23 -12
- package/docs/implementation-guides/authentication.md +15 -15
- package/docs/implementation-guides/component-styling.md +1 -1
- package/docs/implementation-guides/data-tables.md +126 -33
- package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
- package/docs/implementation-guides/dynamic-colors.md +3 -3
- package/docs/implementation-guides/file-upload-storage.md +2 -2
- package/docs/implementation-guides/hierarchical-datatable.md +40 -60
- package/docs/implementation-guides/inactivity-tracking.md +3 -3
- package/docs/implementation-guides/large-datasets.md +3 -2
- package/docs/implementation-guides/organisation-security.md +2 -2
- package/docs/implementation-guides/performance.md +2 -2
- package/docs/implementation-guides/permission-enforcement.md +5 -1
- package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
- package/docs/migration/V0.4.0_rbac-migration.md +6 -6
- package/docs/rbac/MIGRATION_GUIDE.md +819 -0
- package/docs/rbac/RBAC_CONTRACT.md +724 -0
- package/docs/rbac/README.md +17 -8
- package/docs/rbac/advanced-patterns.md +6 -6
- package/docs/rbac/api-reference.md +20 -20
- package/docs/rbac/edge-functions-guide.md +376 -0
- package/docs/rbac/event-based-apps.md +3 -3
- package/docs/rbac/examples.md +41 -41
- package/docs/rbac/getting-started.md +37 -37
- package/docs/rbac/performance.md +1 -1
- package/docs/rbac/quick-start.md +52 -52
- package/docs/rbac/secure-client-protection.md +1 -35
- package/docs/rbac/troubleshooting.md +1 -1
- package/docs/security/README.md +5 -5
- package/docs/standards/0-standards-overview.md +220 -0
- package/docs/standards/1-pace-core-compliance-standards.md +986 -0
- package/docs/standards/2-project-structure-standards.md +949 -0
- package/docs/standards/3-architecture-standards.md +606 -0
- package/docs/standards/4-code-quality-standards.md +728 -0
- package/docs/standards/5-styling-standards.md +348 -0
- package/docs/standards/{07-rbac-and-rls-standard.md → 6-security-rbac-standards.md} +269 -66
- package/docs/standards/7-api-tech-stack-standards.md +662 -0
- package/docs/standards/8-testing-documentation-standards.md +401 -0
- package/docs/standards/9-operations-standards.md +1102 -0
- package/docs/standards/README.md +185 -57
- package/docs/troubleshooting/README.md +4 -4
- package/docs/troubleshooting/common-issues.md +2 -2
- package/docs/troubleshooting/debugging.md +9 -9
- package/docs/troubleshooting/migration.md +4 -4
- package/docs/troubleshooting/organisation-context-setup.md +42 -19
- package/eslint-config-pace-core.cjs +33 -6
- package/package.json +35 -23
- package/scripts/install-cursor-rules.cjs +25 -6
- package/scripts/install-eslint-config.cjs +284 -0
- package/src/__tests__/fixtures/supabase.ts +1 -1
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +3 -3
- package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +13 -13
- package/src/__tests__/helpers/component-test-utils.tsx +1 -1
- package/src/__tests__/helpers/supabaseMock.ts +2 -2
- package/src/__tests__/integration/UserProfile.test.tsx +14 -14
- package/src/__tests__/public-recipe-view.test.ts +38 -9
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
- package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
- package/src/__tests__/templates/component.test.template.tsx +18 -15
- package/src/components/Button/Button.tsx +5 -1
- package/src/components/Calendar/Calendar.tsx +201 -47
- package/src/components/ContextSelector/ContextSelector.tsx +106 -119
- package/src/components/DataTable/AUDIT_REPORT.md +293 -0
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
- package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
- package/src/components/DataTable/components/DataTableCore.tsx +186 -13
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
- package/src/components/DataTable/components/DataTableLayout.tsx +35 -21
- package/src/components/DataTable/components/EditFields.tsx +23 -3
- package/src/components/DataTable/components/EditableRow.tsx +12 -9
- package/src/components/DataTable/components/EmptyState.tsx +10 -9
- package/src/components/DataTable/components/FilterRow.tsx +2 -4
- package/src/components/DataTable/components/ImportModal.tsx +124 -126
- package/src/components/DataTable/components/LoadingState.tsx +5 -6
- package/src/components/DataTable/components/RowComponent.tsx +12 -0
- package/src/components/DataTable/components/SortIndicator.tsx +50 -0
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
- package/src/components/DataTable/components/index.ts +2 -1
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
- package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
- package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
- package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
- package/src/components/DataTable/types.ts +5 -18
- package/src/components/DataTable/utils/a11yUtils.ts +17 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
- package/src/components/DateTimeField/DateTimeField.tsx +10 -9
- package/src/components/Dialog/Dialog.test.tsx +128 -104
- package/src/components/Dialog/Dialog.tsx +742 -24
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
- package/src/components/FileDisplay/FileDisplay.test.tsx +4 -2
- package/src/components/FileDisplay/FileDisplay.tsx +23 -17
- package/src/components/FileUpload/FileUpload.test.tsx +52 -14
- package/src/components/FileUpload/FileUpload.tsx +112 -130
- package/src/components/Form/Form.test.tsx +6 -8
- package/src/components/Form/Form.tsx +365 -4
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
- package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +11 -15
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
- package/src/components/Progress/Progress.tsx +2 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
- package/src/components/Select/Select.tsx +109 -98
- package/src/components/Select/types.ts +4 -1
- package/src/components/UserMenu/UserMenu.tsx +9 -6
- package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
- package/src/hooks/__tests__/hooks.integration.test.tsx +55 -57
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
- package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
- package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
- package/src/hooks/public/usePublicEvent.ts +67 -195
- package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
- package/src/hooks/public/usePublicEventLogo.ts +24 -14
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/public/usePublicRouteParams.ts +5 -5
- package/src/hooks/useAppConfig.ts +28 -26
- package/src/hooks/useEventTheme.test.ts +217 -239
- package/src/hooks/useEventTheme.ts +16 -28
- package/src/hooks/useFileDisplay.ts +2 -2
- package/src/hooks/useOrganisationPermissions.ts +5 -7
- package/src/hooks/useQueryCache.ts +0 -1
- package/src/hooks/useSessionDraft.ts +380 -0
- package/src/hooks/useSessionRestoration.ts +3 -1
- package/src/icons/index.ts +27 -0
- package/src/index.ts +5 -0
- package/src/providers/OrganisationProvider.tsx +23 -14
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
- package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
- package/src/providers/__tests__/EventProvider.test.tsx +61 -61
- package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
- package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
- package/src/providers/services/EventServiceProvider.tsx +1 -24
- package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +13 -10
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
- package/src/rbac/adapters.tsx +7 -295
- package/src/rbac/api.test.ts +44 -56
- package/src/rbac/api.ts +10 -17
- package/src/rbac/cache-invalidation.ts +0 -1
- package/src/rbac/compliance/index.ts +10 -0
- package/src/rbac/compliance/pattern-detector.ts +553 -0
- package/src/rbac/compliance/runtime-compliance.ts +22 -0
- package/src/rbac/components/AccessDenied.tsx +150 -0
- package/src/rbac/components/NavigationGuard.tsx +12 -20
- package/src/rbac/components/PagePermissionGuard.tsx +4 -24
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
- package/src/rbac/components/index.ts +3 -41
- package/src/rbac/eslint-rules.js +1 -1
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/permissions/index.ts +0 -3
- package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
- package/src/rbac/hooks/usePermissions.ts +0 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
- package/src/rbac/hooks/useResolvedScope.ts +58 -140
- package/src/rbac/hooks/useResourcePermissions.test.ts +124 -38
- package/src/rbac/hooks/useResourcePermissions.ts +139 -48
- package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
- package/src/rbac/hooks/useRoleManagement.ts +147 -19
- package/src/rbac/hooks/useSecureSupabase.ts +4 -8
- package/src/rbac/index.ts +7 -9
- package/src/rbac/utils/contextValidator.ts +9 -7
- package/src/services/AuthService.ts +130 -18
- package/src/services/EventService.ts +4 -97
- package/src/services/InactivityService.ts +16 -0
- package/src/services/OrganisationService.ts +7 -44
- package/src/services/__tests__/OrganisationService.test.ts +26 -8
- package/src/services/base/BaseService.ts +0 -3
- package/src/styles/core.css +7 -0
- package/src/theming/__tests__/parseEventColours.test.ts +9 -3
- package/src/theming/parseEventColours.ts +22 -10
- package/src/types/database.generated.ts +4733 -3809
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
- package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
- package/src/utils/context/organisationContext.test.ts +13 -28
- package/src/utils/context/organisationContext.ts +21 -52
- package/src/utils/dynamic/dynamicUtils.ts +1 -1
- package/src/utils/file-reference/index.ts +39 -15
- package/src/utils/formatting/formatDateTime.test.ts +3 -2
- package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
- package/src/utils/index.ts +4 -1
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
- package/src/utils/persistence/keyDerivation.ts +304 -0
- package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
- package/src/utils/security/secureStorage.ts +5 -5
- package/src/utils/storage/README.md +1 -1
- package/src/utils/storage/helpers.ts +3 -3
- package/src/utils/supabase/createBaseClient.ts +147 -0
- package/src/utils/timezone/timezone.test.ts +1 -2
- package/src/utils/timezone/timezone.ts +1 -1
- package/src/utils/validation/csrf.ts +4 -4
- package/cursor-rules/00-pace-core-compliance.mdc +0 -331
- package/cursor-rules/01-standards-compliance.mdc +0 -244
- package/cursor-rules/04-testing-standards.mdc +0 -268
- package/cursor-rules/05-bug-reports-and-features.mdc +0 -246
- package/cursor-rules/06-code-quality.mdc +0 -309
- package/cursor-rules/07-tech-stack-compliance.mdc +0 -214
- package/cursor-rules/CHANGELOG.md +0 -119
- package/cursor-rules/README.md +0 -192
- package/dist/DataTable-AOVNCPTX.js +0 -175
- package/dist/DataTable-AOVNCPTX.js.map +0 -1
- package/dist/UnifiedAuthProvider-4SBX4LU5.js +0 -18
- package/dist/UnifiedAuthProvider-4SBX4LU5.js.map +0 -1
- package/dist/api-O6HTBX5Y.js +0 -52
- package/dist/api-O6HTBX5Y.js.map +0 -1
- package/dist/audit-V53FV5AG.js +0 -17
- package/dist/audit-V53FV5AG.js.map +0 -1
- package/dist/chunk-5DRSZLL2.js.map +0 -1
- package/dist/chunk-63FOKYGO.js.map +0 -1
- package/dist/chunk-6COVEUS7.js.map +0 -1
- package/dist/chunk-AFVQODI2.js +0 -263
- package/dist/chunk-AFVQODI2.js.map +0 -1
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-E66EQZE6.js.map +0 -1
- package/dist/chunk-EFN2EIMK.js.map +0 -1
- package/dist/chunk-FFQEQTNW.js.map +0 -1
- package/dist/chunk-FMUCXFII.js.map +0 -1
- package/dist/chunk-G37KK66H.js.map +0 -1
- package/dist/chunk-G7QEZTYQ.js +0 -2053
- package/dist/chunk-G7QEZTYQ.js.map +0 -1
- package/dist/chunk-HU2C6SSC.js.map +0 -1
- package/dist/chunk-IHB5DR3H.js.map +0 -1
- package/dist/chunk-IVOFDYWT.js.map +0 -1
- package/dist/chunk-J36DSWQK.js.map +0 -1
- package/dist/chunk-JGRYX5UX.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js +0 -1
- package/dist/chunk-KQCRWDSA.js.map +0 -1
- package/dist/chunk-L4OXEN46.js.map +0 -1
- package/dist/chunk-LMC26NLJ.js +0 -84
- package/dist/chunk-LMC26NLJ.js.map +0 -1
- package/dist/chunk-M43Y4SSO.js.map +0 -1
- package/dist/chunk-M7MPQISP.js.map +0 -1
- package/dist/chunk-NTM7ZSB6.js.map +0 -1
- package/dist/chunk-PWLANIRT.js.map +0 -1
- package/dist/chunk-QXHPKYJV.js.map +0 -1
- package/dist/chunk-RGAWHO7N.js.map +0 -1
- package/dist/chunk-UPPMRMYG.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js.map +0 -1
- package/dist/chunk-ZSAAAMVR.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/contextValidator-5OGXSPKS.js +0 -9
- package/dist/contextValidator-5OGXSPKS.js.map +0 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
- package/dist/hooks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/rbac/eslint-rules.js.map +0 -1
- package/dist/rbac/index.js.map +0 -1
- package/dist/styles/index.js.map +0 -1
- package/dist/theming/runtime.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/docs/best-practices/README.md +0 -472
- package/docs/best-practices/accessibility.md +0 -601
- package/docs/best-practices/common-patterns.md +0 -516
- package/docs/best-practices/deployment.md +0 -1103
- package/docs/best-practices/performance.md +0 -1328
- package/docs/best-practices/security.md +0 -940
- package/docs/best-practices/testing.md +0 -1034
- package/docs/rbac/compliance/compliance-guide.md +0 -544
- package/docs/standards/01-architecture-standard.md +0 -44
- package/docs/standards/02-api-and-rpc-standard.md +0 -39
- package/docs/standards/03-component-standard.md +0 -32
- package/docs/standards/04-code-style-standard.md +0 -32
- package/docs/standards/05-security-standard.md +0 -44
- package/docs/standards/06-testing-and-docs-standard.md +0 -29
- package/docs/standards/pace-core-compliance.md +0 -432
- package/scripts/audit/core/checks/accessibility.cjs +0 -197
- package/scripts/audit/core/checks/api-usage.cjs +0 -191
- package/scripts/audit/core/checks/bundle.cjs +0 -142
- package/scripts/audit/core/checks/compliance.cjs +0 -2706
- package/scripts/audit/core/checks/config.cjs +0 -54
- package/scripts/audit/core/checks/coverage.cjs +0 -84
- package/scripts/audit/core/checks/dependencies.cjs +0 -994
- package/scripts/audit/core/checks/documentation.cjs +0 -268
- package/scripts/audit/core/checks/environment.cjs +0 -116
- package/scripts/audit/core/checks/error-handling.cjs +0 -340
- package/scripts/audit/core/checks/forms.cjs +0 -172
- package/scripts/audit/core/checks/heuristics.cjs +0 -68
- package/scripts/audit/core/checks/hooks.cjs +0 -334
- package/scripts/audit/core/checks/imports.cjs +0 -244
- package/scripts/audit/core/checks/performance.cjs +0 -325
- package/scripts/audit/core/checks/routes.cjs +0 -117
- package/scripts/audit/core/checks/state.cjs +0 -130
- package/scripts/audit/core/checks/structure.cjs +0 -65
- package/scripts/audit/core/checks/style.cjs +0 -584
- package/scripts/audit/core/checks/testing.cjs +0 -122
- package/scripts/audit/core/checks/typescript.cjs +0 -61
- package/scripts/audit/core/scanner.cjs +0 -199
- package/scripts/audit/core/utils.cjs +0 -137
- package/scripts/audit/index.cjs +0 -223
- package/scripts/audit/reporters/console.cjs +0 -151
- package/scripts/audit/reporters/json.cjs +0 -54
- package/scripts/audit/reporters/markdown.cjs +0 -124
- package/scripts/audit-consuming-app.cjs +0 -86
- package/src/components/DataTable/components/DataTableBody.tsx +0 -454
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
- package/src/components/DataTable/components/ExpandButton.tsx +0 -113
- package/src/components/DataTable/components/GroupHeader.tsx +0 -54
- package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
- package/src/components/DataTable/core/DataTableContext.tsx +0 -216
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
- package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
- package/src/components/DataTable/utils/debugTools.ts +0 -514
- package/src/eslint-rules/pace-core-compliance.js +0 -638
- package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
- package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
- package/src/rbac/components/NavigationProvider.test.tsx +0 -481
- package/src/rbac/components/NavigationProvider.tsx +0 -345
- package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
- package/src/rbac/components/PagePermissionProvider.tsx +0 -279
- package/src/rbac/components/PermissionEnforcer.tsx +0 -312
- package/src/rbac/components/RoleBasedRouter.tsx +0 -440
- package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
- package/src/rbac/components/SecureDataProvider.tsx +0 -339
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
|
@@ -0,0 +1,586 @@
|
|
|
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: false
|
|
5
|
+
paceCoreVersion: "0.6.x"
|
|
6
|
+
rulesVersion: "2025-01-28"
|
|
7
|
+
---
|
|
8
|
+
# pace-core Compliance Guide
|
|
9
|
+
|
|
10
|
+
**📚 Human-Readable Standard**: See [1-pace-core-compliance-standards.md](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) for complete documentation.
|
|
11
|
+
|
|
12
|
+
This guide ensures consuming apps use pace-core components, hooks, and utilities correctly, preventing duplication and maintaining consistency across the PACE suite.
|
|
13
|
+
|
|
14
|
+
## AI Agent Instructions
|
|
15
|
+
|
|
16
|
+
**When writing or modifying code, ALWAYS:**
|
|
17
|
+
1. **Check pace-core first** - Before creating any component, hook, or utility, verify if pace-core provides it
|
|
18
|
+
2. **Use pace-core components** - Never use native HTML elements (`<button>`, `<input>`) when pace-core provides components
|
|
19
|
+
3. **Use pace-core hooks** - Never create custom hooks when pace-core provides equivalent functionality
|
|
20
|
+
4. **Use secure Supabase client** - Always use `useSecureSupabase()`, never `createClient()` for queries
|
|
21
|
+
5. **Read documentation** - Before using any pace-core component, check its documentation for required props and usage patterns
|
|
22
|
+
6. **Follow provider nesting** - Always nest providers in the correct order (QueryClientProvider → BrowserRouter → UnifiedAuthProvider → OrganisationProvider)
|
|
23
|
+
7. **Configure Vite correctly** - Always exclude `@jmruthers/pace-core` and `react-router-dom` from pre-bundling
|
|
24
|
+
|
|
25
|
+
**Decision Tree: Should I create this or use pace-core?**
|
|
26
|
+
```
|
|
27
|
+
1. What am I trying to create?
|
|
28
|
+
├─ Component (Button, Input, Card, etc.) → Use pace-core
|
|
29
|
+
├─ Hook (auth, permissions, debounce, etc.) → Use pace-core
|
|
30
|
+
├─ Utility (formatDate, cn, validation, etc.) → Use pace-core
|
|
31
|
+
└─ App-specific domain logic → Create custom (but follow pace-core patterns)
|
|
32
|
+
|
|
33
|
+
2. Does pace-core provide this?
|
|
34
|
+
├─ YES → Use pace-core (import from '@jmruthers/pace-core')
|
|
35
|
+
└─ NO → Check if it should be added to pace-core (for shared use)
|
|
36
|
+
|
|
37
|
+
3. Am I about to use native HTML?
|
|
38
|
+
├─ YES → Check if pace-core has equivalent component
|
|
39
|
+
└─ NO → Continue
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## MUST: Use pace-core Instead of Custom Solutions
|
|
43
|
+
|
|
44
|
+
**ALWAYS use pace-core components, hooks, and utilities when they exist.** Creating custom solutions duplicates functionality and breaks consistency.
|
|
45
|
+
|
|
46
|
+
### Components
|
|
47
|
+
|
|
48
|
+
**MUST use pace-core components:**
|
|
49
|
+
- `Button`, `Card`, `Input`, `Label`, `Textarea` - Basic UI components
|
|
50
|
+
- `Dialog`, `Select`, `Tabs`, `Calendar`, `Toast`, `Tooltip` - Advanced UI components
|
|
51
|
+
- `DataTable` - Complex data tables with RBAC integration
|
|
52
|
+
- `Form`, `FormField`, `LoginForm` - Form components
|
|
53
|
+
- `Header`, `Footer`, `PaceAppLayout` - Layout components
|
|
54
|
+
- `FileUpload`, `FileDisplay` - Storage components
|
|
55
|
+
|
|
56
|
+
**MUST NOT:**
|
|
57
|
+
- Create custom button components when `Button` from pace-core exists
|
|
58
|
+
- Use native HTML elements (`<button>`, `<input>`) when pace-core provides components
|
|
59
|
+
- Import directly from `@radix-ui/*` - Use pace-core wrappers instead
|
|
60
|
+
- Import directly from `lucide-react` - Import icons from `@jmruthers/pace-core/icons` instead
|
|
61
|
+
|
|
62
|
+
**Examples:**
|
|
63
|
+
```tsx
|
|
64
|
+
// ❌ WRONG: Native HTML button
|
|
65
|
+
<button className="btn-primary" onClick={handleClick}>
|
|
66
|
+
Click me
|
|
67
|
+
</button>
|
|
68
|
+
|
|
69
|
+
// ✅ CORRECT: pace-core Button component
|
|
70
|
+
import { Button } from '@jmruthers/pace-core';
|
|
71
|
+
<Button onClick={handleClick}>Click me</Button>
|
|
72
|
+
|
|
73
|
+
// ❌ WRONG: Native HTML input
|
|
74
|
+
<input
|
|
75
|
+
type="text"
|
|
76
|
+
className="form-input"
|
|
77
|
+
value={value}
|
|
78
|
+
onChange={handleChange}
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
// ✅ CORRECT: pace-core Input component
|
|
82
|
+
import { Input } from '@jmruthers/pace-core';
|
|
83
|
+
<Input type="text" value={value} onChange={handleChange} />
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Hooks
|
|
87
|
+
|
|
88
|
+
**MUST use pace-core hooks:**
|
|
89
|
+
- `useUnifiedAuth`, `useEvents`, `useOrganisations` - Authentication and data
|
|
90
|
+
- `usePermissions`, `useCan`, `useSecureSupabase` - RBAC hooks
|
|
91
|
+
- `useToast`, `useDebounce`, `useZodForm` - Utility hooks
|
|
92
|
+
- `useFileReference`, `useFileUpload` - File management hooks
|
|
93
|
+
|
|
94
|
+
**MUST NOT:**
|
|
95
|
+
- Create custom `useAuth` when `useUnifiedAuth` exists
|
|
96
|
+
- Create custom `useToast` when pace-core provides it
|
|
97
|
+
- Create custom `useDebounce` when pace-core provides it
|
|
98
|
+
- Create custom form hooks when `useZodForm` exists
|
|
99
|
+
|
|
100
|
+
**Example:**
|
|
101
|
+
```tsx
|
|
102
|
+
// ❌ WRONG: Custom useDebounce hook implementation
|
|
103
|
+
// ✅ CORRECT: import { useDebounce } from '@jmruthers/pace-core'; const debouncedValue = useDebounce(value, 500);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Utilities
|
|
107
|
+
|
|
108
|
+
**MUST use pace-core utilities:**
|
|
109
|
+
- `cn` - Class name utility (replaces clsx/tailwind-merge)
|
|
110
|
+
- `formatDate`, `formatTime`, `formatDateTime` - Date formatting
|
|
111
|
+
- `formatCurrency`, `formatNumber`, `formatPercent` - Number formatting
|
|
112
|
+
- `emailSchema`, `nameSchema`, `passwordSchema` - Validation schemas
|
|
113
|
+
- `validateUserInput`, `sanitizeUserInput` - Input validation
|
|
114
|
+
|
|
115
|
+
**MUST NOT:**
|
|
116
|
+
- Create custom `formatDate` when pace-core provides it
|
|
117
|
+
- Use `clsx` directly - Use `cn` from pace-core
|
|
118
|
+
- Create custom validation when pace-core schemas exist
|
|
119
|
+
|
|
120
|
+
**Example:**
|
|
121
|
+
```tsx
|
|
122
|
+
// ❌ WRONG: Custom formatDate implementation
|
|
123
|
+
// ✅ CORRECT: import { formatDate } from '@jmruthers/pace-core'; const formatted = formatDate(date);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## MUST: Use Secure Supabase Client
|
|
127
|
+
|
|
128
|
+
**ALWAYS use `useSecureSupabase()` for all database operations.** Never use the base Supabase client directly for queries.
|
|
129
|
+
|
|
130
|
+
**When writing database code:**
|
|
131
|
+
1. Import: `import { useSecureSupabase } from '@jmruthers/pace-core/rbac'`
|
|
132
|
+
2. Call hook: `const secureSupabase = useSecureSupabase()`
|
|
133
|
+
3. Use for queries: `await secureSupabase.from('table').select('*')`
|
|
134
|
+
4. Never use: `createClient()` for queries (only for provider setup)
|
|
135
|
+
|
|
136
|
+
### Hard Requirements
|
|
137
|
+
|
|
138
|
+
- **MUST NOT** import or call `createClient()` from `@supabase/supabase-js` in consuming app code **except** for creating the base client passed to `UnifiedAuthProvider`.
|
|
139
|
+
- **MUST NOT** export, pass, or store an insecure Supabase client instance for general use.
|
|
140
|
+
- **MUST** perform all `.from(...)`, `.rpc(...)`, `.auth.*`, and storage operations via the secure client returned by `useSecureSupabase()` (or the approved pace-core equivalent).
|
|
141
|
+
- **MUST** create the base Supabase client ONCE and pass it to `UnifiedAuthProvider` as `supabaseClient` prop.
|
|
142
|
+
- **MUST** call `useSecureSupabase()` without parameters - it automatically uses the base client from `useUnifiedAuth()` provider layer.
|
|
143
|
+
- **MUST NOT** pass a base client directly to `useSecureSupabase()` - the hook gets it from the provider automatically.
|
|
144
|
+
|
|
145
|
+
### Why this is critical
|
|
146
|
+
|
|
147
|
+
Using `createClient()` directly for queries can bypass organisation context enforcement and RLS policies, leading to:
|
|
148
|
+
- Cross-organisation data access
|
|
149
|
+
- Security vulnerabilities
|
|
150
|
+
- Data leakage between organisations
|
|
151
|
+
|
|
152
|
+
### Correct Pattern
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// ✅ CORRECT: Create base client ONCE for UnifiedAuthProvider
|
|
156
|
+
// main.tsx or App.tsx
|
|
157
|
+
import { createClient } from '@supabase/supabase-js';
|
|
158
|
+
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
159
|
+
|
|
160
|
+
const supabase = createClient(
|
|
161
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
162
|
+
import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
function App() {
|
|
166
|
+
return (
|
|
167
|
+
<UnifiedAuthProvider
|
|
168
|
+
supabaseClient={supabase} // Pass base client to provider
|
|
169
|
+
appName="YourApp"
|
|
170
|
+
// ... other props
|
|
171
|
+
>
|
|
172
|
+
<YourApp />
|
|
173
|
+
</UnifiedAuthProvider>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ✅ CORRECT: Use secure client in components (no parameters needed)
|
|
178
|
+
// YourComponent.tsx
|
|
179
|
+
import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
|
|
180
|
+
|
|
181
|
+
function YourComponent() {
|
|
182
|
+
const secureSupabase = useSecureSupabase(); // Gets client from provider automatically
|
|
183
|
+
|
|
184
|
+
if (!secureSupabase) {
|
|
185
|
+
return <div>Loading...</div>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Use secureSupabase for all queries
|
|
189
|
+
const { data } = await secureSupabase.from('users').select('*');
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Incorrect Patterns
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// ❌ FORBIDDEN: Creating client in component or service
|
|
197
|
+
import { createClient } from '@supabase/supabase-js';
|
|
198
|
+
const supabase = createClient(url, key); // Don't do this for queries
|
|
199
|
+
|
|
200
|
+
// ❌ FORBIDDEN: Passing base client to useSecureSupabase
|
|
201
|
+
import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
|
|
202
|
+
import { supabase } from './supabase'; // Don't export base client
|
|
203
|
+
const secureSupabase = useSecureSupabase(supabase); // Don't pass it
|
|
204
|
+
|
|
205
|
+
// ❌ FORBIDDEN: Using base client directly for queries
|
|
206
|
+
const { data } = await supabase.from('users').select('*'); // Bypasses RLS
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Acceptable Exceptions
|
|
210
|
+
|
|
211
|
+
**The ONLY acceptable use of `createClient()` in consuming app code is:**
|
|
212
|
+
|
|
213
|
+
1. **Creating the base client for `UnifiedAuthProvider`** - This MUST be in one of these files:
|
|
214
|
+
- `src/main.tsx` (or `main.jsx`)
|
|
215
|
+
- `src/App.tsx` (or `App.jsx`)
|
|
216
|
+
- `src/lib/supabase.ts` (or `supabase.js`) - ONLY if this file is ONLY used to create the base client for the provider
|
|
217
|
+
|
|
218
|
+
**The file containing the base client creation MUST:**
|
|
219
|
+
- Be clearly named (e.g., `supabase.ts`, `main.tsx`)
|
|
220
|
+
- Only create the client once
|
|
221
|
+
- Pass it directly to `UnifiedAuthProvider` (not export it for general use)
|
|
222
|
+
- Include a comment explaining it's the base client for the provider
|
|
223
|
+
|
|
224
|
+
**NO OTHER EXCEPTIONS ARE PERMITTED** - All other uses of `createClient()` are security violations and MUST be fixed.
|
|
225
|
+
|
|
226
|
+
**Note**: System-level validation of Supabase client usage is handled by the audit tool. See [1-pace-core-compliance-standards.md](../../packages/core/docs/standards/1-pace-core-compliance-standards.md) for complete enforcement details.
|
|
227
|
+
|
|
228
|
+
## MUST: Setup RBAC Before Use
|
|
229
|
+
|
|
230
|
+
**ALWAYS call `setupRBAC()` before any RBAC usage.** This is non-negotiable.
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
// main.tsx - MUST be first
|
|
234
|
+
import { setupRBAC } from '@jmruthers/pace-core/rbac';
|
|
235
|
+
setupRBAC(supabase);
|
|
236
|
+
// Then render app
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## MUST: Read Documentation Before Using Components
|
|
240
|
+
|
|
241
|
+
**ALWAYS read pace-core component documentation before using any component.** Never guess about props, usage patterns, or behavior.
|
|
242
|
+
|
|
243
|
+
### Where to Find Documentation
|
|
244
|
+
|
|
245
|
+
**Component API Reference:**
|
|
246
|
+
- Location: `node_modules/@jmruthers/pace-core/docs/api-reference/components.md`
|
|
247
|
+
- Or: Check pace-core repository `packages/core/docs/api-reference/components.md`
|
|
248
|
+
- Contains: Complete prop definitions, type information, usage examples
|
|
249
|
+
|
|
250
|
+
**Implementation Guides:**
|
|
251
|
+
- Location: `node_modules/@jmruthers/pace-core/docs/implementation-guides/`
|
|
252
|
+
- Contains: Detailed guides for complex components like DataTable, Forms, etc.
|
|
253
|
+
- Examples:
|
|
254
|
+
- `data-tables.md` - DataTable component guide
|
|
255
|
+
- `forms.md` - Form components guide
|
|
256
|
+
- `file-upload-storage.md` - FileUpload/FileDisplay guide
|
|
257
|
+
|
|
258
|
+
**Detailed API Documentation:**
|
|
259
|
+
- Location: `node_modules/@jmruthers/pace-core/docs/api/`
|
|
260
|
+
- Contains: In-depth API documentation for all exports
|
|
261
|
+
|
|
262
|
+
**Quick Reference:**
|
|
263
|
+
- Location: `node_modules/@jmruthers/pace-core/docs/getting-started/quick-reference.md`
|
|
264
|
+
- Contains: Quick lookup for common patterns
|
|
265
|
+
|
|
266
|
+
### How to Find Component-Specific Docs
|
|
267
|
+
|
|
268
|
+
1. **Check API Reference First:**
|
|
269
|
+
```bash
|
|
270
|
+
# In your consuming app
|
|
271
|
+
cat node_modules/@jmruthers/pace-core/docs/api-reference/components.md
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
2. **Search Implementation Guides:**
|
|
275
|
+
- Look for component name in `implementation-guides/` directory
|
|
276
|
+
- Complex components have dedicated guides
|
|
277
|
+
|
|
278
|
+
3. **Check Type Definitions:**
|
|
279
|
+
```tsx
|
|
280
|
+
// Import and check TypeScript types
|
|
281
|
+
import type { DataTableProps } from '@jmruthers/pace-core';
|
|
282
|
+
// Hover over type to see prop definitions
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
4. **Use IDE IntelliSense:**
|
|
286
|
+
- TypeScript types provide inline documentation
|
|
287
|
+
- Hover over component name to see prop types
|
|
288
|
+
- Use autocomplete to discover available props
|
|
289
|
+
|
|
290
|
+
### MUST NOT: Guess About Props or Usage
|
|
291
|
+
|
|
292
|
+
**❌ WRONG - Guessing props:**
|
|
293
|
+
```tsx
|
|
294
|
+
<DataTable data={data} columns={columns} /> // Missing required rbac prop
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**✅ CORRECT - Read documentation first:**
|
|
298
|
+
```tsx
|
|
299
|
+
import { DataTable } from '@jmruthers/pace-core';
|
|
300
|
+
<DataTable data={data} columns={columns} rbac={{ pageName: 'users' }} features={{ search: true }} />
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Documentation Checklist
|
|
304
|
+
|
|
305
|
+
Before using any pace-core component:
|
|
306
|
+
- [ ] Read component API reference
|
|
307
|
+
- [ ] Check for implementation guide if component is complex
|
|
308
|
+
- [ ] Review TypeScript types for prop definitions
|
|
309
|
+
- [ ] Check examples in documentation
|
|
310
|
+
- [ ] Verify required vs optional props
|
|
311
|
+
- [ ] Understand component behavior and limitations
|
|
312
|
+
|
|
313
|
+
### Common Documentation Locations
|
|
314
|
+
|
|
315
|
+
| Component Type | Documentation Location |
|
|
316
|
+
|----------------|----------------------|
|
|
317
|
+
| Basic UI (Button, Card, etc.) | `api-reference/components.md` |
|
|
318
|
+
| DataTable | `implementation-guides/data-tables.md` |
|
|
319
|
+
| Forms | `implementation-guides/forms.md` |
|
|
320
|
+
| RBAC Components | `rbac/getting-started.md` |
|
|
321
|
+
| File Upload/Display | `implementation-guides/file-upload-storage.md` |
|
|
322
|
+
| Hooks | `api-reference/hooks.md` |
|
|
323
|
+
| Utilities | `api-reference/utilities.md` |
|
|
324
|
+
|
|
325
|
+
## SHOULD: Check pace-core Before Creating New Components
|
|
326
|
+
|
|
327
|
+
**Before creating a new component, hook, or utility:**
|
|
328
|
+
|
|
329
|
+
1. Check pace-core exports: `@jmruthers/pace-core`
|
|
330
|
+
2. Review pace-core documentation
|
|
331
|
+
3. Check `core-usage-manifest.json` for available exports
|
|
332
|
+
4. Search pace-core source if needed
|
|
333
|
+
|
|
334
|
+
**If pace-core doesn't provide what you need:**
|
|
335
|
+
- Consider if it should be added to pace-core (for shared use)
|
|
336
|
+
- Document why custom solution is needed
|
|
337
|
+
- Follow pace-core patterns for consistency
|
|
338
|
+
|
|
339
|
+
## MUST: Provider Nesting Order
|
|
340
|
+
|
|
341
|
+
**⚠️ CRITICAL: Provider nesting order matters!** Incorrect nesting causes React context errors.
|
|
342
|
+
|
|
343
|
+
**MUST** nest providers in this exact order (outermost to innermost):
|
|
344
|
+
|
|
345
|
+
1. `QueryClientProvider` (outermost)
|
|
346
|
+
2. `BrowserRouter`
|
|
347
|
+
3. `UnifiedAuthProvider`
|
|
348
|
+
4. `OrganisationProvider`
|
|
349
|
+
5. `App` (innermost)
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
// ✅ CORRECT: main.tsx
|
|
353
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
354
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
355
|
+
import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
|
|
356
|
+
import { createClient } from '@supabase/supabase-js';
|
|
357
|
+
|
|
358
|
+
const queryClient = new QueryClient();
|
|
359
|
+
const supabase = createClient(
|
|
360
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
361
|
+
import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
createRoot(document.getElementById("root")!).render(
|
|
365
|
+
<QueryClientProvider client={queryClient}>
|
|
366
|
+
<BrowserRouter>
|
|
367
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName="YourApp">
|
|
368
|
+
<OrganisationProvider>
|
|
369
|
+
<App />
|
|
370
|
+
</OrganisationProvider>
|
|
371
|
+
</UnifiedAuthProvider>
|
|
372
|
+
</BrowserRouter>
|
|
373
|
+
</QueryClientProvider>
|
|
374
|
+
);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Common mistakes to avoid:**
|
|
378
|
+
- ❌ `BrowserRouter` inside `UnifiedAuthProvider` (causes Router context errors)
|
|
379
|
+
- ❌ `UnifiedAuthProvider` wrapping `BrowserRouter` (causes context errors)
|
|
380
|
+
- ❌ Missing `BrowserRouter` (causes `useNavigate` errors)
|
|
381
|
+
|
|
382
|
+
## MUST: Vite Configuration
|
|
383
|
+
|
|
384
|
+
**⚠️ CRITICAL: Vite configuration prevents React context mismatches!**
|
|
385
|
+
|
|
386
|
+
**MUST** configure Vite to exclude `@jmruthers/pace-core` and `react-router-dom` from pre-bundling:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
// vite.config.ts
|
|
390
|
+
import { defineConfig } from 'vite';
|
|
391
|
+
import react from '@vitejs/plugin-react';
|
|
392
|
+
import path from 'path';
|
|
393
|
+
|
|
394
|
+
export default defineConfig({
|
|
395
|
+
plugins: [react()],
|
|
396
|
+
resolve: {
|
|
397
|
+
alias: {
|
|
398
|
+
'@': path.resolve(__dirname, './src'),
|
|
399
|
+
},
|
|
400
|
+
// CRITICAL: Dedupe React dependencies
|
|
401
|
+
dedupe: ['react', 'react-dom', 'react-router-dom'],
|
|
402
|
+
},
|
|
403
|
+
optimizeDeps: {
|
|
404
|
+
include: [
|
|
405
|
+
'react',
|
|
406
|
+
'react-dom',
|
|
407
|
+
'react/jsx-runtime',
|
|
408
|
+
],
|
|
409
|
+
// CRITICAL: Exclude pace-core to prevent React context mismatches
|
|
410
|
+
exclude: ['@jmruthers/pace-core', 'react-router-dom'],
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Why this matters:**
|
|
416
|
+
- Pre-bundling `@jmruthers/pace-core` creates separate React instances
|
|
417
|
+
- This causes "useUnifiedAuth must be used within a UnifiedAuthProvider" errors
|
|
418
|
+
- Excluding it ensures pace-core uses the same React instance as your app
|
|
419
|
+
- `react-router-dom` must also be excluded and deduped to prevent Router context errors
|
|
420
|
+
|
|
421
|
+
**If you encounter context errors:**
|
|
422
|
+
1. Verify `@jmruthers/pace-core` is in `optimizeDeps.exclude`
|
|
423
|
+
2. Verify `react-router-dom` is in both `resolve.dedupe` and `optimizeDeps.exclude`
|
|
424
|
+
3. Clear Vite cache: `rm -rf node_modules/.vite`
|
|
425
|
+
4. Restart dev server
|
|
426
|
+
|
|
427
|
+
## MUST: Import Core Styles
|
|
428
|
+
|
|
429
|
+
**ALWAYS import pace-core styles via app.css:**
|
|
430
|
+
|
|
431
|
+
The correct pattern is a two-file CSS architecture:
|
|
432
|
+
1. `src/app.css` - Contains `@import "@jmruthers/pace-core/styles/core.css";` (CSS @import)
|
|
433
|
+
2. `src/main.tsx` - Imports `./app.css` (JavaScript import)
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
// main.tsx or App.tsx
|
|
437
|
+
import './app.css'; // ✅ CORRECT - app.css imports core.css
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
```css
|
|
441
|
+
/* src/app.css */
|
|
442
|
+
@import "tailwindcss";
|
|
443
|
+
@import "@jmruthers/pace-core/styles/core.css"; // CSS @import, not JavaScript import
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**MUST NOT:**
|
|
447
|
+
- Import `core.css` directly in `main.tsx` or `App.tsx` - This causes duplicate imports
|
|
448
|
+
- Use JavaScript import for `core.css` - Use CSS `@import` in `app.css` instead
|
|
449
|
+
|
|
450
|
+
**See [5-styling-standards.md](../../packages/core/docs/standards/5-styling-standards.md) for complete CSS setup instructions.**
|
|
451
|
+
|
|
452
|
+
## MUST NOT: Use Inline Styles
|
|
453
|
+
|
|
454
|
+
**NEVER use inline styles (`style={{...}}`).** All styling MUST come from pace-core components and Tailwind classes.
|
|
455
|
+
|
|
456
|
+
### Why No Inline Styles
|
|
457
|
+
|
|
458
|
+
- Inline styles override pace-core component styles
|
|
459
|
+
- Inline styles break consistency across the PACE suite
|
|
460
|
+
- Inline styles are harder to maintain and update
|
|
461
|
+
- Inline styles don't benefit from theme variables and design system
|
|
462
|
+
|
|
463
|
+
### Use pace-core Components for Styling
|
|
464
|
+
|
|
465
|
+
**All styling MUST come from:**
|
|
466
|
+
1. **pace-core components** - Components already have correct styling
|
|
467
|
+
2. **Tailwind utility classes** - Use Tailwind classes for layout and spacing
|
|
468
|
+
3. **Semantic classes** - Use semantic classes from pace-core (e.g., `bg-background`, `text-foreground`)
|
|
469
|
+
|
|
470
|
+
**MUST NOT:**
|
|
471
|
+
- Use `style={{...}}` prop
|
|
472
|
+
- Use inline CSS strings
|
|
473
|
+
- Override component styles with inline styles
|
|
474
|
+
- Create custom CSS for styling that pace-core provides
|
|
475
|
+
|
|
476
|
+
**Example:**
|
|
477
|
+
```tsx
|
|
478
|
+
// ❌ WRONG: <div style={{ backgroundColor: 'blue' }}> or <Button style={{...}}>
|
|
479
|
+
// ✅ CORRECT: <Card className="bg-main-500 p-4"> or <Button variant="default"> or <div className="flex gap-4">
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### When Tailwind Classes Are Acceptable
|
|
483
|
+
|
|
484
|
+
**Tailwind classes are acceptable for:**
|
|
485
|
+
- Layout (flex, grid, positioning)
|
|
486
|
+
- Spacing (margin, padding, gap)
|
|
487
|
+
- Responsive design (breakpoints)
|
|
488
|
+
- Layout-specific styling not provided by pace-core components
|
|
489
|
+
|
|
490
|
+
**Tailwind classes MUST NOT:**
|
|
491
|
+
- Override pace-core component internal styles
|
|
492
|
+
- Duplicate styling that pace-core components already provide
|
|
493
|
+
- Use standard Tailwind colors (use `main-*`, `sec-*`, `acc-*` namespaces)
|
|
494
|
+
|
|
495
|
+
### Styling Checklist
|
|
496
|
+
|
|
497
|
+
Before adding any styling:
|
|
498
|
+
- [ ] Check if pace-core component provides the styling you need
|
|
499
|
+
- [ ] Use pace-core component variants/props for styling
|
|
500
|
+
- [ ] Use Tailwind classes only for layout/spacing
|
|
501
|
+
- [ ] Never use inline `style={{...}}` prop
|
|
502
|
+
- [ ] Never override component styles with inline styles
|
|
503
|
+
- [ ] Use semantic classes (`bg-background`, `text-foreground`) when available
|
|
504
|
+
|
|
505
|
+
## SHOULD: Use pace-core Patterns
|
|
506
|
+
|
|
507
|
+
**Follow pace-core patterns for consistency:**
|
|
508
|
+
- Component structure and composition
|
|
509
|
+
- Error handling patterns
|
|
510
|
+
- Loading state patterns
|
|
511
|
+
- Form validation patterns
|
|
512
|
+
- RBAC permission checking patterns
|
|
513
|
+
|
|
514
|
+
## Common Mistakes to Avoid
|
|
515
|
+
|
|
516
|
+
**When writing code, NEVER:**
|
|
517
|
+
1. **Use native HTML when pace-core provides components** - Always check pace-core first
|
|
518
|
+
```tsx
|
|
519
|
+
// ❌ WRONG
|
|
520
|
+
<button>Click</button>
|
|
521
|
+
<input type="text" />
|
|
522
|
+
|
|
523
|
+
// ✅ CORRECT
|
|
524
|
+
<Button>Click</Button>
|
|
525
|
+
<Input type="text" />
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
2. **Create wrapper functions around pace-core hooks** - Use hooks directly
|
|
529
|
+
```tsx
|
|
530
|
+
// ❌ WRONG
|
|
531
|
+
function useMyAuth() {
|
|
532
|
+
const auth = useUnifiedAuth();
|
|
533
|
+
return { user: auth.user, isAdmin: auth.user?.role === 'admin' };
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// ✅ CORRECT
|
|
537
|
+
const { user } = useUnifiedAuth();
|
|
538
|
+
const { canManage } = useCan(user?.id, scope, 'manage:users');
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
3. **Use createClient() for queries** - Always use `useSecureSupabase()`
|
|
542
|
+
```tsx
|
|
543
|
+
// ❌ WRONG
|
|
544
|
+
const supabase = createClient(url, key);
|
|
545
|
+
const { data } = await supabase.from('users').select('*');
|
|
546
|
+
|
|
547
|
+
// ✅ CORRECT
|
|
548
|
+
const secureSupabase = useSecureSupabase();
|
|
549
|
+
const { data } = await secureSupabase.from('users').select('*');
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
4. **Guess component props** - Always read documentation first
|
|
553
|
+
5. **Use inline styles** - Use pace-core components and Tailwind classes
|
|
554
|
+
6. **Skip provider nesting** - Always nest in correct order
|
|
555
|
+
7. **Skip Vite configuration** - Always exclude pace-core from pre-bundling
|
|
556
|
+
|
|
557
|
+
## Compliance Exceptions
|
|
558
|
+
|
|
559
|
+
**In general, pace-core compliance rules do NOT allow exceptions.** The rules are designed to ensure security, consistency, and maintainability across the PACE suite.
|
|
560
|
+
|
|
561
|
+
### When Exceptions Are NOT Allowed
|
|
562
|
+
|
|
563
|
+
- **Security rules** (e.g., `createClient()` usage) - NO exceptions except the one documented above
|
|
564
|
+
- **RBAC rules** - NO exceptions
|
|
565
|
+
- **Component usage** - NO exceptions (use pace-core components)
|
|
566
|
+
- **Hook usage** - NO exceptions (use pace-core hooks)
|
|
567
|
+
|
|
568
|
+
### Documenting Legitimate Edge Cases
|
|
569
|
+
|
|
570
|
+
If you encounter a situation where a rule seems to conflict with a legitimate requirement:
|
|
571
|
+
|
|
572
|
+
1. **First**: Verify that pace-core doesn't provide a solution
|
|
573
|
+
2. **Second**: Check if the requirement should be added to pace-core
|
|
574
|
+
3. **Third**: If truly unavoidable, document the case clearly with a comment explaining why
|
|
575
|
+
|
|
576
|
+
**Note**: Even with documentation, exceptions should be temporary, rare, reviewed, and tracked for eventual removal.
|
|
577
|
+
|
|
578
|
+
## Reference
|
|
579
|
+
|
|
580
|
+
- **pace-core Exports**: See [pace-core documentation](../../packages/core/docs/README.md) for complete export reference
|
|
581
|
+
- **RBAC Implementation**: See [6-security-rbac-standards.md](../../packages/core/docs/standards/6-security-rbac-standards.md) for RBAC patterns
|
|
582
|
+
- **Component Documentation**:
|
|
583
|
+
- API Reference: `node_modules/@jmruthers/pace-core/docs/api-reference/components.md`
|
|
584
|
+
- Implementation Guides: `node_modules/@jmruthers/pace-core/docs/implementation-guides/`
|
|
585
|
+
- Detailed API: `node_modules/@jmruthers/pace-core/docs/api/`
|
|
586
|
+
- **Always read documentation before using components** - Never guess about props or usage
|
|
@@ -7,8 +7,42 @@ rulesVersion: "2025-01-28"
|
|
|
7
7
|
---
|
|
8
8
|
# Project Structure Standard
|
|
9
9
|
|
|
10
|
+
**📚 Human-Readable Standard**: See [2-project-structure-standards.md](../../packages/core/docs/standards/2-project-structure-standards.md) for complete documentation including migration guides and detailed examples.
|
|
11
|
+
|
|
10
12
|
This guide defines the standard folder structure and file organization for consuming apps in the PACE suite.
|
|
11
13
|
|
|
14
|
+
## AI Agent Instructions
|
|
15
|
+
|
|
16
|
+
**When creating or organizing files, ALWAYS:**
|
|
17
|
+
1. **Organize by feature** - Group components, hooks, and utilities by feature/domain, not by type
|
|
18
|
+
2. **Colocate tests** - Place test files next to source files (`Component.test.tsx` next to `Component.tsx`)
|
|
19
|
+
3. **Follow naming conventions** - Components: `PascalCase.tsx`, Hooks: `use*.ts`, Utils: `camelCase.ts`
|
|
20
|
+
4. **Use absolute imports** - Use `@/` path alias for imports, never relative imports for distant files
|
|
21
|
+
5. **Keep root clean** - Only configuration files and documentation in root, never source files
|
|
22
|
+
6. **Place migrations correctly** - All migrations in `supabase/migrations/` with timestamp format
|
|
23
|
+
|
|
24
|
+
**Decision Tree: File Organization**
|
|
25
|
+
```
|
|
26
|
+
1. Where should this file go?
|
|
27
|
+
├─ Component → src/components/<feature>/ComponentName.tsx
|
|
28
|
+
├─ Hook → src/hooks/useHookName.ts (or colocated with component)
|
|
29
|
+
├─ Utility → src/utils/utilityName.ts
|
|
30
|
+
├─ Type → src/types/typeName.ts (or colocated with feature)
|
|
31
|
+
├─ Test → Next to source file (ComponentName.test.tsx)
|
|
32
|
+
└─ Migration → supabase/migrations/YYYYMMDDHHMMSS_description.sql
|
|
33
|
+
|
|
34
|
+
2. How should I name it?
|
|
35
|
+
├─ Component → PascalCase (EventCard.tsx)
|
|
36
|
+
├─ Hook → camelCase with use prefix (useEventData.ts)
|
|
37
|
+
├─ Utility → camelCase (formatEvent.ts)
|
|
38
|
+
└─ Test → Same as source + .test (EventCard.test.tsx)
|
|
39
|
+
|
|
40
|
+
3. Should I use absolute or relative imports?
|
|
41
|
+
├─ Same directory → Relative (./Component)
|
|
42
|
+
├─ Different directory → Absolute (@/components/events/EventCard)
|
|
43
|
+
└─ pace-core → Package import (@jmruthers/pace-core)
|
|
44
|
+
```
|
|
45
|
+
|
|
12
46
|
## MUST: Follow Standard Directory Structure
|
|
13
47
|
|
|
14
48
|
**Consuming apps MUST follow this structure:**
|
|
@@ -40,7 +74,7 @@ your-app/
|
|
|
40
74
|
|
|
41
75
|
## MUST: Organize Components by Feature
|
|
42
76
|
|
|
43
|
-
**
|
|
77
|
+
**ALWAYS organize components by feature/domain, not by type:**
|
|
44
78
|
|
|
45
79
|
```
|
|
46
80
|
src/
|
|
@@ -62,7 +96,7 @@ src/
|
|
|
62
96
|
|
|
63
97
|
## MUST: Colocate Tests
|
|
64
98
|
|
|
65
|
-
**
|
|
99
|
+
**ALWAYS colocate tests with source files:**
|
|
66
100
|
|
|
67
101
|
```
|
|
68
102
|
src/
|
|
@@ -98,6 +132,10 @@ src/
|
|
|
98
132
|
- Format: `YYYYMMDDHHMMSS_description.sql`
|
|
99
133
|
- Example: `20250115143022_add_user_preferences.sql`
|
|
100
134
|
|
|
135
|
+
- If this app **intentionally has no app-owned migrations** (e.g., relies on shared DB managed elsewhere), you MUST add `supabase/README.md` explaining:
|
|
136
|
+
- where migrations/RLS policies are managed
|
|
137
|
+
- whether the app is expected to add migrations in the future
|
|
138
|
+
|
|
101
139
|
## SHOULD: Organize by Domain
|
|
102
140
|
|
|
103
141
|
**For larger apps, SHOULD organize by domain/feature:**
|
|
@@ -137,7 +175,7 @@ src/
|
|
|
137
175
|
|
|
138
176
|
## MUST: Use Consistent Import Paths
|
|
139
177
|
|
|
140
|
-
**
|
|
178
|
+
**ALWAYS use consistent import patterns:**
|
|
141
179
|
|
|
142
180
|
```tsx
|
|
143
181
|
// ✅ CORRECT - Absolute imports from src
|
|
@@ -197,4 +235,4 @@ Before committing, verify:
|
|
|
197
235
|
|
|
198
236
|
## Reference
|
|
199
237
|
|
|
200
|
-
See
|
|
238
|
+
**Note**: File structure validation is handled by the audit tool. See [2-project-structure-standards.md](../../packages/core/docs/standards/2-project-structure-standards.md) for complete enforcement details.
|