new-site/scripts/workers/services/dnc_review.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

123 lines
4.8 KiB
Python

"""Do-Not-Call (DNC) Compliance Review handler (LLM-based).
Reviews an organization's telemarketing practices and Do-Not-Call compliance
under the Telephone Consumer Protection Act (TCPA), TSR, FCC rules, and
state DNC registries.
"""
from __future__ import annotations
import os
from .base_handler import BaseServiceHandler
SERVICE_SYSTEM_PROMPT = """You are a compliance analyst at Performance West Inc.
generating a Do-Not-Call (DNC) Compliance Review report.
RULES:
- Write in professional, clear business English
- Reference TCPA (47 U.S.C. § 227), FCC rules (47 CFR § 64.1200), and
FTC Telemarketing Sales Rule (16 CFR Part 310)
- Reference applicable state DNC laws and registries
- Never provide legal advice — use "we recommend" not "you must"
- For each finding: what was found, regulation, risk level, remediation
- Consider: national DNC registry, internal DNC lists, EBR exemptions,
prior express consent, autodialer/prerecorded message rules, caller ID requirements
- Note TCPA statutory damages ($500-$1,500 per violation) as risk context
"""
SECTIONS = [
{
"name": "executive_summary",
"prompt": (
"Write a 200-word executive summary of the DNC compliance review. "
"Include scope, calling volume metrics if available, overall "
"compliance posture, and critical findings."
),
},
{
"name": "regulatory_landscape",
"prompt": (
"Summarize the applicable DNC regulatory framework for this "
"organization. Cover: TCPA, FCC rules, FTC TSR, state DNC "
"registries applicable to their calling patterns, and recent "
"enforcement actions and FCC declaratory rulings that affect "
"their operations."
),
},
{
"name": "dnc_list_management",
"prompt": (
"Audit DNC list management practices. Assess: national DNC "
"registry scrubbing frequency (must be every 31 days), state "
"DNC registry subscriptions, internal DNC list maintenance, "
"DNC request processing timeline (must honor within reasonable "
"time), entity-specific vs. seller-specific DNC, and EBR "
"exemption tracking."
),
},
{
"name": "consent_and_calling_practices",
"prompt": (
"Review consent management for telemarketing. Assess: prior "
"express written consent for autodialed/prerecorded calls, "
"consent revocation processes, consent record retention, "
"calling time restrictions (8am-9pm), caller ID transmission, "
"and abandoned call rates (max 3% per campaign per 30 days)."
),
},
{
"name": "technology_compliance",
"prompt": (
"Evaluate technology and systems compliance. Assess: autodialer "
"definition under current TCPA interpretation, predictive dialer "
"settings, prerecorded message opt-out mechanisms (press 2 to "
"opt-out), interactive voice response compliance, and call "
"recording consent (two-party consent states)."
),
},
{
"name": "remediation_plan",
"prompt": (
"Provide a prioritized remediation plan. For each finding: "
"reference, risk level (note TCPA statutory damages exposure), "
"recommended action, responsible party, and timeline. Address "
"both immediate risk reduction and long-term program improvements."
),
},
]
class DNCReviewHandler(BaseServiceHandler):
SERVICE_SLUG = "dnc-compliance"
SERVICE_NAME = "Do-Not-Call Compliance Review"
TEMPLATE_NAME = "dnc_review_template.docx"
REQUIRES_LLM = True
async def process(self, order_data: dict) -> list[str]:
work_dir = self._make_work_dir()
order_number = order_data["name"]
context = self._extract_order_context(order_data)
template_path = self._get_template_path()
docx_filename = self._output_filename(order_number, "docx")
docx_path = os.path.join(work_dir, docx_filename)
variables = {
"order_number": order_number,
"customer_name": order_data.get("customer_name", ""),
"date": __import__("datetime").datetime.now().strftime("%B %d, %Y"),
"service_name": self.SERVICE_NAME,
"company_size": order_data.get("custom_company_size", "N/A"),
"industry": order_data.get("custom_industry", "N/A"),
"state": order_data.get("custom_state", "N/A"),
}
self._fill_template(template_path, variables, docx_path)
sections = await self._generate_sections(
SERVICE_SYSTEM_PROMPT, SECTIONS, context
)
self._add_sections_to_doc(docx_path, sections)
pdf_path = self._convert_to_pdf(docx_path)
return [docx_path, pdf_path]