Conversation
…points - Implemented new API endpoints for creating custom frameworks and requirements in the FrameworksController. - Added DTOs for CreateCustomFrameworkDto, CreateCustomRequirementDto, LinkRequirementsDto, and LinkControlsDto. - Enhanced findAvailable method to filter frameworks by organization ID. - Introduced client components for adding and linking requirements, including AddCustomRequirementSheet and LinkRequirementSheet. - Updated FrameworkOverview to include new actions for managing custom requirements. - Added UI components for creating custom frameworks and linking existing controls. This update enhances the framework management capabilities, allowing users to create and manage custom frameworks and their associated requirements effectively.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ts to controls - Implemented new API endpoints in ControlsController for linking existing policies, tasks, and requirements to a control. - Added corresponding DTOs: LinkPoliciesDto, LinkTasksDto, and LinkRequirementsToControlDto. - Enhanced ControlsService with methods to handle linking logic and validation. - Updated UI components to support linking actions, including LinkPolicySheet, LinkTaskSheet, and LinkRequirementForControlSheet. - Improved data fetching with useControlOptions hook for better management of linked items. This update enhances the control management capabilities, allowing users to effectively link existing resources to controls.
…tables Previously the branch added a nullable organizationId column to the platform FrameworkEditorFramework / FrameworkEditorRequirement tables so a single row was either platform (null) or org-custom (set). That hybrid shape mismatched the template/instance pattern used everywhere else in the codebase and caused two cross-tenant reads (frameworks.service.findOne, findRequirement) to leak one org's custom requirements to another org on the same framework. Move the org-custom data into dedicated CustomFramework / CustomRequirement tables. FrameworkInstance.frameworkId and RequirementMap.requirementId become nullable and gain customFrameworkId / customRequirementId siblings with DB CHECK constraints enforcing exactly one of the two is set. The editor tables are pure platform definitions again, so the leaks vanish structurally (no shared table to filter) rather than relying on filter discipline in each read. - Schema: revert organizationId from FrameworkEditor tables; add CustomFramework + CustomRequirement; relax/branch FrameworkInstance and RequirementMap FKs with CHECK constraints - Migration: move existing per-org rows into the new tables, repoint FKs, drop the old columns - API: rewrite FrameworksService findOne / findRequirement / createCustom / createRequirement / linkRequirements / linkControlsToRequirement / findAvailable to branch on platform vs custom. Update ControlsService create + linkRequirements + DTOs to accept customRequirementId (with exactly-one validation) and persist documentTypes in the same transaction - Frontend: plumb isCustom through the requirement/control sheets, widen FrameworkInstanceWithControls / FrameworkInstanceForTasks to surface customFramework, and fix all fw.framework.* null-unsafe reads - Tests: frameworks.service.spec regression coverage that a custom FI never reads from frameworkEditorRequirement and a platform FI never reads from customRequirement Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the per-request console.log in the requirement page that was dumping internal API status/error payloads into server logs - Return result.count from createMany in linkRequirements, linkControlsToRequirement, and linkDocumentTypes so skipDuplicates-skipped rows no longer inflate the reported count Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
controls.service.create() accepted policyIds, taskIds, and requirementMappings
(frameworkInstanceId, requirementId, customRequirementId) without verifying
they belong to the caller's organization. Prisma FKs only check existence,
not tenancy, so a user with control:create in org A could submit a
frameworkInstanceId from org B — the resulting RequirementMap would join the
attacker's control to the victim's framework, persistently rendering attacker
content inside org B's compliance UI via FrameworksService.findOne /
findRequirement includes.
Validate every FK against organizationId before the transaction, mirroring
the logic already present in linkRequirements:
- policies / tasks: findMany filtered by { id in, organizationId } and
reject if any are missing
- frameworkInstance: must belong to caller org
- requirementId: platform requirement's frameworkId must match the FI's
frameworkId
- customRequirementId: custom requirement must be in caller org and its
customFrameworkId must match the FI's customFrameworkId
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…om-framework parity - Schema: enforce tenant consistency on CustomFramework FKs with composite (id, organizationId) references. CustomRequirement and FrameworkInstance can no longer point at another org's CustomFramework, even if application code regresses. Migration adds a guard that aborts if any existing row already violates the invariant. - Scoring: use EvidenceSubmission.submittedAt (canonical submission time) instead of createdAt for the "within last 6 months" recency check; update all evidenceSubmission selects/orderBys in frameworks.service to match. - Policies (both admin + org): include customFramework when collecting the AI policy-regeneration context so org-custom frameworks influence the prompt instead of being silently dropped. - Frontend framework list: exclude already-added custom frameworks from the "available to add" list on both overview and frameworks pages. - useControls createControl payload: tighten requirementMappings to a discriminated union so invalid requirementId+customRequirementId combos fail at compile time (matches the backend's exactly-one rule). - Controls controller: validate :formType path param with ParseEnumPipe. - Document-type labels map: type as Record<EvidenceFormType, string> so Prisma enum drift becomes a compile error. - DocumentsTable: disable every unlink button while any unlink is pending so users can't click enabled controls that no-op. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
validatePolicyIds / validateTaskIds compared findMany row count to the raw input length. Duplicate ids in the request (e.g. [p1, p1, p2]) made the input longer than the set of rows returned, so a legitimate request with repeated ids was rejected as invalid. Dedupe via Set before the findMany lookup and length check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolve bun.lock and package.json conflicts by accepting main.
[dev] [carhartlewis] lewis/comp-framework-controls
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Lewis Carhart seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
There was a problem hiding this comment.
3 issues found across 64 files
Note: This PR contains a large number of files. During the trial, cubic reviews up to 50 files per PR. Paid plans get a higher limit.
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/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/controls/[controlId]/components/useControlOptions.ts">
<violation number="1" location="apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/controls/[controlId]/components/useControlOptions.ts:33">
P1: This hook uses raw `useSWR` instead of the project's `useApiSWR` wrapper, which scopes the SWR cache key by organization ID. Without org scoping, switching organizations will return stale cached control options from the previous org.
Use `useApiSWR` from `@/hooks/use-api-swr` to stay consistent with the rest of the codebase and get automatic org-scoped cache invalidation.</violation>
</file>
<file name="apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/components/AddCustomRequirementSheet.tsx">
<violation number="1" location="apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/components/AddCustomRequirementSheet.tsx:46">
P2: Form state is not reset when the sheet is closed without submitting. The sibling `LinkRequirementSheet` handles this via a `useEffect` that clears state on close. Add a similar effect here so reopening the sheet always shows a clean form.</violation>
</file>
<file name="apps/api/src/frameworks/frameworks-scores.helper.ts">
<violation number="1" location="apps/api/src/frameworks/frameworks-scores.helper.ts:270">
P1: Controls with no associated policies, tasks, or document types are now counted as incomplete (`hasAnyArtifact` is false), dragging down the compliance score. The old code excluded such controls from the calculation entirely. If frameworks commonly have controls that haven't been fully configured with artifacts yet, this will cause unexpected score drops for users.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
- useControlOptions: switch to useApiSWR for org-scoped cache invalidation - AddCustomRequirementSheet: reset form state when sheet closes - frameworks-scores: exclude controls without artifacts from score calculation instead of counting them as incomplete Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-fix [dev] [carhartlewis] lewis/comp-framework-controls-fix
…n control create (#2605) Creating a control from a framework's controls tab auto-connected every requirement in that framework to the new control. Users expect to commit the empty control and then link requirements manually. Removed the requirement fetch/connect from ControlTemplateService.create, dropped the now-unused frameworkId query param from the POST endpoint, and stopped forwarding it from the frontend. Added a regression test that fails if the auto-link behavior is reintroduced (CS-271). Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com> Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
|
🎉 This PR is included in version 3.25.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.
Summary by cubic
Adds first-class org-custom frameworks and requirements, and lets you link policies, tasks, requirements, and required evidence types to controls in a new Documents tab. Updates scoring to use submission time, ignores controls without artifacts, hardens multi-tenant safety, removes control-template auto-linking, and fixes policy alerts when a pending version is cleared.
New Features
useApiSWR), requirement sheet resets on close.frameworkIdparam and added a regression test.Migration
CustomFrameworkandCustomRequirement;FrameworkInstance/RequirementMapsupport platform or custom IDs.Written for commit a7389a1. Summary will update on new commits.