Planes de Continuidad

Planes de Continuidad (también “Business Continuity Plans” o “Planes de Continuidad del Negocio”) son estrategias y procedimientos diseñados para mantener las operaciones críticas de una organización durante interrupciones causadas por incidentes de seguridad, desastres naturales o fallas tecnológicas. Estos planes establecen procedimientos para identificar funciones críticas, definir estrategias de recuperación y establecer objetivos de tiempo de recuperación (RTO) y punto de recuperación (RPO), siendo esenciales para minimizar el impacto de las interrupciones.

¿Qué son los Planes de Continuidad?

Los planes de continuidad son documentos estratégicos que definen cómo una organización mantendrá sus operaciones esenciales durante y después de una interrupción, asegurando la supervivencia del negocio y la recuperación rápida.

Componentes del Plan

Análisis de Impacto al Negocio

  • Identificación de Procesos Críticos: Procesos esenciales para el negocio
  • Evaluación de Dependencias: Dependencias internas y externas
  • Análisis de Tolerancia: Tiempo máximo de interrupción aceptable
  • Priorización de Recursos: Recursos críticos y su prioridad

Estrategias de Continuidad

  • Estrategias de Prevención: Medidas para prevenir interrupciones
  • Estrategias de Mitigación: Medidas para reducir el impacto
  • Estrategias de Recuperación: Procedimientos de recuperación
  • Estrategias Alternativas: Planes de respaldo

Procedimientos Operativos

  • Procedimientos de Activación: Cuándo y cómo activar el plan
  • Procedimientos de Comunicación: Comunicación durante la crisis
  • Procedimientos de Recuperación: Pasos para recuperar operaciones
  • Procedimientos de Pruebas: Validación regular del plan

Sistema de Gestión de Continuidad

Gestión de Planes

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import json

