Skip to content

ENG-2943: PBAC Dashboard#7640

Merged
kruulik merged 86 commits intomainfrom
access-control-summary-dashboard
Mar 24, 2026
Merged

ENG-2943: PBAC Dashboard#7640
kruulik merged 86 commits intomainfrom
access-control-summary-dashboard

Conversation

@kruulik
Copy link
Copy Markdown
Contributor

@kruulik kruulik commented Mar 12, 2026

Ticket [ENG-2943]

Description Of Changes

Adds the PBAC (Policy-Based Access Control) summary dashboard with violation charts, data consumer rankings, faceted search, and a drill-down violation log.

Dashboard layout:

  • Violations over time — area/bar chart with line/bar toggle, trend statistic
  • Violation rate — donut chart showing violation percentage of total requests
  • Data consumers — top 5 consumers ranked by violation count

Table tabs:

  • Summary tab — paginated findings table (policy × control aggregates); clicking a row applies facet filters and switches to the log tab
  • Log tab — cursor-paginated violation logs with infinite scroll and IntersectionObserver; clicking a row opens a detail drawer

Filters & navigation:

  • Faceted search input (consumer, policy, dataset, data use, control) synced to URL query params
  • Date range picker
  • Violation detail drawer with SQL statement viewer, policy info, and AI-generated violation reason

Code Changes

New feature files (src/features/access-control/):

  • access-control.slice.ts — RTK Query slice with 7 endpoints injected into baseApi
  • types.ts — TypeScript interfaces for all API response shapes
  • trendUtils.ts — shared trend prefix/color helpers
  • AccessControlTableTabs.tsx — tab container managing summary ↔ log switching and detail drawer
  • ViolationsChartCard.tsx — area/bar chart card with line/bar toggle
  • ViolationRateCard.tsx — donut chart violation rate card
  • DataConsumersCard.tsx — top consumers mini-table
  • FindingsTable.tsx — paginated policy violations summary table
  • RequestLogTable.tsx — infinite-scroll violation log table
  • ViolationDetailDrawer.tsx — side drawer with violation details and SQL viewer
  • FacetedSearchInput.tsx — multi-select grouped search input
  • requestLogColumns.tsx / violationsColumns.tsx — column definitions
  • hooks/useRequestLogFilters.ts — filter state context (date range, facets, URL sync)
  • hooks/useInfiniteViolationLogs.ts — cursor pagination accumulator with live-tail polling

Modified files:

  • src/features/common/api.slice.ts — added "Access Control" tag type
  • src/features/common/nav/routes.ts — removed unused sub-route constants
  • src/pages/data-discovery/access-control/index.tsx — replaced placeholder with full dashboard
  • Deleted summary/index.tsx and request-log/index.tsx (flattened into single page)

fidesui tweaks:

  • ChartText.tsx — added maxLines={1} to prevent label overflow
  • chart-constants.ts — widened LABEL_WIDTH from 110 → 120

Steps to Confirm

  1. Run npm run dev from clients/admin-ui/ with a local backend
  2. Navigate to /data-discovery/access-control
  3. Verify the three summary cards render (violations chart, violation rate, data consumers)
  4. Toggle between Line and Bar chart modes
  5. Use the faceted search to filter by consumer, policy, etc.
  6. Change the date range and confirm cards/tables update
  7. Click a row in the Summary tab — confirm it applies facets and switches to Log tab
  8. Click a row in the Log tab — confirm the detail drawer opens with violation info
  9. Scroll to the bottom of the Log tab — confirm infinite scroll loads more rows

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
  • Followup issues:
    • No followup issues
  • Database migrations:
    • No migrations
  • Documentation:
    • No documentation updates required

Add RTK Query slice, MSW mock handlers, and three summary cards
(violations over time chart, violation rate, top data consumers)
with time range toggle for the access control summary page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fides-plus-nightly Ready Ready Preview, Comment Mar 24, 2026 9:18pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored Mar 24, 2026 9:18pm

Request Review

