Skip to content

ENG-3160: BE - Access policy agent chat (types + prompt explorer)#7992

Open
thabofletcher wants to merge 39 commits intomainfrom
ENG-3160-BE-access-policy-chat
Open

ENG-3160: BE - Access policy agent chat (types + prompt explorer)#7992
thabofletcher wants to merge 39 commits intomainfrom
ENG-3160-BE-access-policy-chat

Conversation

@thabofletcher
Copy link
Copy Markdown
Contributor

@thabofletcher thabofletcher commented Apr 21, 2026

Ticket ENG-3160

Description Of Changes

Backend support changes for the access policy agent chat feature. This PR adds the TypeScript types needed by the UI, wires the agent chat RTK Query slice, fixes save/edit error handling, and extends the prompt explorer developer tool to support the new chat prompt.

To test with the fidesplus APIs required, use this branch
https://github.com/ethyca/fidesplus/pull/3447

Code Changes

Types

  • Add AccessPoliciesApplicationConfig TypeScript type with agent_enabled field
  • Wire AccessPoliciesApplicationConfig into PlusApplicationConfig
  • Export type from types/api/index.ts

Agent chat wiring

  • agent-chat.slice.ts — RTK Query mutation for POST /plus/access-policy/agent
  • mocks/access-policies/agent-chat-handlers.ts — MSW handler for local dev / tests

Error handling

  • helpers.ts — fix getErrorMessage to read from error.data.detail (FastAPI wraps validation errors one level deeper than previously assumed)
  • pages/access-policies/new/ and edit/[id]/ — fix RTK .unwrap() error cast so save/delete failures show the real message instead of "An unexpected error occurred"

Prompt explorer

  • Add ACCESS_POLICY_CHAT prompt type and ACCESS_POLICIES category to prompt explorer types
  • Add agentPrompt / currentPolicyYaml editable inputs to QuestionnaireControls for the chat prompt type
  • Extend buildQuestionnaireVariables to handle access_policy_chat
  • Add Access Policies category to the prompt explorer filter

Single-control refactor (merge conflict resolution)

  • AccessPolicyEditor.tsx, policy-yaml.ts, PolicyNode.tsx — resolved conflicts from the controls → single control refactor on main; updated tests accordingly

Steps to Confirm

  1. Enable the feature flag: FIDESPLUS__ACCESS_POLICIES__AGENT_ENABLED=true
  2. Navigate to Access Policies → open or create a policy — chat panel should appear on the right
  3. Save a policy — errors (if any) should show the real validation message, not "An unexpected error occurred"
  4. In the prompt explorer (/poc/prompt-explorer), select "Access Policy Agent Chat" — editable User Prompt and Current Policy YAML fields should appear before clicking Render Prompt

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:
    • No UX review needed
  • Followup issues:
    • No followup issues
  • Database migrations:
    • No migrations
  • Documentation:
    • No documentation updates required

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 21, 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 Apr 23, 2026 9:43pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored Apr 23, 2026 9:43pm

Request Review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 22, 2026

Title Lines Statements Branches Functions
admin-ui Coverage: 8%
6.33% (2799/44172) 5.57% (1398/25093) 4.43% (579/13061)
fides-js Coverage: 78%
78.98% (1962/2484) 65.55% (1214/1852) 72.57% (336/463)
privacy-center Coverage: 88%
85.97% (331/385) 81.36% (179/220) 78.87% (56/71)

@thabofletcher thabofletcher force-pushed the ENG-3160-BE-access-policy-chat branch from c02560e to 698134e Compare April 22, 2026 18:34
@thabofletcher thabofletcher marked this pull request as ready for review April 22, 2026 18:39
@thabofletcher thabofletcher requested a review from a team as a code owner April 22, 2026 18:39
@thabofletcher thabofletcher requested review from jpople and removed request for a team April 22, 2026 18:39
@ant-design/x bundles refractor (and react-syntax-highlighter) which
ship as ESM-only packages. Jest's CJS transform config can't handle
them without a full transform exception chain. Instead, mock @ant-design/x
entirely in unit tests — Bubble/Sender are not exercised there anyway.
Change `*/api/v1/plus/llm/access-policy-chat` to `*/api/v1/plus/access-policy/agent`
to match the endpoint defined in the route.
@thabofletcher
Copy link
Copy Markdown
Contributor Author

/code-review

Copy link
Copy Markdown
Contributor

