Skip to content

[dev] [Marfuen] mariano/fix-custom-framework-control-scoping#2923

Merged
Marfuen merged 10 commits into
mainfrom
mariano/fix-custom-framework-control-scoping
May 26, 2026
Merged

[dev] [Marfuen] mariano/fix-custom-framework-control-scoping#2923
Marfuen merged 10 commits into
mainfrom
mariano/fix-custom-framework-control-scoping

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 25, 2026

This is an automated pull request to merge mariano/fix-custom-framework-control-scoping into dev.
It was created by the [Auto Pull Request] action.


Summary by cubic

Fixes control scoping for custom frameworks by merging direct and framework-scoped links and syncing them on writes, with transactional, guarded cleanup. Also corrects task aggregation to prioritize direct links and avoid empty-control entries, keeping compliance scores accurate.

  • Bug Fixes
    • Reads (custom frameworks): merge direct + framework-scoped policies/tasks/doc types across control detail, frameworks list/findAll, and requirement views; filter archived; dedupe by id/formType; preserve “not relevant” flags; include direct tasks; in findAll, drop tasks with no controls and dedupe with direct tasks first to avoid shadowing.
    • controlFamily support: extract frameworkControlFamilies per framework instance in findAll, findOne, and findRequirement so controls show the correct family.
    • Writes (custom frameworks): syncDirectLinksToCustomFrameworks mirrors direct policy/task/doc links when linking without frameworkInstanceId, when linking controls to a requirement, and on control create when mapped to custom requirements.
    • Unlink cleanup: on direct policy unlink, cascade-delete matching framework-scoped policy links for custom FIs only if a direct link existed; on direct doc unlink, delete framework-scoped doc links only if a direct link was removed; both cascades run in a single transaction to prevent partial state.
    • Performance: early exit in syncDirectLinksToCustomFrameworks when org has no custom frameworks.
    • Utilities/Tests: added deduplicateBy (deduplicateById, deduplicateByFormType) and tests for merge + sync + built-in vs custom handling.

Written for commit aa349ab. Summary will update on new commits. Review in cubic

Custom frameworks never populate FrameworkControlPolicyLink/TaskLink
junction tables, so findOneForFramework returned empty policies/tasks.
Now merges both framework-scoped and direct relationships with dedup.

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

vercel Bot commented May 25, 2026

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

Project Deployment Actions Updated (UTC)
comp-framework-editor Ready Ready Preview, Comment May 26, 2026 1:50pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped May 26, 2026 1:50pm
portal Skipped Skipped May 26, 2026 1:50pm

Request Review

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

Avoids regression for built-in frameworks where framework-scoped links
are intentionally per-framework. Also applies the same fix to
findRequirement() in frameworks service for list/detail consistency.
Extracts deduplicateById to shared util.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ameworks

Write side: syncDirectLinksToCustomFrameworks mirrors direct policy/task/
document links into framework-scoped junction tables for all custom FIs
using a control. Called from linkPolicies/linkTasks/linkDocumentTypes
(no frameworkInstanceId) and linkControlsToRequirement (custom FI).

Read side: all 4 read paths (findOneForFramework, findOne, findAll,
findRequirement) fall back to direct relationships for custom frameworks,
covering existing data without a migration.

Extracts mergeControlLinks helper to deduplicate mapping logic between
findOne and findRequirement. Collapses deduplicateById/deduplicateByFormType
into a generic deduplicateBy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avoids the requirementMap query on every direct-link operation for
orgs that don't use custom frameworks (vast majority of traffic).

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/controls/controls.service.ts
@vercel vercel Bot temporarily deployed to Preview – app May 25, 2026 16:35 Inactive
@vercel vercel Bot temporarily deployed to Preview – portal May 25, 2026 16:35 Inactive
When unlinking a direct ControlDocumentType, also delete the
corresponding FrameworkControlDocumentTypeLink rows for custom
framework instances. Prevents stale evidence showing up in custom
framework views after the direct link is removed.

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/controls/controls.service.ts Outdated
Skip framework-scoped cleanup if deleteMany removed 0 direct rows,
preventing deletion of explicitly-scoped custom framework links.

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

