fix(config): reconcile config-policy ownership with the Assignments tab - #2107
Merged
ToddHebebrand merged 1 commit intoJul 1, 2026
Merged
Conversation
The create-page "Apply to" owner picker (#2064) collided with the Assignments tab: both surfaced a "partner-wide / all orgs" choice for two different axes — ownership (org_id XOR partner_id, set at create) and assignment (what resolveEffectiveConfig actually reads). The picker applied nothing (zero assignments seeded), the tab was blind to ownership, and the org-owned + partner-level combo was a silent no-op. Make ownership the single source of truth and the tab ownership-aware: - crud.ts: creating a partner-owned policy auto-seeds the matching partner-level assignment so "All organizations" applies immediately. Non-unique seed failure rolls back the orphan and surfaces the error (logged with the policy id); unique violations are tolerated. - configurationPolicy.ts: validateAssignmentTarget now rejects org-owned policies at the partner level (was a silent no-op footgun). - AssignmentsTab.tsx: partner-owned shows a banner + re-assign card only when unassigned; org-owned drops the Partner-Wide level option. Guards against a null orgId in the site/group target fetch. - ConfigPolicyDetailPage.tsx: PolicyDetail carries partnerId (orgId now nullable); passed to the tab. - ConfigPolicyCreatePage.tsx: "Apply to" -> "Scope"; clarified helper text. - aiToolsConfigPolicy.ts: documented the partner-level constraint. Tests: validateAssignmentTarget ownership gating, auto-assign swallow/rollback paths, org-owned + partner re-assign POST bodies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying breeze with
|
| Latest commit: |
49284b0
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://23fdf8fd.breeze-9te.pages.dev |
| Branch Preview URL: | https://toddhebebrand-config-policy.breeze-9te.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The create-page "Apply to" owner picker (#2064) collided with the Assignments tab. Both surfaced a "partner-wide / all orgs" choice, but they control two independent axes:
configuration_policies.org_idXORpartner_id(DB CHECK), set once at create. The eligibility universe.config_policy_assignmentsrows, whatresolveEffectiveConfigactually reads.Three concrete breakages:
orgId=nullfor partner-owned policies (breaking target lookups) and offered all 5 levels regardless.Fix — ownership is the single source of truth; the tab is ownership-aware
crud.ts— creating a partner-owned policy auto-seeds the matching partner-level assignment, so "All organizations" applies immediately. The two inserts aren't transactional, so a non-unique seed failure rolls back the orphan and surfaces the error (logged with the policy id) rather than leaving a committed-but-unassigned policy; unique violations are tolerated.configurationPolicy.ts—validateAssignmentTargetnow rejects org-owned policies at the Partner level with an actionable message.AssignmentsTab.tsx— partner-owned shows a banner + a re-assign card only when unassigned; org-owned drops the Partner-Wide level option. Guards against a nullorgIdin the site/group target fetch.ConfigPolicyDetailPage.tsx—PolicyDetailcarriespartnerId(orgIdnow nullable), passed to the tab.ConfigPolicyCreatePage.tsx— relabeled "Apply to" → "Scope"; clarified helper text.aiToolsConfigPolicy.ts— documented the partner-level constraint in the tool description.Tests
configurationPolicy.validateAssignment.test.ts— ownership gating (all four combinations), asserting the illegal combos short-circuit before any DB query.crud.test.ts— partner auto-assign, org-owned does-not-auto-assign, unique-swallow (still 201), non-unique-rollback (500 +deleteConfigPolicycalled).AssignmentsTab.test.tsx— partner banner/no-picker, re-assign POST body (level + priority + role/OS filters, notargetId), card hiding, org-owned level list excludespartner, org-owned assign POST includestargetId.Verification
astro check0 errors · APItscclean · eslint clean (both apps) · API 94 config-policy tests + web 14 component tests green.This is a follow-up to #2064. Reviewed via the pr-review-toolkit (code / tests / silent-failure / comments / types); all surfaced findings were addressed in this branch.
🤖 Generated with Claude Code