Iteration Teil D: Lieferantenmanagement (VDA-ISA 2027 Kap. 6 + NIS2)

Datenmodell (Prisma, RLS): Supplier + SupplierAsset, SupplierAssessment,
Contract, Nda, SupplierEvidence, ServiceResponsibility, Subcontractor,
ManagementDecision, SupplierControl (globaler Katalog) +
SupplierControlMaturity.

- VDA-ISA-2027-Kap.-6-Mini-Katalog (Controls 6.1.1–6.1.3) mit Zielbild,
  Muss/Soll, Anforderungen für hoch/sehr hoch, Simplified Group
  Assessment, Ziel-Reifegrad 3 und Cross-Referenzen (ISO/NIST/BSI); im
  Seed befüllt
- Lieferantenverzeichnis mit KPIs (gesamt, NIS2-relevant, ablaufend,
  Reviews fällig), Kritikalität, NIS2-Flag, Review-Fristen
- Detail-Popup: Stammdaten (Sektor/Leistung/Datenkategorien/CIA),
  betroffene Assets, VDA-ISA-Reifegrade je Control (Ziel 3, farbige
  Balken), Nachweise (Angemessenheit + Ablauf), Assessments, Verträge
  (AV/DPA, Flow-down, Fristen), NDAs (Fristen), Shared-Responsibility-
  Matrix, Subunternehmer, Managemententscheidungen
- Bearbeiten-Popup: Stammdaten (ein Speichern), Reifegrad je Control,
  Add/Delete für alle Kind-Entitäten, Löschen im ⋯-Menü
- Regel 6.1.1: fehlt geprüfter Audit-/TISAX-Nachweis → Warnung, dass
  eine dokumentierte risikobasierte Managemententscheidung nötig ist
- Server-Actions mit Zod/RBAC/Audit-Log; Seed mit Demo-Lieferant
  (TISAX-Label, AV/DPA, NDA, Assessment, RACI, Reifegrade)
- Menüpunkt „Lieferanten" aktiv; Lieferant ↔ Asset verknüpft (Graph)

