new-site/docs/crm.md
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

14 KiB

Performance West — ERPNext CRM Integration

Last updated: 2026-04-06

Architecture Overview

Browser                  Astro Site                Express API              ERPNext
  |                        |                         |                       |
  +- Place order --------->+- POST /api/orders ----->+- Create DocType ----->|
  |                        |                         |                       |
  |                        |                         |    ERPNext Webhook     |
  |                        |                         |         |              |
  |                        |                         |    +----+----+        |
  |                        |                         |    | Webhook |------->|
  |                        |                         |    | triggers|        |
  |                        |                         |    | workers |        |
  |                        |                         |    +----+----+        |
  |                        |                         |         |              |
  |                        |                         |    +----+----+        |
  |                        |                         |    | Generate |        |
  |                        |                         |    | Docs     |        |
  |                        |                         |    +----+----+        |
  |                        |                         |         |              |
  |                        |                         |    +----+----+        |
  |                        |                         |    | Upload  |        |
  |                        |                         |    | to MinIO|        |
  |                        |                         |    +----+----+        |
  |                        |                         |         |              |
  |                        |                         |    Update status ---->|
  |                        |                         |                       |
  <-- email with docs -----|                         |                       |

Data flow:

  1. Customer submits order on Astro site
  2. Express API creates ERPNext Sales Invoice + Payment Request
  3. Customer pays via Adyen or SHKeeper (payment routed through ERPNext gateways)
  4. ERPNext marks invoice as Paid, webhook fires to Express API
  5. Express API dispatches job to Workers HTTP server (:8090)
  6. Workers generate documents (DOCX templates or LLM-written), convert to PDF
  7. Documents are uploaded to MinIO
  8. Worker updates ERPNext order status and attaches the MinIO URL
  9. Admin reviews in ERPNext; approves or requests revision
  10. Delivery worker emails documents to customer

Key principle: ERPNext is the single source of truth for all customer data, orders, and tickets. The Express API and Python workers read/write to ERPNext via its REST API. The API's own PostgreSQL database stores only state filing fees, API keys, session data, discount codes, payment surcharges, and commission ledger backup.

ERPNext Setup

  • URL: https://crm.performancewest.net
  • Admin: Administrator (password in Ansible vault)
  • API keys: Set in Express API .env as ERPNEXT_API_KEY / ERPNEXT_API_SECRET
  • Image: performancewest-erpnext:latest (custom, extends frappe/erpnext:version-15)
  • 6 apps installed: frappe, erpnext, payments, frappe_crypto, frappe_adyen, performancewest_erpnext
  • Timezone: America/Chicago

Custom DocTypes

Formation Order

Tracks LLC/Corp formation orders through the pipeline.

Field Type Description
customer Link (Customer) ERPNext Customer record
entity_name Data Desired company name
entity_type Select LLC, Corporation, Nonprofit
state Data Two-letter state code
members Table (Formation Member) Member names, ownership %, capital
management_type Select Member-managed, Manager-managed
registered_agent Data RA provider name
add_ons Table (Formation Add-On) Operating agreement, EIN, RA service
status Select See Order Flow below
minio_path Data Path to generated documents in MinIO
filing_number Data State filing confirmation number
order_total Currency Total amount charged

Compliance Calendar

Tracks recurring compliance deadlines per entity.

Field Type Description
customer Link (Customer) ERPNext Customer
entity_name Data Company name
state Data State code
event_type Select Annual Report, Franchise Tax, RA Renewal, etc.
due_date Date Next due date
recurrence Select Annual, Quarterly, Monthly
status Select Upcoming, Due Soon, Overdue, Completed
reminder_sent Check Whether reminder email was sent

Sensitive ID

Stores SSN/EIN with encryption. Uses ERPNext's Password field type, which encrypts values at rest.

Field Type Description
customer Link (Customer) ERPNext Customer
id_type Select SSN, EIN, ITIN
id_value Password Encrypted value (never exposed in API responses)
entity_name Data Associated entity (for EIN)

Referral Partner

Tracks affiliate/referral partners and their commissions.

