new-site/scripts/workers/services/stir_shaken.py
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
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>
2026-04-27 06:54:22 -05:00

115 lines
4.6 KiB
Python

"""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)