diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 38d1a74ec8..d716722e3b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -23,10 +23,27 @@ "Bash(git commit:*)", "Bash(git push:*)", "Bash(npx vitest run:*)", + "Bash(cp /Users/harsh/Data/vw/verifywise/Servers/structures/ISO-27001/annexes/iso27001.annex.struct.ts /tmp/annex.bak.ts)", + "Bash(cp /Users/harsh/Data/vw/verifywise/Servers/structures/ISO-27001/clauses/iso27001.clause.struct.ts /tmp/clause.bak.ts)", + "Bash(node /tmp/apply-iso27001-content.js)", + "Bash(node /tmp/rename-iso27001-titles.js)", + "Bash(awk 'NR>=3200 && NR<=3260' /Users/harsh/Data/vw/verifywise/Servers/structures/ISO-27001/annexes/iso27001.annex.struct.ts)", + "Bash(awk '/^ \\\\],$/ && prev ~ /^ \\\\],$/ { print NR\": stray at line \"NR; } { prev = $0 }' /Users/harsh/Data/vw/verifywise/Servers/structures/ISO-27001/annexes/iso27001.annex.struct.ts)", + "Bash(awk 'BEGIN{ prev=\"\" } *)", + "Bash(awk '/^ \\\\],$/ && prev ~ /^ \\\\],$/ { c++ } { prev = $0 } END { print c+0 }' /Users/harsh/Data/vw/verifywise/Servers/structures/ISO-27001/annexes/iso27001.annex.struct.ts)", + "Bash(awk *)", "Bash(cmd.exe /c \"where gh\")", "Bash(curl:*)", "WebFetch(domain:api.github.com)", "Bash(git status:*)", + "Bash(node -c database/migrations/20260417150653-reseed-eu-act-struct-with-metadata.js)", + "Bash(node -c database/migrations/20260420105041-iso42001-split-clause-6-1.js)", + "Bash(node -c database/migrations/20260420105042-iso42001-add-clause-6-3.js)", + "Bash(PGPASSWORD=test psql *)", + "Bash(lsof *)", + "Bash(node *)", + "Bash(npx sequelize *)", + "Bash(psql -h localhost -p 5433 -U postgres -d vwtest4 -c ' *)", "Bash(node -e:*)", "Bash(test:*)", "Bash(npx ts-node:*)", @@ -37,7 +54,10 @@ "Bash(kill:*)", "Bash(wait:*)", "WebSearch", - "Bash(git --version)" + "Bash(git --version)", + "Bash(npm run *)", + "Bash(grep \"error TS\" /tmp/buildout.txt)", + "Bash(npm install *)" ] } } diff --git a/Clients/src/application/mappers/project.mapper.ts b/Clients/src/application/mappers/project.mapper.ts index 287b1b4a59..a4e7a203b6 100644 --- a/Clients/src/application/mappers/project.mapper.ts +++ b/Clients/src/application/mappers/project.mapper.ts @@ -46,27 +46,14 @@ export function mapRiskClassification( */ export function mapHighRiskRole(value: number | string): HighRiskRole { if (typeof value === "number") { - // Map numeric values to enum (assuming 0-5 mapping) - const numericMapping: Record = { - 0: HighRiskRole.DEPLOYER, - 1: HighRiskRole.PROVIDER, - 2: HighRiskRole.DISTRIBUTOR, - 3: HighRiskRole.IMPORTER, - 4: HighRiskRole.PRODUCT_MANUFACTURER, - 5: HighRiskRole.AUTHORIZED_REPRESENTATIVE, - }; - return numericMapping[value] || HighRiskRole.DEPLOYER; + return value === 1 ? HighRiskRole.PROVIDER : HighRiskRole.DEPLOYER; } - // Map string values to enum - const mapping: Record = { - "deployer": HighRiskRole.DEPLOYER, - "provider": HighRiskRole.PROVIDER, - "distributor": HighRiskRole.DISTRIBUTOR, - "importer": HighRiskRole.IMPORTER, - "product manufacturer": HighRiskRole.PRODUCT_MANUFACTURER, - "authorized representative": HighRiskRole.AUTHORIZED_REPRESENTATIVE, - }; - return mapping[value.toLowerCase()] || HighRiskRole.DEPLOYER; + // Legacy values (Distributor, Importer, Product manufacturer, + // Authorized representative) collapse onto Provider; not_applicable onto + // Deployer — matches the DB migration's remap. + const v = value.toLowerCase(); + if (v === "deployer" || v === "not_applicable") return HighRiskRole.DEPLOYER; + return HighRiskRole.PROVIDER; } /** diff --git a/Clients/src/application/mappers/tests/project.mappers.test.ts b/Clients/src/application/mappers/tests/project.mappers.test.ts index 213cc2e9cd..ff5561fb7f 100644 --- a/Clients/src/application/mappers/tests/project.mappers.test.ts +++ b/Clients/src/application/mappers/tests/project.mappers.test.ts @@ -54,36 +54,31 @@ describe("Test project mappers functions", () => { expect(result).toBe(HighRiskRole.DEPLOYER); result = mapHighRiskRole(1); expect(result).toBe(HighRiskRole.PROVIDER); - result = mapHighRiskRole(2); - expect(result).toBe(HighRiskRole.DISTRIBUTOR); - result = mapHighRiskRole(3); - expect(result).toBe(HighRiskRole.IMPORTER); - result = mapHighRiskRole(4); - expect(result).toBe(HighRiskRole.PRODUCT_MANUFACTURER); - result = mapHighRiskRole(5); - expect(result).toBe(HighRiskRole.AUTHORIZED_REPRESENTATIVE); }); it("should receive a valid string and return the mapped value", () => { let result = mapHighRiskRole("Deployer"); expect(result).toBe(HighRiskRole.DEPLOYER); result = mapHighRiskRole("Provider"); expect(result).toBe(HighRiskRole.PROVIDER); - result = mapHighRiskRole("Distributor"); - expect(result).toBe(HighRiskRole.DISTRIBUTOR); - result = mapHighRiskRole("Importer"); - expect(result).toBe(HighRiskRole.IMPORTER); - result = mapHighRiskRole("Product Manufacturer"); - expect(result).toBe(HighRiskRole.PRODUCT_MANUFACTURER); - result = mapHighRiskRole("Authorized Representative"); - expect(result).toBe(HighRiskRole.AUTHORIZED_REPRESENTATIVE); }); - it("should receive an invalid number and return the default value", () => { + it("should collapse legacy provider-tier strings onto PROVIDER", () => { + // Pre-reduction values (Distributor/Importer/Product manufacturer/ + // Authorized representative) now map to Provider. + expect(mapHighRiskRole("Distributor")).toBe(HighRiskRole.PROVIDER); + expect(mapHighRiskRole("Importer")).toBe(HighRiskRole.PROVIDER); + expect(mapHighRiskRole("Product Manufacturer")).toBe(HighRiskRole.PROVIDER); + expect(mapHighRiskRole("Authorized Representative")).toBe(HighRiskRole.PROVIDER); + }); + it("should collapse legacy 'not_applicable' onto DEPLOYER", () => { + expect(mapHighRiskRole("not_applicable")).toBe(HighRiskRole.DEPLOYER); + }); + it("should receive an invalid number and return PROVIDER (non-zero fallback)", () => { const result = mapHighRiskRole(99); - expect(result).toBe(HighRiskRole.DEPLOYER); + expect(result).toBe(HighRiskRole.PROVIDER); }); - it("should receive an invalid string and return the default value", () => { + it("should receive an invalid string and return PROVIDER (non-matching fallback)", () => { const result = mapHighRiskRole("InvalidString"); - expect(result).toBe(HighRiskRole.DEPLOYER); + expect(result).toBe(HighRiskRole.PROVIDER); }); }); describe("mapProjectResponseDTOToProject", () => { diff --git a/Clients/src/application/utils/lazyRoute.tsx b/Clients/src/application/utils/lazyRoute.tsx index 7ae90eefcb..3b43e256bd 100644 --- a/Clients/src/application/utils/lazyRoute.tsx +++ b/Clients/src/application/utils/lazyRoute.tsx @@ -19,13 +19,13 @@ export const LazyFallback = () => ( * Wraps React.lazy() with retry logic for chunk load failures. * Retries up to 3 times with exponential backoff (1.5s, 3s, 6s). */ -export function lazyRoute>( +export function lazyRoute>( factory: () => Promise<{ default: T }> ) { return lazy(() => retryImport(factory)); } -function retryImport>( +function retryImport>( factory: () => Promise<{ default: T }>, retries = 3, delay = 1500 diff --git a/Clients/src/domain/enums/aiRiskClassification.enum.ts b/Clients/src/domain/enums/aiRiskClassification.enum.ts index 1d2420409c..1e4e34f76f 100644 --- a/Clients/src/domain/enums/aiRiskClassification.enum.ts +++ b/Clients/src/domain/enums/aiRiskClassification.enum.ts @@ -3,4 +3,6 @@ export enum AiRiskClassification { HIGH_RISK = "High risk", LIMITED_RISK = "Limited risk", MINIMAL_RISK = "Minimal risk", + GPAI = "GPAI", + GENERAL_RISK = "General Risk", } diff --git a/Clients/src/domain/enums/highRiskRole.enum.ts b/Clients/src/domain/enums/highRiskRole.enum.ts index 870b8050fd..e120e51a89 100644 --- a/Clients/src/domain/enums/highRiskRole.enum.ts +++ b/Clients/src/domain/enums/highRiskRole.enum.ts @@ -1,8 +1,4 @@ export enum HighRiskRole { DEPLOYER = "Deployer", PROVIDER = "Provider", - DISTRIBUTOR = "Distributor", - IMPORTER = "Importer", - PRODUCT_MANUFACTURER = "Product manufacturer", - AUTHORIZED_REPRESENTATIVE = "Authorized representative", } diff --git a/Clients/src/infrastructure/api/__tests__/automationsService.test.ts b/Clients/src/infrastructure/api/__tests__/automationsService.test.ts index 71050e24d5..67c628096a 100644 --- a/Clients/src/infrastructure/api/__tests__/automationsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/automationsService.test.ts @@ -12,7 +12,7 @@ vi.mock("../customAxios", () => ({ import { automationsService } from "../automationsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("automationsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/biasAuditService.test.ts b/Clients/src/infrastructure/api/__tests__/biasAuditService.test.ts index 80d624a6bb..318a59c10f 100644 --- a/Clients/src/infrastructure/api/__tests__/biasAuditService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/biasAuditService.test.ts @@ -12,7 +12,7 @@ vi.mock("../customAxios", () => ({ import { biasAuditService } from "../biasAuditService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("biasAuditService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/ceMarkingService.test.ts b/Clients/src/infrastructure/api/__tests__/ceMarkingService.test.ts index 9939d07081..4c956856e4 100644 --- a/Clients/src/infrastructure/api/__tests__/ceMarkingService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/ceMarkingService.test.ts @@ -10,7 +10,7 @@ vi.mock("../customAxios", () => ({ import { ceMarkingService } from "../ceMarkingService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("ceMarkingService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/deepEvalArenaService.test.ts b/Clients/src/infrastructure/api/__tests__/deepEvalArenaService.test.ts index b71a633146..574b5dba32 100644 --- a/Clients/src/infrastructure/api/__tests__/deepEvalArenaService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/deepEvalArenaService.test.ts @@ -11,7 +11,7 @@ vi.mock("../customAxios", () => ({ import { deepEvalArenaService } from "../deepEvalArenaService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("deepEvalArenaService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/deepEvalDatasetsService.test.ts b/Clients/src/infrastructure/api/__tests__/deepEvalDatasetsService.test.ts index 6320b88d4a..32fc56bc96 100644 --- a/Clients/src/infrastructure/api/__tests__/deepEvalDatasetsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/deepEvalDatasetsService.test.ts @@ -19,7 +19,7 @@ vi.mock("../deepEvalOrgsService", () => ({ import { deepEvalDatasetsService } from "../deepEvalDatasetsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("deepEvalDatasetsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/deepEvalOrgsService.test.ts b/Clients/src/infrastructure/api/__tests__/deepEvalOrgsService.test.ts index ccf3640f4b..af49b51d8e 100644 --- a/Clients/src/infrastructure/api/__tests__/deepEvalOrgsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/deepEvalOrgsService.test.ts @@ -12,7 +12,7 @@ vi.mock("../customAxios", () => ({ import { deepEvalOrgsService } from "../deepEvalOrgsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("deepEvalOrgsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/deepEvalProjectsService.test.ts b/Clients/src/infrastructure/api/__tests__/deepEvalProjectsService.test.ts index ecd065d927..421b93a3ac 100644 --- a/Clients/src/infrastructure/api/__tests__/deepEvalProjectsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/deepEvalProjectsService.test.ts @@ -12,7 +12,7 @@ vi.mock("../customAxios", () => ({ import { deepEvalProjectsService } from "../deepEvalProjectsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("deepEvalProjectsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/deepEvalScorersService.test.ts b/Clients/src/infrastructure/api/__tests__/deepEvalScorersService.test.ts index da168ecd96..6a62c2d343 100644 --- a/Clients/src/infrastructure/api/__tests__/deepEvalScorersService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/deepEvalScorersService.test.ts @@ -20,7 +20,7 @@ vi.mock("../deepEvalOrgsService", () => ({ import { deepEvalScorersService } from "../deepEvalScorersService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("deepEvalScorersService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/evalModelsService.test.ts b/Clients/src/infrastructure/api/__tests__/evalModelsService.test.ts index b627a7be6e..32715fc1d6 100644 --- a/Clients/src/infrastructure/api/__tests__/evalModelsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/evalModelsService.test.ts @@ -12,7 +12,7 @@ vi.mock("../customAxios", () => ({ import { evalModelsService } from "../evalModelsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("evalModelsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/evaluationLlmApiKeysService.test.ts b/Clients/src/infrastructure/api/__tests__/evaluationLlmApiKeysService.test.ts index 37b5a64f67..f478111bdd 100644 --- a/Clients/src/infrastructure/api/__tests__/evaluationLlmApiKeysService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/evaluationLlmApiKeysService.test.ts @@ -11,7 +11,7 @@ vi.mock("../customAxios", () => ({ import { evaluationLlmApiKeysService } from "../evaluationLlmApiKeysService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("evaluationLlmApiKeysService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/evaluationLogsService.test.ts b/Clients/src/infrastructure/api/__tests__/evaluationLogsService.test.ts index 7cd29ac721..4a1903ae12 100644 --- a/Clients/src/infrastructure/api/__tests__/evaluationLogsService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/evaluationLogsService.test.ts @@ -19,7 +19,7 @@ import { } from "../evaluationLogsService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("evaluationLogsService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/networkServices.test.ts b/Clients/src/infrastructure/api/__tests__/networkServices.test.ts index 2f368483c3..3ebd3d7a90 100644 --- a/Clients/src/infrastructure/api/__tests__/networkServices.test.ts +++ b/Clients/src/infrastructure/api/__tests__/networkServices.test.ts @@ -23,7 +23,7 @@ vi.mock("axios", () => { import { apiServices } from "../networkServices"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("apiServices", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/postMarketMonitoringService.test.ts b/Clients/src/infrastructure/api/__tests__/postMarketMonitoringService.test.ts index 506f3daa33..339b11b0df 100644 --- a/Clients/src/infrastructure/api/__tests__/postMarketMonitoringService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/postMarketMonitoringService.test.ts @@ -32,7 +32,7 @@ import { } from "../postMarketMonitoringService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("postMarketMonitoringService", () => { beforeEach(() => { diff --git a/Clients/src/infrastructure/api/__tests__/searchService.test.ts b/Clients/src/infrastructure/api/__tests__/searchService.test.ts index 46fe75c67d..77dd645609 100644 --- a/Clients/src/infrastructure/api/__tests__/searchService.test.ts +++ b/Clients/src/infrastructure/api/__tests__/searchService.test.ts @@ -9,7 +9,7 @@ vi.mock("../customAxios", () => ({ import { wiseSearch, getEntityDisplayName, ENTITY_DISPLAY_NAMES } from "../searchService"; import CustomAxios from "../customAxios"; -const mockAxios = vi.mocked(CustomAxios); +const mockAxios = vi.mocked(CustomAxios, { deep: true }); describe("searchService", () => { beforeEach(() => { diff --git a/Clients/src/presentation/components/AddNewRiskForm/index.tsx b/Clients/src/presentation/components/AddNewRiskForm/index.tsx index da6241edf8..5c459019c4 100644 --- a/Clients/src/presentation/components/AddNewRiskForm/index.tsx +++ b/Clients/src/presentation/components/AddNewRiskForm/index.tsx @@ -64,17 +64,6 @@ const COMPONENT_CONSTANTS = { COMPACT_CONTENT_WIDTH: 970, // Account for scrollbar (~17px) } as const; -const VALIDATION_LIMITS = { - RISK_NAME: { MIN: 3, MAX: 255 }, - RISK_DESCRIPTION: { MIN: 1, MAX: 256 }, - POTENTIAL_IMPACT: { MIN: 1, MAX: 256 }, - REVIEW_NOTES: { MIN: 0, MAX: 1024 }, - MITIGATION_PLAN: { MIN: 1, MAX: 1024 }, - IMPLEMENTATION_STRATEGY: { MIN: 1, MAX: 1024 }, - RECOMMENDATIONS: { MIN: 1, MAX: 1024 }, - REQUIRED_FIELD: { MIN: 1 }, -} as const; - const riskInitialState: RiskFormValues = { riskName: "", actionOwner: 0, diff --git a/Clients/src/presentation/components/Cards/ProjectCard/index.tsx b/Clients/src/presentation/components/Cards/ProjectCard/index.tsx index 3343469ffb..ee198e78f9 100644 --- a/Clients/src/presentation/components/Cards/ProjectCard/index.tsx +++ b/Clients/src/presentation/components/Cards/ProjectCard/index.tsx @@ -265,7 +265,7 @@ export const ProjectCard = React.memo(function ProjectCard({ project, isLoading /> - {`Subcontrols: ${ + {`Requirements: ${ complianceProgressData?.allDonesubControls ?? 0 } out of ${complianceProgressData?.allsubControls ?? 0}`} @@ -303,7 +303,7 @@ export const ProjectCard = React.memo(function ProjectCard({ project, isLoading /> - {`Assessments: ${ + {`Controls: ${ assessmentProgressData?.answeredQuestions ?? 0 } out of ${assessmentProgressData?.totalQuestions ?? 0}`} @@ -373,7 +373,7 @@ export const ProjectCard = React.memo(function ProjectCard({ project, isLoading /> - {`Subcontrols: ${ + {`Requirements: ${ complianceProgressData?.allDonesubControls ?? 0 } out of ${complianceProgressData?.allsubControls ?? 0}`} @@ -411,7 +411,7 @@ export const ProjectCard = React.memo(function ProjectCard({ project, isLoading /> - {`Assessments: ${ + {`Controls: ${ assessmentProgressData?.answeredQuestions ?? 0 } out of ${assessmentProgressData?.totalQuestions ?? 0}`} diff --git a/Clients/src/presentation/components/CreateProjectForm/index.tsx b/Clients/src/presentation/components/CreateProjectForm/index.tsx index 954d850cc4..cab833ae45 100644 --- a/Clients/src/presentation/components/CreateProjectForm/index.tsx +++ b/Clients/src/presentation/components/CreateProjectForm/index.tsx @@ -225,10 +225,6 @@ export function CreateProjectForm({ () => [ { _id: 1, name: HighRiskRole.DEPLOYER }, { _id: 2, name: HighRiskRole.PROVIDER }, - { _id: 3, name: HighRiskRole.DISTRIBUTOR }, - { _id: 4, name: HighRiskRole.IMPORTER }, - { _id: 5, name: HighRiskRole.PRODUCT_MANUFACTURER }, - { _id: 6, name: HighRiskRole.AUTHORIZED_REPRESENTATIVE }, ], [] ); diff --git a/Clients/src/presentation/components/Drawer/ClauseDrawerDialog/index.tsx b/Clients/src/presentation/components/Drawer/ClauseDrawerDialog/index.tsx index 4858b29eea..019ad19187 100644 --- a/Clients/src/presentation/components/Drawer/ClauseDrawerDialog/index.tsx +++ b/Clients/src/presentation/components/Drawer/ClauseDrawerDialog/index.tsx @@ -725,9 +725,10 @@ const ISO42001ClauseDrawerDialog: React.FC = ({ padding="15px 20px" > - {clause?.clause_no - ? `${clause.clause_no}.${subclause?.order_no || 1}` - : "Clause"}{" "} + {subclause?.subclause_id + ?? (clause?.clause_no + ? `${clause.clause_no}.${subclause?.order_no || 1}` + : "Clause")}{" "} {subclause?.title}