Field Type Description
partner_name Data Partner name
partner_email Data Email
referral_code Data Unique referral code
commission_rate Percent Commission percentage
total_referrals Int Count of referred customers
total_paid Currency Total commissions paid

Compliance Service

Tracks compliance consulting service orders (FLSA audit, CCPA audit, etc.).

Field Type Description
customer Link (Customer) ERPNext Customer
service_type Select FLSA Audit, CCPA Audit, TCPA Audit, Contractor Assessment, Handbook Review, Breach Response Plan, Privacy Policy
status Select See Order Flow below
intake_data JSON Service-specific intake form data
minio_path Data Path to generated documents in MinIO
order_total Currency Total amount charged

Sales Agent

Tracks sales agents and their referral codes.

Field Type Description
agent_name Data Agent full name
agent_email Data Email
referral_code Data REF-XXXXX format code
commission_tier Select Standard, Premium
payout_method Select Relay ACH

Commission Ledger

Per-order commission records.

Field Type Description
agent Link (Sales Agent) Referring agent
order Link (Sales Order) The order
service_type Select Formation, CRTC, Bundle
commission_amount Currency Flat commission ($50/$100/$300)
status Select Pending, Eligible, Paid
paid_date Date When commission was paid

Custom Fields on Standard DocTypes

DocType Field Type Purpose
Sales Order custom_identity_status Select Identity verification status for CRTC orders
Sales Order custom_order_type Select formation, crtc, bundle, compliance
Sales Order custom_external_order_id Data PostgreSQL order ID
Sales Invoice custom_surcharge_pct Percent Payment method surcharge applied
Sales Invoice custom_payment_gateway Data Which gateway processed payment
Payment Request custom_adyen_session_id Data Adyen session reference

Order Flow

All orders (Formation Order and Compliance Service) follow this status pipeline:

Ordered --> Queued --> Processing --> Review --> Approved --> Ready --> Delivered
Status Description
Ordered Customer has paid; order created in ERPNext
Queued Payment confirmed; order queued for processing
Processing Worker is actively generating documents or filing
Review Documents generated; awaiting admin review
Approved Admin approved; documents ready for delivery
Ready All reviews passed; documents ready for delivery
Delivered Documents emailed to customer; order complete

Error states:

Status Description
Failed Worker encountered an error; needs manual intervention
Revision Reviewer requested changes; returns to Processing
Refunded Order cancelled and refunded

Document Generation Pipeline

Two paths depending on the service:

Template-Based (Formation Orders)

Used for: Operating agreements, invoices, privacy policies.

  1. Worker fetches the DOCX template from MinIO (templates/operating-agreement.docx)
  2. DocxBuilder fills Jinja2 placeholders with order data from ERPNext
  3. DocServer converts DOCX to PDF (or LibreOffice headless as fallback)
  4. Both files uploaded to MinIO at orders/{order_id}/
  5. ERPNext order updated with minio_path

LLM-Based (Compliance Services)

Used for: FLSA audits, CCPA audits, TCPA audits, contractor assessments, handbook reviews, breach response plans.

  1. Worker fetches the DOCX template from MinIO (provides structure/formatting)
  2. Worker calls Ollama (qwen2.5:7b) with a service-specific prompt + intake data
  3. LLM generates analysis text for each section
  4. DocxBuilder fills template placeholders and inserts LLM-generated sections
  5. DocServer converts to PDF (LibreOffice fallback)
  6. Both files uploaded to MinIO
  7. Order status set to Review (always requires human review for LLM output)

Hybrid

Some documents use both approaches: template for structure/boilerplate, LLM for analysis sections. Example: FLSA audit uses a template for the report structure, table formatting, and disclaimer, but LLM writes the executive summary, classification analysis, and remediation plan.

MinIO Storage Structure

