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