class BusinessContinuityManagement:
    def __init__(self):
        self.business_processes = {}
        self.continuity_plans = {}
        self.risk_assessments = {}
        self.recovery_procedures = {}
        self.testing_schedules = {}
        self.incident_tracking = {}
    
    def identify_critical_processes(self, process_id, process_data):
        """Identificar procesos críticos del negocio"""
        self.business_processes[process_id] = {
            'process_id': process_id,
            'name': process_data['name'],
            'description': process_data['description'],
            'department': process_data['department'],
            'criticality_level': process_data['criticality_level'],
            'business_impact': process_data['business_impact'],
            'dependencies': process_data.get('dependencies', []),
            'resources_required': process_data.get('resources_required', []),
            'max_downtime_hours': process_data.get('max_downtime_hours', 24),
            'recovery_time_objective': process_data.get('recovery_time_objective', 4),
            'recovery_point_objective': process_data.get('recovery_point_objective', 1),
            'stakeholders': process_data.get('stakeholders', []),
            'created_date': datetime.now()
        }
    
    def create_continuity_plan(self, plan_id, plan_config):
        """Crear plan de continuidad"""
        self.continuity_plans[plan_id] = {
            'plan_id': plan_id,
            'name': plan_config['name'],
            'description': plan_config['description'],
            'scope': plan_config['scope'],
            'critical_processes': plan_config.get('critical_processes', []),
            'activation_criteria': plan_config.get('activation_criteria', []),
            'recovery_strategies': plan_config.get('recovery_strategies', []),
            'communication_plan': plan_config.get('communication_plan', {}),
            'resource_requirements': plan_config.get('resource_requirements', []),
            'testing_schedule': plan_config.get('testing_schedule', {}),
            'review_schedule': plan_config.get('review_schedule', {}),
            'status': 'draft',
            'created_date': datetime.now(),
            'last_updated': datetime.now()
        }
    
    def assess_business_impact(self, process_id, impact_data):
        """Evaluar impacto al negocio de un proceso"""
        if process_id not in self.business_processes:
            return False
        
        process = self.business_processes[process_id]
        
        impact_assessment = {
            'process_id': process_id,
            'assessment_date': datetime.now(),
            'financial_impact': impact_data.get('financial_impact', 0),
            'operational_impact': impact_data.get('operational_impact', 'medium'),
            'reputation_impact': impact_data.get('reputation_impact', 'medium'),
            'regulatory_impact': impact_data.get('regulatory_impact', 'low'),
            'customer_impact': impact_data.get('customer_impact', 'medium'),
            'supplier_impact': impact_data.get('supplier_impact', 'low'),
            'employee_impact': impact_data.get('employee_impact', 'medium'),
            'technology_impact': impact_data.get('technology_impact', 'high'),
            'data_impact': impact_data.get('data_impact', 'high'),
            'overall_impact_score': 0
        }
        
        # Calcular score de impacto general
        impact_scores = {
            'financial': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'operational': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'reputation': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'regulatory': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'customer': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'supplier': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'employee': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'technology': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4},
            'data': {'low': 1, 'medium': 2, 'high': 3, 'critical': 4}
        }
        
        total_score = 0
        for impact_type, impact_value in impact_assessment.items():
            if impact_type in impact_scores and impact_value in impact_scores[impact_type]:
                total_score += impact_scores[impact_type][impact_value]
        
        impact_assessment['overall_impact_score'] = total_score
        
        # Determinar nivel de criticidad
        if total_score >= 30:
            impact_level = 'critical'
        elif total_score >= 20:
            impact_level = 'high'
        elif total_score >= 10:
            impact_level = 'medium'
        else:
            impact_level = 'low'
        
        impact_assessment['impact_level'] = impact_level
        
        # Actualizar proceso
        process['impact_assessment'] = impact_assessment
        process['last_impact_assessment'] = datetime.now()
        
        return True
    
    def create_recovery_procedure(self, procedure_id, procedure_config):
        """Crear procedimiento de recuperación"""
        self.recovery_procedures[procedure_id] = {
            'procedure_id': procedure_id,
            'name': procedure_config['name'],
            'description': procedure_config['description'],
            'process_id': procedure_config['process_id'],
            'recovery_type': procedure_config['recovery_type'],
            'steps': procedure_config.get('steps', []),
            'resources_required': procedure_config.get('resources_required', []),
            'estimated_duration': procedure_config.get('estimated_duration', 0),
            'success_criteria': procedure_config.get('success_criteria', []),
            'dependencies': procedure_config.get('dependencies', []),
            'escalation_procedures': procedure_config.get('escalation_procedures', []),
            'testing_requirements': procedure_config.get('testing_requirements', []),
            'created_date': datetime.now()
        }
    
    def activate_continuity_plan(self, plan_id, activation_data):
        """Activar plan de continuidad"""
        if plan_id not in self.continuity_plans:
            return False
        
        plan = self.continuity_plans[plan_id]
        
        activation = {
            'activation_id': f"ACT-{len(self.incident_tracking) + 1}",
            'plan_id': plan_id,
            'activation_reason': activation_data['activation_reason'],
            'activation_date': datetime.now(),
            'activated_by': activation_data['activated_by'],
            'severity_level': activation_data.get('severity_level', 'medium'),
            'affected_processes': activation_data.get('affected_processes', []),
            'estimated_duration': activation_data.get('estimated_duration', 0),
            'status': 'active',
            'recovery_procedures': [],
            'communication_log': [],
            'resource_allocations': [],
            'milestones': []
        }
        
        self.incident_tracking[activation['activation_id']] = activation
        
        # Actualizar estado del plan
        plan['status'] = 'active'
        plan['last_activation'] = datetime.now()
        
        return activation['activation_id']
    
    def execute_recovery_procedure(self, activation_id, procedure_id, execution_data):
        """Ejecutar procedimiento de recuperación"""
        if activation_id not in self.incident_tracking:
            return False
        
        if procedure_id not in self.recovery_procedures:
            return False
        
        activation = self.incident_tracking[activation_id]
        procedure = self.recovery_procedures[procedure_id]
        
        execution = {
            'execution_id': f"EXEC-{len(activation.get('recovery_procedures', [])) + 1}",
            'procedure_id': procedure_id,
            'start_time': datetime.now(),
            'executed_by': execution_data['executed_by'],
            'status': 'in_progress',
            'steps_completed': 0,
            'total_steps': len(procedure['steps']),
            'resources_used': [],
            'issues_encountered': [],
            'completion_time': None,
            'success': False
        }
        
        if 'recovery_procedures' not in activation:
            activation['recovery_procedures'] = []
        
        activation['recovery_procedures'].append(execution)
        
        return execution['execution_id']
    
    def update_recovery_progress(self, activation_id, execution_id, progress_data):
        """Actualizar progreso de recuperación"""
        if activation_id not in self.incident_tracking:
            return False
        
        activation = self.incident_tracking[activation_id]
        
        for execution in activation.get('recovery_procedures', []):
            if execution['execution_id'] == execution_id:
                execution['steps_completed'] = progress_data.get('steps_completed', execution['steps_completed'])
                execution['status'] = progress_data.get('status', execution['status'])
                
                if 'issues_encountered' in progress_data:
                    execution['issues_encountered'].extend(progress_data['issues_encountered'])
                
                if execution['status'] == 'completed':
                    execution['completion_time'] = datetime.now()
                    execution['success'] = progress_data.get('success', False)
                
                return True
        
        return False
    
    def schedule_plan_testing(self, plan_id, test_config):
        """Programar pruebas del plan"""
        if plan_id not in self.continuity_plans:
            return False
        
        test_id = f"TEST-{len(self.testing_schedules) + 1}"
        
        test = {
            'test_id': test_id,
            'plan_id': plan_id,
            'test_type': test_config['test_type'],
            'test_scope': test_config['test_scope'],
            'scheduled_date': test_config['scheduled_date'],
            'duration_hours': test_config.get('duration_hours', 4),
            'participants': test_config.get('participants', []),
            'test_scenarios': test_config.get('test_scenarios', []),
            'success_criteria': test_config.get('success_criteria', []),
            'status': 'scheduled',
            'results': {},
            'created_date': datetime.now()
        }
        
        self.testing_schedules[test_id] = test
        
        return test_id
    
    def conduct_plan_test(self, test_id, test_data):
        """Realizar prueba del plan"""
        if test_id not in self.testing_schedules:
            return False
        
        test = self.testing_schedules[test_id]
        
        test['status'] = 'in_progress'
        test['start_time'] = datetime.now()
        
        # Simular ejecución de prueba
        test_results = {
            'test_id': test_id,
            'start_time': test['start_time'],
            'end_time': test['start_time'] + timedelta(hours=test['duration_hours']),
            'participants_attended': len(test_data.get('participants_attended', [])),
            'scenarios_tested': len(test_data.get('scenarios_tested', [])),
            'scenarios_passed': len(test_data.get('scenarios_passed', [])),
            'scenarios_failed': len(test_data.get('scenarios_failed', [])),
            'issues_identified': test_data.get('issues_identified', []),
            'recommendations': test_data.get('recommendations', []),
            'overall_success': test_data.get('overall_success', False),
            'success_rate': 0
        }
        
        # Calcular tasa de éxito
        total_scenarios = test_results['scenarios_tested']
        if total_scenarios > 0:
            test_results['success_rate'] = (test_results['scenarios_passed'] / total_scenarios * 100)
        
        test['results'] = test_results
        test['status'] = 'completed'
        test['end_time'] = test_results['end_time']
        
        return True
    
    def generate_continuity_report(self, plan_id):
        """Generar reporte de continuidad"""
        if plan_id not in self.continuity_plans:
            return None
        
        plan = self.continuity_plans[plan_id]
        
        # Obtener procesos críticos
        critical_processes = []
        for process_id in plan.get('critical_processes', []):
            if process_id in self.business_processes:
                critical_processes.append(self.business_processes[process_id])
        
        # Obtener activaciones recientes
        recent_activations = [
            activation for activation in self.incident_tracking.values()
            if activation['plan_id'] == plan_id
        ]
        
        # Obtener pruebas recientes
        recent_tests = [
            test for test in self.testing_schedules.values()
            if test['plan_id'] == plan_id
        ]
        
        # Calcular métricas
        total_activations = len(recent_activations)
        successful_activations = len([a for a in recent_activations if a['status'] == 'completed'])
        
        total_tests = len(recent_tests)
        successful_tests = len([t for t in recent_tests if t.get('results', {}).get('overall_success', False)])
        
        # Calcular score de madurez
        maturity_score = self.calculate_maturity_score(plan, critical_processes, recent_tests)
        
        report = {
            'plan_id': plan_id,
            'plan_name': plan['name'],
            'report_date': datetime.now(),
            'plan_status': plan['status'],
            'critical_processes_count': len(critical_processes),
            'activation_metrics': {
                'total_activations': total_activations,
                'successful_activations': successful_activations,
                'success_rate': (successful_activations / total_activations * 100) if total_activations > 0 else 0
            },
            'testing_metrics': {
                'total_tests': total_tests,
                'successful_tests': successful_tests,
                'success_rate': (successful_tests / total_tests * 100) if total_tests > 0 else 0
            },
            'maturity_score': maturity_score,
            'recommendations': self.generate_continuity_recommendations(plan, critical_processes, recent_tests)
        }
        
        return report
    
    def calculate_maturity_score(self, plan, critical_processes, recent_tests):
        """Calcular score de madurez del plan"""
        score = 0
        
        # Factor de completitud del plan
        if plan.get('recovery_strategies'):
            score += 20
        if plan.get('communication_plan'):
            score += 15
        if plan.get('resource_requirements'):
            score += 15
        if plan.get('testing_schedule'):
            score += 10
        
        # Factor de procesos críticos
        if critical_processes:
            score += 20
        
        # Factor de pruebas
        if recent_tests:
            successful_tests = len([t for t in recent_tests if t.get('results', {}).get('overall_success', False)])
            if successful_tests > 0:
                score += 20
        
        return min(score, 100)
    
    def generate_continuity_recommendations(self, plan, critical_processes, recent_tests):
        """Generar recomendaciones de continuidad"""
        recommendations = []
        
        # Recomendaciones basadas en completitud del plan
        if not plan.get('recovery_strategies'):
            recommendations.append({
                'type': 'plan_completeness',
                'priority': 'high',
                'description': 'Definir estrategias de recuperación específicas',
                'action': 'Develop detailed recovery strategies for each critical process'
            })
        
        if not plan.get('communication_plan'):
            recommendations.append({
                'type': 'communication',
                'priority': 'high',
                'description': 'Desarrollar plan de comunicación de crisis',
                'action': 'Create comprehensive crisis communication plan'
            })
        
        # Recomendaciones basadas en pruebas
        if recent_tests:
            failed_tests = [t for t in recent_tests if not t.get('results', {}).get('overall_success', False)]
            if failed_tests:
                recommendations.append({
                    'type': 'testing_improvement',
                    'priority': 'medium',
                    'description': f'Mejorar plan basado en {len(failed_tests)} pruebas fallidas',
                    'action': 'Review and update plan based on test failures'
                })
        
        # Recomendaciones basadas en procesos críticos
        if not critical_processes:
            recommendations.append({
                'type': 'process_identification',
                'priority': 'critical',
                'description': 'Identificar y documentar procesos críticos del negocio',
                'action': 'Conduct business impact analysis to identify critical processes'
            })
        
        return recommendations

