Skip to content

Commit 2eabfe9

Browse files
committed
Update zod dependency to version 3.25.76 across multiple files
- Changed zod version from 4.0.14 to 3.25.76 in package.json and bun.lock. - Updated zod version in apps/app/package.json from 4.0.17 to 3.25.76. - Refactored onboarding helpers to utilize new zod schema validation methods. These changes ensure compatibility with the updated zod version and improve the overall stability of the application.
1 parent 44924b2 commit 2eabfe9

File tree

4 files changed

+141
-56
lines changed

4 files changed

+141
-56
lines changed

apps/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"use-long-press": "^3.3.0",
9292
"xml2js": "^0.6.2",
9393
"zaraz-ts": "^1.2.0",
94-
"zod": "^4.0.17",
94+
"zod": "^3.25.76",
9595
"zustand": "^5.0.3"
9696
},
9797
"devDependencies": {

apps/app/src/jobs/tasks/onboarding/onboard-organization-helpers.ts

Lines changed: 126 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import {
88
Likelihood,
99
Risk,
1010
RiskCategory,
11+
RiskStatus,
1112
RiskTreatmentType,
1213
VendorCategory,
1314
} from '@db';
1415
import { logger, tasks } from '@trigger.dev/sdk';
15-
import { generateObject, generateText } from 'ai';
16+
import { generateObject, generateText, jsonSchema } from 'ai';
1617
import axios from 'axios';
17-
import z from 'zod';
1818
import type { researchVendor } from '../scrape/research';
1919
import { RISK_MITIGATION_PROMPT } from './prompts/risk-mitigation';
2020
import { VENDOR_RISK_ASSESSMENT_PROMPT } from './prompts/vendor-risk-assessment';
@@ -53,6 +53,58 @@ export type RiskData = {
5353
department: Departments;
5454
};
5555

56+
// Baseline risks that must always exist for every organization regardless of frameworks
57+
const BASELINE_RISKS: Array<{
58+
title: string;
59+
description: string;
60+
category: RiskCategory;
61+
department: Departments;
62+
status: RiskStatus;
63+
}> = [
64+
{
65+
title: 'Intentional Fraud and Misuse',
66+
description:
67+
'Intentional misrepresentation or deception by an internal actor (employee, contractor) or by the organization as a whole, for the purpose of achieving an unauthorized or improper gain.',
68+
category: RiskCategory.governance,
69+
department: Departments.gov,
70+
status: RiskStatus.closed,
71+
},
72+
];
73+
74+
/**
75+
* Ensures baseline risks are present for the organization.
76+
* Creates them if missing. Returns the list of risks that were created.
77+
*/
78+
export async function ensureBaselineRisks(organizationId: string): Promise<Risk[]> {
79+
const created: Risk[] = [];
80+
81+
for (const base of BASELINE_RISKS) {
82+
const existing = await db.risk.findFirst({
83+
where: {
84+
organizationId,
85+
title: base.title,
86+
},
87+
});
88+
89+
if (!existing) {
90+
const risk = await db.risk.create({
91+
data: {
92+
title: base.title,
93+
description: base.description,
94+
category: base.category,
95+
department: base.department,
96+
status: base.status,
97+
organizationId,
98+
},
99+
});
100+
created.push(risk);
101+
logger.info(`Created baseline risk: ${risk.id} (${risk.title})`);
102+
}
103+
}
104+
105+
return created;
106+
}
107+
56108
/**
57109
* Revalidates the organization path for cache busting
58110
*/
@@ -114,28 +166,47 @@ export async function getOrganizationContext(organizationId: string) {
114166
export async function extractVendorsFromContext(
115167
questionsAndAnswers: ContextItem[],
116168
): Promise<VendorData[]> {
117-
const result = await generateObject({
169+
const { object } = await generateObject({
118170
model: openai('gpt-4.1-mini'),
119-
schema: z.object({
120-
vendors: z.array(
121-
z.object({
122-
vendor_name: z.string(),
123-
vendor_website: z.string(),
124-
vendor_description: z.string(),
125-
category: z.enum(Object.values(VendorCategory) as [string, ...string[]]),
126-
inherent_probability: z.enum(Object.values(Likelihood) as [string, ...string[]]),
127-
inherent_impact: z.enum(Object.values(Impact) as [string, ...string[]]),
128-
residual_probability: z.enum(Object.values(Likelihood) as [string, ...string[]]),
129-
residual_impact: z.enum(Object.values(Impact) as [string, ...string[]]),
130-
}),
131-
),
171+
mode: 'json',
172+
schema: jsonSchema({
173+
type: 'object',
174+
properties: {
175+
vendors: {
176+
type: 'array',
177+
items: {
178+
type: 'object',
179+
properties: {
180+
vendor_name: { type: 'string' },
181+
vendor_website: { type: 'string' },
182+
vendor_description: { type: 'string' },
183+
category: { type: 'string', enum: Object.values(VendorCategory) },
184+
inherent_probability: { type: 'string', enum: Object.values(Likelihood) },
185+
inherent_impact: { type: 'string', enum: Object.values(Impact) },
186+
residual_probability: { type: 'string', enum: Object.values(Likelihood) },
187+
residual_impact: { type: 'string', enum: Object.values(Impact) },
188+
},
189+
required: [
190+
'vendor_name',
191+
'vendor_website',
192+
'vendor_description',
193+
'category',
194+
'inherent_probability',
195+
'inherent_impact',
196+
'residual_probability',
197+
'residual_impact',
198+
],
199+
},
200+
},
201+
},
202+
required: ['vendors'],
132203
}),
133204
system:
134205
'Extract vendor names from the following questions and answers. Return their name (grammar-correct), website, description, category, inherent probability, inherent impact, residual probability, and residual impact.',
135206
prompt: questionsAndAnswers.map((q) => `${q.question}\n${q.answer}`).join('\n'),
136207
});
137208

138-
return result.object.vendors as VendorData[];
209+
return (object as { vendors: VendorData[] }).vendors;
139210
}
140211

141212
/**
@@ -335,23 +406,40 @@ export async function extractRisksFromContext(
335406
organizationName: string,
336407
existingRisks: { title: string }[],
337408
): Promise<RiskData[]> {
338-
const result = await generateObject({
409+
const { object } = await generateObject({
339410
model: openai('gpt-4.1-mini'),
340-
schema: z.object({
341-
risks: z.array(
342-
z.object({
343-
risk_name: z.string(),
344-
risk_description: z.string(),
345-
risk_treatment_strategy: z.enum(
346-
Object.values(RiskTreatmentType) as [string, ...string[]],
347-
),
348-
risk_treatment_strategy_description: z.string(),
349-
risk_residual_probability: z.enum(Object.values(Likelihood) as [string, ...string[]]),
350-
risk_residual_impact: z.enum(Object.values(Impact) as [string, ...string[]]),
351-
category: z.enum(Object.values(RiskCategory) as [string, ...string[]]),
352-
department: z.enum(Object.values(Departments) as [string, ...string[]]),
353-
}),
354-
),
411+
mode: 'json',
412+
schema: jsonSchema({
413+
type: 'object',
414+
properties: {
415+
risks: {
416+
type: 'array',
417+
items: {
418+
type: 'object',
419+
properties: {
420+
risk_name: { type: 'string' },
421+
risk_description: { type: 'string' },
422+
risk_treatment_strategy: { type: 'string', enum: Object.values(RiskTreatmentType) },
423+
risk_treatment_strategy_description: { type: 'string' },
424+
risk_residual_probability: { type: 'string', enum: Object.values(Likelihood) },
425+
risk_residual_impact: { type: 'string', enum: Object.values(Impact) },
426+
category: { type: 'string', enum: Object.values(RiskCategory) },
427+
department: { type: 'string', enum: Object.values(Departments) },
428+
},
429+
required: [
430+
'risk_name',
431+
'risk_description',
432+
'risk_treatment_strategy',
433+
'risk_treatment_strategy_description',
434+
'risk_residual_probability',
435+
'risk_residual_impact',
436+
'category',
437+
'department',
438+
],
439+
},
440+
},
441+
},
442+
required: ['risks'],
355443
}),
356444
system: `Create a list of 8-12 risks that are relevant to the organization. Use action-oriented language, assume reviewers understand basic termilology - skip definitions.
357445
Your mandate is to propose risks that satisfy both ISO 27001:2022 clause 6.1 (risk management) and SOC 2 trust services criteria CC3 and CC4.
@@ -367,7 +455,7 @@ export async function extractRisksFromContext(
367455
`,
368456
});
369457

370-
return result.object.risks as RiskData[];
458+
return (object as { risks: RiskData[] }).risks;
371459
}
372460

373461
/**
@@ -489,7 +577,10 @@ export async function createRisks(
489577
organizationId: string,
490578
organizationName: string,
491579
): Promise<Risk[]> {
492-
// Get existing risks to avoid duplicates
580+
// Ensure baseline risks exist first so the AI doesn't recreate them
581+
await ensureBaselineRisks(organizationId);
582+
583+
// Get existing risks to avoid duplicates (includes baseline)
493584
const existingRisks = await getExistingRisks(organizationId);
494585

495586
// Extract risks using AI

bun.lock

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"workspaces": {
44
"": {
55
"name": "comp",
6+
"dependencies": {
7+
"zod": "^3.25.76",
8+
},
69
"devDependencies": {
710
"@azure/core-http": "^3.0.5",
811
"@azure/core-rest-pipeline": "^1.21.0",
@@ -51,7 +54,6 @@
5154
"turbo": "^2.5.4",
5255
"typescript": "^5.8.3",
5356
"use-debounce": "^10.0.4",
54-
"zod": "^4.0.14",
5557
},
5658
},
5759
"apps/api": {
@@ -194,7 +196,7 @@
194196
"use-long-press": "^3.3.0",
195197
"xml2js": "^0.6.2",
196198
"zaraz-ts": "^1.2.0",
197-
"zod": "^4.0.17",
199+
"zod": "^3.25.76",
198200
"zustand": "^5.0.3",
199201
},
200202
"devDependencies": {
@@ -4941,7 +4943,7 @@
49414943

49424944
"zip-stream": ["[email protected]", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
49434945

4944-
"zod": ["zod@4.0.17", "", {}, "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ=="],
4946+
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
49454947

49464948
"zod-error": ["[email protected]", "", { "dependencies": { "zod": "^3.20.2" } }, "sha512-zzopKZ/skI9iXpqCEPj+iLCKl9b88E43ehcU+sbRoHuwGd9F1IDVGQ70TyO6kmfiRL1g4IXkjsXK+g1gLYl4WQ=="],
49474949

@@ -5019,6 +5021,8 @@
50195021

50205022
"@commitlint/types/chalk": ["[email protected]", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="],
50215023

5024+
"@comp/api/zod": ["[email protected]", "", {}, "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ=="],
5025+
50225026
"@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
50235027

50245028
"@discordjs/rest/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
@@ -5027,8 +5031,6 @@
50275031

50285032
"@discordjs/ws/@types/ws": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
50295033

5030-
"@dub/better-auth/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5031-
50325034
"@dub/embed-react/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", "rollup": "^4.13.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw=="],
50335035

50345036
"@eslint-community/eslint-utils/eslint-visitor-keys": ["[email protected]", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
@@ -5079,8 +5081,6 @@
50795081

50805082
"@jest/transform/slash": ["[email protected]", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
50815083

5082-
"@mendable/firecrawl-js/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5083-
50845084
"@nangohq/types/type-fest": ["[email protected]", "", {}, "sha512-rfgpoi08xagF3JSdtJlCwMq9DGNDE0IMh3Mkpc1wUypg9vPi786AiqeBBKcqvIkq42azsBM85N490fyZjeUftw=="],
50855085

50865086
"@nestjs/cli/commander": ["[email protected]", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
@@ -5183,17 +5183,15 @@
51835183

51845184
"@trigger.dev/core/tinyexec": ["[email protected]", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
51855185

5186-
"@trigger.dev/core/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5187-
51885186
"@trigger.dev/sdk/chalk": ["[email protected]", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="],
51895187

51905188
"@trigger.dev/sdk/uuid": ["[email protected]", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
51915189

51925190
"@trycompai/db/dotenv": ["[email protected]", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
51935191

5194-
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
5192+
"@trycompai/integrations/zod": ["zod@4.0.17", "", {}, "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ=="],
51955193

5196-
"@vercel/sdk/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5194+
"@typescript-eslint/eslint-plugin/ignore": ["[email protected]", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
51975195

51985196
"accepts/mime-types": ["[email protected]", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
51995197

@@ -5227,8 +5225,6 @@
52275225

52285226
"chalk-template/chalk": ["[email protected]", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="],
52295227

5230-
"chromium-bidi/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5231-
52325228
"cli-highlight/parse5": ["[email protected]", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="],
52335229

52345230
"cli-highlight/yargs": ["[email protected]", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="],
@@ -5255,8 +5251,6 @@
52555251

52565252
"dotenv-expand/dotenv": ["[email protected]", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
52575253

5258-
"dub/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5259-
52605254
"duplexer2/readable-stream": ["[email protected]", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
52615255

52625256
"ecdsa-sig-formatter/safe-buffer": ["[email protected]", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
@@ -5989,8 +5983,6 @@
59895983

59905984
"yauzl/buffer-crc32": ["[email protected]", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
59915985

5992-
"zod-error/zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
5993-
59945986
"@angular-devkit/core/ajv/json-schema-traverse": ["[email protected]", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
59955987

59965988
"@angular-devkit/schematics/ora/cli-cursor": ["[email protected]", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="],

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
"tsup": "^8.5.0",
4949
"turbo": "^2.5.4",
5050
"typescript": "^5.8.3",
51-
"use-debounce": "^10.0.4",
52-
"zod": "^4.0.14"
51+
"use-debounce": "^10.0.4"
5352
},
5453
"engines": {
5554
"node": ">=18"
@@ -92,5 +91,8 @@
9291
"packages/tsconfig",
9392
"packages/ui",
9493
"packages/utils"
95-
]
94+
],
95+
"dependencies": {
96+
"zod": "^3.25.76"
97+
}
9698
}

0 commit comments

Comments
 (0)