# SDK Workflow — Sequenznummern & Navigation Vollständige Referenz für das SDK-Workflow-System: Sequenznummern, Pakete, bedingte Sichtbarkeit und Navigationsfunktionen. **Quelle:** `admin-compliance/lib/sdk/types.ts` --- ## Konzept Jeder SDK-Schritt (Step) hat eine **globale Sequenznummer** (`seq`), die seine Position im gesamten Workflow eindeutig bestimmt — unabhängig vom Paket. ### Warum seq statt order? Das alte `order`-Feld war paket-lokal (1, 2, 3 innerhalb eines Pakets). Das führte zu Problemen: - Paket-zu-Paket-Navigation war hardcoded (Phasen 1→2) - Neue Steps konnten nicht einfach zwischen bestehende Steps eingefügt werden - Bedingte Sichtbarkeit (DSFA nur bei L2+) war nicht systematisch Das `seq`-System löst alle drei Probleme: - Navigation basiert auf globalem `seq`-Sort → kein hardcoded Phasenwechsel - 100er-Lücken zwischen Steps erlauben späteres Einfügen ohne Umnummerierung - `visibleWhen`-Funktion pro Step steuert Sichtbarkeit state-abhängig --- ## Lücken-Konvention ``` 100er-Lücken: innerhalb eines Pakets (Platz für 9 neue Steps zwischen je zwei) 300er-Lücken: an Paket-Grenzen (700→1000, 1600→2000, 2400→3000, 3400→4000) ``` Beispiel — neuer Step zwischen `requirements` (1000) und `controls` (1100): → `seq: 1050` vergeben, `order` entsprechend setzen. **Ausnahme `email-templates` (seq 4350):** Nachträglich zwischen `consent-management` (4300) und `notfallplan` (4400) eingefügt — nutzt die Hälfte der Lücke. --- ## Vollständige Step-Tabelle ### Paket 1 — Vorbereitung | seq | id | Name | visibleWhen | isOptional | |-----|----|------|-------------|-----------| | 100 | `company-profile` | Unternehmensprofil | immer | nein | | 200 | `compliance-scope` | Compliance Scope | immer | nein | | 300 | `use-case-assessment` | Anwendungsfall-Erfassung | immer | nein | | 400 | `import` | Dokument-Import | `customerType === 'existing'` | **ja** | | 500 | `screening` | System Screening | immer | nein | | 600 | `modules` | Compliance Modules | immer | nein | | 700 | `source-policy` | Source Policy | immer | nein | ### Paket 2 — Analyse | seq | id | Name | visibleWhen | isOptional | |-----|----|------|-------------|-----------| | 1000 | `requirements` | Requirements | immer | nein | | 1100 | `controls` | Controls | immer | nein | | 1200 | `evidence` | Evidence | immer | nein | | 1300 | `risks` | Risk Matrix | immer | nein | | 1400 | `ai-act` | AI Act Klassifizierung | immer | nein | | 1500 | `audit-checklist` | Audit Checklist | immer | nein | | 1600 | `audit-report` | Audit Report | immer | nein | ### Paket 3 — Dokumentation | seq | id | Name | visibleWhen | isOptional | |-----|----|------|-------------|-----------| | 2000 | `obligations` | Pflichtübersicht | immer | nein | | 2100 | `dsfa` | DSFA | Scope L2/L3/L4 oder `dsfaRequired`-Trigger | **ja** | | 2200 | `tom` | TOMs | immer | nein | | 2300 | `loeschfristen` | Löschfristen | immer | nein | | 2400 | `vvt` | VVT | immer | nein | ### Paket 4 — Rechtliche Texte | seq | id | Name | visibleWhen | isOptional | |-----|----|------|-------------|-----------| | 3000 | `einwilligungen` | Einwilligungen | immer | nein | | 3100 | `consent` | Rechtliche Vorlagen | immer | nein | | 3200 | `cookie-banner` | Cookie Banner | immer | nein | | 3300 | `document-generator` | Dokumentengenerator | immer (→ `true`) | **ja** | | 3400 | `workflow` | Document Workflow | immer | nein | ### Paket 5 — Betrieb | seq | id | Name | visibleWhen | isOptional | |-----|----|------|-------------|-----------| | 4000 | `dsr` | DSR Portal | immer | nein | | 4100 | `escalations` | Escalations | immer | nein | | 4200 | `vendor-compliance` | Vendor Compliance | immer | nein | | 4300 | `consent-management` | Consent Verwaltung | immer | nein | | 4350 | `email-templates` | E-Mail-Templates | immer | nein | | 4400 | `notfallplan` | Notfallplan & Breach Response | immer | nein | | 4500 | `incidents` | Incident Management | immer | nein | | 4600 | `whistleblower` | Hinweisgebersystem | immer | nein | | 4700 | `academy` | Compliance Academy | immer | nein | | 4800 | `training` | Training Engine | immer | nein | --- ## Bedingte Sichtbarkeit (`visibleWhen`) Drei Steps haben eine `visibleWhen`-Funktion, die den `SDKState` auswertet: ### `import` (seq 400) ```typescript visibleWhen: (state) => state.customerType === 'existing' ``` Nur sichtbar für **Bestandskunden**. Neukunden überspringen den Import-Schritt. ### `dsfa` (seq 2100) ```typescript visibleWhen: (state) => { const level = state.complianceScope?.decision?.determinedLevel if (level && ['L2', 'L3', 'L4'].includes(level)) return true const triggers = state.complianceScope?.decision?.triggeredHardTriggers || [] return triggers.some(t => t.rule.dsfaRequired) } ``` Sichtbar wenn: - Compliance-Scope-Level **L2, L3 oder L4** ermittelt wurde, **oder** - Ein Hard-Trigger mit `dsfaRequired: true` ausgelöst wurde (z.B. Gesundheitsdaten, Minderjährige, Hochrisiko-KI) Bei **L1-Kunden ohne DSFA-Trigger** ist der Schritt unsichtbar — TOM folgt direkt nach `obligations`. ### `document-generator` (seq 3300) ```typescript visibleWhen: () => true ``` Immer sichtbar, aber `isOptional: true` — kann übersprungen werden. --- ## Prerequisite-Kette Steps sind sequenziell verknüpft. Wichtige Besonderheiten: | Step | prerequisiteSteps | Hinweis | |------|-------------------|---------| | `dsfa` | `['obligations']` | Nicht von `audit-report` abhängig | | `tom` | `['obligations']` | Nicht von `dsfa` abhängig (da optional) | | `workflow` | `['cookie-banner']` | Nicht von `document-generator` abhängig (da optional) | **Regel:** Optionale Steps (`isOptional: true`) dürfen **keine** Pflicht-Steps als Voraussetzung haben. --- ## Navigationsfunktionen Alle Funktionen in `admin-compliance/lib/sdk/types.ts`: ```typescript // Alle Steps global nach seq sortiert (privat) function getAllStepsSorted(): SDKStep[] // Sichtbare Steps für aktuellen State export function getVisibleSteps(state: SDKState): SDKStep[] // Nächster/vorheriger sichtbarer Step export function getNextVisibleStep(currentStepId: string, state: SDKState): SDKStep | undefined export function getPreviousVisibleStep(currentStepId: string, state: SDKState): SDKStep | undefined // Rückwärtskompatible Wrapper (state optional) export function getNextStep(currentStepId: string, state?: SDKState): SDKStep | undefined export function getPreviousStep(currentStepId: string, state?: SDKState): SDKStep | undefined // Package/Phase gefiltert, seq-sortiert export function getStepsForPackage(packageId: SDKPackageId): SDKStep[] export function getStepsForPhase(phase: SDKPhase): SDKStep[] ``` ### Verhalten ohne `state` Wird kein State übergeben (Fallback), navigiert `getNextStep`/`getPreviousStep` seq-sortiert **ohne** `visibleWhen`-Filter. Das ist für Initialisierung und Tests nützlich. ### Context-Integration `admin-compliance/lib/sdk/context.tsx` übergibt den State automatisch: ```typescript const goToNextStep = useCallback(() => { const nextStep = getNextStep(state.currentStep, state) // state mitgeben! if (nextStep) goToStep(nextStep.id) }, [state, goToStep]) const canGoNext = useMemo(() => { return getNextStep(state.currentStep, state) !== undefined }, [state]) ``` --- ## Neuen Step einfügen 1. **seq wählen:** Freien Wert in der gewünschten Lücke wählen (z.B. 1050 zwischen 1000 und 1100) 2. **Step-Eintrag anlegen** in `SDK_STEPS` (types.ts): ```typescript { id: 'my-new-step', seq: 1050, phase: 1, package: 'analyse', order: 2, // Lokale Ordnung innerhalb des Pakets name: 'Neuer Step', nameShort: 'Neu', description: 'Beschreibung', url: '/sdk/my-new-step', checkpointId: 'CP-NEW', prerequisiteSteps: ['requirements'], isOptional: false, // optional: visibleWhen: (state) => state.someFlag === true, } ``` 3. **Frontend-Seite** anlegen: `admin-compliance/app/sdk/my-new-step/page.tsx` 4. **Docs** erstellen: `docs-src/services/sdk-modules/my-new-step.md` 5. **mkdocs.yml** nav-Eintrag hinzufügen --- ## Deprecated ```typescript /** @deprecated Use getVisibleSteps(state) instead */ export function getVisibleStepsForCustomerType(customerType: CustomerType): SDKStep[] ``` Diese Funktion filtert nur den `import`-Step nach Kundentyp — nicht state-aware. Bitte `getVisibleSteps(state)` verwenden.