# Ejemplo de uso
continuity_mgmt = BusinessContinuityManagement()

# Identificar proceso crítico
continuity_mgmt.identify_critical_processes('PROC-001', {
    'name': 'Customer Order Processing',
    'description': 'Procesamiento de pedidos de clientes',
    'department': 'Sales',
    'criticality_level': 'critical',
    'business_impact': 'high',
    'max_downtime_hours': 2,
    'recovery_time_objective': 1,
    'recovery_point_objective': 0.5,
    'stakeholders': ['Sales Team', 'Customer Service', 'IT Team']
})

# Evaluar impacto al negocio
continuity_mgmt.assess_business_impact('PROC-001', {
    'financial_impact': 'high',
    'operational_impact': 'critical',
    'reputation_impact': 'high',
    'customer_impact': 'critical',
    'technology_impact': 'high',
    'data_impact': 'high'
})

# Crear plan de continuidad
continuity_mgmt.create_continuity_plan('PLAN-001', {
    'name': 'Business Continuity Plan 2025',
    'description': 'Plan de continuidad del negocio para 2025',
    'scope': 'organization_wide',
    'critical_processes': ['PROC-001'],
    'activation_criteria': ['System outage > 1 hour', 'Data breach', 'Natural disaster'],
    'recovery_strategies': ['Backup systems', 'Alternative processes', 'Remote work'],
    'communication_plan': {
        'internal': ['Email', 'Slack', 'Phone'],
        'external': ['Website', 'Social media', 'Press release']
    }
})

