Skip to content

Commit c39a7c5

Browse files
Lewis Carhartclaude
authored andcommitted
fix(frameworks): dedupe linked requirements and scope lookups by org
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a81af3e commit c39a7c5

File tree

4 files changed

+27
-3
lines changed

4 files changed

+27
-3
lines changed

apps/api/src/frameworks/dto/create-custom-requirement.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export class CreateCustomRequirementDto {
1010

1111
@ApiProperty({ description: 'Identifier', example: '10.3' })
1212
@IsString()
13+
@MinLength(1)
1314
@MaxLength(80)
1415
identifier: string;
1516

apps/api/src/frameworks/frameworks.service.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,25 @@ export class FrameworksService {
257257
throw new BadRequestException('No valid requirements to link');
258258
}
259259

260+
const existing = await db.frameworkEditorRequirement.findMany({
261+
where: {
262+
frameworkId: fi.frameworkId,
263+
organizationId,
264+
identifier: { in: sources.map((r) => r.identifier) },
265+
},
266+
select: { identifier: true },
267+
});
268+
const existingIdentifiers = new Set(existing.map((r) => r.identifier));
269+
const toCreate = sources.filter(
270+
(r) => !existingIdentifiers.has(r.identifier),
271+
);
272+
273+
if (toCreate.length === 0) {
274+
return { count: 0, requirements: [] };
275+
}
276+
260277
const created = await db.frameworkEditorRequirement.createManyAndReturn({
261-
data: sources.map((r) => ({
278+
data: toCreate.map((r) => ({
262279
name: r.name,
263280
identifier: r.identifier,
264281
description: r.description,
@@ -288,6 +305,7 @@ export class FrameworksService {
288305
where: {
289306
id: requirementKey,
290307
frameworkId: fi.frameworkId,
308+
OR: [{ organizationId: null }, { organizationId }],
291309
},
292310
});
293311
if (!requirement) {

apps/app/src/app/(app)/[orgId]/frameworks/[frameworkInstanceId]/components/LinkRequirementSheet.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function LinkRequirementSheet({
4646
[frameworks, frameworkInstanceId],
4747
);
4848

49-
const { data: options = [] } = useSWR<RequirementOption[]>(
49+
const { data: options = [], isLoading } = useSWR<RequirementOption[]>(
5050
isOpen && otherFrameworkIds.length > 0
5151
? ['link-requirements-options', ...otherFrameworkIds]
5252
: null,
@@ -131,7 +131,11 @@ export function LinkRequirementSheet({
131131
<SheetTitle>Link Existing Requirements</SheetTitle>
132132
</SheetHeader>
133133
<SheetBody>
134-
{options.length === 0 ? (
134+
{isLoading ? (
135+
<Text size="sm" variant="muted">
136+
Loading requirements…
137+
</Text>
138+
) : options.length === 0 ? (
135139
<Text size="sm" variant="muted">
136140
No requirements available from other frameworks.
137141
</Text>

apps/app/src/trigger/tasks/onboarding/update-policy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const updatePolicy = schemaTask({
2727
version: z.string(),
2828
description: z.string(),
2929
visible: z.boolean(),
30+
organizationId: z.string().nullable(),
3031
createdAt: z.date(),
3132
updatedAt: z.date(),
3233
}),

0 commit comments

Comments
 (0)