refactor(admin): split vvt page.tsx into colocated components
Split the 1371-line VVT page into _components/ extractions (FormPrimitives, api, TabVerzeichnis, TabEditor, TabExport) to bring page.tsx under the 300 LOC soft target. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
140
admin-compliance/app/sdk/vvt/_components/api.ts
Normal file
140
admin-compliance/app/sdk/vvt/_components/api.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import type { VVTActivity, VVTOrganizationHeader } from '@/lib/sdk/vvt-types'
|
||||
|
||||
export const VVT_API_BASE = '/api/sdk/v1/compliance/vvt'
|
||||
|
||||
export function activityFromApi(raw: any): VVTActivity {
|
||||
return {
|
||||
id: raw.id,
|
||||
vvtId: raw.vvt_id,
|
||||
name: raw.name || '',
|
||||
description: raw.description || '',
|
||||
purposes: raw.purposes || [],
|
||||
legalBases: raw.legal_bases || [],
|
||||
dataSubjectCategories: raw.data_subject_categories || [],
|
||||
personalDataCategories: raw.personal_data_categories || [],
|
||||
recipientCategories: raw.recipient_categories || [],
|
||||
thirdCountryTransfers: raw.third_country_transfers || [],
|
||||
retentionPeriod: raw.retention_period || { description: '' },
|
||||
tomDescription: raw.tom_description || '',
|
||||
businessFunction: raw.business_function || 'other',
|
||||
systems: raw.systems || [],
|
||||
deploymentModel: raw.deployment_model || 'cloud',
|
||||
dataSources: raw.data_sources || [],
|
||||
dataFlows: raw.data_flows || [],
|
||||
protectionLevel: raw.protection_level || 'MEDIUM',
|
||||
dpiaRequired: raw.dpia_required || false,
|
||||
structuredToms: raw.structured_toms || { accessControl: [], confidentiality: [], integrity: [], availability: [], separation: [] },
|
||||
status: raw.status || 'DRAFT',
|
||||
responsible: raw.responsible || '',
|
||||
owner: raw.owner || '',
|
||||
createdAt: raw.created_at || new Date().toISOString(),
|
||||
updatedAt: raw.updated_at || raw.created_at || new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
export function activityToApi(act: VVTActivity): Record<string, unknown> {
|
||||
return {
|
||||
vvt_id: act.vvtId,
|
||||
name: act.name,
|
||||
description: act.description,
|
||||
purposes: act.purposes,
|
||||
legal_bases: act.legalBases,
|
||||
data_subject_categories: act.dataSubjectCategories,
|
||||
personal_data_categories: act.personalDataCategories,
|
||||
recipient_categories: act.recipientCategories,
|
||||
third_country_transfers: act.thirdCountryTransfers,
|
||||
retention_period: act.retentionPeriod,
|
||||
tom_description: act.tomDescription,
|
||||
business_function: act.businessFunction,
|
||||
systems: act.systems,
|
||||
deployment_model: act.deploymentModel,
|
||||
data_sources: act.dataSources,
|
||||
data_flows: act.dataFlows,
|
||||
protection_level: act.protectionLevel,
|
||||
dpia_required: act.dpiaRequired,
|
||||
structured_toms: act.structuredToms,
|
||||
status: act.status,
|
||||
responsible: act.responsible,
|
||||
owner: act.owner,
|
||||
}
|
||||
}
|
||||
|
||||
export function orgHeaderFromApi(raw: any): VVTOrganizationHeader {
|
||||
return {
|
||||
organizationName: raw.organization_name || '',
|
||||
industry: raw.industry || '',
|
||||
locations: raw.locations || [],
|
||||
employeeCount: raw.employee_count || 0,
|
||||
dpoName: raw.dpo_name || '',
|
||||
dpoContact: raw.dpo_contact || '',
|
||||
vvtVersion: raw.vvt_version || '1.0',
|
||||
lastReviewDate: raw.last_review_date || '',
|
||||
nextReviewDate: raw.next_review_date || '',
|
||||
reviewInterval: raw.review_interval || 'annual',
|
||||
}
|
||||
}
|
||||
|
||||
export function orgHeaderToApi(org: VVTOrganizationHeader): Record<string, unknown> {
|
||||
return {
|
||||
organization_name: org.organizationName,
|
||||
industry: org.industry,
|
||||
locations: org.locations,
|
||||
employee_count: org.employeeCount,
|
||||
dpo_name: org.dpoName,
|
||||
dpo_contact: org.dpoContact,
|
||||
vvt_version: org.vvtVersion,
|
||||
last_review_date: org.lastReviewDate || null,
|
||||
next_review_date: org.nextReviewDate || null,
|
||||
review_interval: org.reviewInterval,
|
||||
}
|
||||
}
|
||||
|
||||
export async function apiListActivities(): Promise<VVTActivity[]> {
|
||||
const res = await fetch(`${VVT_API_BASE}/activities`)
|
||||
if (!res.ok) throw new Error(`GET activities failed: ${res.status}`)
|
||||
const data = await res.json()
|
||||
return data.map(activityFromApi)
|
||||
}
|
||||
|
||||
export async function apiGetOrganization(): Promise<VVTOrganizationHeader | null> {
|
||||
const res = await fetch(`${VVT_API_BASE}/organization`)
|
||||
if (!res.ok) return null
|
||||
const data = await res.json()
|
||||
if (!data) return null
|
||||
return orgHeaderFromApi(data)
|
||||
}
|
||||
|
||||
export async function apiCreateActivity(act: VVTActivity): Promise<VVTActivity> {
|
||||
const res = await fetch(`${VVT_API_BASE}/activities`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(activityToApi(act)),
|
||||
})
|
||||
if (!res.ok) throw new Error(`POST activity failed: ${res.status}`)
|
||||
return activityFromApi(await res.json())
|
||||
}
|
||||
|
||||
export async function apiUpdateActivity(id: string, act: VVTActivity): Promise<VVTActivity> {
|
||||
const res = await fetch(`${VVT_API_BASE}/activities/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(activityToApi(act)),
|
||||
})
|
||||
if (!res.ok) throw new Error(`PUT activity failed: ${res.status}`)
|
||||
return activityFromApi(await res.json())
|
||||
}
|
||||
|
||||
export async function apiDeleteActivity(id: string): Promise<void> {
|
||||
const res = await fetch(`${VVT_API_BASE}/activities/${id}`, { method: 'DELETE' })
|
||||
if (!res.ok) throw new Error(`DELETE activity failed: ${res.status}`)
|
||||
}
|
||||
|
||||
export async function apiUpsertOrganization(org: VVTOrganizationHeader): Promise<VVTOrganizationHeader> {
|
||||
const res = await fetch(`${VVT_API_BASE}/organization`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(orgHeaderToApi(org)),
|
||||
})
|
||||
if (!res.ok) throw new Error(`PUT organization failed: ${res.status}`)
|
||||
return orgHeaderFromApi(await res.json())
|
||||
}
|
||||
Reference in New Issue
Block a user