@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.
- package/{scripts/audit/audit-dependencies.cjs → audit-tool/00-dependencies.cjs} +12 -13
- 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/cursor-rules/00-standards-overview.mdc +156 -0
- package/cursor-rules/{00-pace-core-compliance.mdc → 01-pace-core-compliance.mdc} +187 -34
- package/cursor-rules/02-project-structure.mdc +37 -5
- package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +125 -11
- package/cursor-rules/04-code-quality.mdc +419 -0
- package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +55 -10
- package/cursor-rules/{09-rbac-compliance.mdc → 06-security-rbac.mdc} +62 -6
- 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/DataTable-7PMH7XN7.js +15 -0
- package/dist/{DataTable-2N_tqbfq.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
- package/dist/{PublicPageProvider-BBH6Vqg7.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +26 -16
- package/dist/{chunk-FENMYN2U.js → chunk-5X4QLXRG.js} +1 -3
- package/dist/{chunk-4T7OBVTU.js → chunk-6F3IILHI.js} +1 -1
- package/dist/{chunk-SD6WQY43.js → chunk-7ILTDCL2.js} +9 -1
- package/dist/{chunk-3QC3KRHK.js → chunk-A3W6LW53.js} +16 -1
- package/dist/{chunk-7TYHROIV.js → chunk-BM4CQ5P3.js} +50 -8
- package/dist/{chunk-2HGJFNAH.js → chunk-FEJLJNWA.js} +1 -15
- package/dist/{chunk-OHIK3MIO.js → chunk-GHYHJTYV.js} +2 -2
- package/dist/{chunk-UIYSCEV7.js → chunk-IUBRCBSY.js} +1 -1
- package/dist/{chunk-LAZMKTTF.js → chunk-JGWDVX64.js} +281 -347
- package/dist/{chunk-MAGBIDNS.js → chunk-L4XMVJKY.js} +2 -2
- package/dist/{chunk-A55DK444.js → chunk-OJ4SKRSV.js} +1 -7
- package/dist/{chunk-ZS5VO5JB.js → chunk-Q7Q7V5NV.js} +406 -451
- package/dist/{chunk-3O3WHILE.js → chunk-VBCS3DUA.js} +236 -60
- package/dist/{chunk-BVP2BCJF.js → chunk-ZKAWKYT4.js} +8 -8
- package/dist/components.d.ts +5 -4
- package/dist/components.js +27 -32
- package/dist/eslint-rules/index.cjs +22 -9
- package/{src/eslint-rules/rules/compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +184 -23
- 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/{rbac.cjs → 06-security-rbac.cjs} +26 -10
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
- package/dist/eslint-rules/rules/08-testing.cjs +94 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +18 -17
- package/dist/rbac/index.js +6 -6
- package/dist/theming/runtime.d.ts +14 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/{types-B-K_5VnO.d.ts → types-DXstZpNI.d.ts} +0 -17
- package/dist/{usePublicRouteParams-COZ28Mvq.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +19 -19
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +8 -8
- package/docs/README.md +1 -1
- package/docs/api/modules.md +47 -31
- package/docs/api-reference/components.md +18 -20
- package/docs/api-reference/hooks.md +80 -80
- 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/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/quick-reference.md +4 -4
- 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 +1 -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/README.md +5 -5
- package/docs/rbac/advanced-patterns.md +6 -6
- package/docs/rbac/api-reference.md +20 -20
- 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 -1
- 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/{00-pace-core-compliance.md → 1-pace-core-compliance-standards.md} +204 -185
- package/docs/standards/{02-project-structure.md → 2-project-structure-standards.md} +11 -47
- package/docs/standards/3-architecture-standards.md +606 -0
- package/docs/standards/4-code-quality-standards.md +728 -0
- package/docs/standards/{08-markup-quality.md → 5-styling-standards.md} +12 -9
- package/docs/standards/{09-rbac-compliance.md → 6-security-rbac-standards.md} +126 -18
- 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 +203 -104
- 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/eslint-config-pace-core.cjs +21 -10
- package/package.json +6 -5
- package/scripts/install-cursor-rules.cjs +11 -243
- package/scripts/install-eslint-config.cjs +284 -0
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +10 -10
- package/src/__tests__/integration/UserProfile.test.tsx +14 -14
- 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/Calendar/Calendar.tsx +201 -47
- package/src/components/ContextSelector/ContextSelector.tsx +137 -153
- 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/DataTableErrorBoundary.tsx +9 -11
- package/src/components/DataTable/components/DataTableLayout.tsx +5 -16
- package/src/components/DataTable/components/EditableRow.tsx +5 -7
- 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/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/index.ts +2 -1
- package/src/components/DataTable/types.ts +0 -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 +7 -8
- package/src/components/Dialog/Dialog.test.tsx +1 -0
- package/src/components/Dialog/Dialog.tsx +25 -8
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
- package/src/components/FileUpload/FileUpload.test.tsx +52 -14
- package/src/components/FileUpload/FileUpload.tsx +112 -130
- package/src/components/Progress/Progress.tsx +2 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
- package/src/components/Select/Select.tsx +86 -77
- package/src/components/Select/types.ts +3 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
- package/src/hooks/__tests__/hooks.integration.test.tsx +49 -49
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
- package/src/hooks/public/usePublicEvent.ts +5 -5
- package/src/hooks/public/usePublicEventLogo.ts +5 -5
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/public/usePublicRouteParams.ts +5 -5
- package/src/hooks/useAppConfig.ts +2 -2
- package/src/hooks/useEventTheme.test.ts +7 -7
- package/src/hooks/useEventTheme.ts +1 -4
- package/src/hooks/useFileDisplay.ts +2 -2
- 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/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +10 -10
- 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/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
- package/src/utils/storage/README.md +1 -1
- package/cursor-rules/01-standards-compliance.mdc +0 -285
- package/cursor-rules/04-testing-standards.mdc +0 -270
- package/cursor-rules/05-bug-reports-and-features.mdc +0 -248
- package/cursor-rules/06-code-quality.mdc +0 -311
- package/cursor-rules/07-tech-stack-compliance.mdc +0 -216
- package/cursor-rules/10-error-handling-patterns.mdc +0 -179
- package/cursor-rules/11-performance-optimization.mdc +0 -169
- package/cursor-rules/12-ci-cd-integration.mdc +0 -150
- package/dist/DataTable-LRJL4IRV.js +0 -15
- package/dist/eslint-rules/rules/compliance.cjs +0 -348
- package/dist/eslint-rules/rules/components.cjs +0 -113
- package/dist/eslint-rules/rules/imports.cjs +0 -102
- package/docs/best-practices/README.md +0 -472
- package/docs/best-practices/accessibility.md +0 -604
- 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-standards-compliance.md +0 -188
- package/docs/standards/03-solid-principles.md +0 -39
- package/docs/standards/04-testing-standards.md +0 -36
- package/docs/standards/05-bug-reports-and-features.md +0 -27
- package/docs/standards/06-code-quality.md +0 -34
- package/docs/standards/07-tech-stack-compliance.md +0 -30
- package/docs/standards/10-error-handling-patterns.md +0 -401
- package/docs/standards/11-performance-optimization.md +0 -348
- package/docs/standards/12-ci-cd-integration.md +0 -370
- package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +0 -192
- package/scripts/audit/audit-compliance.cjs +0 -1295
- package/scripts/audit/audit-components.cjs +0 -260
- package/scripts/audit/audit-rbac.cjs +0 -954
- package/scripts/audit/audit-standards.cjs +0 -1268
- package/scripts/audit/index.cjs +0 -1927
- package/src/components/DataTable/components/DataTableBody.tsx +0 -478
- 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/index.cjs +0 -22
- package/src/eslint-rules/rules/components.cjs +0 -113
- package/src/eslint-rules/rules/imports.cjs +0 -102
- package/src/eslint-rules/rules/rbac.cjs +0 -790
- package/src/eslint-rules/utils/helpers.cjs +0 -42
- package/src/eslint-rules/utils/manifest-loader.cjs +0 -75
|
@@ -158,12 +158,12 @@ function Dashboard() {
|
|
|
158
158
|
<PagePermissionGuard
|
|
159
159
|
pageName="dashboard"
|
|
160
160
|
operation="read"
|
|
161
|
-
fallback={<
|
|
161
|
+
fallback={<p>Access Denied</p>}
|
|
162
162
|
>
|
|
163
|
-
<
|
|
163
|
+
<section>
|
|
164
164
|
<h1>Dashboard</h1>
|
|
165
165
|
<EventContent />
|
|
166
|
-
</
|
|
166
|
+
</section>
|
|
167
167
|
</PagePermissionGuard>
|
|
168
168
|
);
|
|
169
169
|
}
|
|
@@ -193,14 +193,14 @@ function UserActions() {
|
|
|
193
193
|
}
|
|
194
194
|
);
|
|
195
195
|
|
|
196
|
-
if (isLoading) return <
|
|
197
|
-
if (error) return <
|
|
196
|
+
if (isLoading) return <p>Loading permissions...</p>;
|
|
197
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
198
198
|
|
|
199
199
|
return (
|
|
200
|
-
<
|
|
200
|
+
<section>
|
|
201
201
|
{permissions['page-1']?.includes('read') && <ReadButton />}
|
|
202
202
|
{permissions['page-1']?.includes('manage') && <ManageButton />}
|
|
203
|
-
</
|
|
203
|
+
</section>
|
|
204
204
|
);
|
|
205
205
|
}
|
|
206
206
|
```
|
|
@@ -229,13 +229,13 @@ function UserActions() {
|
|
|
229
229
|
'page-123' // optional pageId
|
|
230
230
|
);
|
|
231
231
|
|
|
232
|
-
if (isLoading) return <
|
|
233
|
-
if (error) return <
|
|
232
|
+
if (isLoading) return <p>Checking permission...</p>;
|
|
233
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
234
234
|
|
|
235
235
|
return (
|
|
236
|
-
<
|
|
236
|
+
<section>
|
|
237
237
|
{can ? <AdminPanel /> : <AccessDenied />}
|
|
238
|
-
</
|
|
238
|
+
</section>
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
```
|
|
@@ -298,17 +298,17 @@ function Dashboard() {
|
|
|
298
298
|
|
|
299
299
|
// Pattern 1: PermissionEnforcer (automatic scope resolution)
|
|
300
300
|
return (
|
|
301
|
-
<
|
|
301
|
+
<main>
|
|
302
302
|
<h1>Dashboard</h1>
|
|
303
303
|
|
|
304
304
|
{/* Always visible */}
|
|
305
|
-
<
|
|
305
|
+
<p>Welcome to the dashboard!</p>
|
|
306
306
|
|
|
307
307
|
{/* Pattern 1: PermissionEnforcer - automatic scope resolution */}
|
|
308
308
|
<PermissionEnforcer
|
|
309
309
|
permissions={['read:admin']}
|
|
310
310
|
operation="admin-panel"
|
|
311
|
-
fallback={<
|
|
311
|
+
fallback={<p>Admin access required</p>}
|
|
312
312
|
>
|
|
313
313
|
<AdminPanel />
|
|
314
314
|
</PermissionEnforcer>
|
|
@@ -318,7 +318,7 @@ function Dashboard() {
|
|
|
318
318
|
|
|
319
319
|
{/* Pattern 3: usePermissions - for custom logic */}
|
|
320
320
|
<CustomPermissionLogic userId={user?.id} organisationId={selectedOrganisationId} />
|
|
321
|
-
</
|
|
321
|
+
</main>
|
|
322
322
|
);
|
|
323
323
|
}
|
|
324
324
|
|
|
@@ -330,20 +330,20 @@ function UserManagement({ userId, organisationId }) {
|
|
|
330
330
|
'update:users'
|
|
331
331
|
);
|
|
332
332
|
|
|
333
|
-
if (isLoading) return <
|
|
334
|
-
if (error) return <
|
|
333
|
+
if (isLoading) return <p>Checking permissions...</p>;
|
|
334
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
335
335
|
|
|
336
336
|
return (
|
|
337
|
-
<
|
|
337
|
+
<section>
|
|
338
338
|
{can ? (
|
|
339
|
-
<
|
|
339
|
+
<section>
|
|
340
340
|
<h2>User Management</h2>
|
|
341
341
|
<UserList />
|
|
342
|
-
</
|
|
342
|
+
</section>
|
|
343
343
|
) : (
|
|
344
|
-
<
|
|
344
|
+
<p>You need user management permissions</p>
|
|
345
345
|
)}
|
|
346
|
-
</
|
|
346
|
+
</section>
|
|
347
347
|
);
|
|
348
348
|
}
|
|
349
349
|
|
|
@@ -354,27 +354,27 @@ function CustomPermissionLogic({ userId, organisationId }) {
|
|
|
354
354
|
{ organisationId: organisationId || '' }
|
|
355
355
|
);
|
|
356
356
|
|
|
357
|
-
if (isLoading) return <
|
|
358
|
-
if (error) return <
|
|
357
|
+
if (isLoading) return <p>Loading permissions...</p>;
|
|
358
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
359
359
|
|
|
360
360
|
return (
|
|
361
|
-
<
|
|
361
|
+
<section>
|
|
362
362
|
<h2>Your Permissions</h2>
|
|
363
363
|
{Object.entries(permissions).map(([pageId, operations]) => (
|
|
364
|
-
<
|
|
364
|
+
<p key={pageId}>
|
|
365
365
|
<strong>{pageId}:</strong> {operations.join(', ')}
|
|
366
|
-
</
|
|
366
|
+
</p>
|
|
367
367
|
))}
|
|
368
|
-
</
|
|
368
|
+
</section>
|
|
369
369
|
);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
function AdminPanel() {
|
|
373
|
-
return <
|
|
373
|
+
return <section>Admin Panel Content</section>;
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
function UserList() {
|
|
377
|
-
return <
|
|
377
|
+
return <section>User List</section>;
|
|
378
378
|
}
|
|
379
379
|
```
|
|
380
380
|
|
|
@@ -391,7 +391,7 @@ export default function AdminPage() {
|
|
|
391
391
|
<PermissionGuard
|
|
392
392
|
permission="admin:read"
|
|
393
393
|
scope={{ organisationId: 'org-123' }}
|
|
394
|
-
fallback={<
|
|
394
|
+
fallback={<p>Access Denied</p>}
|
|
395
395
|
>
|
|
396
396
|
<AdminPageContent />
|
|
397
397
|
</PermissionGuard>
|
|
@@ -407,7 +407,7 @@ import { PermissionGuard } from '@jmruthers/pace-core/rbac';
|
|
|
407
407
|
|
|
408
408
|
function UserCard({ user, organisationId }) {
|
|
409
409
|
return (
|
|
410
|
-
<
|
|
410
|
+
<section className="user-card">
|
|
411
411
|
<h3>{user.name}</h3>
|
|
412
412
|
|
|
413
413
|
<PermissionGuard
|
|
@@ -538,7 +538,7 @@ function Navigation({ userId, organisationId }) {
|
|
|
538
538
|
```tsx
|
|
539
539
|
const { selectedOrganisationId } = useUnifiedAuth();
|
|
540
540
|
if (!selectedOrganisationId) {
|
|
541
|
-
return <
|
|
541
|
+
return <p>Please select an organisation first</p>;
|
|
542
542
|
}
|
|
543
543
|
```
|
|
544
544
|
|
|
@@ -622,9 +622,9 @@ function MyComponent() {
|
|
|
622
622
|
'update:users'
|
|
623
623
|
);
|
|
624
624
|
|
|
625
|
-
if (isLoading) return <
|
|
626
|
-
if (error) return <
|
|
627
|
-
if (!can) return <
|
|
625
|
+
if (isLoading) return <p>Checking permissions...</p>;
|
|
626
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
627
|
+
if (!can) return <p>Access denied</p>;
|
|
628
628
|
|
|
629
629
|
return <AdminContent />;
|
|
630
630
|
}
|
|
@@ -818,7 +818,7 @@ function AdaptiveComponent({ appId }) {
|
|
|
818
818
|
loadAppConfig();
|
|
819
819
|
}, [appId]);
|
|
820
820
|
|
|
821
|
-
if (!appConfig) return <
|
|
821
|
+
if (!appConfig) return <p>Loading app configuration...</p>;
|
|
822
822
|
|
|
823
823
|
// Determine required context based on app type
|
|
824
824
|
const scope = appConfig.requires_event
|
package/docs/rbac/performance.md
CHANGED
|
@@ -315,6 +315,6 @@ If performance monitoring isn't showing data:
|
|
|
315
315
|
|
|
316
316
|
- [PagePermissionGuard API Reference](./api-reference.md#pagepermissionguard) - Component API
|
|
317
317
|
- [RBAC Configuration](./api-reference.md#configuration) - Configuration options
|
|
318
|
-
- [Performance
|
|
318
|
+
- [Performance Optimization](../standards/9-operations-standards.md#performance-optimization) - General performance guide
|
|
319
319
|
- [RBAC Getting Started](./getting-started.md) - Getting started guide
|
|
320
320
|
|
package/docs/rbac/quick-start.md
CHANGED
|
@@ -357,15 +357,15 @@ export function Login() {
|
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
return (
|
|
360
|
-
<
|
|
361
|
-
<
|
|
362
|
-
<
|
|
360
|
+
<main className="min-h-screen flex items-center justify-center bg-sec-50">
|
|
361
|
+
<section className="max-w-md w-full space-y-8">
|
|
362
|
+
<section>
|
|
363
363
|
<h2 className="mt-6 text-center text-3xl font-extrabold text-sec-900">
|
|
364
364
|
Sign in to your account
|
|
365
365
|
</h2>
|
|
366
|
-
</
|
|
366
|
+
</section>
|
|
367
367
|
<form className="mt-8 space-y-6" onSubmit={handleLogin}>
|
|
368
|
-
<
|
|
368
|
+
<section>
|
|
369
369
|
<label htmlFor="email" className="sr-only">
|
|
370
370
|
Email address
|
|
371
371
|
</label>
|
|
@@ -379,8 +379,8 @@ export function Login() {
|
|
|
379
379
|
value={email}
|
|
380
380
|
onChange={(e) => setEmail(e.target.value)}
|
|
381
381
|
/>
|
|
382
|
-
</
|
|
383
|
-
<
|
|
382
|
+
</section>
|
|
383
|
+
<section>
|
|
384
384
|
<label htmlFor="password" className="sr-only">
|
|
385
385
|
Password
|
|
386
386
|
</label>
|
|
@@ -394,8 +394,8 @@ export function Login() {
|
|
|
394
394
|
value={password}
|
|
395
395
|
onChange={(e) => setPassword(e.target.value)}
|
|
396
396
|
/>
|
|
397
|
-
</
|
|
398
|
-
<
|
|
397
|
+
</section>
|
|
398
|
+
<section>
|
|
399
399
|
<button
|
|
400
400
|
type="submit"
|
|
401
401
|
disabled={loading}
|
|
@@ -403,10 +403,10 @@ export function Login() {
|
|
|
403
403
|
>
|
|
404
404
|
{loading ? 'Signing in...' : 'Sign in'}
|
|
405
405
|
</button>
|
|
406
|
-
</
|
|
406
|
+
</section>
|
|
407
407
|
</form>
|
|
408
|
-
</
|
|
409
|
-
</
|
|
408
|
+
</section>
|
|
409
|
+
</main>
|
|
410
410
|
)
|
|
411
411
|
}
|
|
412
412
|
```
|
|
@@ -427,18 +427,18 @@ export function Dashboard() {
|
|
|
427
427
|
const { user, selectedOrganisationId } = useUnifiedAuth()
|
|
428
428
|
|
|
429
429
|
if (!user) {
|
|
430
|
-
return <
|
|
430
|
+
return <p>Please log in</p>
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
return (
|
|
434
|
-
<
|
|
434
|
+
<main className="min-h-screen bg-sec-50">
|
|
435
435
|
<nav className="bg-background shadow">
|
|
436
|
-
<
|
|
437
|
-
<
|
|
438
|
-
<
|
|
436
|
+
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
437
|
+
<section className="flex justify-between h-16">
|
|
438
|
+
<section className="flex items-center">
|
|
439
439
|
<h1 className="text-xl font-semibold">Dashboard</h1>
|
|
440
|
-
</
|
|
441
|
-
<
|
|
440
|
+
</section>
|
|
441
|
+
<section className="flex items-center space-x-4">
|
|
442
442
|
<span className="text-sm text-sec-700">
|
|
443
443
|
{user.email} | Org: {selectedOrganisationId}
|
|
444
444
|
</span>
|
|
@@ -448,39 +448,39 @@ export function Dashboard() {
|
|
|
448
448
|
>
|
|
449
449
|
Sign out
|
|
450
450
|
</button>
|
|
451
|
-
</
|
|
452
|
-
</
|
|
453
|
-
</
|
|
451
|
+
</section>
|
|
452
|
+
</section>
|
|
453
|
+
</section>
|
|
454
454
|
</nav>
|
|
455
455
|
|
|
456
456
|
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
|
457
|
-
<
|
|
458
|
-
<
|
|
457
|
+
<section className="px-4 py-6 sm:px-0">
|
|
458
|
+
<section className="border-4 border-dashed border-sec-200 rounded-lg h-96 p-8">
|
|
459
459
|
<h2 className="text-2xl font-bold mb-4">Welcome to your Dashboard</h2>
|
|
460
460
|
|
|
461
461
|
{/* CRITICAL: Use PagePermissionGuard for page-level permissions */}
|
|
462
462
|
<PagePermissionGuard
|
|
463
463
|
pageName="dashboard"
|
|
464
464
|
operation="read"
|
|
465
|
-
fallback={<
|
|
465
|
+
fallback={<p>You don't have permission to view the dashboard</p>}
|
|
466
466
|
>
|
|
467
|
-
<
|
|
467
|
+
<section className="space-y-4">
|
|
468
468
|
<p>You have access to the dashboard!</p>
|
|
469
469
|
|
|
470
|
-
<
|
|
470
|
+
<section className="space-x-4">
|
|
471
471
|
<Link
|
|
472
472
|
to="/users"
|
|
473
473
|
className="bg-main-500 text-main-50 px-4 py-2 rounded hover:bg-main-600"
|
|
474
474
|
>
|
|
475
475
|
View Users
|
|
476
476
|
</Link>
|
|
477
|
-
</
|
|
478
|
-
</
|
|
477
|
+
</section>
|
|
478
|
+
</section>
|
|
479
479
|
</PagePermissionGuard>
|
|
480
|
-
</
|
|
481
|
-
</
|
|
480
|
+
</section>
|
|
481
|
+
</section>
|
|
482
482
|
</main>
|
|
483
|
-
</
|
|
483
|
+
</main>
|
|
484
484
|
)
|
|
485
485
|
}
|
|
486
486
|
```
|
|
@@ -501,21 +501,21 @@ export function Users() {
|
|
|
501
501
|
const { user, selectedOrganisationId } = useUnifiedAuth()
|
|
502
502
|
|
|
503
503
|
if (!user) {
|
|
504
|
-
return <
|
|
504
|
+
return <p>Please log in</p>
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
return (
|
|
508
|
-
<
|
|
508
|
+
<main className="min-h-screen bg-sec-50">
|
|
509
509
|
<nav className="bg-background shadow">
|
|
510
|
-
<
|
|
511
|
-
<
|
|
512
|
-
<
|
|
510
|
+
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
511
|
+
<section className="flex justify-between h-16">
|
|
512
|
+
<section className="flex items-center">
|
|
513
513
|
<Link to="/" className="text-main-600 hover:text-main-800 mr-4">
|
|
514
514
|
← Back to Dashboard
|
|
515
515
|
</Link>
|
|
516
516
|
<h1 className="text-xl font-semibold">Users</h1>
|
|
517
|
-
</
|
|
518
|
-
<
|
|
517
|
+
</section>
|
|
518
|
+
<section className="flex items-center space-x-4">
|
|
519
519
|
<span className="text-sm text-sec-700">
|
|
520
520
|
{user.email} | Org: {selectedOrganisationId}
|
|
521
521
|
</span>
|
|
@@ -525,35 +525,35 @@ export function Users() {
|
|
|
525
525
|
>
|
|
526
526
|
Sign out
|
|
527
527
|
</button>
|
|
528
|
-
</
|
|
529
|
-
</
|
|
530
|
-
</
|
|
528
|
+
</section>
|
|
529
|
+
</section>
|
|
530
|
+
</section>
|
|
531
531
|
</nav>
|
|
532
532
|
|
|
533
533
|
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
|
534
|
-
<
|
|
535
|
-
<
|
|
534
|
+
<section className="px-4 py-6 sm:px-0">
|
|
535
|
+
<section className="border-4 border-dashed border-sec-200 rounded-lg h-96 p-8">
|
|
536
536
|
<h2 className="text-2xl font-bold mb-4">User Management</h2>
|
|
537
537
|
|
|
538
538
|
{/* CRITICAL: Use PagePermissionGuard for page-level permissions */}
|
|
539
539
|
<PagePermissionGuard
|
|
540
540
|
pageName="users"
|
|
541
541
|
operation="read"
|
|
542
|
-
fallback={<
|
|
542
|
+
fallback={<p>You don't have permission to view users</p>}
|
|
543
543
|
>
|
|
544
|
-
<
|
|
544
|
+
<section className="space-y-4">
|
|
545
545
|
<p>You have access to the users page!</p>
|
|
546
546
|
<p>This means your RBAC system is working correctly.</p>
|
|
547
547
|
|
|
548
|
-
<
|
|
548
|
+
<section className="bg-main-100 border border-main-400 text-main-700 px-4 py-3 rounded">
|
|
549
549
|
<strong>Success!</strong> Your RBAC setup is working correctly.
|
|
550
|
-
</
|
|
551
|
-
</
|
|
550
|
+
</section>
|
|
551
|
+
</section>
|
|
552
552
|
</PagePermissionGuard>
|
|
553
|
-
</
|
|
554
|
-
</
|
|
553
|
+
</section>
|
|
554
|
+
</section>
|
|
555
555
|
</main>
|
|
556
|
-
</
|
|
556
|
+
</main>
|
|
557
557
|
)
|
|
558
558
|
}
|
|
559
559
|
```
|
package/docs/security/README.md
CHANGED
|
@@ -126,14 +126,14 @@ function ProtectedComponent() {
|
|
|
126
126
|
const { user, session, isLoading } = useUnifiedAuth();
|
|
127
127
|
|
|
128
128
|
if (isLoading) {
|
|
129
|
-
return <
|
|
129
|
+
return <p>Loading...</p>;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
if (!user || !session) {
|
|
133
|
-
return <
|
|
133
|
+
return <p>Please log in</p>;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
return <
|
|
136
|
+
return <p>Welcome, {user.email}!</p>;
|
|
137
137
|
}
|
|
138
138
|
```
|
|
139
139
|
|
|
@@ -672,9 +672,9 @@ test('hides content when user lacks permission', () => {
|
|
|
672
672
|
<PermissionEnforcer
|
|
673
673
|
operation="read"
|
|
674
674
|
resource="users"
|
|
675
|
-
fallback={<
|
|
675
|
+
fallback={<p>Access denied</p>}
|
|
676
676
|
>
|
|
677
|
-
<
|
|
677
|
+
<section>User data</section>
|
|
678
678
|
</PermissionEnforcer>
|
|
679
679
|
);
|
|
680
680
|
|