Intake Pipeline Flowchart
What happens when a nonprofit submits the intake form
User fills out Intake Form
/solar/apply/ — Contact info, nonprofit details, mission, motivations, file uploads (IRS letter, utility bills)
Form Validates & Saves to Database
Security scan on uploaded files → Save all text data to PostgreSQL IntakeSubmission → Audit log created
User Redirected to Calendly Page
/solar/apply/schedule-call/?sid=123&source=intake-form
Calendly prefilled with name + email + UTM tracking. User sees "Application Received!" instantly.
Background Tasks (Celery Worker)
All tasks run async — user doesn't wait. Retries 3x on failure.
Task Chain 1: Salesforce
lead_idPre_underwriting_Form_URL__cTask 2: Confirmation Email
Task 3: Campaign Monitor
Task 4: Staff Notification
If SF file upload fails after 3 retries: Marked as UPLOAD FAILED on the submission's files record for staff follow-up
If SF Lead creation fails: Marked as sf_status=failed → retry from Django admin
Pre-Underwriting Form Email Sent
User receives email with unique token link: /forms/<uuid>/
Link expires in 30 days. Automated reminders on Day 2, 5, 10, 17, 24.
User Fills Out Pre-Underwriting Form
Financial docs (990s, bank statements), EIN, roof info, governance, signer details, demographics
Check: Has Lead Been Converted?
Queries Salesforce: SELECT IsConverted, ConvertedOpportunityId FROM Lead WHERE Id = '...'
Not Converted (still a Lead)
Converted (has Opportunity)
Impact Data Survey Email Sent
"Almost There! One More Step" email with impact survey token link.
Impact survey URL also pushed to Lead: Impact_data_Form_URL__c
User Fills Out Impact Data Survey
Mission, savings usage, community impact, board of directors, employees, social media, marketing preferences
Check: Has Lead Been Converted?
Not Converted (still a Lead)
Converted (has Opportunity)
All Forms Complete!
"You're All Set!" email sent → User sees completion page → Staff reviews in Salesforce & Django admin
Data Safety Summary
| Form text data | PostgreSQL (always saved first) |
| Uploaded files | Salesforce Files (ContentVersion + ContentDocumentLink) |
| Lead/Opportunity fields | Pushed field-by-field (partial success OK) |
| Emails | Amazon SES with 3x retry |
| Newsletter opt-in | Campaign Monitor with source tracking |
| Async tasks | Redis queue with AOF persistence → Celery worker with auto-restart |
| Failed integrations | Tracked per-submission → retry from Django admin |