@kruulik kruulik changed the title Add access control summary dashboard ENG-2943: Add Access Control Summary Dashboard cards and data layer Mar 12, 2026
kruulik and others added 2 commits March 12, 2026 14:28
@kruulik kruulik marked this pull request as ready for review March 12, 2026 18:32
@kruulik kruulik requested a review from a team as a code owner March 12, 2026 18:32
@kruulik kruulik requested review from galvana, gilluminate and lucanovera and removed request for a team and gilluminate March 12, 2026 18:32
@greptile-apps

This comment was marked as outdated.

kruulik and others added 7 commits March 13, 2026 00:01
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kruulik kruulik changed the title [DEMO] ENG-2943: Add Access Control Summary and Logs ENG-2943: Add Access Control Summary and Logs Mar 24, 2026
@kruulik kruulik changed the title ENG-2943: Add Access Control Summary and Logs ENG-2943: PBAC Dashboard Mar 24, 2026
return 80;
}
const lineCount = (violation.sql_statement ?? "").split("\n").length;
return Math.max(80, lineCount * 18 + 42);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somewhat arbitrary sizing/nudging

@kruulik kruulik marked this pull request as ready for review March 24, 2026 19:56
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: ENG-2943 PBAC Dashboard

Good overall structure — the feature is well-decomposed into small, single-purpose components and the RTK Query slice is clean. A few issues worth addressing before merge:

Critical (Must Fix)

router.query read in lazy initializer may be empty on first render (useRequestLogFilters.ts, line 65–73)
In Next.js, router.query is not populated until after hydration. The lazy useState initializer runs synchronously on first render, where router.query is {}, so URL-encoded facets from a direct link or page refresh will be silently dropped. See inline comment for the fix.

Suggestions

Dual URL mutation systems (useRequestLogFilters.ts, line 97)
applyFacets uses window.history.replaceState while the useEffect sync uses router.replace. The skipUrlSyncRef flag is the glue holding this together, but it's fragile — any missed skipUrlSyncRef.current = true set causes a double-update. Consolidating to a single navigation method would eliminate the coordination overhead entirely.

Live tail doesn't reset cursor (useInfiniteViolationLogs.ts, line 32)
When a user has scrolled down (cursor is set) and then enables live tail, the polling re-fetches the same mid-list page rather than the newest violations. The cursor should be reset to null when live tail becomes active.

Timestamp formatted via string slicing (ViolationDetailDrawer.tsx, line 113–114)
.toISOString().slice(0, 10) / .slice(11, 19) is fragile if the string shape ever changes and doesn't respect locale. date-fns format() is already in the project.

skip option missing on useGetFiltersQuery (index.tsx)
When the feature flag is off, useGetFiltersQuery still fires because hooks must be called unconditionally. Passing skip: !flags.alphaPurposeBasedAccessControl prevents the unnecessary network request.

Nice to Have

Row key separator collision (FindingsTable.tsx, line 43)
${policy}-${control} can theoretically collide if either value contains a hyphen. Using :: as the separator is safer.

Disabled footer buttons (ViolationDetailDrawer.tsx, lines 59–62)
"Edit policy" and "Create new policy" are always disabled. A brief TODO comment would make it clear this is intentional placeholder UI rather than a bug.

@gilluminate
Copy link
Copy Markdown
Contributor

Not sure what's supposed to be going on with the search, but I see a bunch of what look like suggestions that can't be clicked
image

- Fix router.query hydration: use useEffect with router.isReady instead of lazy useState
- Remove live tail feature entirely (liveTail state, polling, LIVE_TAIL_POLL_MS)
- Skip useGetFiltersQuery when alphaPurposeBasedAccessControl flag is off

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DataConsumersCard: use Row/Col with wrap={false}, add Dividers, request size=5 server-side
- ViolationDetailDrawer: remove redundant width, use PageSpinner
- ChartText: accept width prop to prevent label wrapping
- access-control.slice: add size param to ConsumersByViolationsParams

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kruulik
Copy link
Copy Markdown
Contributor Author

kruulik commented Mar 24, 2026

@gilluminate hm I should handle the empty data state for the faceted search.

Copy link
Copy Markdown
Contributor

@gilluminate gilluminate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it!

@kruulik kruulik added this pull request to the merge queue Mar 24, 2026
Merged via the queue into main with commit 88dfdcc Mar 24, 2026
46 of 49 checks passed
@kruulik kruulik deleted the access-control-summary-dashboard branch March 24, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants