"""STIR/SHAKEN Implementation Assistance handler. STIR/SHAKEN has two moving pieces: 1. The STI Certification Authority (STI-CA) issues the actual digital certificate used to sign calls. This is an external vendor handoff (Peeringhub, iconectiv, Neustar, TransNexus, etc.) — we cannot file this automatically on the customer's behalf. 2. The carrier's STIR/SHAKEN implementation status must be accurately reflected in the Robocall Mitigation Database (RMD). Our RMD filing handler already drives that portal; we reuse it here. This handler: * Reuses ``RMDFilingHandler`` to update the RMD entry with the new STIR/SHAKEN posture (e.g., moving from ``robocall_mitigation_only`` to ``partial_implementation``). * Creates an ERPNext ToDo assigned to the Accounting Advisor to shepherd the customer through the STI-CA cert provisioning with the vendor of their choice. The ToDo captures the carrier's preferred vendor from the intake data if present. * On successful STI-CA issuance (recorded manually on the telecom_entity through the admin UI), the next compliance checkup will see ``stir_shaken_cert_issued_at`` populated and flip the STIR/SHAKEN check from red/yellow to green. """ from __future__ import annotations import logging from .base_handler import BaseServiceHandler from .rmd_filing import RMDFilingHandler logger = logging.getLogger(__name__) class StirShakenHandler(BaseServiceHandler): SERVICE_SLUG = "stir-shaken" SERVICE_NAME = "STIR/SHAKEN Implementation Assistance" REQUIRES_LLM = False async def process(self, order_data: dict) -> list[str]: order_number = order_data["name"] entity = order_data.get("entity", {}) intake = order_data.get("intake_data") or {} # ── 1. Update RMD entry with new STIR/SHAKEN status ──────────── # The customer's order intake should carry the target posture; if # not, we default to partial_implementation (most common uplift # path for non-facilities-based carriers). target_status = ( intake.get("target_stir_shaken_status") or entity.get("stir_shaken_status") or "partial_implementation" ) entity_with_target = dict(entity) entity_with_target["stir_shaken_status"] = target_status rmd_handler = RMDFilingHandler() rmd_order = dict(order_data) rmd_order["entity"] = entity_with_target generated = await rmd_handler.process(rmd_order) # ── 2. Create admin ToDo for STI-CA vendor coordination ───────── self._create_sti_ca_todo( order_number=order_number, entity=entity, preferred_vendor=intake.get("sti_ca_vendor", ""), current_status=entity.get("stir_shaken_status", ""), target_status=target_status, ) return generated def _create_sti_ca_todo( self, *, order_number: str, entity: dict, preferred_vendor: str, current_status: str, target_status: str, ) -> None: try: from scripts.workers.erpnext_client import ERPNextClient description = ( f"[{self.SERVICE_SLUG}] {order_number}\n\n" f"Coordinate STI-CA digital certificate issuance with the " f"carrier's chosen STI Certification Authority.\n\n" f"Carrier: {entity.get('legal_name', '')}\n" f"FRN: {entity.get('frn', 'N/A')}\n" f"Current STIR/SHAKEN posture: {current_status or 'N/A'}\n" f"Target STIR/SHAKEN posture: {target_status}\n" f"Preferred STI-CA vendor (if specified): {preferred_vendor or 'not specified'}\n\n" f"Steps:\n" f" 1. Introduce customer to chosen STI-CA (Peeringhub, iconectiv, " f"Neustar, TransNexus, etc.).\n" f" 2. Coordinate OCN / SPC code issuance (via iconectiv) if needed.\n" f" 3. Track cert issuance; when received, update telecom_entities." f"stir_shaken_cert_issued_at and stir_shaken_cert_authority.\n" f" 4. Run the compliance checkup again to confirm STIR/SHAKEN check " f"flips green.\n" ) ERPNextClient().create_resource( "ToDo", { "description": description, "priority": "High", "role": "Accounting Advisor", }, ) except Exception as exc: logger.error("Could not create STI-CA ToDo: %s", exc)