'use client' // ============================================================================= // Step 3: Architecture & Hosting // Hosting model, location, and provider configuration // ============================================================================= import React, { useState, useEffect } from 'react' import { useTOMGenerator } from '@/lib/sdk/tom-generator' import { ArchitectureProfile, HostingModel, HostingLocation, MultiTenancy, CloudProvider, } from '@/lib/sdk/tom-generator/types' // ============================================================================= // CONSTANTS // ============================================================================= const HOSTING_MODELS: { value: HostingModel; label: string; description: string; icon: string }[] = [ { value: 'ON_PREMISE', label: 'On-Premise', description: 'Eigenes Rechenzentrum oder Co-Location', icon: '🏢', }, { value: 'PRIVATE_CLOUD', label: 'Private Cloud', description: 'Dedizierte Cloud-Infrastruktur', icon: '☁️', }, { value: 'PUBLIC_CLOUD', label: 'Public Cloud', description: 'AWS, Azure, GCP oder andere', icon: '🌐', }, { value: 'HYBRID', label: 'Hybrid', description: 'Kombination aus On-Premise und Cloud', icon: '🔄', }, ] const HOSTING_LOCATIONS: { value: HostingLocation; label: string; description: string }[] = [ { value: 'DE', label: 'Deutschland', description: 'Rechenzentrum in Deutschland' }, { value: 'EU', label: 'EU (nicht DE)', description: 'Innerhalb der EU, aber nicht in Deutschland' }, { value: 'EEA', label: 'EWR', description: 'Europäischer Wirtschaftsraum' }, { value: 'THIRD_COUNTRY_ADEQUATE', label: 'Drittland (Angemessenheit)', description: 'Mit Angemessenheitsbeschluss' }, { value: 'THIRD_COUNTRY', label: 'Drittland (andere)', description: 'Ohne Angemessenheitsbeschluss' }, ] const MULTI_TENANCY_OPTIONS: { value: MultiTenancy; label: string; description: string }[] = [ { value: 'SINGLE_TENANT', label: 'Single-Tenant', description: 'Dedizierte Instanz pro Kunde' }, { value: 'MULTI_TENANT', label: 'Multi-Tenant', description: 'Geteilte Infrastruktur mit logischer Trennung' }, { value: 'DEDICATED', label: 'Dedicated', description: 'Dedizierte Hardware, aber gemeinsame Software' }, ] const COMMON_CERTIFICATIONS = [ 'ISO 27001', 'SOC 2 Type II', 'C5', 'TISAX', 'PCI DSS', 'HIPAA', 'FedRAMP', ] // ============================================================================= // COMPONENT // ============================================================================= export function ArchitectureStep() { const { state, setArchitectureProfile, completeCurrentStep } = useTOMGenerator() const [formData, setFormData] = useState>({ hostingModel: 'PUBLIC_CLOUD', hostingLocation: 'EU', providers: [], multiTenancy: 'MULTI_TENANT', hasSubprocessors: false, subprocessorCount: 0, encryptionAtRest: false, encryptionInTransit: false, }) const [newProvider, setNewProvider] = useState>({ name: '', location: 'EU', certifications: [], }) const [certificationInput, setCertificationInput] = useState('') // Load existing data useEffect(() => { if (state.architectureProfile) { setFormData(state.architectureProfile) } }, [state.architectureProfile]) // Handle provider addition const addProvider = () => { if (newProvider.name?.trim()) { const provider: CloudProvider = { name: newProvider.name.trim(), location: newProvider.location || 'EU', certifications: newProvider.certifications || [], } setFormData((prev) => ({ ...prev, providers: [...(prev.providers || []), provider], })) setNewProvider({ name: '', location: 'EU', certifications: [] }) } } const removeProvider = (index: number) => { setFormData((prev) => ({ ...prev, providers: (prev.providers || []).filter((_, i) => i !== index), })) } // Handle certification toggle const toggleCertification = (cert: string) => { setNewProvider((prev) => { const current = prev.certifications || [] const updated = current.includes(cert) ? current.filter((c) => c !== cert) : [...current, cert] return { ...prev, certifications: updated } }) } // Handle submit const handleSubmit = (e: React.FormEvent) => { e.preventDefault() const profile: ArchitectureProfile = { hostingModel: formData.hostingModel || 'PUBLIC_CLOUD', hostingLocation: formData.hostingLocation || 'EU', providers: formData.providers || [], multiTenancy: formData.multiTenancy || 'MULTI_TENANT', hasSubprocessors: formData.hasSubprocessors || false, subprocessorCount: formData.subprocessorCount || 0, encryptionAtRest: formData.encryptionAtRest || false, encryptionInTransit: formData.encryptionInTransit || false, } setArchitectureProfile(profile) completeCurrentStep(profile) } const showProviderSection = formData.hostingModel !== 'ON_PREMISE' return (
{/* Hosting Model */}

Hosting-Modell

Wie wird Ihre Infrastruktur betrieben?

{HOSTING_MODELS.map((model) => ( ))}
{/* Hosting Location */}

Primärer Hosting-Standort

Wo werden die Daten primär gespeichert?

{HOSTING_LOCATIONS.map((location) => ( ))}
{formData.hostingLocation?.startsWith('THIRD_COUNTRY') && (

Hinweis: Bei Hosting in Drittländern sind zusätzliche Garantien nach Art. 46 DSGVO erforderlich (z.B. Standardvertragsklauseln).

)}
{/* Cloud Providers */} {showProviderSection && (

Cloud-Provider / Rechenzentren

FĂźgen Sie Ihre genutzten Provider hinzu.

{/* Existing providers */} {formData.providers && formData.providers.length > 0 && (
{formData.providers.map((provider, index) => (
{provider.name} ({provider.location}) {provider.certifications.length > 0 && (
{provider.certifications.map((cert) => ( {cert} ))}
)}
))}
)} {/* Add new provider */}
setNewProvider((prev) => ({ ...prev, name: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" placeholder="z.B. AWS, Azure, Hetzner" />
{COMMON_CERTIFICATIONS.map((cert) => ( ))}
)} {/* Multi-Tenancy */}

Mandantentrennung

Wie ist die Trennung zwischen verschiedenen Mandanten/Kunden umgesetzt?

{MULTI_TENANCY_OPTIONS.map((option) => ( ))}
{/* Subprocessors */}

Unterauftragsverarbeiter

{formData.hasSubprocessors && (
setFormData((prev) => ({ ...prev, subprocessorCount: parseInt(e.target.value) || 0 }))} className="w-32 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" />
)}
{/* Encryption */}

VerschlĂźsselung

) } export default ArchitectureStep