# Crear procedimiento de recuperación
continuity_mgmt.create_recovery_procedure('PROC-001', {
    'name': 'Order Processing Recovery',
    'description': 'Recuperación del procesamiento de pedidos',
    'process_id': 'PROC-001',
    'recovery_type': 'automated',
    'steps': [
        'Activate backup systems',
        'Restore data from backup',
        'Verify system functionality',
        'Notify stakeholders'
    ],
    'estimated_duration': 2,
    'success_criteria': ['System operational', 'Data integrity verified', 'Stakeholders notified']
})

# Programar prueba del plan
test_id = continuity_mgmt.schedule_plan_testing('PLAN-001', {
    'test_type': 'tabletop',
    'test_scope': 'critical_processes',
    'scheduled_date': datetime.now() + timedelta(days=30),
    'duration_hours': 4,
    'participants': ['CISO', 'IT Manager', 'Sales Manager'],
    'test_scenarios': ['System outage', 'Data breach', 'Natural disaster']
})

# Generar reporte
report = continuity_mgmt.generate_continuity_report('PLAN-001')
print(f"Reporte de continuidad: {report['plan_name']}")
print(f"Score de madurez: {report['maturity_score']}")
print(f"Procesos críticos: {report['critical_processes_count']}")

Gestión de Crisis

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
class CrisisManagement:
    def __init__(self):
        self.crisis_events = {}
        self.emergency_contacts = {}
        self.communication_templates = {}
        self.escalation_procedures = {}
    
    def declare_crisis(self, crisis_id, crisis_data):
        """Declarar crisis"""
        self.crisis_events[crisis_id] = {
            'crisis_id': crisis_id,
            'title': crisis_data['title'],
            'description': crisis_data['description'],
            'severity_level': crisis_data['severity_level'],
            'crisis_type': crisis_data['crisis_type'],
            'declared_by': crisis_data['declared_by'],
            'declared_date': datetime.now(),
            'affected_systems': crisis_data.get('affected_systems', []),
            'affected_processes': crisis_data.get('affected_processes', []),
            'estimated_impact': crisis_data.get('estimated_impact', 'unknown'),
            'status': 'active',
            'response_team': crisis_data.get('response_team', []),
            'communication_log': [],
            'actions_taken': [],
            'resolution_date': None
        }
        
        return crisis_id
    
    def activate_crisis_response(self, crisis_id, response_data):
        """Activar respuesta a crisis"""
        if crisis_id not in self.crisis_events:
            return False
        
        crisis = self.crisis_events[crisis_id]
        
        response = {
            'response_id': f"RESP-{len(crisis.get('actions_taken', [])) + 1}",
            'crisis_id': crisis_id,
            'action_type': response_data['action_type'],
            'description': response_data['description'],
            'assigned_to': response_data['assigned_to'],
            'priority': response_data.get('priority', 'medium'),
            'start_time': datetime.now(),
            'status': 'in_progress',
            'completion_time': None,
            'success': False
        }
        
        if 'actions_taken' not in crisis:
            crisis['actions_taken'] = []
        
        crisis['actions_taken'].append(response)
        
        return response['response_id']
    
    def update_crisis_status(self, crisis_id, status_data):
        """Actualizar estado de crisis"""
        if crisis_id not in self.crisis_events:
            return False
        
        crisis = self.crisis_events[crisis_id]
        
        crisis['status'] = status_data['status']
        crisis['last_updated'] = datetime.now()
        
        if status_data['status'] == 'resolved':
            crisis['resolution_date'] = datetime.now()
        
        # Añadir entrada al log de comunicación
        crisis['communication_log'].append({
            'timestamp': datetime.now(),
            'message': status_data.get('message', 'Status updated'),
            'author': status_data.get('author', 'system')
        })
        
        return True
    
    def generate_crisis_report(self, crisis_id):
        """Generar reporte de crisis"""
        if crisis_id not in self.crisis_events:
            return None
        
        crisis = self.crisis_events[crisis_id]
        
        # Calcular duración
        if crisis['status'] == 'resolved' and crisis['resolution_date']:
            duration = crisis['resolution_date'] - crisis['declared_date']
        else:
            duration = datetime.now() - crisis['declared_date']
        
        # Contar acciones
        total_actions = len(crisis.get('actions_taken', []))
        completed_actions = len([a for a in crisis.get('actions_taken', []) if a['status'] == 'completed'])
        
        report = {
            'crisis_id': crisis_id,
            'title': crisis['title'],
            'severity_level': crisis['severity_level'],
            'crisis_type': crisis['crisis_type'],
            'declared_date': crisis['declared_date'],
            'resolution_date': crisis['resolution_date'],
            'duration': duration,
            'status': crisis['status'],
            'affected_systems': crisis['affected_systems'],
            'affected_processes': crisis['affected_processes'],
            'response_metrics': {
                'total_actions': total_actions,
                'completed_actions': completed_actions,
                'completion_rate': (completed_actions / total_actions * 100) if total_actions > 0 else 0
            },
            'communication_log': crisis['communication_log'],
            'lessons_learned': self.extract_lessons_learned(crisis)
        }
        
        return report
    
    def extract_lessons_learned(self, crisis):
        """Extraer lecciones aprendidas de la crisis"""
        lessons = []
        
        # Lecciones basadas en duración
        if crisis['status'] == 'resolved':
            duration_hours = (crisis['resolution_date'] - crisis['declared_date']).total_seconds() / 3600
            if duration_hours > 24:
                lessons.append({
                    'category': 'response_time',
                    'lesson': 'Response time was longer than expected',
                    'recommendation': 'Review and improve response procedures'
                })
        
        # Lecciones basadas en acciones
        actions = crisis.get('actions_taken', [])
        failed_actions = [a for a in actions if a['status'] == 'failed']
        if failed_actions:
            lessons.append({
                'category': 'execution',
                'lesson': f'{len(failed_actions)} actions failed during response',
                'recommendation': 'Review and improve action procedures'
            })
        
        # Lecciones basadas en comunicación
        comm_log = crisis.get('communication_log', [])
        if len(comm_log) < 5:
            lessons.append({
                'category': 'communication',
                'lesson': 'Limited communication during crisis',
                'recommendation': 'Improve crisis communication procedures'
            })
        
        return lessons

