"""Marketing Campaign Compliance Review handler (LLM-based). Reviews marketing campaigns for compliance with CAN-SPAM, TCPA, FTC Endorsement Guides, state advertising laws, and industry-specific marketing regulations. """ 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 Marketing Campaign Compliance Review report. RULES: - Write in professional, clear business English - Reference CAN-SPAM Act (15 U.S.C. § 7701), TCPA, FTC Act § 5, FTC Endorsement Guides (16 CFR Part 255), and state consumer protection laws - Never provide legal advice — use "we recommend" not "you must" - For each finding: what was found, regulation, risk level (Low/Medium/High/Critical), remediation - Consider: email marketing, SMS marketing, social media advertising, influencer partnerships, testimonials, sweepstakes/contests, and pricing claims - Assess truthfulness, substantiation, disclosures, and consent requirements """ SECTIONS = [ { "name": "executive_summary", "prompt": ( "Write a 200-word executive summary of the marketing campaign " "compliance review. Include scope (channels and campaigns reviewed), " "overall compliance posture, and highest-risk findings." ), }, { "name": "email_marketing", "prompt": ( "Review email marketing compliance under CAN-SPAM. Assess: " "from/reply-to accuracy, subject line deceptiveness, commercial " "message identification, physical address inclusion, opt-out " "mechanism (must process within 10 business days), opt-out " "honoring, third-party email obligations, and transactional " "vs. commercial message classification." ), }, { "name": "sms_and_calling", "prompt": ( "Review SMS/text and calling campaign compliance under TCPA " "and state laws. Assess: prior express written consent for " "marketing texts, autodialer usage, opt-out mechanisms (STOP " "keyword), frequency disclosures, and compliance with CTIA " "short code monitoring handbook guidelines." ), }, { "name": "advertising_claims", "prompt": ( "Review advertising claims for FTC Act § 5 compliance. Assess: " "truthfulness of claims, adequate substantiation, clear and " "conspicuous disclosures, comparative advertising accuracy, " "environmental/green marketing claims (FTC Green Guides), " "health/safety claims, and 'free' offer compliance." ), }, { "name": "endorsements_and_social", "prompt": ( "Review endorsement and social media marketing under FTC " "Endorsement Guides. Assess: material connection disclosures, " "influencer/ambassador agreements, employee social media " "guidelines, testimonial substantiation, review solicitation " "practices, and platform-specific compliance (FTC vs. platform " "rules)." ), }, { "name": "promotions_and_contests", "prompt": ( "Review sweepstakes, contests, and promotional offers. Assess: " "official rules completeness, no-purchase-necessary compliance, " "void-where-prohibited disclosures, prize descriptions, odds " "disclosures, state registration requirements, and bonding " "requirements where applicable." ), }, { "name": "remediation_plan", "prompt": ( "Provide a prioritized remediation plan for all findings. " "For each item: finding reference, risk level, recommended action, " "responsible party, timeline. Distinguish between in-market " "corrections (urgent) and process improvements (ongoing)." ), }, ] class CampaignReviewHandler(BaseServiceHandler): SERVICE_SLUG = "campaign-review" SERVICE_NAME = "Marketing Campaign Compliance Review" TEMPLATE_NAME = "campaign_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]