Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
3.7 KiB
Python
72 lines
3.7 KiB
Python
"""Data Breach Response Plan handler (template-based).
|
|
|
|
Generates a data breach incident response plan by filling a comprehensive
|
|
DOCX template with customer-specific information. Does not require LLM
|
|
generation — uses pre-written plan sections with variable substitution.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from datetime import datetime
|
|
|
|
from .base_handler import BaseServiceHandler
|
|
|
|
|
|
class BreachResponseHandler(BaseServiceHandler):
|
|
SERVICE_SLUG = "breach-response"
|
|
SERVICE_NAME = "Data Breach Response Plan"
|
|
TEMPLATE_NAME = "breach_response_template.docx"
|
|
REQUIRES_LLM = False
|
|
|
|
async def process(self, order_data: dict) -> list[str]:
|
|
work_dir = self._make_work_dir()
|
|
order_number = order_data["name"]
|
|
|
|
template_path = self._get_template_path()
|
|
docx_filename = self._output_filename(order_number, "docx")
|
|
docx_path = os.path.join(work_dir, docx_filename)
|
|
|
|
now = datetime.now()
|
|
variables = {
|
|
"order_number": order_number,
|
|
"customer_name": order_data.get("customer_name", ""),
|
|
"date": now.strftime("%B %d, %Y"),
|
|
"effective_date": now.strftime("%B %d, %Y"),
|
|
"service_name": self.SERVICE_NAME,
|
|
# Company details
|
|
"company_name": order_data.get("custom_company_legal_name", order_data.get("customer_name", "")),
|
|
"company_address": order_data.get("custom_company_address", "[ADDRESS]"),
|
|
"company_phone": order_data.get("custom_contact_phone", "[PHONE]"),
|
|
"company_email": order_data.get("custom_contact_email", "[EMAIL]"),
|
|
# Incident response team
|
|
"irt_lead": order_data.get("custom_irt_lead", "[IRT LEAD]"),
|
|
"irt_lead_title": order_data.get("custom_irt_lead_title", "[TITLE]"),
|
|
"irt_lead_phone": order_data.get("custom_irt_lead_phone", "[PHONE]"),
|
|
"irt_lead_email": order_data.get("custom_irt_lead_email", "[EMAIL]"),
|
|
"legal_counsel": order_data.get("custom_legal_counsel", "[LEGAL COUNSEL]"),
|
|
"legal_counsel_phone": order_data.get("custom_legal_counsel_phone", "[PHONE]"),
|
|
"it_security_lead": order_data.get("custom_it_security_lead", "[IT SECURITY LEAD]"),
|
|
"communications_lead": order_data.get("custom_communications_lead", "[COMMUNICATIONS LEAD]"),
|
|
"hr_lead": order_data.get("custom_hr_lead", "[HR LEAD]"),
|
|
# External contacts
|
|
"cyber_insurance_carrier": order_data.get("custom_cyber_insurance_carrier", "[CARRIER]"),
|
|
"cyber_insurance_policy": order_data.get("custom_cyber_insurance_policy", "[POLICY #]"),
|
|
"forensics_vendor": order_data.get("custom_forensics_vendor", "[FORENSICS VENDOR]"),
|
|
"pr_firm": order_data.get("custom_pr_firm", "[PR FIRM]"),
|
|
# Jurisdiction & regulation
|
|
"state": order_data.get("custom_state", "California"),
|
|
"notification_deadline_days": order_data.get("custom_notification_deadline", "30"),
|
|
"ag_notification_threshold": order_data.get("custom_ag_threshold", "500"),
|
|
"applicable_laws": order_data.get("custom_applicable_breach_laws", "Cal. Civ. Code § 1798.82"),
|
|
# Infrastructure
|
|
"total_records": order_data.get("custom_total_records", "[TOTAL RECORDS]"),
|
|
"data_types": order_data.get("custom_sensitive_data_types", "SSN, financial account numbers, health information"),
|
|
"primary_systems": order_data.get("custom_primary_systems", "[PRIMARY SYSTEMS]"),
|
|
}
|
|
|
|
self._fill_template(template_path, variables, docx_path)
|
|
|
|
pdf_path = self._convert_to_pdf(docx_path)
|
|
|
|
return [docx_path, pdf_path]
|