# Ejemplo de uso
crisis_mgmt = CrisisManagement()

# Declarar crisis
crisis_id = crisis_mgmt.declare_crisis('CRISIS-001', {
    'title': 'Major System Outage',
    'description': 'Critical systems down due to cyber attack',
    'severity_level': 'critical',
    'crisis_type': 'cyber_attack',
    'declared_by': 'CISO',
    'affected_systems': ['Order Processing', 'Customer Database'],
    'affected_processes': ['PROC-001'],
    'estimated_impact': 'high',
    'response_team': ['CISO', 'IT Manager', 'Security Team']
})

# Activar respuesta
response_id = crisis_mgmt.activate_crisis_response('CRISIS-001', {
    'action_type': 'incident_response',
    'description': 'Activate incident response team',
    'assigned_to': 'Security Team',
    'priority': 'critical'
})

# Actualizar estado
crisis_mgmt.update_crisis_status('CRISIS-001', {
    'status': 'resolved',
    'message': 'Systems restored and incident contained',
    'author': 'CISO'
})

# Generar reporte
report = crisis_mgmt.generate_crisis_report('CRISIS-001')
print(f"Reporte de crisis: {report['title']}")
print(f"Duración: {report['duration']}")
print(f"Lecciones aprendidas: {len(report['lessons_learned'])}")

Mejores Prácticas

Desarrollo del Plan

  • Análisis de Impacto: Evaluación exhaustiva del impacto al negocio
  • Procesos Críticos: Identificación clara de procesos críticos
  • Recursos: Identificación y asignación de recursos
  • Comunicación: Plan de comunicación de crisis

Implementación

  • Pruebas Regulares: Pruebas regulares del plan
  • Actualización: Actualización regular del plan
  • Capacitación: Capacitación del personal en el plan
  • Comunicación: Comunicación clara del plan

Gestión de Crisis

  • Respuesta Rápida: Activación rápida del plan
  • Comunicación: Comunicación efectiva durante la crisis
  • Coordinación: Coordinación efectiva de la respuesta
  • Lecciones Aprendidas: Aprendizaje de cada crisis

Conceptos Relacionados

Referencias