@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: PR #7992 — BE - Access policy agent chat (types + prompt explorer)

Overall this is a clean, focused change — the URL fix is correct and the new prompt-explorer wiring works logically. Two themes run through most of the findings:

1. Enum members vs. raw strings (all files)

The PR defines PromptCategory.ACCESS_POLICIES and PromptType.ACCESS_POLICY_CHAT in types.ts, then doesn't use them for any of the comparisons it adds. Every new conditional (=== "access_policy_chat", === "access_policies", === "questionnaire") should use the corresponding enum member. See inline comments on utils.ts:68, QuestionnaireControls.tsx:75, prompt-explorer.tsx:175, and prompt-explorer.tsx:321.

2. Generated enum divergence

types/api/models/PromptCategory.ts and PromptType.ts (auto-generated) do not include the new ACCESS_POLICIES / ACCESS_POLICY_CHAT values. The comment in types.ts notes these are "hardcoded until openapi:generate properly generates them," which is an acceptable short-term workaround — but it's worth tracking. If any code path uses the generated enums for comparison (e.g., via PromptInfo.category from the API response), those checks will silently miss the new values. The fix is to re-run npm run openapi:generate once the backend OpenAPI spec includes the new enum members.

3. QuestionnaireControls scope creep

The component now handles two unrelated prompt categories under one name and interface. The 4 new props are irrelevant to all non-access-policy paths. See inline comment on QuestionnaireControls.tsx:265 for a grouping option that keeps the interface manageable without a full refactor.

Minor

  • Default agentPrompt state vs. placeholder text duplication (see inline on prompt-explorer.tsx:82) — nit for a dev-tool page.

🔬 Codegraph: connected (47303 nodes)


💡 Write /code-review in a comment to re-run this review.

Comment thread clients/admin-ui/src/features/prompt-explorer/utils.ts
Comment thread clients/admin-ui/src/pages/poc/prompt-explorer.tsx
Comment thread clients/admin-ui/src/pages/poc/prompt-explorer.tsx Outdated
Comment thread clients/admin-ui/src/pages/poc/prompt-explorer.tsx
The backend uses control (singular string) but the frontend had controls
(plural array) throughout. This caused 422s on create/update because
extra="forbid" on the request schema rejected the unknown field.

- Rename AccessPolicy.controls to control throughout
- Map SidebarFormValues.controls[0] to control in save handlers
- Fix list filtering, grouping, and table column to use control
- Fix MSW mock data to match

Note: AccessPolicyYaml.controls (the YAML content field) remains a list
— that is a separate concept from the API metadata field.
Base automatically changed from ENG-2959-FE-Astralis-agent-chat-for-policy-building to main April 23, 2026 15:19
The API contract uses `control: str | None` (singular) but the canvas
editor's internal data model was still `controls: string[]` everywhere.
This renames the field end-to-end so the save path no longer needs the
`controls?.[0]` workaround and the PolicyNode Select is single-select.

YAML documents still emit `controls: [value]` (list) per the schema.
…errors

Changes the "Controls" label to "Control" to match the single-select model,
and adds handling for structured { message, errors } API responses so save
failures show an actionable message instead of the generic fallback.
.unwrap() throws the FetchBaseQueryError directly, not wrapped in
{ error: ... }. The cast was accessing .error on undefined, causing
every save failure to show the generic fallback message.
The backend wraps structured errors as { detail: { message, errors } },
so the check needs to inspect error.data.detail, not error.data directly.
- Resolve add/add conflicts in agent-chat.slice.ts and agent-chat-handlers.ts
  keeping the correct /plus/access-policy/agent URL
- Resolve content conflict in AccessPolicyEditor.tsx keeping single-control refactor
- Replace raw string literals with PromptCategory/PromptType enum members
  in utils.ts, QuestionnaireControls.tsx, and prompt-explorer.tsx
- Use empty string default for agentPrompt state (placeholder is sufficient)
…changelog

- Fix prettier formatting in PoliciesTable.tsx and useAccessPolicyGroups.ts
  introduced by merge from main
- Import PromptCategory directly from types.ts instead of the slice
  (re-exported as `export type` making it unusable as a value)
- Add changelog entry for PR 7992
PolicyNodeData.control changed from controls: string[] to control?: string.
Update yamlToNodesAndEdges test to assert on the singular field and value,
and update nodesToYaml test to pass control (string) in node data instead
of the old controls (array) shape.
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.

2 participants