NORCAL SBDC COMPLETE LOGIC FLOW
• Google Search
• Partner referral
• Social media
MaxMind GeoIP2
Fallback: Browser API
Default: Ask user
→ Show banner
ELSE:
→ ZIP prompt
Store: localStorage
Cookie: 30 days
URL: /center/marin
News: region_tag
Advisors: location
Resources: all+local
Local events first
Center phone/address
Advisor photos
Click: "Register"
Click: "MySBDC"
Click: Event CTA
→ Skip to 641
ELSE:
→ SSO modal
Microsoft Azure AD
Email + Password
(Forgot password flow)
Token exchange
JWT generation
Session: 30 days
Create: user_id
Link: center_id
Set: created_date
→ Dashboard
ELSE:
→ Form 641
Show: 8-step bar
Time: ~7 minutes
Auto-save: onChange
Contact info
Consent checkboxes
Newsletter opt-in
→ Existing (fields A)
→ Starting (fields B)
→ Exploring (fields C)
Business details
Stage & capital
Goals/needs matrix
Range: 0-100
Threshold: 60+
Store: client_score
Map: 641 → Neoserra
Return: client_id
Queue: if offline
Fetch: milestones
Fetch: trainings
Fetch: advisor
→ Basic resources
IF score 40-59:
→ Group training
IF score 60+:
→ 1:1 advising
1. Missing docs
2. Scheduled call
3. Training reg
4. Milestone log
Milestones: Local DB
Advisor: Assignment
Resources: CMS
Jobs: COUNT(hires)
Progress: % complete
Status: realtime
Check: messages
Check: deadlines
Badge: count
No form needed
Uses: 641 data
Time: < 1 sec
→ Zoom API
IF type = in-person:
→ Neoserra only
Body: {email, name}
Auto-approval: true
Return: join_url
Link: client_id
Status: registered
Attendance: pending
Include: join_url
Reminder: 1 hour
Download: auto
Email: instant
Dashboard: updated
Status: ✓ Registered
Course ID: passed
User: authenticated
Include: user_id
Include: email
Sign: private_key
Create: learner
Enroll: course_id
Redirect: lesson_1
Update: dashboard
Log: Neoserra
Credit: hours
Email: to user
Store: profile
Share: LinkedIn
Types: Capital/Job/Rev
Form: 3 fields
Check: date range
Check: duplicate
Flag: verification
Queue: Neoserra
Update: dashboard
Recalc: metrics
Update: county totals
Update: impact map
Flag: story candidate
Board: monthly
Grants: on-demand
Public: anonymous
GET /api/trainings
POST /api/training/register
PUT /api/milestones
GET /api/reports
GET /meetings/{id}
GET /report/webinars/{id}
Webhook: attendee.joined
POST /api/users
POST /api/enrollments
Webhook: course.completed
PUT /lists/{list_id}/contacts
POST /campaigns
GET /reports/{campaign_id}
| Condition | Check | True Path | False Path | Data Storage |
|---|---|---|---|---|
| Has Account? | Check email in DB | Login flow | Create account | users.email |
| Completed 641? | Check user.form_641_date | Show dashboard | Start Form 641 | users.form_641_complete |
| Business Status? | 641 Step 3 selection | Show relevant fields | Hide irrelevant fields | clients.business_status |
| Score >= 60? | Calculate from 641 | Enable advising | Suggest training first | clients.readiness_score |
| Event Type? | Check training.format | Zoom API if virtual | Direct registration | trainings.format |
| Has Advisor? | Check advisor_assignments | Show advisor card | Show "Request Advisor" | advisor_assignments.advisor_id |
| Newsletter Opt-in? | Check preferences.newsletter | Add to Constant Contact | Skip email automation | preferences.newsletter_opt_in |