VBAF.Center.CrisisTree.ps1
|
#Requires -Version 5.1 <# .SYNOPSIS VBAF-Center Phase 13 — Crisis Response Tree .DESCRIPTION When signals hit critical levels VBAF-Center activates a structured crisis response — walking the dispatcher through every possible recovery step. Like a defibrillator — it takes over when the human freezes. Human gut feeling stays in the background — the tree just makes sure nothing is forgotten in the heat of the moment. Domains: Logistics — vehicle breakdown, late delivery, driver missing IT — server down, disk full, CPU critical Healthcare — bed shortage, staff missing, equipment failure Manufacturing — machine breakdown, quality alert, supply delay Functions: Start-VBAFCenterCrisis — activate crisis response wizard Get-VBAFCenterCrisisTree — show all crisis trees New-VBAFCenterCrisisTree — add custom crisis tree Get-VBAFCenterCrisisHistory — show past crisis responses #> # ============================================================ # CRISIS TREES # ============================================================ $script:CrisisTrees = @{ # ── LOGISTICS ──────────────────────────────────────────── "LOGISTICS-VEHICLE-BREAKDOWN" = @{ Domain = "Logistics" Trigger = "Empty Driving above 45% or Fleet Availability below 75%" Title = "Vehicle Breakdown Response" Steps = @( @{ Step = 1 Question = "Is a backup vehicle available in the depot?" Yes = "Deploy backup vehicle immediately — assign to affected route" No = "Proceed to Step 2" } @{ Step = 2 Question = "Can the load be split between remaining trucks?" Yes = "Redistribute load — prioritise time-sensitive deliveries first" No = "Proceed to Step 3" } @{ Step = 3 Question = "Can delivery time be renegotiated with the customer?" Yes = "Call customer now — explain situation, agree new ETA" No = "Proceed to Step 4" } @{ Step = 4 Question = "Is an external subcontractor available?" Yes = "Contact subcontractor — confirm availability and cost" No = "ESCALATE — Call operations manager immediately" } ) } "LOGISTICS-LATE-DELIVERY" = @{ Domain = "Logistics" Trigger = "On-Time Delivery below 65% or ETA Accuracy below 60%" Title = "Late Delivery Response" Steps = @( @{ Step = 1 Question = "Is the delay due to traffic or weather?" Yes = "Reroute to fastest available alternative — check Google Maps" No = "Proceed to Step 2" } @{ Step = 2 Question = "Is the delay more than 60 minutes?" Yes = "Call customer proactively — do not wait for them to call you" No = "Monitor — update ETA every 15 minutes" } @{ Step = 3 Question = "Is this a high-priority customer?" Yes = "Reassign nearest available truck to take over delivery" No = "Log delay — update delivery status in TMS" } ) } "LOGISTICS-HIGH-COST" = @{ Domain = "Logistics" Trigger = "Cost Per Trip above 2500 DKK" Title = "Cost Spike Response" Steps = @( @{ Step = 1 Question = "Is the cost spike due to fuel price?" Yes = "Check if routes can be shortened — combine deliveries where possible" No = "Proceed to Step 2" } @{ Step = 2 Question = "Are multiple trucks running near-empty?" Yes = "Consolidate loads — cancel unnecessary runs" No = "Proceed to Step 3" } @{ Step = 3 Question = "Is overtime driving the cost up?" Yes = "Review driver schedules — reassign to avoid overtime rates" No = "Log for weekly cost review — no immediate action needed" } ) } # ── IT INFRASTRUCTURE ──────────────────────────────────── "IT-SERVER-DOWN" = @{ Domain = "IT" Trigger = "Fleet Availability below 70% or CPU Load above 90%" Title = "Server Down Response" Steps = @( @{ Step = 1 Question = "Is the server responding to ping?" Yes = "Service likely crashed — attempt service restart" No = "Proceed to Step 2" } @{ Step = 2 Question = "Is a backup server available?" Yes = "Failover to backup server — notify users of temporary switch" No = "Proceed to Step 3" } @{ Step = 3 Question = "Can users work offline temporarily?" Yes = "Notify all users — estimated recovery time?" No = "ESCALATE — Call IT vendor immediately" } @{ Step = 4 Question = "Is this affecting business-critical systems?" Yes = "Declare incident — notify management and all affected departments" No = "Continue recovery — update status every 15 minutes" } ) } "IT-DISK-FULL" = @{ Domain = "IT" Trigger = "Disk Space Free below 20%" Title = "Disk Space Critical Response" Steps = @( @{ Step = 1 Question = "Are there old log files or temp files that can be deleted?" Yes = "Run disk cleanup — delete logs older than 30 days" No = "Proceed to Step 2" } @{ Step = 2 Question = "Are there old backups taking up space?" Yes = "Move old backups to archive storage or external drive" No = "Proceed to Step 3" } @{ Step = 3 Question = "Can additional storage be added quickly?" Yes = "Expand disk — contact IT vendor for emergency storage" No = "ESCALATE — Risk of system crash within hours" } ) } # ── MANUFACTURING ──────────────────────────────────────── "MFG-MACHINE-BREAKDOWN" = @{ Domain = "Manufacturing" Trigger = "Fleet Availability below 70% or Cost above threshold" Title = "Machine Breakdown Response" Steps = @( @{ Step = 1 Question = "Is a backup machine or line available?" Yes = "Switch production to backup line immediately" No = "Proceed to Step 2" } @{ Step = 2 Question = "Can production be rescheduled to another shift?" Yes = "Reschedule — notify shift manager and production planner" No = "Proceed to Step 3" } @{ Step = 3 Question = "Is the repair estimated under 2 hours?" Yes = "Hold production — begin repair immediately" No = "ESCALATE — Notify customers of potential delivery delays" } ) } # ── HEALTHCARE ─────────────────────────────────────────── "HEALTH-BED-SHORTAGE" = @{ Domain = "Healthcare" Trigger = "Capacity Utilisation above 95%" Title = "Bed Shortage Response" Steps = @( @{ Step = 1 Question = "Are any patients ready for discharge today?" Yes = "Expedite discharge process — free beds immediately" No = "Proceed to Step 2" } @{ Step = 2 Question = "Can any patients be transferred to another ward?" Yes = "Coordinate transfer with receiving ward" No = "Proceed to Step 3" } @{ Step = 3 Question = "Can elective procedures be postponed?" Yes = "Postpone non-urgent admissions — notify patients" No = "ESCALATE — Activate hospital overflow protocol" } ) } } # ============================================================ # START-VBAFCENTERCROSS # ============================================================ function Start-VBAFCenterCrisis { param( [Parameter(Mandatory)] [string] $CustomerID, [string] $CrisisType = "" ) $profilePath = Join-Path $env:USERPROFILE "VBAFCenter\customers\$CustomerID.json" if (-not (Test-Path $profilePath)) { Write-Host "Customer not found: $CustomerID" -ForegroundColor Red return } $profile = Get-Content $profilePath -Raw | ConvertFrom-Json Write-Host "" Write-Host " +--------------------------------------------------+" -ForegroundColor Red Write-Host " | VBAF-Center CRISIS RESPONSE ACTIVATED |" -ForegroundColor Red Write-Host " | Follow the steps. Do not skip any. |" -ForegroundColor Red Write-Host " +--------------------------------------------------+" -ForegroundColor Red Write-Host (" | Customer : {0,-39}|" -f $profile.CompanyName) -ForegroundColor White Write-Host (" | Time : {0,-39}|" -f (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")) -ForegroundColor White Write-Host " +--------------------------------------------------+" -ForegroundColor Red Write-Host "" # Select crisis type if ($CrisisType -eq "") { Write-Host " Select crisis type:" -ForegroundColor Yellow Write-Host "" $domain = $profile.BusinessType.ToLower() $relevant = $script:CrisisTrees.Keys | Where-Object { $script:CrisisTrees[$_].Domain.ToLower() -eq $domain -or $domain -eq "logistics" -and $_ -like "LOGISTICS-*" -or $domain -eq "it" -and $_ -like "IT-*" -or $domain -eq "manufacturing" -and $_ -like "MFG-*" -or $domain -eq "healthcare" -and $_ -like "HEALTH-*" } if ($relevant.Count -eq 0) { $relevant = $script:CrisisTrees.Keys } $i = 1 $menu = @{} foreach ($key in ($relevant | Sort-Object)) { $tree = $script:CrisisTrees[$key] Write-Host (" {0}. {1}" -f $i, $tree.Title) -ForegroundColor White Write-Host (" Trigger: {0}" -f $tree.Trigger) -ForegroundColor DarkGray $menu[$i.ToString()] = $key $i++ } Write-Host "" $choice = Read-Host " Enter number" $CrisisType = $menu[$choice] if (-not $CrisisType) { Write-Host " Invalid selection." -ForegroundColor Red return } } $tree = $script:CrisisTrees[$CrisisType] if (-not $tree) { Write-Host "Crisis type not found: $CrisisType" -ForegroundColor Red return } Write-Host "" Write-Host (" CRISIS: {0}" -f $tree.Title) -ForegroundColor Red Write-Host (" Trigger: {0}" -f $tree.Trigger) -ForegroundColor Yellow Write-Host "" $responses = @() $startTime = Get-Date $allResolved = $true foreach ($step in $tree.Steps) { Write-Host (" ─── Step {0} ───" -f $step.Step) -ForegroundColor Cyan Write-Host (" {0}" -f $step.Question) -ForegroundColor White Write-Host "" Write-Host " Y = Yes N = No" -ForegroundColor DarkGray Write-Host "" $answer = Read-Host " Your answer (Y/N)" if ($answer.ToUpper() -eq "Y") { Write-Host "" Write-Host (" ACTION: {0}" -f $step.Yes) -ForegroundColor Green $responses += @{ Step=$step.Step; Question=$step.Question; Answer="Yes"; Action=$step.Yes } Write-Host "" $confirm = Read-Host " Action taken? Mark as done (Y/N)" if ($confirm.ToUpper() -eq "Y") { Write-Host " Step $($step.Step) complete." -ForegroundColor Green break } } else { Write-Host "" Write-Host (" CONTINUE: {0}" -f $step.No) -ForegroundColor Yellow $responses += @{ Step=$step.Step; Question=$step.Question; Answer="No"; Action=$step.No } Write-Host "" if ($step.No -like "ESCALATE*") { $allResolved = $false } } Write-Host "" } $endTime = Get-Date $duration = [Math]::Round(($endTime - $startTime).TotalMinutes, 1) $resolution = if ($allResolved) { "Resolved" } else { "Escalated" } $resColor = if ($allResolved) { "Green" } else { "Red" } # Save crisis log $historyPath = Join-Path $env:USERPROFILE "VBAFCenter\crisis" if (-not (Test-Path $historyPath)) { New-Item -ItemType Directory -Path $historyPath -Force | Out-Null } $logFile = Join-Path $historyPath "$CustomerID-crisis-$(Get-Date -Format 'yyyyMMdd_HHmmss').json" @{ CustomerID = $CustomerID CrisisType = $CrisisType Title = $tree.Title StartTime = $startTime.ToString("yyyy-MM-dd HH:mm:ss") EndTime = $endTime.ToString("yyyy-MM-dd HH:mm:ss") Duration = $duration Resolution = $resolution Responses = $responses } | ConvertTo-Json -Depth 5 | Set-Content $logFile -Encoding UTF8 Write-Host "" Write-Host " +--------------------------------------------------+" -ForegroundColor $resColor Write-Host (" | Crisis Resolution: {0,-31}|" -f $resolution) -ForegroundColor $resColor Write-Host (" | Duration : {0} minutes{1,-30}|" -f $duration, "") -ForegroundColor White Write-Host (" | Logged to : {0,-35}|" -f (Split-Path $logFile -Leaf)) -ForegroundColor White Write-Host " +--------------------------------------------------+" -ForegroundColor $resColor Write-Host "" } # ============================================================ # GET-VBAFCENTERCRISISTREEE # ============================================================ function Get-VBAFCenterCrisisTree { Write-Host "" Write-Host " VBAF-Center Crisis Trees" -ForegroundColor Cyan Write-Host "" Write-Host (" {0,-35} {1,-15} {2}" -f "Crisis Type", "Domain", "Steps") -ForegroundColor Yellow Write-Host (" {0}" -f ("-" * 70)) -ForegroundColor DarkGray foreach ($key in ($script:CrisisTrees.Keys | Sort-Object)) { $tree = $script:CrisisTrees[$key] Write-Host (" {0,-35} {1,-15} {2}" -f $tree.Title, $tree.Domain, $tree.Steps.Count) -ForegroundColor White } Write-Host "" } # ============================================================ # NEW-VBAFCENTERCRISISTREEE # ============================================================ function New-VBAFCenterCrisisTree { param( [Parameter(Mandatory)] [string] $TreeKey, [Parameter(Mandatory)] [string] $Domain, [Parameter(Mandatory)] [string] $Title, [Parameter(Mandatory)] [string] $Trigger ) $script:CrisisTrees[$TreeKey] = @{ Domain = $Domain Trigger = $Trigger Title = $Title Steps = @() } Write-Host ("Crisis tree added: {0}" -f $Title) -ForegroundColor Green } # ============================================================ # GET-VBAFCENTERCRISISHISTORY # ============================================================ function Get-VBAFCenterCrisisHistory { param( [Parameter(Mandatory)] [string] $CustomerID, [int] $Last = 10 ) $historyPath = Join-Path $env:USERPROFILE "VBAFCenter\crisis" if (-not (Test-Path $historyPath)) { Write-Host "No crisis history found." -ForegroundColor Yellow return } $logs = Get-ChildItem $historyPath -Filter "$CustomerID-crisis-*.json" | Sort-Object LastWriteTime -Descending | Select-Object -First $Last if ($logs.Count -eq 0) { Write-Host "No crisis history for $CustomerID." -ForegroundColor Yellow return } Write-Host "" Write-Host (" Crisis History: {0} (last {1})" -f $CustomerID, $Last) -ForegroundColor Cyan Write-Host (" {0,-22} {1,-30} {2,-12} {3}" -f "Time", "Crisis", "Duration", "Resolution") -ForegroundColor Yellow Write-Host (" {0}" -f ("-" * 80)) -ForegroundColor DarkGray foreach ($log in $logs) { $h = Get-Content $log.FullName -Raw | ConvertFrom-Json $color = if ($h.Resolution -eq "Resolved") { "Green" } else { "Red" } Write-Host (" {0,-22} {1,-30} {2,-12} {3}" -f $h.StartTime, $h.Title, "$($h.Duration) min", $h.Resolution) -ForegroundColor $color } Write-Host "" } # ============================================================ # LOAD MESSAGE # ============================================================ Write-Host "" Write-Host " +--------------------------------------------------+" -ForegroundColor Red Write-Host " | VBAF-Center Phase 13 - Crisis Response Tree |" -ForegroundColor Red Write-Host " | Step-by-step recovery when signals go critical |" -ForegroundColor Red Write-Host " +--------------------------------------------------+" -ForegroundColor Red Write-Host "" Write-Host " Start-VBAFCenterCrisis — activate crisis wizard" -ForegroundColor White Write-Host " Get-VBAFCenterCrisisTree — show all crisis trees" -ForegroundColor White Write-Host " New-VBAFCenterCrisisTree — add custom crisis tree" -ForegroundColor White Write-Host " Get-VBAFCenterCrisisHistory — show past crisis responses"-ForegroundColor White Write-Host "" Write-Host " Quick start:" -ForegroundColor Yellow Write-Host " Start-VBAFCenterCrisis -CustomerID 'TruckCompanyDK'" -ForegroundColor Green Write-Host " Get-VBAFCenterCrisisTree" -ForegroundColor Green Write-Host "" |