Wire CPNI, CALEA, 499-A engagement, and discontinuance to generic eSign

Each handler now pauses for officer signature via the eSign portal
before filing/submitting. esign_completed callback re-dispatches
through standard pipeline with client_approved=true.

- CPNI: officer signs certification before ECFS submission (perjury)
- CALEA SSI: officer signs plan before delivery
- 499-A engagement: replaced custom JWT/email with request_esign()
- Discontinuance: officer signs deactivation letter before USAC email
- job_server: injects client_approved + order_number into order_data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-05-04 10:53:59 -05:00
parent 40844b2aff
commit ff47f47a37
5 changed files with 161 additions and 74 deletions

View file

@ -167,6 +167,46 @@ class CALEASSIHandler(BaseServiceHandler):
except Exception as exc:
logger.warning("CALEA SSI PDF conversion failed: %s", exc)
# ── Client eSign gate ──────────────────────────────────────────
# The CALEA SSI plan requires officer signature before delivery.
client_approved = order_data.get("client_approved", False)
if not client_approved and generated:
from scripts.document_gen import MinioStorage
storage = MinioStorage()
pdf_minio_key = ""
for path in generated:
if path.endswith(".pdf"):
remote = f"compliance/{order_number}/{os.path.basename(path)}"
try:
storage.upload_file(path, remote)
pdf_minio_key = remote
except Exception as exc:
logger.warning("MinIO upload failed for %s: %s", path, exc)
break
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
from scripts.workers.services.telecom.esign_helper import request_esign
request_esign(
conn=conn,
order_number=order_number,
document_type="calea",
document_title="CALEA System Security & Integrity Plan",
entity_name=entity.get("legal_name", ""),
customer_email=order_data.get("customer_email") or entity.get("contact_email", ""),
customer_name=order_data.get("customer_name") or entity.get("contact_name", ""),
document_minio_key=pdf_minio_key,
requires_perjury=False,
metadata={"frn": entity.get("frn", "")},
)
conn.close()
except Exception as exc:
logger.warning("Could not create CALEA eSign record: %s", exc)
logger.info("CALEASSIHandler: paused for client eSign — order %s", order_number)
return generated
# Persist + schedule annual review
if entity_id:
self._persist_calea_state(

View file

@ -188,7 +188,50 @@ class CPNIFilingHandler(BaseServiceHandler):
)
return generated
# ── 2a. Auto-filing toggle ──────────────────────────────────────
# ── 2a. Client eSign gate ──────────────────────────────────────
# Officer must sign the CPNI certification before FCC submission
# (47 CFR § 64.2009(e) requires officer attestation).
client_approved = order_data.get("client_approved", False)
if not client_approved:
# Upload cert PDF to MinIO for the signing portal preview
from scripts.document_gen import MinioStorage
storage = MinioStorage()
pdf_minio_key = ""
for path in generated:
if path.endswith(".pdf") and "certification" in path.lower():
remote = f"compliance/{order_number}/{os.path.basename(path)}"
try:
storage.upload_file(path, remote)
pdf_minio_key = remote
except Exception as exc:
logger.warning("MinIO upload failed for %s: %s", path, exc)
break
# Create eSign record + send signing email
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
from scripts.workers.services.telecom.esign_helper import request_esign
request_esign(
conn=conn,
order_number=order_number,
document_type="cpni",
document_title="CPNI Annual Certification",
entity_name=entity.get("legal_name", ""),
customer_email=order_data.get("customer_email") or entity.get("contact_email", ""),
customer_name=order_data.get("customer_name") or entity.get("contact_name", ""),
document_minio_key=pdf_minio_key,
requires_perjury=True,
metadata={"frn": entity.get("frn", ""), "docket": CPNI_DOCKET},
)
conn.close()
except Exception as exc:
logger.warning("Could not create CPNI eSign record: %s", exc)
logger.info("CPNIFilingHandler: paused for client eSign — order %s", order_number)
return generated
# ── 2b. Auto-filing toggle ──────────────────────────────────────
decision = check_auto_filing(order_data)
if not decision.may_submit:
logger.info(

View file

@ -179,7 +179,7 @@ class Form499AHandler(BaseServiceHandler):
or (multi_year and len(multi_year) >= 2)
)
if needs_engagement:
esign_signed = order_data.get("engagement_esign_signed_at")
esign_signed = order_data.get("engagement_esign_signed_at") or order_data.get("client_approved")
if not esign_signed:
# Check if we already generated the letter (avoid re-sending on re-dispatch)
already_required = order_data.get("engagement_esign_required")
@ -1537,72 +1537,37 @@ class Form499AHandler(BaseServiceHandler):
cur.execute(
"""UPDATE compliance_orders
SET engagement_esign_required = TRUE,
engagement_letter_minio_key = %s,
payment_status = 'pending_esign'
engagement_letter_minio_key = %s
WHERE order_number = %s""",
(minio_key, order_number),
)
conn.commit()
cur.close()
conn.close()
except Exception as exc:
logger.warning("Could not update engagement status: %s", exc)
conn = None
# Email client the engagement signing link
if customer_email:
# Create eSign record + send signing email via generic portal
if customer_email and conn:
try:
try:
import jwt as pyjwt
except ImportError:
import PyJWT as pyjwt
secret = os.environ.get("CUSTOMER_JWT_SECRET", "changeme")
domain = os.environ.get("DOMAIN", "performancewest.net")
token = pyjwt.encode(
{"order_id": order_number, "order_type": "compliance", "email": customer_email},
secret, algorithm="HS256",
)
sign_url = f"https://{domain}/portal/engagement-sign?token={token}"
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
first_name = customer_name.split(" ")[0] if customer_name else "there"
from scripts.workers.services.telecom.esign_helper import request_esign
years_str = ", ".join(str(y) for y in multi_year) if multi_year else "current year"
subject = f"Engagement Letter — 499-A Revenue Audit for {entity.get('legal_name', order_number)}"
body = (
f"<h2>Engagement Letter Ready for Signature</h2>"
f"<p>Hi {first_name},</p>"
f"<p>Before we begin your FCC Form 499-A revenue audit and revised filing "
f"for calendar year(s) <strong>{years_str}</strong>, we need your signature "
f"on the engagement letter.</p>"
f"<p>Please review and sign the letter by clicking below:</p>"
f"<p><a href='{sign_url}' style='display:inline-block;background:#1e3a5f;color:#fff;"
f"padding:12px 28px;border-radius:6px;text-decoration:none;font-weight:600;'>"
f"Review & Sign Engagement Letter</a></p>"
f"<p style='font-size:12px;color:#9ca3af;'>Order: {order_number}</p>"
f"<p style='font-size:11px;color:#9ca3af;margin-top:16px;'>"
f"Performance West Inc. | 525 Randall Ave Ste 100-1195, Cheyenne, WY 82001 | 1-888-411-0383</p>"
request_esign(
conn=conn,
order_number=order_number,
document_type="499a-engagement",
document_title=f"Engagement Letter — 499-A Filing ({years_str})",
entity_name=entity.get("legal_name") or intake.get("entity_legal_name", ""),
customer_email=customer_email,
customer_name=customer_name,
document_minio_key=minio_key,
requires_perjury=False,
metadata={"frn": entity.get("frn", ""), "filing_years": multi_year},
)
msg = MIMEMultipart("alternative")
msg["Subject"] = subject
msg["From"] = os.environ.get("SMTP_FROM", "Performance West <noreply@performancewest.net>")
msg["To"] = customer_email
msg.attach(MIMEText(body, "html"))
smtp_host = os.environ.get("SMTP_HOST", "co.carrierone.com")
smtp_port = int(os.environ.get("SMTP_PORT", "587"))
smtp_user = os.environ.get("SMTP_USER", "")
smtp_pass = os.environ.get("SMTP_PASS", "")
with smtplib.SMTP(smtp_host, smtp_port) as server:
server.starttls()
if smtp_user and smtp_pass:
server.login(smtp_user, smtp_pass)
server.send_message(msg)
logger.info("Engagement letter email sent to %s for %s", customer_email, order_number)
except Exception as exc:
logger.warning("Could not send engagement email for %s: %s", order_number, exc)
logger.warning("Could not create engagement eSign record for %s: %s", order_number, exc)
finally:
conn.close()
# Create admin todo
try:

View file

@ -98,6 +98,34 @@ class Form499ADiscontinuanceHandler(BaseServiceHandler):
except Exception as exc:
logger.warning("Discontinuance letter generation failed: %s", exc)
# ── Client eSign gate ──────────────────────────────────────────
# Officer must sign the deactivation letter before we send to USAC.
client_approved = order_data.get("client_approved", False)
if not client_approved and letter_path:
minio_key = f"compliance/{order_number}/usac_deactivation_letter_{datetime.now().strftime('%Y%m%d')}.docx"
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
from scripts.workers.services.telecom.esign_helper import request_esign
request_esign(
conn=conn,
order_number=order_number,
document_type="discontinuance",
document_title="USAC Filer ID Deactivation Letter",
entity_name=legal_name,
customer_email=entity.get("contact_email") or order_data.get("customer_email", ""),
customer_name=order_data.get("customer_name") or entity.get("contact_name", ""),
document_minio_key=minio_key,
requires_perjury=False,
metadata={"frn": frn, "filer_id": filer_id},
)
conn.close()
except Exception as exc:
logger.warning("Could not create discontinuance eSign record: %s", exc)
logger.info("Form499ADiscontinuanceHandler: paused for client eSign — order %s", order_number)
return [letter_path] if letter_path else []
# Per FCC 499-A Instructions: discontinuance requires TWO steps:
# 1. File the final 499-A (may have actual revenue from the portion
# of the year the company operated — NOT required to be zero)