refactor(admin): split 9 more oversized lib/ files into focused modules
Files split by agents before rate limit: - dsr/api.ts (669 → barrel + helpers) - einwilligungen/context.tsx (669 → barrel + hooks/reducer) - export.ts (753 → barrel + domain exporters) - incidents/api.ts (845 → barrel + api-helpers) - tom-generator/context.tsx (720 → barrel + hooks/reducer) - vendor-compliance/context.tsx (1010 → 234 provider + hooks/reducer) - api-docs/endpoints.ts — partially split (3 domain files created) - academy/api.ts — partially split (helpers extracted) - whistleblower/api.ts — partially split (helpers extracted) next build passes. api-client.ts (885) deferred to next session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
238
admin-compliance/lib/sdk/tom-generator/reducer.ts
Normal file
238
admin-compliance/lib/sdk/tom-generator/reducer.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
// =============================================================================
|
||||
// TOM Generator Reducer
|
||||
// Action types and state reducer for the TOM Generator Wizard
|
||||
// =============================================================================
|
||||
|
||||
import {
|
||||
TOMGeneratorState,
|
||||
TOMGeneratorStepId,
|
||||
CompanyProfile,
|
||||
DataProfile,
|
||||
ArchitectureProfile,
|
||||
SecurityProfile,
|
||||
RiskProfile,
|
||||
EvidenceDocument,
|
||||
DerivedTOM,
|
||||
GapAnalysisResult,
|
||||
ExportRecord,
|
||||
WizardStep,
|
||||
createInitialTOMGeneratorState,
|
||||
calculateProtectionLevel,
|
||||
isDSFARequired,
|
||||
hasSpecialCategories,
|
||||
} from './types'
|
||||
|
||||
// =============================================================================
|
||||
// ACTION TYPES
|
||||
// =============================================================================
|
||||
|
||||
export type TOMGeneratorAction =
|
||||
| { type: 'INITIALIZE'; payload: { tenantId: string; state?: TOMGeneratorState } }
|
||||
| { type: 'RESET'; payload: { tenantId: string } }
|
||||
| { type: 'SET_CURRENT_STEP'; payload: TOMGeneratorStepId }
|
||||
| { type: 'SET_COMPANY_PROFILE'; payload: CompanyProfile }
|
||||
| { type: 'UPDATE_COMPANY_PROFILE'; payload: Partial<CompanyProfile> }
|
||||
| { type: 'SET_DATA_PROFILE'; payload: DataProfile }
|
||||
| { type: 'UPDATE_DATA_PROFILE'; payload: Partial<DataProfile> }
|
||||
| { type: 'SET_ARCHITECTURE_PROFILE'; payload: ArchitectureProfile }
|
||||
| { type: 'UPDATE_ARCHITECTURE_PROFILE'; payload: Partial<ArchitectureProfile> }
|
||||
| { type: 'SET_SECURITY_PROFILE'; payload: SecurityProfile }
|
||||
| { type: 'UPDATE_SECURITY_PROFILE'; payload: Partial<SecurityProfile> }
|
||||
| { type: 'SET_RISK_PROFILE'; payload: RiskProfile }
|
||||
| { type: 'UPDATE_RISK_PROFILE'; payload: Partial<RiskProfile> }
|
||||
| { type: 'COMPLETE_STEP'; payload: { stepId: TOMGeneratorStepId; data: unknown } }
|
||||
| { type: 'UNCOMPLETE_STEP'; payload: TOMGeneratorStepId }
|
||||
| { type: 'ADD_EVIDENCE'; payload: EvidenceDocument }
|
||||
| { type: 'UPDATE_EVIDENCE'; payload: { id: string; data: Partial<EvidenceDocument> } }
|
||||
| { type: 'DELETE_EVIDENCE'; payload: string }
|
||||
| { type: 'SET_DERIVED_TOMS'; payload: DerivedTOM[] }
|
||||
| { type: 'UPDATE_DERIVED_TOM'; payload: { id: string; data: Partial<DerivedTOM> } }
|
||||
| { type: 'SET_GAP_ANALYSIS'; payload: GapAnalysisResult }
|
||||
| { type: 'ADD_EXPORT'; payload: ExportRecord }
|
||||
| { type: 'BULK_UPDATE_TOMS'; payload: { updates: Array<{ id: string; data: Partial<DerivedTOM> }> } }
|
||||
| { type: 'LOAD_STATE'; payload: TOMGeneratorState }
|
||||
|
||||
// =============================================================================
|
||||
// REDUCER
|
||||
// =============================================================================
|
||||
|
||||
export function tomGeneratorReducer(
|
||||
state: TOMGeneratorState,
|
||||
action: TOMGeneratorAction
|
||||
): TOMGeneratorState {
|
||||
const updateState = (updates: Partial<TOMGeneratorState>): TOMGeneratorState => ({
|
||||
...state,
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
|
||||
switch (action.type) {
|
||||
case 'INITIALIZE': {
|
||||
if (action.payload.state) {
|
||||
return action.payload.state
|
||||
}
|
||||
return createInitialTOMGeneratorState(action.payload.tenantId)
|
||||
}
|
||||
|
||||
case 'RESET': {
|
||||
return createInitialTOMGeneratorState(action.payload.tenantId)
|
||||
}
|
||||
|
||||
case 'SET_CURRENT_STEP': {
|
||||
return updateState({ currentStep: action.payload })
|
||||
}
|
||||
|
||||
case 'SET_COMPANY_PROFILE': {
|
||||
return updateState({ companyProfile: action.payload })
|
||||
}
|
||||
|
||||
case 'UPDATE_COMPANY_PROFILE': {
|
||||
if (!state.companyProfile) return state
|
||||
return updateState({
|
||||
companyProfile: { ...state.companyProfile, ...action.payload },
|
||||
})
|
||||
}
|
||||
|
||||
case 'SET_DATA_PROFILE': {
|
||||
const profile: DataProfile = {
|
||||
...action.payload,
|
||||
hasSpecialCategories: hasSpecialCategories(action.payload.categories),
|
||||
}
|
||||
return updateState({ dataProfile: profile })
|
||||
}
|
||||
|
||||
case 'UPDATE_DATA_PROFILE': {
|
||||
if (!state.dataProfile) return state
|
||||
const updatedProfile = { ...state.dataProfile, ...action.payload }
|
||||
if (action.payload.categories) {
|
||||
updatedProfile.hasSpecialCategories = hasSpecialCategories(
|
||||
action.payload.categories
|
||||
)
|
||||
}
|
||||
return updateState({ dataProfile: updatedProfile })
|
||||
}
|
||||
|
||||
case 'SET_ARCHITECTURE_PROFILE': {
|
||||
return updateState({ architectureProfile: action.payload })
|
||||
}
|
||||
|
||||
case 'UPDATE_ARCHITECTURE_PROFILE': {
|
||||
if (!state.architectureProfile) return state
|
||||
return updateState({
|
||||
architectureProfile: { ...state.architectureProfile, ...action.payload },
|
||||
})
|
||||
}
|
||||
|
||||
case 'SET_SECURITY_PROFILE': {
|
||||
return updateState({ securityProfile: action.payload })
|
||||
}
|
||||
|
||||
case 'UPDATE_SECURITY_PROFILE': {
|
||||
if (!state.securityProfile) return state
|
||||
return updateState({
|
||||
securityProfile: { ...state.securityProfile, ...action.payload },
|
||||
})
|
||||
}
|
||||
|
||||
case 'SET_RISK_PROFILE': {
|
||||
const profile: RiskProfile = {
|
||||
...action.payload,
|
||||
protectionLevel: calculateProtectionLevel(action.payload.ciaAssessment),
|
||||
dsfaRequired: isDSFARequired(state.dataProfile, action.payload),
|
||||
}
|
||||
return updateState({ riskProfile: profile })
|
||||
}
|
||||
|
||||
case 'UPDATE_RISK_PROFILE': {
|
||||
if (!state.riskProfile) return state
|
||||
const updatedProfile = { ...state.riskProfile, ...action.payload }
|
||||
if (action.payload.ciaAssessment) {
|
||||
updatedProfile.protectionLevel = calculateProtectionLevel(
|
||||
action.payload.ciaAssessment
|
||||
)
|
||||
}
|
||||
updatedProfile.dsfaRequired = isDSFARequired(state.dataProfile, updatedProfile)
|
||||
return updateState({ riskProfile: updatedProfile })
|
||||
}
|
||||
|
||||
case 'COMPLETE_STEP': {
|
||||
const updatedSteps = state.steps.map((step) =>
|
||||
step.id === action.payload.stepId
|
||||
? {
|
||||
...step,
|
||||
completed: true,
|
||||
data: action.payload.data,
|
||||
validatedAt: new Date(),
|
||||
}
|
||||
: step
|
||||
)
|
||||
return updateState({ steps: updatedSteps })
|
||||
}
|
||||
|
||||
case 'UNCOMPLETE_STEP': {
|
||||
const updatedSteps = state.steps.map((step) =>
|
||||
step.id === action.payload
|
||||
? { ...step, completed: false, validatedAt: null }
|
||||
: step
|
||||
)
|
||||
return updateState({ steps: updatedSteps })
|
||||
}
|
||||
|
||||
case 'ADD_EVIDENCE': {
|
||||
return updateState({
|
||||
documents: [...state.documents, action.payload],
|
||||
})
|
||||
}
|
||||
|
||||
case 'UPDATE_EVIDENCE': {
|
||||
const updatedDocuments = state.documents.map((doc) =>
|
||||
doc.id === action.payload.id ? { ...doc, ...action.payload.data } : doc
|
||||
)
|
||||
return updateState({ documents: updatedDocuments })
|
||||
}
|
||||
|
||||
case 'DELETE_EVIDENCE': {
|
||||
return updateState({
|
||||
documents: state.documents.filter((doc) => doc.id !== action.payload),
|
||||
})
|
||||
}
|
||||
|
||||
case 'SET_DERIVED_TOMS': {
|
||||
return updateState({ derivedTOMs: action.payload })
|
||||
}
|
||||
|
||||
case 'UPDATE_DERIVED_TOM': {
|
||||
const updatedTOMs = state.derivedTOMs.map((tom) =>
|
||||
tom.id === action.payload.id ? { ...tom, ...action.payload.data } : tom
|
||||
)
|
||||
return updateState({ derivedTOMs: updatedTOMs })
|
||||
}
|
||||
|
||||
case 'SET_GAP_ANALYSIS': {
|
||||
return updateState({ gapAnalysis: action.payload })
|
||||
}
|
||||
|
||||
case 'ADD_EXPORT': {
|
||||
return updateState({
|
||||
exports: [...state.exports, action.payload],
|
||||
})
|
||||
}
|
||||
|
||||
case 'BULK_UPDATE_TOMS': {
|
||||
let updatedTOMs = [...state.derivedTOMs]
|
||||
for (const update of action.payload.updates) {
|
||||
updatedTOMs = updatedTOMs.map((tom) =>
|
||||
tom.id === update.id ? { ...tom, ...update.data } : tom
|
||||
)
|
||||
}
|
||||
return updateState({ derivedTOMs: updatedTOMs })
|
||||
}
|
||||
|
||||
case 'LOAD_STATE': {
|
||||
return action.payload
|
||||
}
|
||||
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user