Unified Incident Opening Workflowยค
Date: October 10, 2025 Status: Current implementation
๐ Overviewยค
The incident opening workflow in FireFighter now uses a unified form for all incident priorities (P1-P5). This simplified workflow eliminates the need for incident type selection (Step 3) and uses dynamic field visibility based on selected impacts.
๐ Key Changes from Previous Workflowยค
Before (Multiple Forms)ยค
- 6 separate forms: 1 critical form + 5 RAID forms (Customer, Seller, Internal, Documentation, Feature Request)
- STEP 3 required: Users had to select incident type for P4/P5
- Static forms: Each form had fixed fields regardless of impact selection
After (Unified Form)ยค
- 1 unified form:
UnifiedIncidentForm
handles all priorities - STEP 3 hidden: Automatically skipped since only one form type exists
- Dynamic fields: Fields show/hide based on selected impacts
๐ Complete Unified Workflowยค
PART 1: All Incidents (P1-P5)ยค
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 0: Intro โ
โ - Welcome message โ
โ - Warning if recent incidents in the last hour โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 1: Set Impacts (SelectImpactForm) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Dynamic fields for each ImpactType: โ
โ โข Business Impact (HIGH/MEDIUM/LOW/LOWEST/NO) โ
โ โข Operational Impact (HIGH/MEDIUM/LOW/LOWEST/NO) โ
โ โข Technical Impact (HIGH/MEDIUM/LOW/LOWEST/NO) โ
โ โ
โ โ Auto-calculates priority_value and response_type โ
โ - priority_value < 4 โ response_type = "critical" (P1-P3) โ
โ - priority_value >= 4 โ response_type = "normal" (P4-P5) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 2: Priority/SLA Display (Response Type Block) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Displays (non-editable): โ
โ โข ๐ด๐ก๐ข Selected priority: P1/P2/P3/P4/P5 - Description โ
โ โข โฑ๏ธ SLA: 15min / 30min / 1h / 2days / 5days โ
โ โข :gear: Process: Slack+Jira or Jira only โ
โ โข :pushpin: Selected impacts: [detailed list] โ
โ โข :warning: Critical warning (P1-P3 only) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 3: Select Incident Type โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โก AUTOMATICALLY HIDDEN โก โ
โ โ
โ Since len(INCIDENT_TYPES[response_type]) == 1, โ
โ this step is skipped entirely. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 4: Set Details (UnifiedIncidentFormSlack) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ COMMON Fields (always shown): โ
โ โข incident_category (GroupedModelChoiceField) โ
โ โข environment (ModelMultipleChoiceField) - ALL priorities โ
โ โข platform (MultipleChoiceField, default ALL) - ALL โ
โ โข title (CharField, 10-128 chars) โ
โ โข description (TextField, 10-1200 chars) โ
โ โข priority (HiddenInput - auto-determined) โ
โ โ
โ CONDITIONAL Fields (based on response_type): โ
โ โข suggested_team_routing (P4/P5 ONLY) โ
โ โ
โ DYNAMIC Fields (based on selected impacts): โ
โ IF Customer Impact selected: โ
โ โข zendesk_ticket_id (optional) โ
โ IF Seller Impact selected: โ
โ โข seller_contract_id (optional) โ
โ โข is_key_account (boolean) โ
โ โข is_seller_in_golden_list (boolean) โ
โ โข zoho_desk_ticket_id (optional) โ
โ IF Employee Impact selected: โ
โ โข (no additional fields) โ
โ โ
โ Note: Multiple impact types can be selected simultaneously โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEP 5: Review & Submit โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Displays (based on response_type): โ
โ IF Critical (P1-P3): โ
โ โข :slack: Dedicated Slack channel will be created โ
โ โข ~X responders will be invited โ
โ โข :jira_new: Associated Jira ticket will be created โ
โ โข :pagerduty: (if outside office hours) โ
โ IF Normal (P4-P5): โ
โ โข :jira_new: A Jira ticket will be created โ
โ โข (NO Slack channel, NO PagerDuty) โ
โ โ
โ Button: "Create the incident" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
[SUBMIT TRIGGERED]
โ
โโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโ
โ โ
[CRITICAL P1-P3] [NORMAL P4-P5]
โ โ
_trigger_critical_incident_workflow _trigger_normal_incident_workflow
โ โ
Create Incident object Prepare fields (prepare_jira_fields):
Save impacts - Extract environments, platforms
Create Slack channel - Compute business_impact
Create Jira ticket - Gather optional fields
Invite responders Create Jira (jira_client.create_issue)
Alert PagerDuty (if needed) - Passes ALL custom fields
Process ticket (process_jira_issue):
- Save impacts, set watchers
- Alert Slack
๐ฏ Dynamic Field Visibility Logicยค
Decision Tree for Field Displayยค
START: User selects impacts in STEP 1
โ
Calculate priority_value โ Determine response_type
โ
Build visible_fields list:
โโ ALWAYS include: title, description, incident_category,
โ environment, platform, priority
โ
IF response_type == "normal" (P4/P5):
โโ ADD: suggested_team_routing
โ
FOR EACH selected impact:
โโ IF customers_impact != NONE:
โ โโ ADD: zendesk_ticket_id
โโ IF sellers_impact != NONE:
โ โโ ADD: seller_contract_id, is_key_account,
โ is_seller_in_golden_list, zoho_desk_ticket_id
โโ IF employees_impact != NONE:
โโ (no additional fields)
โ
Remove all fields NOT in visible_fields from form
โ
Display final form with only relevant fields
Example Scenariosยค
Scenario 1: P1 Critical with Customer Impact
Response Type: critical
Impacts: customers_impact = HIGH
Visible Fields:
โ
title, description, incident_category
โ
environment (multiple), platform (multiple)
โ
priority (hidden)
โ
zendesk_ticket_id (customer impact)
โ suggested_team_routing (not P4/P5)
โ seller fields (no seller impact)
Scenario 2: P4 Normal with Seller + Customer Impact
Response Type: normal
Impacts: sellers_impact = MEDIUM, customers_impact = LOW
Visible Fields:
โ
title, description, incident_category
โ
environment (multiple), platform (multiple)
โ
priority (hidden)
โ
suggested_team_routing (P4/P5)
โ
zendesk_ticket_id (customer impact)
โ
seller_contract_id, is_key_account, etc. (seller impact)
Scenario 3: P5 Normal with Employee Impact Only
Response Type: normal
Impacts: employees_impact = LOW
Visible Fields:
โ
title, description, incident_category
โ
environment (multiple), platform (multiple)
โ
priority (hidden)
โ
suggested_team_routing (P4/P5)
โ customer fields (no customer impact)
โ seller fields (no seller impact)
๐ง Technical Implementationยค
Core Filesยค
1. Unified Form (Django)ยค
File: src/firefighter/incidents/forms/unified_incident.py
class UnifiedIncidentForm(CreateIncidentFormBase):
"""Unified form for all incident types and priorities (P1-P5)."""
def get_visible_fields_for_impacts(
self, impacts_data: dict[str, ImpactLevel], response_type: str
) -> list[str]:
"""Determine which fields should be visible based on impacts."""
# Returns list of field names that should be displayed
def trigger_incident_workflow(
self, creator: User, impacts_data: dict[str, ImpactLevel],
response_type: str = "critical"
) -> None:
"""Trigger appropriate workflow based on response type."""
if response_type == "critical":
self._trigger_critical_incident_workflow(creator, impacts_data)
else:
self._trigger_normal_incident_workflow(creator, impacts_data)
2. Slack Form Wrapperยค
File: src/firefighter/slack/views/modals/opening/details/unified.py
class UnifiedIncidentFormSlack(UnifiedIncidentForm):
"""Slack version with Slack-specific field configurations."""
def __init__(self, *args, impacts_data=None, response_type="critical", **kwargs):
super().__init__(*args, **kwargs)
self._impacts_data = impacts_data or {}
self._response_type = response_type
self._configure_field_visibility() # Hide/show fields dynamically
def _configure_field_visibility(self):
"""Remove fields that shouldn't be visible."""
visible_fields = self.get_visible_fields_for_impacts(
self._impacts_data, self._response_type
)
for field_name in list(self.fields.keys()):
if field_name not in visible_fields:
del self.fields[field_name]
3. Configuration Registrationยค
File: src/firefighter/raid/apps.py
INCIDENT_TYPES["normal"] = {
"normal": {
"label": "Normal",
"slack_form": OpeningUnifiedModal,
},
}
# Since len() == 1, STEP 3 is automatically hidden
File: src/firefighter/slack/views/modals/open.py
INCIDENT_TYPES["critical"] = {
"critical": {
"label": "Critical",
"slack_form": OpeningUnifiedModal,
},
}
# Same unified form used for both critical and normal
๐ Key Benefitsยค
1. Simplified User Experienceยค
- No more incident type selection for P4/P5 incidents
- Fewer steps in the workflow (4 instead of 5)
- Contextual fields only show what's relevant
2. Reduced Code Complexityยค
- 1 form instead of 6:
UnifiedIncidentForm
replaces all previous forms - Single source of truth: All incident creation logic in one place
- Easier maintenance: Changes apply to all incident types
3. Flexible Field Managementยค
- Dynamic visibility: Fields adapt to user selections
- Multiple impacts: Can combine customer + seller impacts
- Consistent behavior: Same form structure for all priorities
4. Preserved Functionalityยค
- โ All Jira ticket creation logic preserved
- โ All Slack notifications preserved
- โ All validation rules preserved
- โ All workflow integrations preserved
๐ Migration from Old Workflowยค
Removed Componentsยค
Component | Status | Replacement |
---|---|---|
CreateNormalIncidentFormBase | โ Deleted | UnifiedIncidentForm |
CreateNormalCustomerIncidentForm | โ Deleted | UnifiedIncidentForm |
CreateRaidSellerForm | โ Deleted | UnifiedIncidentForm |
CreateRaidInternalForm | โ Deleted | UnifiedIncidentForm |
CreateRaidDocumentationForm | โ Deleted | Not supported |
CreateRaidFeatureRequestForm | โ Deleted | Not supported |
CreateIncidentFormSlack (critical) | โ Deleted | UnifiedIncidentFormSlack |
raid/views/open_normal.py | โ Deleted | opening/details/unified.py |
Preserved Componentsยค
Component | Location | Purpose |
---|---|---|
prepare_jira_fields() | raid/forms.py | Centralize all Jira field preparation (GT-1334 fix) |
PlatformChoices | raid/forms.py | Platform enum (FR/DE/IT/ES/UK/ALL/Internal) |
initial_priority() | raid/forms.py | Get default priority |
process_jira_issue() | raid/forms.py | Create Jira ticket + impacts |
get_business_impact() | raid/forms.py | Calculate business impact |
alert_slack_new_jira_ticket() | raid/forms.py | Send Slack notifications |
set_jira_ticket_watchers_raid() | raid/forms.py | Add Jira watchers |
get_partner_alert_conversations() | raid/forms.py | Find partner Slack channels |
get_internal_alert_conversations() | raid/forms.py | Find internal Slack channels |
Deprecated Featuresยค
No longer supported: - โ Documentation Request incidents (P4/P5) - โ Feature Request incidents (P4/P5)
Rationale: These were specialized types that can be handled through standard P4/P5 internal incidents.
๐งช Testingยค
Tests for the unified form should be added in:
Existing utility function tests remain in: