Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
151 lines
4.9 KiB
TypeScript
151 lines
4.9 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
/**
|
|
* SDK Flow API
|
|
*
|
|
* GET /api/sdk/v1/flow - Get current flow state and suggestions
|
|
* POST /api/sdk/v1/flow/next - Navigate to next step
|
|
* POST /api/sdk/v1/flow/previous - Navigate to previous step
|
|
*/
|
|
|
|
const SDK_STEPS = [
|
|
// Phase 1
|
|
{ id: 'company-profile', phase: 1, order: 1, name: 'Unternehmensprofil', url: '/sdk/company-profile' },
|
|
{ id: 'use-case-assessment', phase: 1, order: 2, name: 'Anwendungsfall-Erfassung', url: '/sdk/advisory-board' },
|
|
{ id: 'screening', phase: 1, order: 3, name: 'System Screening', url: '/sdk/screening' },
|
|
{ id: 'modules', phase: 1, order: 4, name: 'Compliance Modules', url: '/sdk/modules' },
|
|
{ id: 'requirements', phase: 1, order: 5, name: 'Requirements', url: '/sdk/requirements' },
|
|
{ id: 'controls', phase: 1, order: 6, name: 'Controls', url: '/sdk/controls' },
|
|
{ id: 'evidence', phase: 1, order: 7, name: 'Evidence', url: '/sdk/evidence' },
|
|
{ id: 'audit-checklist', phase: 1, order: 8, name: 'Audit Checklist', url: '/sdk/audit-checklist' },
|
|
{ id: 'risks', phase: 1, order: 9, name: 'Risk Matrix', url: '/sdk/risks' },
|
|
// Phase 2
|
|
{ id: 'ai-act', phase: 2, order: 1, name: 'AI Act Klassifizierung', url: '/sdk/ai-act' },
|
|
{ id: 'obligations', phase: 2, order: 2, name: 'Pflichtenübersicht', url: '/sdk/obligations' },
|
|
{ id: 'dsfa', phase: 2, order: 3, name: 'DSFA', url: '/sdk/dsfa' },
|
|
{ id: 'tom', phase: 2, order: 4, name: 'TOMs', url: '/sdk/tom' },
|
|
{ id: 'loeschfristen', phase: 2, order: 5, name: 'Löschfristen', url: '/sdk/loeschfristen' },
|
|
{ id: 'vvt', phase: 2, order: 6, name: 'Verarbeitungsverzeichnis', url: '/sdk/vvt' },
|
|
{ id: 'consent', phase: 2, order: 7, name: 'Rechtliche Vorlagen', url: '/sdk/consent' },
|
|
{ id: 'cookie-banner', phase: 2, order: 8, name: 'Cookie Banner', url: '/sdk/cookie-banner' },
|
|
{ id: 'einwilligungen', phase: 2, order: 9, name: 'Einwilligungen', url: '/sdk/einwilligungen' },
|
|
{ id: 'dsr', phase: 2, order: 10, name: 'DSR Portal', url: '/sdk/dsr' },
|
|
{ id: 'escalations', phase: 2, order: 11, name: 'Escalations', url: '/sdk/escalations' },
|
|
]
|
|
|
|
function getStepIndex(stepId: string): number {
|
|
return SDK_STEPS.findIndex(s => s.id === stepId)
|
|
}
|
|
|
|
function getNextStep(currentStepId: string) {
|
|
const currentIndex = getStepIndex(currentStepId)
|
|
if (currentIndex === -1 || currentIndex >= SDK_STEPS.length - 1) {
|
|
return null
|
|
}
|
|
return SDK_STEPS[currentIndex + 1]
|
|
}
|
|
|
|
function getPreviousStep(currentStepId: string) {
|
|
const currentIndex = getStepIndex(currentStepId)
|
|
if (currentIndex <= 0) {
|
|
return null
|
|
}
|
|
return SDK_STEPS[currentIndex - 1]
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url)
|
|
const currentStepId = searchParams.get('currentStep') || 'company-profile'
|
|
|
|
const currentStep = SDK_STEPS.find(s => s.id === currentStepId)
|
|
const nextStep = getNextStep(currentStepId)
|
|
const previousStep = getPreviousStep(currentStepId)
|
|
|
|
// Generate suggestions based on context
|
|
const suggestions = [
|
|
{
|
|
type: 'NAVIGATION',
|
|
label: nextStep ? `Weiter zu ${nextStep.name}` : 'Flow abgeschlossen',
|
|
action: nextStep ? `navigate:${nextStep.url}` : null,
|
|
},
|
|
{
|
|
type: 'ACTION',
|
|
label: 'Checkpoint validieren',
|
|
action: 'validate:current',
|
|
},
|
|
{
|
|
type: 'HELP',
|
|
label: 'Hilfe anzeigen',
|
|
action: 'help:show',
|
|
},
|
|
]
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
currentStep,
|
|
nextStep,
|
|
previousStep,
|
|
totalSteps: SDK_STEPS.length,
|
|
currentIndex: getStepIndex(currentStepId) + 1,
|
|
suggestions,
|
|
steps: SDK_STEPS,
|
|
})
|
|
} catch (error) {
|
|
console.error('Failed to get flow:', error)
|
|
return NextResponse.json(
|
|
{ error: 'Failed to get flow' },
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json()
|
|
const { action, currentStepId } = body
|
|
|
|
if (!action || !currentStepId) {
|
|
return NextResponse.json(
|
|
{ error: 'action and currentStepId are required' },
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
let targetStep = null
|
|
|
|
switch (action) {
|
|
case 'next':
|
|
targetStep = getNextStep(currentStepId)
|
|
break
|
|
case 'previous':
|
|
targetStep = getPreviousStep(currentStepId)
|
|
break
|
|
default:
|
|
return NextResponse.json(
|
|
{ error: 'Invalid action' },
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
if (!targetStep) {
|
|
return NextResponse.json(
|
|
{ error: 'No target step available' },
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
targetStep,
|
|
redirectUrl: targetStep.url,
|
|
})
|
|
} catch (error) {
|
|
console.error('Failed to navigate flow:', error)
|
|
return NextResponse.json(
|
|
{ error: 'Failed to navigate flow' },
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|