Verifiziert: Register/Detail/Bearbeiten dunkel & vollständig, Reifegrad-
Save (6.1.2→4 mit Audit), Managemententscheidungs-Logik.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Martin
2026-07-03 10:23:02 +02:00
co-authored by Claude Opus 4.8
parent 18bd82e54a
commit 32ab91efbf
12 changed files with 2110 additions and 1 deletions
@@ -0,0 +1,260 @@
-- CreateEnum
CREATE TYPE "SupplierStatus" AS ENUM ('ACTIVE', 'ONBOARDING', 'UNDER_REVIEW', 'OFFBOARDED');
-- CreateEnum
CREATE TYPE "AssessmentType" AS ENUM ('QUESTIONNAIRE', 'SELF_ASSESSMENT', 'AUDIT');
-- CreateEnum
CREATE TYPE "AssessmentStatus" AS ENUM ('SENT', 'RECEIVED', 'EVALUATED', 'OVERDUE');
-- CreateEnum
CREATE TYPE "EvidenceKind" AS ENUM ('CERTIFICATE', 'TISAX_LABEL', 'ATTESTATION', 'AUDIT_REPORT', 'SELF_ASSESSMENT');
-- CreateEnum
CREATE TYPE "ResponsibleParty" AS ENUM ('CLIENT', 'SUPPLIER', 'SHARED');
-- CreateTable
CREATE TABLE "suppliers" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"ref_no" INTEGER NOT NULL,
"name" TEXT NOT NULL,
"sector" TEXT,
"services" TEXT,
"criticality" INTEGER NOT NULL DEFAULT 1,
"data_categories" TEXT[] DEFAULT ARRAY[]::TEXT[],
"confidentiality" INTEGER NOT NULL DEFAULT 1,
"integrity" INTEGER NOT NULL DEFAULT 1,
"availability" INTEGER NOT NULL DEFAULT 1,
"nis2_relevant" BOOLEAN NOT NULL DEFAULT false,
"status" "SupplierStatus" NOT NULL DEFAULT 'ACTIVE',
"contact" TEXT,
"next_review" TIMESTAMP(3),
"notes" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
CONSTRAINT "suppliers_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "supplier_assets" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"asset_id" TEXT NOT NULL,
CONSTRAINT "supplier_assets_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "supplier_assessments" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"type" "AssessmentType" NOT NULL,
"status" "AssessmentStatus" NOT NULL DEFAULT 'SENT',
"score" INTEGER,
"date" TIMESTAMP(3),
"next_review" TIMESTAMP(3),
"result" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "supplier_assessments_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "contracts" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"type" TEXT NOT NULL DEFAULT 'service',
"av_dpa" BOOLEAN NOT NULL DEFAULT false,
"security_clauses" BOOLEAN NOT NULL DEFAULT false,
"flowdown" BOOLEAN NOT NULL DEFAULT false,
"customer_transparency" BOOLEAN NOT NULL DEFAULT false,
"valid_from" TIMESTAMP(3),
"valid_to" TIMESTAMP(3),
"reference" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "contracts_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ndas" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"parties" TEXT,
"info_scope" TEXT,
"subject" TEXT,
"valid_from" TIMESTAMP(3),
"valid_to" TIMESTAMP(3),
"obligations" TEXT,
"extension_status" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ndas_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "supplier_evidence" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"kind" "EvidenceKind" NOT NULL,
"name" TEXT,
"protects_cia" TEXT,
"valid_to" TIMESTAMP(3),
"adequacy_checked" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "supplier_evidence_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "service_responsibilities" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"it_service" TEXT NOT NULL,
"requirement" TEXT NOT NULL,
"responsible_party" "ResponsibleParty" NOT NULL DEFAULT 'SHARED',
"isa_applicability" TEXT,
"evidence" TEXT,
"integrated_local_controls" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "service_responsibilities_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "subcontractors" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"flowdown_obligation" BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT "subcontractors_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "management_decisions" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"reason_no_audit" TEXT NOT NULL,
"decision" TEXT NOT NULL,
"decided_by" TEXT,
"date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"record_ref" TEXT,
CONSTRAINT "management_decisions_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "supplier_controls" (
"id" TEXT NOT NULL,
"ref" TEXT NOT NULL,
"title" TEXT NOT NULL,
"objective" TEXT NOT NULL,
"must_req" TEXT,
"should_req" TEXT,
"high_req" TEXT,
"very_high_req" TEXT,
"simplified_group_assessment" BOOLEAN NOT NULL DEFAULT false,
"target_maturity" INTEGER NOT NULL DEFAULT 3,
"references" TEXT,
CONSTRAINT "supplier_controls_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "supplier_control_maturity" (
"id" TEXT NOT NULL,
"tenant_id" TEXT NOT NULL,
"supplier_id" TEXT NOT NULL,
"control_id" TEXT NOT NULL,
"maturity" INTEGER NOT NULL DEFAULT 0,
"notes" TEXT,
CONSTRAINT "supplier_control_maturity_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "suppliers_tenant_id_idx" ON "suppliers"("tenant_id");
-- CreateIndex
CREATE UNIQUE INDEX "suppliers_tenant_id_ref_no_key" ON "suppliers"("tenant_id", "ref_no");
-- CreateIndex
CREATE INDEX "supplier_assets_tenant_id_idx" ON "supplier_assets"("tenant_id");
-- CreateIndex
CREATE UNIQUE INDEX "supplier_assets_supplier_id_asset_id_key" ON "supplier_assets"("supplier_id", "asset_id");
-- CreateIndex
CREATE INDEX "supplier_assessments_tenant_id_idx" ON "supplier_assessments"("tenant_id");
-- CreateIndex
CREATE INDEX "contracts_tenant_id_idx" ON "contracts"("tenant_id");
-- CreateIndex
CREATE INDEX "ndas_tenant_id_idx" ON "ndas"("tenant_id");
-- CreateIndex
CREATE INDEX "supplier_evidence_tenant_id_idx" ON "supplier_evidence"("tenant_id");
-- CreateIndex
CREATE INDEX "service_responsibilities_tenant_id_idx" ON "service_responsibilities"("tenant_id");
-- CreateIndex
CREATE INDEX "subcontractors_tenant_id_idx" ON "subcontractors"("tenant_id");
-- CreateIndex
CREATE INDEX "management_decisions_tenant_id_idx" ON "management_decisions"("tenant_id");
-- CreateIndex
CREATE UNIQUE INDEX "supplier_controls_ref_key" ON "supplier_controls"("ref");
-- CreateIndex
CREATE INDEX "supplier_control_maturity_tenant_id_idx" ON "supplier_control_maturity"("tenant_id");
-- CreateIndex
CREATE UNIQUE INDEX "supplier_control_maturity_supplier_id_control_id_key" ON "supplier_control_maturity"("supplier_id", "control_id");
-- AddForeignKey
ALTER TABLE "supplier_assets" ADD CONSTRAINT "supplier_assets_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "supplier_assets" ADD CONSTRAINT "supplier_assets_asset_id_fkey" FOREIGN KEY ("asset_id") REFERENCES "assets"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "supplier_assessments" ADD CONSTRAINT "supplier_assessments_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ndas" ADD CONSTRAINT "ndas_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "supplier_evidence" ADD CONSTRAINT "supplier_evidence_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "service_responsibilities" ADD CONSTRAINT "service_responsibilities_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "subcontractors" ADD CONSTRAINT "subcontractors_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "management_decisions" ADD CONSTRAINT "management_decisions_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "supplier_control_maturity" ADD CONSTRAINT "supplier_control_maturity_supplier_id_fkey" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "supplier_control_maturity" ADD CONSTRAINT "supplier_control_maturity_control_id_fkey" FOREIGN KEY ("control_id") REFERENCES "supplier_controls"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,16 @@
-- RLS-Policies für die Lieferanten-Tabellen (analog zu row_level_security)
DO $$
DECLARE t text;
BEGIN
FOREACH t IN ARRAY ARRAY[
'suppliers','supplier_assets','supplier_assessments','contracts','ndas',
'supplier_evidence','service_responsibilities','subcontractors',
'management_decisions','supplier_control_maturity'
] LOOP
EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY', t);
EXECUTE format(
'CREATE POLICY tenant_isolation ON %I USING (tenant_id = current_setting(''app.tenant_id'', true))',
t
);
END LOOP;
END $$;
+248
View File
@@ -166,6 +166,7 @@ model Asset {
relationsTo AssetRelation[] @relation("relationTo")
processAssets ProcessAsset[]
riskAssets RiskAsset[]
supplierLinks SupplierAsset[]
@@index([tenantId])
@@index([tenantId, type])
@@ -396,6 +397,253 @@ model Vulnerability {
@@map("vulnerabilities")
}
// ── Lieferantenmanagement (SPEC §4.14, VDA-ISA 2027 Kap. 6, NIS2 Art. 21(2)(d)) ──
enum SupplierStatus {
ACTIVE
ONBOARDING
UNDER_REVIEW
OFFBOARDED
}
enum AssessmentType {
QUESTIONNAIRE
SELF_ASSESSMENT
AUDIT
}
enum AssessmentStatus {
SENT
RECEIVED
EVALUATED
OVERDUE
}
enum EvidenceKind {
CERTIFICATE
TISAX_LABEL
ATTESTATION
AUDIT_REPORT
SELF_ASSESSMENT
}
enum ResponsibleParty {
CLIENT
SUPPLIER
SHARED
}
model Supplier {
id String @id @default(cuid())
tenantId String @map("tenant_id")
refNo Int @map("ref_no") // Anzeige "L-001"
name String
sector String?
services String? // erbrachte Leistung / IT-Services
criticality Int @default(1) // 14
dataCategories String[] @default([]) @map("data_categories")
// Schutzbedarf der verarbeiteten Informationen (C/I/A 14)
confidentiality Int @default(1)
integrity Int @default(1)
availability Int @default(1)
nis2Relevant Boolean @default(false) @map("nis2_relevant") // Teil der Lieferkette
status SupplierStatus @default(ACTIVE)
contact String?
nextReview DateTime? @map("next_review")
notes String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
assessments SupplierAssessment[]
contracts Contract[]
ndas Nda[]
evidence SupplierEvidence[]
responsibilities ServiceResponsibility[]
subcontractors Subcontractor[]
decisions ManagementDecision[]
controlMaturity SupplierControlMaturity[]
assetLinks SupplierAsset[]
@@unique([tenantId, refNo])
@@index([tenantId])
@@map("suppliers")
}
// Lieferant ↔ Asset (welcher Dienstleister betrifft welche Assets) — speist den Graph
model SupplierAsset {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
assetId String @map("asset_id")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
asset Asset @relation(fields: [assetId], references: [id], onDelete: Cascade)
@@unique([supplierId, assetId])
@@index([tenantId])
@@map("supplier_assets")
}
model SupplierAssessment {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
type AssessmentType
status AssessmentStatus @default(SENT)
score Int? // 0100 Scoring
date DateTime?
nextReview DateTime? @map("next_review")
result String?
createdAt DateTime @default(now()) @map("created_at")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("supplier_assessments")
}
model Contract {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
type String @default("service") // service | av_dpa | nda | sla …
avDpa Boolean @default(false) @map("av_dpa") // AV/DPA (DSGVO Art. 28)
securityClauses Boolean @default(false) @map("security_clauses")
flowdown Boolean @default(false) // Weitergabe an Subunternehmer
customerTransparency Boolean @default(false) @map("customer_transparency")
validFrom DateTime? @map("valid_from")
validTo DateTime? @map("valid_to")
reference String?
createdAt DateTime @default(now()) @map("created_at")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("contracts")
}
model Nda {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
parties String?
infoScope String? @map("info_scope")
subject String?
validFrom DateTime? @map("valid_from")
validTo DateTime? @map("valid_to")
obligations String?
extensionStatus String? @map("extension_status") // z. B. offen | verlängert | ausgelaufen
createdAt DateTime @default(now()) @map("created_at")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("ndas")
}
model SupplierEvidence {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
kind EvidenceKind
name String?
protectsCia String? @map("protects_cia") // z. B. "C,I,A"
validTo DateTime? @map("valid_to")
adequacyChecked Boolean @default(false) @map("adequacy_checked")
createdAt DateTime @default(now()) @map("created_at")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("supplier_evidence")
}
model ServiceResponsibility {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
itService String @map("it_service")
requirement String
responsibleParty ResponsibleParty @default(SHARED) @map("responsible_party")
isaApplicability String? @map("isa_applicability")
evidence String?
integratedLocalControls String? @map("integrated_local_controls")
createdAt DateTime @default(now()) @map("created_at")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("service_responsibilities")
}
model Subcontractor {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
name String
flowdownObligation Boolean @default(false) @map("flowdown_obligation")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("subcontractors")
}
model ManagementDecision {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
reasonNoAudit String @map("reason_no_audit")
decision String
decidedBy String? @map("decided_by")
date DateTime @default(now())
recordRef String? @map("record_ref")
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@map("management_decisions")
}
// VDA-ISA 2027 Kapitel 6 — Supplier Relationships (globaler Katalog, per Import versioniert)
model SupplierControl {
id String @id @default(cuid())
ref String @unique // 6.1.1 / 6.1.2 / 6.1.3
title String
objective String
mustReq String? @map("must_req")
shouldReq String? @map("should_req")
highReq String? @map("high_req") // Additional for high protection
veryHighReq String? @map("very_high_req") // Additional for very high protection
simplifiedGroupAssessment Boolean @default(false) @map("simplified_group_assessment")
targetMaturity Int @default(3) @map("target_maturity")
references String? // ISO 27001, NIST CSF, BSI …
maturity SupplierControlMaturity[]
@@map("supplier_controls")
}
model SupplierControlMaturity {
id String @id @default(cuid())
tenantId String @map("tenant_id")
supplierId String @map("supplier_id")
controlId String @map("control_id")
maturity Int @default(0) // 05
notes String?
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
control SupplierControl @relation(fields: [controlId], references: [id], onDelete: Cascade)
@@unique([supplierId, controlId])
@@index([tenantId])
@@map("supplier_control_maturity")
}
model AuditLog {
id String @id @default(cuid())
tenantId String @map("tenant_id")
+164
View File
@@ -452,6 +452,170 @@ async function main() {
}
console.log(`${measures.length} Beispiel-Maßnahmen angelegt, Rest-Risiken berechnet`);
}
// 8. VDA-ISA 2027 Kapitel 6 — Supplier Relationships (globaler Katalog)
const controls = [
{
ref: "6.1.1",
title:
"To what extent is information security ensured among contractors and cooperation partners?",
objective:
"Ein angemessenes Informationssicherheitsniveau wird auch bei der Zusammenarbeit mit Partnern und Auftragnehmern aufrechterhalten.",
mustReq:
"Auftragnehmer/Partner werden einer Sicherheits­risikobewertung unterzogen; angemessenes Niveau vertraglich sichergestellt; Kundenanforderungen ggf. weitergegeben.",
shouldReq:
"Vertragliche Verpflichtung zur Weitergabe an Subunternehmer; Prüfung von Service-Reports/Dokumenten.",
highReq:
"Nachweis eines angemessenen Sicherheitsniveaus (geprüfter Fragebogen/Self-Assessment, Attest, Zertifikat, Lieferantenaudit) (C,I,A); Compliance dokumentiert, regelmäßig & anlassbezogen überwacht.",
veryHighReq:
"Nachweis durch Third-Party-Audit (adäquates TISAX-Label o. Ä.) oder Lieferantenaudit; ohne Audit: risikobasierte Management­entscheidung mit Protokoll (C,I,A); Transparenzpflichten gegenüber Kunden erfüllt.",
targetMaturity: 3,
simplifiedGroupAssessment: true,
references:
"ISO 27001:2022 A.5.19A.5.22 · NIST CSF 2.0 GV.SC-02..06 · BSI OPS.2.1/OPS.2.2/OPS.3.1/ORP.2 · NIST SP800-53r5 MA-4, CA-3, CA-6, PM-16, PM-30, SR-2, SR-3, SR-6, SR-7, SR-8",
},
{
ref: "6.1.2",
title:
"To what extent is non-disclosure regarding the exchange of information contractually agreed?",
objective:
"Geheimhaltungsvereinbarungen schützen den Informationsaustausch über Organisationsgrenzen hinweg rechtlich.",
mustReq:
"Geheimhaltungs­anforderungen bestimmt und erfüllt; allen Beteiligten bekannt; gültige NDAs vor Weitergabe sensibler Infos; regelmäßige Überprüfung.",
shouldReq:
"Geprüfte NDA-Vorlagen; NDAs mit Parteien, Informationsart, Gegenstand, Gültigkeit, Pflichten; Nachweis-/Auditrechte; Prozess zur Fristenüberwachung und rechtzeitigen Verlängerung.",
highReq: null,
veryHighReq: null,
targetMaturity: 3,
simplifiedGroupAssessment: true,
references: "ISO 27001:2022 A.5.14, A.6.6 · BSI OPS.2.1/OPS.2.2/OPS.3.1/ORP.5/CON.2",
},
{
ref: "6.1.3",
title:
"To what extent are the responsibilities between external IT service providers and the own organization defined?",
objective:
"Gemeinsames Verständnis der Verantwortungsteilung; alle Sicherheitsanforderungen umgesetzt und nachweislich dokumentiert.",
mustReq:
"Betroffene IT-Services identifiziert; Anforderungen bestimmt; verantwortliche Organisation je Anforderung definiert; Mechanismen für geteilte Verantwortung umgesetzt.",
shouldReq:
"Konfiguration konzeptioniert/umgesetzt/dokumentiert; zuständiges Personal geschult.",
highReq:
"Liste der IT-Services und Provider (C,I,A); ISA-Control-Anwendbarkeit bewertet; regelmäßige Security-Assessments; Nachweis der Pflichterfüllung; Integration in lokale Schutzmaßnahmen dokumentiert.",
veryHighReq: null,
targetMaturity: 3,
simplifiedGroupAssessment: false,
references:
"ISO 27001:2022 A.5.23, A.8.9 · ISO 27017 CLD.6.3.1 · IEC 62443-2-1 6.2.3 · NIST CSF 2.0 GV.OC-05, GV.SC-01/02 · BSI 200-2, OPS.2.1/OPS.2.2/OPS.3.1/ORP.2 · NIST SP800-53r5 MA-4, PT-1, PL-2",
},
];
for (const c of controls) {
await prisma.supplierControl.upsert({ where: { ref: c.ref }, update: c, create: c });
}
console.log(`✔ VDA-ISA 2027 Kap. 6: ${controls.length} Supplier-Controls`);
// 9. Demo-Lieferant mit Nachweisen/Verträgen (nur wenn noch keiner existiert)
const supplierCount = await prisma.supplier.count({ where: { tenantId: tenant.id } });
if (supplierCount === 0) {
const hoster = await prisma.asset.findFirst({
where: { tenantId: tenant.id, name: "Cloud-Hoster (IaaS)" },
});
const sup = await prisma.supplier.create({
data: {
tenantId: tenant.id,
refNo: 1,
name: "Cloud-Hoster GmbH",
sector: "IT-Dienstleistung / IaaS",
services: "Rechenzentrum, Virtualisierung, Backup für ERP & CRM",
criticality: 4,
dataCategories: ["Kundendaten", "Auftragsdaten"],
confidentiality: 3,
integrity: 3,
availability: 4,
nis2Relevant: true,
status: "ACTIVE",
contact: "security@cloud-hoster.example",
nextReview: new Date(Date.now() + 90 * 24 * 3600 * 1000),
},
});
if (hoster) {
await prisma.supplierAsset.create({
data: { tenantId: tenant.id, supplierId: sup.id, assetId: hoster.id },
});
}
await prisma.supplierEvidence.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
kind: "TISAX_LABEL",
name: "TISAX AL3 (info high)",
protectsCia: "C,I,A",
validTo: new Date(Date.now() + 200 * 24 * 3600 * 1000),
adequacyChecked: true,
},
});
await prisma.contract.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
type: "av_dpa",
avDpa: true,
securityClauses: true,
flowdown: true,
customerTransparency: false,
validFrom: new Date(Date.now() - 300 * 24 * 3600 * 1000),
validTo: new Date(Date.now() + 400 * 24 * 3600 * 1000),
reference: "AV-2025-014",
},
});
await prisma.nda.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
parties: "Demo GmbH ↔ Cloud-Hoster GmbH",
infoScope: "Betriebs- und Kundendaten",
subject: "Betrieb der ERP-/CRM-Infrastruktur",
validFrom: new Date(Date.now() - 300 * 24 * 3600 * 1000),
validTo: new Date(Date.now() + 60 * 24 * 3600 * 1000),
extensionStatus: "offen",
},
});
await prisma.supplierAssessment.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
type: "SELF_ASSESSMENT",
status: "EVALUATED",
score: 82,
date: new Date(Date.now() - 120 * 24 * 3600 * 1000),
nextReview: new Date(Date.now() + 245 * 24 * 3600 * 1000),
result: "angemessen",
},
});
await prisma.serviceResponsibility.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
itService: "IaaS-Plattform",
requirement: "Patch-Management der Hypervisor-Ebene",
responsibleParty: "SUPPLIER",
isaApplicability: "5.x IT/Cyber Security",
integratedLocalControls: "Sichere Authentisierung, Monitoring beim Kunden",
},
});
const dbControls = await prisma.supplierControl.findMany();
for (const c of dbControls) {
await prisma.supplierControlMaturity.create({
data: {
tenantId: tenant.id,
supplierId: sup.id,
controlId: c.id,
maturity: c.ref === "6.1.2" ? 2 : 3,
},
});
}
console.log("✔ Demo-Lieferant mit Nachweisen/Vertrag/NDA/Assessment angelegt");
}
}
main()