performancewest/                        # Bucket
+-- templates/                          # DOCX templates (9 uploaded)
|   +-- operating-agreement.docx
|   +-- privacy-policy.docx
|   +-- breach-response-plan.docx
|   +-- flsa-audit-report.docx
|   +-- contractor-assessment.docx
|   +-- handbook-review.docx
|   +-- ccpa-audit-report.docx
|   +-- tcpa-audit-report.docx
|   +-- invoice.docx
+-- orders/                             # Generated documents per order
|   +-- FO-2026-0001/                   # Formation Order
|   |   +-- operating-agreement.docx
|   |   +-- operating-agreement.pdf
|   |   +-- articles-of-organization.pdf
|   |   +-- ein-confirmation.pdf
|   +-- CS-2026-0042/                   # Compliance Service
|   |   +-- flsa-audit-report.docx
|   |   +-- flsa-audit-report.pdf
|   |   +-- remediation-checklist.pdf
|   +-- ...
+-- invoices/                           # Generated invoices
|   +-- INV-2026-0001.pdf
|   +-- ...
+-- backups/                            # Encrypted database backups
    +-- erpnext-2026-03-19.sql.gpg
    +-- ...

Access control: MinIO is internal only (not exposed to the internet). Documents are served to customers via pre-signed URLs generated by the Express API, valid for 1 hour.

Listmonk Integration

Listmonk (lists.performancewest.net) handles email marketing campaigns. It does not store customer orders or tickets — ERPNext is the CRM source of truth.

Admin: admin / F6IHwDFeMjaDGDPR1OQcKtUA86BGfs2

Sync flow:

  1. When a new Customer is created in ERPNext, the Express API pushes the subscriber to Listmonk via its REST API
  2. Listmonk manages email campaigns, drip sequences, and newsletter sends
  3. Listmonk tracks email opens/clicks and manages subscriber lists
  4. Bounce processing via POP3 from Carbonio (co.carrierone.com)

Mass email: SMTP2GO is used for Listmonk campaign sends (not Carbonio — Carbonio is for transactional email only).

Campaigns:

Campaign Trigger Content
Welcome drip New customer created 3-email series: welcome, services overview, compliance tips
Formation follow-up Formation delivered Annual report reminder, RA renewal, compliance calendar
CRTC follow-up CRTC carrier delivered Banking setup, BITS filing, ATS survey prep
Compliance upsell 30 days post-formation FLSA audit, handbook review, privacy policy offers
Renewal reminder 30 days before RA renewal Registered agent renewal notice

Important: Listmonk subscribers are synced one-way from ERPNext. ERPNext remains the source of truth. If a subscriber unsubscribes in Listmonk, the email_opted_out flag is synced back to ERPNext via webhook.

ERPNext Helpdesk

ERPNext's built-in Helpdesk module handles all customer support:

Feature ERPNext Helpdesk
Ticket creation Via API (contact form), email, or ERPNext UI
Assignment Auto-assign rules based on ticket type
SLA tracking Built-in SLA configuration per priority
Knowledge base ERPNext Knowledge Base module
Customer portal ERPNext portal (customers can view their tickets)
Email integration ERPNext Email Account (incoming/outgoing)

This eliminates the need for a separate ticketing system. All customer data stays in one place with native linking between tickets and orders.

Security

Encrypted Backups

  • ERPNext database is backed up daily via bench backup
  • Backups are GPG-encrypted before upload to MinIO backups/ prefix
  • Retention: 30 daily, 12 monthly, indefinite yearly
  • Restore tested monthly

RBAC (Role-Based Access Control)

ERPNext provides granular role permissions:

Role Access
Admin Full access to all DocTypes
Operations Formation Orders, Compliance Services (read/write), Customers (read)
Support Helpdesk tickets (read/write), Customers (read)
API User REST API access with specific DocType permissions
Sales Agent Own referrals and commission ledger (read)

Audit Logging

  • ERPNext Version (audit log) tracks all changes to all DocTypes
  • Every create/update/delete is logged with user, timestamp, and field-level diff
  • Audit logs are included in encrypted backups
  • Access logs retained for 1 year

Sensitive Data (SSN/EIN)

  • Stored in ERPNext Password fields (AES-256 encrypted at rest)
  • Never returned in API list responses; only accessible via explicit single-record GET with appropriate role
  • Masked in the ERPNext UI (shown as ***-**-1234)
  • Workers decrypt only when needed for IRS EIN application, then discard from memory