Marfuen commented May 25, 2026

@cubic-dev-ai re-review this

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 25, 2026

@cubic-dev-ai re-review this

@Marfuen I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

- removePolicyControl: cascade-delete framework-scoped policy links
  for custom FIs when disconnecting a policy from a control
- findAll: add custom framework fallback for policies, documents, and
  tasks so dashboard compliance scores are correct
- create: sync framework-scoped links within the creation transaction
  when the control is mapped to custom framework requirements

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/frameworks/frameworks.service.ts Outdated
Comment thread apps/api/src/policies/policies.controller.ts Outdated
Marfuen and others added 2 commits May 25, 2026 13:02
Integrates controlFamily support into all custom framework read paths:
findAll, findOne, and findRequirement now extract frameworkControlFamilies
alongside the existing mergeControlLinks pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- removePolicyControl: check link exists before cascading framework-
  scoped cleanup, preventing deletion of explicitly-scoped links
- findAll: filter empty-controls tasks before dedup and prioritize
  direct tasks, so custom framework tasks aren't dropped by
  empty framework-scoped entries shadowing valid direct entries

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – app May 25, 2026 17:05 Inactive
@vercel vercel Bot temporarily deployed to Preview – portal May 25, 2026 17:05 Inactive
@Marfuen
Copy link
Copy Markdown
Contributor

Marfuen commented May 25, 2026

@cubic-dev-ai re-review this

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 25, 2026

@cubic-dev-ai re-review this

@Marfuen I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 7 files

Confidence score: 3/5

  • There is some meaningful merge risk: both findings are medium severity (6/10) with high confidence, and they affect unlink/write behavior in core API flows rather than just internal refactoring.
  • In apps/api/src/policies/policies.controller.ts, related writes are not transactional, so cleanup failures can leave partially applied unlink state and create data consistency/regression risk for users.
  • In apps/api/src/controls/controls.service.ts, direct doc-type unlink cleanup is not source-aware and may delete explicitly scoped custom framework links, which can remove associations more broadly than intended.
  • Pay close attention to apps/api/src/policies/policies.controller.ts and apps/api/src/controls/controls.service.ts - transactional safety and source-aware unlink cleanup need validation.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/api/src/controls/controls.service.ts">

<violation number="1" location="apps/api/src/controls/controls.service.ts:875">
P2: Direct doc-type unlink now deletes all matching custom framework-scoped links, including explicitly scoped ones, because cleanup is not source-aware.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/policies/policies.controller.ts Outdated
distinct: ['frameworkInstanceId'],
});
if (customFiIds.length > 0) {
await db.frameworkControlDocumentTypeLink.deleteMany({
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 25, 2026

Choose a reason for hiding this comment

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

P2: Direct doc-type unlink now deletes all matching custom framework-scoped links, including explicitly scoped ones, because cleanup is not source-aware.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/api/src/controls/controls.service.ts, line 875:

<comment>Direct doc-type unlink now deletes all matching custom framework-scoped links, including explicitly scoped ones, because cleanup is not source-aware.</comment>

<file context>
@@ -827,9 +855,33 @@ export class ControlsService {
+      distinct: ['frameworkInstanceId'],
+    });
+    if (customFiIds.length > 0) {
+      await db.frameworkControlDocumentTypeLink.deleteMany({
+        where: {
+          controlId,
</file context>
Fix with Cubic

Both removePolicyControl and unlinkDocumentType now run their
direct-link removal and framework-scoped cleanup in a single
transaction, preventing partial state on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – portal May 26, 2026 13:49 Inactive
@vercel vercel Bot temporarily deployed to Preview – app May 26, 2026 13:49 Inactive
@Marfuen Marfuen merged commit a32ec37 into main May 26, 2026
11 checks passed
@Marfuen Marfuen deleted the mariano/fix-custom-framework-control-scoping branch May 26, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant