refactor: remove 473 lines of dead code across 5 SDK modules
- obligations: unused vendors state/fetch, unreachable filter==='ai' path - tom: unused vendorControlsLoading state, unused bulkUpdateTOMs import - loeschfristen: unused BASELINE_TEMPLATES imports, sdk hook, managingLegalHolds state - vvt: unused apiGetCompleteness/apiGetLibrary, 7 unused VVTLib* interfaces - vendor-compliance: 11 unused context methods, 6 unused selector hooks, ContractUploadData type Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,16 +15,9 @@ import {
|
||||
VendorComplianceAction,
|
||||
VendorComplianceContextValue,
|
||||
ProcessingActivity,
|
||||
Vendor,
|
||||
ContractDocument,
|
||||
Finding,
|
||||
Control,
|
||||
ControlInstance,
|
||||
RiskAssessment,
|
||||
VendorStatistics,
|
||||
ComplianceStatistics,
|
||||
RiskOverview,
|
||||
ExportFormat,
|
||||
VendorStatus,
|
||||
VendorRole,
|
||||
RiskLevel,
|
||||
@@ -475,24 +468,6 @@ export function VendorComplianceProvider({
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const updateProcessingActivity = useCallback(
|
||||
async (id: string, data: Partial<ProcessingActivity>): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/processing-activities/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Aktualisieren der Verarbeitungstätigkeit')
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_PROCESSING_ACTIVITY', payload: { id, data } })
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const deleteProcessingActivity = useCallback(
|
||||
async (id: string): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/processing-activities/${id}`, {
|
||||
@@ -537,49 +512,6 @@ export function VendorComplianceProvider({
|
||||
// VENDOR ACTIONS
|
||||
// ==========================================
|
||||
|
||||
const createVendor = useCallback(
|
||||
async (
|
||||
data: Omit<Vendor, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>
|
||||
): Promise<Vendor> => {
|
||||
const response = await fetch(`${apiBase}/vendors`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Erstellen des Vendors')
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
const vendor = result.data
|
||||
|
||||
dispatch({ type: 'ADD_VENDOR', payload: vendor })
|
||||
|
||||
return vendor
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const updateVendor = useCallback(
|
||||
async (id: string, data: Partial<Vendor>): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/vendors/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Aktualisieren des Vendors')
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_VENDOR', payload: { id, data } })
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const deleteVendor = useCallback(
|
||||
async (id: string): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/vendors/${id}`, {
|
||||
@@ -600,67 +532,6 @@ export function VendorComplianceProvider({
|
||||
// CONTRACT ACTIONS
|
||||
// ==========================================
|
||||
|
||||
const uploadContract = useCallback(
|
||||
async (
|
||||
vendorId: string,
|
||||
file: File,
|
||||
metadata: Partial<ContractDocument>
|
||||
): Promise<ContractDocument> => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('vendorId', vendorId)
|
||||
formData.append('metadata', JSON.stringify(metadata))
|
||||
|
||||
const response = await fetch(`${apiBase}/contracts`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Hochladen des Vertrags')
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
const contract = result.data
|
||||
|
||||
dispatch({ type: 'ADD_CONTRACT', payload: contract })
|
||||
|
||||
// Update vendor's contracts list
|
||||
const vendor = state.vendors.find((v) => v.id === vendorId)
|
||||
if (vendor) {
|
||||
dispatch({
|
||||
type: 'UPDATE_VENDOR',
|
||||
payload: {
|
||||
id: vendorId,
|
||||
data: { contracts: [...vendor.contracts, contract.id] },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return contract
|
||||
},
|
||||
[apiBase, state.vendors]
|
||||
)
|
||||
|
||||
const updateContract = useCallback(
|
||||
async (id: string, data: Partial<ContractDocument>): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/contracts/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Aktualisieren des Vertrags')
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_CONTRACT', payload: { id, data } })
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const deleteContract = useCallback(
|
||||
async (id: string): Promise<void> => {
|
||||
const contract = state.contracts.find((c) => c.id === id)
|
||||
@@ -736,125 +607,6 @@ export function VendorComplianceProvider({
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
// ==========================================
|
||||
// FINDINGS ACTIONS
|
||||
// ==========================================
|
||||
|
||||
const updateFinding = useCallback(
|
||||
async (id: string, data: Partial<Finding>): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/findings/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Aktualisieren des Findings')
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_FINDING', payload: { id, data } })
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const resolveFinding = useCallback(
|
||||
async (id: string, resolution: string): Promise<void> => {
|
||||
await updateFinding(id, {
|
||||
status: 'RESOLVED',
|
||||
resolution,
|
||||
resolvedAt: new Date(),
|
||||
})
|
||||
},
|
||||
[updateFinding]
|
||||
)
|
||||
|
||||
// ==========================================
|
||||
// CONTROL ACTIONS
|
||||
// ==========================================
|
||||
|
||||
const updateControlInstance = useCallback(
|
||||
async (id: string, data: Partial<ControlInstance>): Promise<void> => {
|
||||
const response = await fetch(`${apiBase}/control-instances/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Aktualisieren des Control-Status')
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_CONTROL_INSTANCE', payload: { id, data } })
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
// ==========================================
|
||||
// EXPORT ACTIONS
|
||||
// ==========================================
|
||||
|
||||
const exportVVT = useCallback(
|
||||
async (format: ExportFormat, activityIds?: string[]): Promise<string> => {
|
||||
const params = new URLSearchParams({ format })
|
||||
if (activityIds && activityIds.length > 0) {
|
||||
params.append('activityIds', activityIds.join(','))
|
||||
}
|
||||
|
||||
const response = await fetch(`${apiBase}/export/vvt?${params}`)
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Exportieren des VVT')
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
const url = URL.createObjectURL(blob)
|
||||
|
||||
return url
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const exportVendorAuditPack = useCallback(
|
||||
async (vendorId: string, format: ExportFormat): Promise<string> => {
|
||||
const params = new URLSearchParams({ format, vendorId })
|
||||
|
||||
const response = await fetch(`${apiBase}/export/vendor-audit?${params}`)
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Exportieren des Vendor Audit Packs')
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
const url = URL.createObjectURL(blob)
|
||||
|
||||
return url
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
const exportRoPA = useCallback(
|
||||
async (format: ExportFormat): Promise<string> => {
|
||||
const params = new URLSearchParams({ format })
|
||||
|
||||
const response = await fetch(`${apiBase}/export/ropa?${params}`)
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
throw new Error(error.error || 'Fehler beim Exportieren des RoPA')
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
const url = URL.createObjectURL(blob)
|
||||
|
||||
return url
|
||||
},
|
||||
[apiBase]
|
||||
)
|
||||
|
||||
// ==========================================
|
||||
// INITIALIZATION
|
||||
// ==========================================
|
||||
@@ -877,23 +629,11 @@ export function VendorComplianceProvider({
|
||||
vendorStats,
|
||||
complianceStats,
|
||||
riskOverview,
|
||||
createProcessingActivity,
|
||||
updateProcessingActivity,
|
||||
deleteProcessingActivity,
|
||||
duplicateProcessingActivity,
|
||||
createVendor,
|
||||
updateVendor,
|
||||
deleteVendor,
|
||||
uploadContract,
|
||||
updateContract,
|
||||
deleteContract,
|
||||
startContractReview,
|
||||
updateFinding,
|
||||
resolveFinding,
|
||||
updateControlInstance,
|
||||
exportVVT,
|
||||
exportVendorAuditPack,
|
||||
exportRoPA,
|
||||
loadData,
|
||||
refresh,
|
||||
}),
|
||||
@@ -902,23 +642,11 @@ export function VendorComplianceProvider({
|
||||
vendorStats,
|
||||
complianceStats,
|
||||
riskOverview,
|
||||
createProcessingActivity,
|
||||
updateProcessingActivity,
|
||||
deleteProcessingActivity,
|
||||
duplicateProcessingActivity,
|
||||
createVendor,
|
||||
updateVendor,
|
||||
deleteVendor,
|
||||
uploadContract,
|
||||
updateContract,
|
||||
deleteContract,
|
||||
startContractReview,
|
||||
updateFinding,
|
||||
resolveFinding,
|
||||
updateControlInstance,
|
||||
exportVVT,
|
||||
exportVendorAuditPack,
|
||||
exportRoPA,
|
||||
loadData,
|
||||
refresh,
|
||||
]
|
||||
@@ -947,64 +675,3 @@ export function useVendorCompliance(): VendorComplianceContextValue {
|
||||
return context
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// SELECTORS
|
||||
// ==========================================
|
||||
|
||||
export function useVendor(vendorId: string | null) {
|
||||
const { vendors } = useVendorCompliance()
|
||||
return useMemo(
|
||||
() => vendors.find((v) => v.id === vendorId) ?? null,
|
||||
[vendors, vendorId]
|
||||
)
|
||||
}
|
||||
|
||||
export function useProcessingActivity(activityId: string | null) {
|
||||
const { processingActivities } = useVendorCompliance()
|
||||
return useMemo(
|
||||
() => processingActivities.find((a) => a.id === activityId) ?? null,
|
||||
[processingActivities, activityId]
|
||||
)
|
||||
}
|
||||
|
||||
export function useVendorContracts(vendorId: string | null) {
|
||||
const { contracts } = useVendorCompliance()
|
||||
return useMemo(
|
||||
() => contracts.filter((c) => c.vendorId === vendorId),
|
||||
[contracts, vendorId]
|
||||
)
|
||||
}
|
||||
|
||||
export function useVendorFindings(vendorId: string | null) {
|
||||
const { findings } = useVendorCompliance()
|
||||
return useMemo(
|
||||
() => findings.filter((f) => f.vendorId === vendorId),
|
||||
[findings, vendorId]
|
||||
)
|
||||
}
|
||||
|
||||
export function useContractFindings(contractId: string | null) {
|
||||
const { findings } = useVendorCompliance()
|
||||
return useMemo(
|
||||
() => findings.filter((f) => f.contractId === contractId),
|
||||
[findings, contractId]
|
||||
)
|
||||
}
|
||||
|
||||
export function useControlInstancesForEntity(
|
||||
entityType: 'VENDOR' | 'PROCESSING_ACTIVITY',
|
||||
entityId: string | null
|
||||
) {
|
||||
const { controlInstances, controls } = useVendorCompliance()
|
||||
|
||||
return useMemo(() => {
|
||||
if (!entityId) return []
|
||||
|
||||
return controlInstances
|
||||
.filter((ci) => ci.entityType === entityType && ci.entityId === entityId)
|
||||
.map((ci) => ({
|
||||
...ci,
|
||||
control: controls.find((c) => c.id === ci.controlId),
|
||||
}))
|
||||
}, [controlInstances, controls, entityType, entityId])
|
||||
}
|
||||
|
||||
@@ -21,12 +21,6 @@ export * from './types'
|
||||
export {
|
||||
VendorComplianceProvider,
|
||||
useVendorCompliance,
|
||||
useVendor,
|
||||
useProcessingActivity,
|
||||
useVendorContracts,
|
||||
useVendorFindings,
|
||||
useContractFindings,
|
||||
useControlInstancesForEntity,
|
||||
} from './context'
|
||||
|
||||
// ==========================================
|
||||
|
||||
@@ -828,34 +828,16 @@ export interface VendorComplianceContextValue extends VendorComplianceState {
|
||||
riskOverview: RiskOverview
|
||||
|
||||
// Actions - Processing Activities
|
||||
createProcessingActivity: (data: Omit<ProcessingActivity, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>) => Promise<ProcessingActivity>
|
||||
updateProcessingActivity: (id: string, data: Partial<ProcessingActivity>) => Promise<void>
|
||||
deleteProcessingActivity: (id: string) => Promise<void>
|
||||
duplicateProcessingActivity: (id: string) => Promise<ProcessingActivity>
|
||||
|
||||
// Actions - Vendors
|
||||
createVendor: (data: Omit<Vendor, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>) => Promise<Vendor>
|
||||
updateVendor: (id: string, data: Partial<Vendor>) => Promise<void>
|
||||
deleteVendor: (id: string) => Promise<void>
|
||||
|
||||
// Actions - Contracts
|
||||
uploadContract: (vendorId: string, file: File, metadata: Partial<ContractDocument>) => Promise<ContractDocument>
|
||||
updateContract: (id: string, data: Partial<ContractDocument>) => Promise<void>
|
||||
deleteContract: (id: string) => Promise<void>
|
||||
startContractReview: (contractId: string) => Promise<void>
|
||||
|
||||
// Actions - Findings
|
||||
updateFinding: (id: string, data: Partial<Finding>) => Promise<void>
|
||||
resolveFinding: (id: string, resolution: string) => Promise<void>
|
||||
|
||||
// Actions - Controls
|
||||
updateControlInstance: (id: string, data: Partial<ControlInstance>) => Promise<void>
|
||||
|
||||
// Actions - Export
|
||||
exportVVT: (format: ExportFormat, activityIds?: string[]) => Promise<string>
|
||||
exportVendorAuditPack: (vendorId: string, format: ExportFormat) => Promise<string>
|
||||
exportRoPA: (format: ExportFormat) => Promise<string>
|
||||
|
||||
// Data Loading
|
||||
loadData: () => Promise<void>
|
||||
refresh: () => Promise<void>
|
||||
@@ -959,15 +941,6 @@ export interface VendorFormData {
|
||||
notes?: string
|
||||
}
|
||||
|
||||
export interface ContractUploadData {
|
||||
vendorId: string
|
||||
documentType: DocumentType
|
||||
version: string
|
||||
effectiveDate?: Date
|
||||
expirationDate?: Date
|
||||
autoRenewal?: boolean
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// HELPER FUNCTIONS
|
||||
// ==========================================
|
||||
|
||||
@@ -182,74 +182,6 @@ export const ART9_CATEGORIES: string[] = [
|
||||
'CRIMINAL_DATA',
|
||||
]
|
||||
|
||||
// =============================================================================
|
||||
// LIBRARY TYPES (Master Libraries)
|
||||
// =============================================================================
|
||||
|
||||
export interface VVTLibraryItem {
|
||||
id: string
|
||||
labelDe: string
|
||||
descriptionDe?: string
|
||||
sortOrder?: number
|
||||
}
|
||||
|
||||
export interface VVTDataCategory extends VVTLibraryItem {
|
||||
parentId?: string | null
|
||||
isArt9: boolean
|
||||
isArt10?: boolean
|
||||
riskWeight: number
|
||||
defaultRetentionRule?: string
|
||||
defaultLegalBasis?: string
|
||||
children?: VVTDataCategory[]
|
||||
}
|
||||
|
||||
export interface VVTLibRecipient extends VVTLibraryItem {
|
||||
type: 'INTERNAL' | 'PROCESSOR' | 'CONTROLLER' | 'AUTHORITY'
|
||||
isThirdCountry?: boolean
|
||||
country?: string
|
||||
}
|
||||
|
||||
export interface VVTLibLegalBasis extends VVTLibraryItem {
|
||||
article: string
|
||||
type: string
|
||||
isArt9?: boolean
|
||||
}
|
||||
|
||||
export interface VVTLibRetentionRule extends VVTLibraryItem {
|
||||
legalBasis?: string
|
||||
duration: number
|
||||
durationUnit: 'DAYS' | 'MONTHS' | 'YEARS'
|
||||
startEvent?: string
|
||||
deletionProcedure?: string
|
||||
}
|
||||
|
||||
export interface VVTLibTom extends VVTLibraryItem {
|
||||
category: 'accessControl' | 'confidentiality' | 'integrity' | 'availability' | 'separation'
|
||||
art32Reference?: string
|
||||
}
|
||||
|
||||
export interface VVTProcessTemplate {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
businessFunction: BusinessFunction
|
||||
purposeRefs: string[]
|
||||
legalBasisRefs: string[]
|
||||
dataSubjectRefs: string[]
|
||||
dataCategoryRefs: string[]
|
||||
recipientRefs: string[]
|
||||
tomRefs: string[]
|
||||
transferMechanismRefs: string[]
|
||||
retentionRuleRef?: string
|
||||
typicalSystems: string[]
|
||||
protectionLevel: string
|
||||
dpiaRequired: boolean
|
||||
riskScore?: number
|
||||
tags: string[]
|
||||
isSystem: boolean
|
||||
sortOrder: number
|
||||
}
|
||||
|
||||
export interface VVTCompleteness {
|
||||
score: number
|
||||
missing: string[]
|
||||
|
||||
Reference in New Issue
Block a user