import { SDKState, getStepById, } from './types' import { ExtendedSDKAction, initialState } from './context-types' // ============================================================================= // REDUCER // ============================================================================= export function sdkReducer(state: SDKState, action: ExtendedSDKAction): SDKState { const updateState = (updates: Partial): SDKState => ({ ...state, ...updates, lastModified: new Date(), }) switch (action.type) { case 'SET_STATE': return updateState(action.payload) case 'LOAD_DEMO_DATA': // Load demo data while preserving user preferences return { ...initialState, ...action.payload, tenantId: state.tenantId, userId: state.userId, preferences: state.preferences, lastModified: new Date(), } case 'SET_CURRENT_STEP': { const step = getStepById(action.payload) return updateState({ currentStep: action.payload, currentPhase: step?.phase || state.currentPhase, }) } case 'COMPLETE_STEP': if (state.completedSteps.includes(action.payload)) { return state } return updateState({ completedSteps: [...state.completedSteps, action.payload], }) case 'SET_CHECKPOINT_STATUS': return updateState({ checkpoints: { ...state.checkpoints, [action.payload.id]: action.payload.status, }, }) case 'SET_CUSTOMER_TYPE': return updateState({ customerType: action.payload }) case 'SET_COMPANY_PROFILE': return updateState({ companyProfile: action.payload }) case 'UPDATE_COMPANY_PROFILE': return updateState({ companyProfile: state.companyProfile ? { ...state.companyProfile, ...action.payload } : null, }) case 'SET_COMPLIANCE_SCOPE': return updateState({ complianceScope: action.payload }) case 'UPDATE_COMPLIANCE_SCOPE': return updateState({ complianceScope: state.complianceScope ? { ...state.complianceScope, ...action.payload } : null, }) case 'ADD_IMPORTED_DOCUMENT': return updateState({ importedDocuments: [...state.importedDocuments, action.payload], }) case 'UPDATE_IMPORTED_DOCUMENT': return updateState({ importedDocuments: state.importedDocuments.map(doc => doc.id === action.payload.id ? { ...doc, ...action.payload.data } : doc ), }) case 'DELETE_IMPORTED_DOCUMENT': return updateState({ importedDocuments: state.importedDocuments.filter(doc => doc.id !== action.payload), }) case 'SET_GAP_ANALYSIS': return updateState({ gapAnalysis: action.payload }) case 'ADD_USE_CASE': return updateState({ useCases: [...state.useCases, action.payload], }) case 'UPDATE_USE_CASE': return updateState({ useCases: state.useCases.map(uc => uc.id === action.payload.id ? { ...uc, ...action.payload.data } : uc ), }) case 'DELETE_USE_CASE': return updateState({ useCases: state.useCases.filter(uc => uc.id !== action.payload), activeUseCase: state.activeUseCase === action.payload ? null : state.activeUseCase, }) case 'SET_ACTIVE_USE_CASE': return updateState({ activeUseCase: action.payload }) case 'SET_SCREENING': return updateState({ screening: action.payload }) case 'ADD_MODULE': return updateState({ modules: [...state.modules, action.payload], }) case 'UPDATE_MODULE': return updateState({ modules: state.modules.map(m => m.id === action.payload.id ? { ...m, ...action.payload.data } : m ), }) case 'ADD_REQUIREMENT': return updateState({ requirements: [...state.requirements, action.payload], }) case 'UPDATE_REQUIREMENT': return updateState({ requirements: state.requirements.map(r => r.id === action.payload.id ? { ...r, ...action.payload.data } : r ), }) case 'ADD_CONTROL': return updateState({ controls: [...state.controls, action.payload], }) case 'UPDATE_CONTROL': return updateState({ controls: state.controls.map(c => c.id === action.payload.id ? { ...c, ...action.payload.data } : c ), }) case 'ADD_EVIDENCE': return updateState({ evidence: [...state.evidence, action.payload], }) case 'UPDATE_EVIDENCE': return updateState({ evidence: state.evidence.map(e => e.id === action.payload.id ? { ...e, ...action.payload.data } : e ), }) case 'DELETE_EVIDENCE': return updateState({ evidence: state.evidence.filter(e => e.id !== action.payload), }) case 'ADD_RISK': return updateState({ risks: [...state.risks, action.payload], }) case 'UPDATE_RISK': return updateState({ risks: state.risks.map(r => r.id === action.payload.id ? { ...r, ...action.payload.data } : r ), }) case 'DELETE_RISK': return updateState({ risks: state.risks.filter(r => r.id !== action.payload), }) case 'SET_AI_ACT_RESULT': return updateState({ aiActClassification: action.payload }) case 'ADD_OBLIGATION': return updateState({ obligations: [...state.obligations, action.payload], }) case 'UPDATE_OBLIGATION': return updateState({ obligations: state.obligations.map(o => o.id === action.payload.id ? { ...o, ...action.payload.data } : o ), }) case 'SET_DSFA': return updateState({ dsfa: action.payload }) case 'ADD_TOM': return updateState({ toms: [...state.toms, action.payload], }) case 'UPDATE_TOM': return updateState({ toms: state.toms.map(t => t.id === action.payload.id ? { ...t, ...action.payload.data } : t ), }) case 'ADD_RETENTION_POLICY': return updateState({ retentionPolicies: [...state.retentionPolicies, action.payload], }) case 'UPDATE_RETENTION_POLICY': return updateState({ retentionPolicies: state.retentionPolicies.map(p => p.id === action.payload.id ? { ...p, ...action.payload.data } : p ), }) case 'ADD_PROCESSING_ACTIVITY': return updateState({ vvt: [...state.vvt, action.payload], }) case 'UPDATE_PROCESSING_ACTIVITY': return updateState({ vvt: state.vvt.map(p => p.id === action.payload.id ? { ...p, ...action.payload.data } : p ), }) case 'ADD_DOCUMENT': return updateState({ documents: [...state.documents, action.payload], }) case 'UPDATE_DOCUMENT': return updateState({ documents: state.documents.map(d => d.id === action.payload.id ? { ...d, ...action.payload.data } : d ), }) case 'SET_COOKIE_BANNER': return updateState({ cookieBanner: action.payload }) case 'SET_DSR_CONFIG': return updateState({ dsrConfig: action.payload }) case 'ADD_ESCALATION_WORKFLOW': return updateState({ escalationWorkflows: [...state.escalationWorkflows, action.payload], }) case 'UPDATE_ESCALATION_WORKFLOW': return updateState({ escalationWorkflows: state.escalationWorkflows.map(w => w.id === action.payload.id ? { ...w, ...action.payload.data } : w ), }) case 'ADD_SECURITY_ISSUE': return updateState({ securityIssues: [...state.securityIssues, action.payload], }) case 'UPDATE_SECURITY_ISSUE': return updateState({ securityIssues: state.securityIssues.map(i => i.id === action.payload.id ? { ...i, ...action.payload.data } : i ), }) case 'ADD_BACKLOG_ITEM': return updateState({ securityBacklog: [...state.securityBacklog, action.payload], }) case 'UPDATE_BACKLOG_ITEM': return updateState({ securityBacklog: state.securityBacklog.map(i => i.id === action.payload.id ? { ...i, ...action.payload.data } : i ), }) case 'ADD_COMMAND_HISTORY': return updateState({ commandBarHistory: [action.payload, ...state.commandBarHistory].slice(0, 50), }) case 'SET_PREFERENCES': return updateState({ preferences: { ...state.preferences, ...action.payload }, }) case 'ADD_CUSTOM_CATALOG_ENTRY': { const entry = action.payload const existing = state.customCatalogs[entry.catalogId] || [] return updateState({ customCatalogs: { ...state.customCatalogs, [entry.catalogId]: [...existing, entry], }, }) } case 'UPDATE_CUSTOM_CATALOG_ENTRY': { const { catalogId, entryId, data } = action.payload const entries = state.customCatalogs[catalogId] || [] return updateState({ customCatalogs: { ...state.customCatalogs, [catalogId]: entries.map(e => e.id === entryId ? { ...e, data: { ...e.data, ...data }, updatedAt: new Date().toISOString() } : e ), }, }) } case 'DELETE_CUSTOM_CATALOG_ENTRY': { const { catalogId, entryId } = action.payload const items = state.customCatalogs[catalogId] || [] return updateState({ customCatalogs: { ...state.customCatalogs, [catalogId]: items.filter(e => e.id !== entryId), }, }) } case 'RESET_STATE': return { ...initialState, lastModified: new Date() } default: return state } }