From 561d9b18f60d280d8a6627d6ebbdc552ecc8efff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:44:31 -0400 Subject: [PATCH 1/3] fix(app): handle potential null for integrationsUsed in UnifiedWorkflowCard (#1612) Co-authored-by: Mariano Fuentes --- .../components/workflow/components/UnifiedWorkflowCard.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/components/workflow/components/UnifiedWorkflowCard.tsx b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/components/workflow/components/UnifiedWorkflowCard.tsx index 1744cc5c8..a5558ebb4 100644 --- a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/components/workflow/components/UnifiedWorkflowCard.tsx +++ b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/components/workflow/components/UnifiedWorkflowCard.tsx @@ -49,13 +49,14 @@ export function UnifiedWorkflowCard({ steps, title, onTest, integrationsUsed }: {/* Header with integration icons */}
- {integrationsUsed.map((integration) => ( + {integrationsUsed?.map((integration) => (
{integration.link}
))} From 5264c76690ae3ec27bb7d66b13c497fda8dc6d5e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:52:53 -0400 Subject: [PATCH 2/3] fix(app): set portal url to new-policy-email sent to employees (#1614) Co-authored-by: chasprowebdev --- .../app/src/actions/policies/accept-requested-policy-changes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app/src/actions/policies/accept-requested-policy-changes.ts b/apps/app/src/actions/policies/accept-requested-policy-changes.ts index 63d66c423..bdaa73637 100644 --- a/apps/app/src/actions/policies/accept-requested-policy-changes.ts +++ b/apps/app/src/actions/policies/accept-requested-policy-changes.ts @@ -103,7 +103,7 @@ export const acceptRequestedPolicyChangesAction = authActionClient userName: employee.user.name || employee.user.email || 'Employee', policyName: policy.name, organizationName: policy.organization.name, - url: `${process.env.NEXT_PUBLIC_APP_URL ?? 'https://app.trycomp.ai'}/${session.activeOrganizationId}/policies/${policy.id}`, + url: `${process.env.NEXT_PUBLIC_PORTAL_URL ?? 'https://portal.trycomp.ai'}/${session.activeOrganizationId}`, description: `The "${policy.name}" policy has been ${isNewPolicy ? 'created' : 'updated'}.`, })); From e5e8067c13791008f4223530fec3cbd79690da62 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:56:59 -0400 Subject: [PATCH 3/3] CS-35 [New Framework] - NEN7510 (#1611) * feat(db): add nen7510 columns to Trust model * feat(app): add new badge - NEN 7510 --------- Co-authored-by: chasprowebdev Co-authored-by: Mariano Fuentes --- apps/app/public/badges/nen7510.svg | 20 ++++++ .../components/FrameworksOverview.tsx | 4 ++ .../actions/update-trust-portal-frameworks.ts | 6 ++ .../components/TrustPortalSwitch.tsx | 49 +++++++++++++-- .../trust-portal/components/logos.tsx | 61 +++++++++++++++++++ .../[orgId]/settings/trust-portal/page.tsx | 4 ++ packages/db/package.json | 2 +- .../migration.sql | 3 + packages/db/prisma/schema/trust.prisma | 2 + 9 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 apps/app/public/badges/nen7510.svg create mode 100644 packages/db/prisma/migrations/20251006210937_add_nen7510_fields/migration.sql diff --git a/apps/app/public/badges/nen7510.svg b/apps/app/public/badges/nen7510.svg new file mode 100644 index 000000000..e0be98b47 --- /dev/null +++ b/apps/app/public/badges/nen7510.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksOverview.tsx b/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksOverview.tsx index 45fe711c9..d792e8b51 100644 --- a/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksOverview.tsx +++ b/apps/app/src/app/(app)/[orgId]/frameworks/components/FrameworksOverview.tsx @@ -44,6 +44,10 @@ export function mapFrameworkToBadge(framework: FrameworkInstanceWithControls) { return '/badges/pci-dss.svg'; } + if (framework.framework.name === 'NEN 7510') { + return '/badges/nen7510.svg'; + } + return null; } diff --git a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/actions/update-trust-portal-frameworks.ts b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/actions/update-trust-portal-frameworks.ts index 050b5c9ee..03b9193fb 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/actions/update-trust-portal-frameworks.ts +++ b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/actions/update-trust-portal-frameworks.ts @@ -14,6 +14,7 @@ interface UpdateTrustPortalFrameworksParams { gdpr?: boolean; hipaa?: boolean; pcidss?: boolean; + nen7510?: boolean; soc2type1Status?: 'started' | 'in_progress' | 'compliant'; soc2type2Status?: 'started' | 'in_progress' | 'compliant'; iso27001Status?: 'started' | 'in_progress' | 'compliant'; @@ -21,6 +22,7 @@ interface UpdateTrustPortalFrameworksParams { gdprStatus?: 'started' | 'in_progress' | 'compliant'; hipaaStatus?: 'started' | 'in_progress' | 'compliant'; pcidssStatus?: 'started' | 'in_progress' | 'compliant'; + nen7510Status?: 'started' | 'in_progress' | 'compliant'; } export async function updateTrustPortalFrameworks({ @@ -32,6 +34,7 @@ export async function updateTrustPortalFrameworks({ gdpr, hipaa, pcidss, + nen7510, soc2type1Status, soc2type2Status, iso27001Status, @@ -39,6 +42,7 @@ export async function updateTrustPortalFrameworks({ gdprStatus, hipaaStatus, pcidssStatus, + nen7510Status, }: UpdateTrustPortalFrameworksParams) { const session = await auth.api.getSession({ headers: await headers(), @@ -71,6 +75,7 @@ export async function updateTrustPortalFrameworks({ gdpr: gdpr ?? trustPortal.gdpr, hipaa: hipaa ?? trustPortal.hipaa, pci_dss: pcidss ?? trustPortal.pci_dss, + nen7510: nen7510 ?? trustPortal.nen7510, soc2_status: soc2type2Status ?? trustPortal.soc2_status, soc2type1_status: soc2type1Status ?? trustPortal.soc2type1_status, soc2type2_status: soc2type2Status ?? trustPortal.soc2type2_status, @@ -79,6 +84,7 @@ export async function updateTrustPortalFrameworks({ gdpr_status: gdprStatus ?? trustPortal.gdpr_status, hipaa_status: hipaaStatus ?? trustPortal.hipaa_status, pci_dss_status: pcidssStatus ?? trustPortal.pci_dss_status, + nen7510_status: nen7510Status ?? trustPortal.nen7510_status, }, }); diff --git a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/TrustPortalSwitch.tsx b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/TrustPortalSwitch.tsx index a31dedd30..1a6d4c8cb 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/TrustPortalSwitch.tsx +++ b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/TrustPortalSwitch.tsx @@ -17,7 +17,7 @@ import { z } from 'zod'; import { isFriendlyAvailable } from '../actions/is-friendly-available'; import { trustPortalSwitchAction } from '../actions/trust-portal-switch'; import { updateTrustPortalFrameworks } from '../actions/update-trust-portal-frameworks'; -import { GDPR, HIPAA, ISO27001, SOC2Type1, SOC2Type2, PCIDSS, ISO42001 } from './logos'; +import { GDPR, HIPAA, ISO27001, SOC2Type1, SOC2Type2, PCIDSS, ISO42001, NEN7510 } from './logos'; const trustPortalSwitchSchema = z.object({ enabled: z.boolean(), @@ -30,6 +30,7 @@ const trustPortalSwitchSchema = z.object({ gdpr: z.boolean(), hipaa: z.boolean(), pcidss: z.boolean(), + nen7510: z.boolean(), soc2type1Status: z.enum(['started', 'in_progress', 'compliant']), soc2type2Status: z.enum(['started', 'in_progress', 'compliant']), iso27001Status: z.enum(['started', 'in_progress', 'compliant']), @@ -37,6 +38,7 @@ const trustPortalSwitchSchema = z.object({ gdprStatus: z.enum(['started', 'in_progress', 'compliant']), hipaaStatus: z.enum(['started', 'in_progress', 'compliant']), pcidssStatus: z.enum(['started', 'in_progress', 'compliant']), + nen7510Status: z.enum(['started', 'in_progress', 'compliant']), }); export function TrustPortalSwitch({ @@ -60,6 +62,8 @@ export function TrustPortalSwitch({ gdprStatus, hipaaStatus, pcidssStatus, + nen7510, + nen7510Status, friendlyUrl, }: { enabled: boolean; @@ -75,6 +79,7 @@ export function TrustPortalSwitch({ gdpr: boolean; hipaa: boolean; pcidss: boolean; + nen7510: boolean; soc2type1Status: 'started' | 'in_progress' | 'compliant'; soc2type2Status: 'started' | 'in_progress' | 'compliant'; iso27001Status: 'started' | 'in_progress' | 'compliant'; @@ -82,6 +87,7 @@ export function TrustPortalSwitch({ gdprStatus: 'started' | 'in_progress' | 'compliant'; hipaaStatus: 'started' | 'in_progress' | 'compliant'; pcidssStatus: 'started' | 'in_progress' | 'compliant'; + nen7510Status: 'started' | 'in_progress' | 'compliant'; friendlyUrl: string | null; }) { const trustPortalSwitch = useAction(trustPortalSwitchAction, { @@ -107,6 +113,7 @@ export function TrustPortalSwitch({ gdpr: gdpr ?? false, hipaa: hipaa ?? false, pcidss: pcidss ?? false, + nen7510: nen7510 ?? false, soc2type1Status: soc2type1Status ?? 'started', soc2type2Status: soc2type2Status ?? 'started', iso27001Status: iso27001Status ?? 'started', @@ -114,6 +121,7 @@ export function TrustPortalSwitch({ gdprStatus: gdprStatus ?? 'started', hipaaStatus: hipaaStatus ?? 'started', pcidssStatus: pcidssStatus ?? 'started', + nen7510Status: nen7510Status ?? 'started', friendlyUrl: friendlyUrl ?? undefined, }, }); @@ -541,6 +549,35 @@ export function TrustPortalSwitch({ } }} /> + {/* NEN 7510 */} + { + try { + await updateTrustPortalFrameworks({ + orgId, + nen7510Status: value as 'started' | 'in_progress' | 'compliant', + }); + toast.success('NEN 7510 status updated'); + } catch (error) { + toast.error('Failed to update NEN 7510 status'); + } + }} + onToggle={async (checked) => { + try { + await updateTrustPortalFrameworks({ + orgId, + nen7510: checked, + }); + toast.success('NEN 7510 status updated'); + } catch (error) { + toast.error('Failed to update NEN 7510 status'); + } + }} + />
@@ -594,9 +631,13 @@ function ComplianceFramework({ ) : title === 'PCI DSS' ? ( -
- -
+
+ +
+ ) : title === 'NEN 7510' ? ( +
+ +
) : null; return ( diff --git a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/logos.tsx b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/logos.tsx index 433e97f1d..3e5999279 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/logos.tsx +++ b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/components/logos.tsx @@ -398,3 +398,64 @@ export const ISO42001 = (props: React.SVGProps) => ( /> ); + +export const NEN7510 = (props: React.SVGProps) => ( + + + + + + + + + + + + + + + + + + + + + +); diff --git a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/page.tsx b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/page.tsx index 59cbf66a8..d2cd6f276 100644 --- a/apps/app/src/app/(app)/[orgId]/settings/trust-portal/page.tsx +++ b/apps/app/src/app/(app)/[orgId]/settings/trust-portal/page.tsx @@ -30,6 +30,7 @@ export default async function TrustPortalSettings({ gdpr={trustPortal?.gdpr ?? false} hipaa={trustPortal?.hipaa ?? false} pcidss={trustPortal?.pcidss ?? false} + nen7510={trustPortal?.nen7510 ?? false} soc2type1Status={trustPortal?.soc2type1Status ?? 'started'} soc2type2Status={trustPortal?.soc2type2Status ?? 'started'} iso27001Status={trustPortal?.iso27001Status ?? 'started'} @@ -37,6 +38,7 @@ export default async function TrustPortalSettings({ gdprStatus={trustPortal?.gdprStatus ?? 'started'} hipaaStatus={trustPortal?.hipaaStatus ?? 'started'} pcidssStatus={trustPortal?.pcidssStatus ?? 'started'} + nen7510Status={trustPortal?.nen7510Status ?? 'started'} friendlyUrl={trustPortal?.friendlyUrl ?? null} /> { gdpr: trustPortal?.gdpr, hipaa: trustPortal?.hipaa, pcidss: trustPortal?.pci_dss, + nen7510: trustPortal?.nen7510, soc2type1Status: trustPortal?.soc2type1_status, soc2type2Status: !trustPortal?.soc2type2 && trustPortal?.soc2 ? trustPortal?.soc2_status : trustPortal?.soc2type2_status, iso27001Status: trustPortal?.iso27001_status, @@ -84,6 +87,7 @@ const getTrustPortal = cache(async (orgId: string) => { gdprStatus: trustPortal?.gdpr_status, hipaaStatus: trustPortal?.hipaa_status, pcidssStatus: trustPortal?.pci_dss_status, + nen7510Status: trustPortal?.nen7510_status, isVercelDomain: trustPortal?.isVercelDomain, vercelVerification: trustPortal?.vercelVerification, friendlyUrl: trustPortal?.friendlyUrl, diff --git a/packages/db/package.json b/packages/db/package.json index 5c072ba8a..5c613f514 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,7 +1,7 @@ { "name": "@trycompai/db", "description": "Database package with Prisma client and schema for Comp AI", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "@prisma/client": "^6.13.0", "dotenv": "^16.4.5" diff --git a/packages/db/prisma/migrations/20251006210937_add_nen7510_fields/migration.sql b/packages/db/prisma/migrations/20251006210937_add_nen7510_fields/migration.sql new file mode 100644 index 000000000..056291a2f --- /dev/null +++ b/packages/db/prisma/migrations/20251006210937_add_nen7510_fields/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "public"."Trust" ADD COLUMN "nen7510" BOOLEAN NOT NULL DEFAULT false, +ADD COLUMN "nen7510_status" "public"."FrameworkStatus" NOT NULL DEFAULT 'started'; diff --git a/packages/db/prisma/schema/trust.prisma b/packages/db/prisma/schema/trust.prisma index 5acbeecb2..422742697 100644 --- a/packages/db/prisma/schema/trust.prisma +++ b/packages/db/prisma/schema/trust.prisma @@ -16,6 +16,7 @@ model Trust { soc2type2 Boolean @default(false) iso27001 Boolean @default(false) iso42001 Boolean @default(false) + nen7510 Boolean @default(false) gdpr Boolean @default(false) hipaa Boolean @default(false) pci_dss Boolean @default(false) @@ -25,6 +26,7 @@ model Trust { soc2type2_status FrameworkStatus @default(started) iso27001_status FrameworkStatus @default(started) iso42001_status FrameworkStatus @default(started) + nen7510_status FrameworkStatus @default(started) gdpr_status FrameworkStatus @default(started) hipaa_status FrameworkStatus @default(started) pci_dss_status FrameworkStatus @default(started)