[dev] [Marfuen] mariano/fix-custom-framework-control-scoping#2923
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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>
There was a problem hiding this comment.
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
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>
There was a problem hiding this comment.
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
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>
|
@cubic-dev-ai re-review this |
@Marfuen I have started the AI code review. It will take a few minutes to complete. |
- 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>
There was a problem hiding this comment.
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
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>
|
@cubic-dev-ai re-review this |
@Marfuen I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
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.tsandapps/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
| distinct: ['frameworkInstanceId'], | ||
| }); | ||
| if (customFiIds.length > 0) { | ||
| await db.frameworkControlDocumentTypeLink.deleteMany({ |
There was a problem hiding this comment.
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>
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>
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.
findAll, drop tasks with no controls and dedupe with direct tasks first to avoid shadowing.frameworkControlFamiliesper framework instance in findAll, findOne, and findRequirement so controls show the correct family.syncDirectLinksToCustomFrameworksmirrors direct policy/task/doc links when linking withoutframeworkInstanceId, when linking controls to a requirement, and on control create when mapped to custom requirements.syncDirectLinksToCustomFrameworkswhen org has no custom frameworks.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