# Customer Portal Flow Review: Shop, Eligibility, ID Verification & Opportunity Management
**Review Date:** December 23, 2025
**Last Updated:** December 23, 2025
**Scope:** Complete end-to-end analysis of customer acquisition flows
**Priority Focus:** Customer Experience (CX)
---
## Table of Contents
1. [Executive Summary](#executive-summary)
2. [System Architecture Overview](#system-architecture-overview)
3. [Flow Diagrams](#flow-diagrams)
4. [Detailed Behavior Analysis](#detailed-behavior-analysis)
5. [Salesforce Field Changes Reference](#salesforce-field-changes-reference)
6. [Agent Workflow & Checklist](#agent-workflow--checklist)
7. [Critical Issues & Recommendations](#critical-issues--recommendations)
8. [Customer Experience Analysis](#customer-experience-analysis)
9. [Implementation Improvements](#implementation-improvements)
---
## Executive Summary
### Current State Assessment
| Area | Status | CX Impact | Notes |
| ---------------------- | -------- | --------- | ---------------------------------------- |
| Shop/Catalog | ✅ Good | Low Risk | Well-structured, cached |
| Internet Eligibility | ✅ Good | Low Risk | Manual NTT check, email notifications |
| ID Verification | ✅ Good | Low Risk | Integrated into Profile page |
| Opportunity Management | ✅ Good | Low Risk | Fields exist, WHMCS linking works |
| Order Fulfillment | ✅ Good | Low Risk | Distributed transaction support |
| Profile Data | ✅ Fixed | Low Risk | Customer number, DOB, gender now display |
### Key Findings
1. **Internet Subscription Detection** - Now matches "SonixNet via NTT Optical Fiber" products in addition to "Internet" named products.
2. **ID Verification Integrated** - Upload functionality is now built into the Profile page (`/account/settings`) rather than requiring a separate page.
3. **Opportunity Lifecycle Fields Exist** - `Opportunity_Source__c` (with portal picklist values) and `WHMCS_Service_ID__c` are in place and working.
4. **SIM vs Internet Flows Have Different Requirements** - SIM requires ID verification but not eligibility; Internet requires eligibility but not ID verification.
5. **Opportunity ↔ WHMCS Linking** - After provisioning, Opportunity is linked via `WHMCS_Service_ID__c` to enable cancellation workflows.
6. **Cancellation is NOT Automated to WHMCS** - Portal updates Salesforce Opportunity and creates Case, but WHMCS service termination requires agent action.
---
## System Architecture Overview
### Three-Tier Integration
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ CUSTOMER PORTAL │
│ (Next.js Frontend) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ Shop/Catalog │ Checkout │ Verification │ Dashboard │ Service Mgmt │
└───────┬────────┴─────┬──────┴───────┬────────┴──────┬──────┴─────────┬─────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ BFF (NestJS) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ CatalogService │ CheckoutService │ VerificationService │ OrderService │
│ │ │ │ │
│ Opportunity Resolution │ OrderOrchestrator │ FulfillmentOrchestrator │
└───────┬──────────────────────┴─────────┬──────────┴────────────┬───────────────┘
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌──────────────┐
│ SALESFORCE │ │ WHMCS │ │ PRISMA │
│ (CRM/Orders) │ │ (Billing) │ │ (Portal DB) │
└───────────────┘ └─────────────────┘ └──────────────┘
```
### Data Flow by Product Type
| Product | Eligibility Required | ID Verification Required | Opportunity Created At |
| ------------ | ------------------------- | ------------------------ | ---------------------- |
| **Internet** | ✅ Yes (Manual NTT check) | ❌ Not enforced | Eligibility Request |
| **SIM** | ❌ No | ✅ Yes (Residence Card) | Order Placement |
| **VPN** | ❌ No | ❌ No | Order Placement |
---
## Flow Diagrams
### 1. Internet Customer Journey
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ INTERNET CUSTOMER JOURNEY │
└─────────────────────────────────────────────────────────────────────────────────┘
CUSTOMER ACTION SYSTEM BEHAVIOR SALESFORCE CHANGES
═══════════════ ═══════════════ ══════════════════
1. Browse Internet Plans
└─► Catalog loads from SF GET /api/catalog/internet (none - read only)
(cached 5 min)
2. Click "Select Plan"
└─► Redirect to checkout User must be authenticated (none)
3. Enter Service Address
└─► Address validation Frontend validation (none)
4. Submit Eligibility Request
└─► API call triggered POST /eligibility-request ┌─────────────────────┐
│ CASE: │
│ • Created │
│ • Subject=Internet │
│ availability check│
│ • Origin=Portal │
├─────────────────────┤
│ ACCOUNT: │
│ • Internet_ │
│ Eligibility_ │
│ Status__c=Pending │
│ • Internet_ │
│ Eligibility_ │
│ Request_Date_ │
│ Time__c=NOW() │
│ • Internet_ │
│ Eligibility_ │
│ Case_Id__c= │
│ (Case ID) │
├─────────────────────┤
│ NOTE: Opportunity │
│ is NOT created at │
│ this step - only │
│ at order placement │
└─────────────────────┘
⏳ CUSTOMER WAITS (no SLA shown)
════════════════════════════════
5. Agent Processes Case (MANUAL AGENT WORK) ┌─────────────────────┐
└─► NTT Check Checks serviceability │ ACCOUNT: │
└─► Update Account │ • Internet_ │
└─► SF Flow sends email │ Eligibility__c= │
│ "Home 1G" (or │
│ other result) │
│ • Internet_ │
│ Eligibility_ │
│ Status__c= │
│ Eligible/ │
│ Ineligible │
│ • Internet_ │
│ Eligibility_ │
│ Checked_Date_ │
│ Time__c=NOW() │
├─────────────────────┤
│ SALESFORCE FLOW: │
│ • Sends email to │
│ customer with │
│ eligibility result│
└─────────────────────┘
6. Customer Returns/Refreshes
└─► Sees eligible plans GET /api/catalog/internet (read only)
filtered by eligibility /eligibility
7. Proceed to Payment
└─► Add payment method Stripe integration (none)
8. Place Order
└─► Order created POST /api/orders ┌─────────────────────┐
│ ORDER: │
│ • Created │
│ • OpportunityId= │
│ (linked) │
│ • Status=Created │
├─────────────────────┤
│ OPPORTUNITY: │
│ • Stage=Post │
│ Processing │
└─────────────────────┘
9. Agent Approves Order
└─► Fulfillment triggered Order.Status='Approved' ┌─────────────────────┐
triggers CDC event │ ORDER: │
│ • Activation_ │
│ Status__c= │
│ Activating │
└─────────────────────┘
10. WHMCS Provisioning
└─► Service created addOrder → acceptOrder ┌─────────────────────┐
│ ORDER: │
│ • Status=Completed │
│ • Activation_ │
│ Status__c= │
│ Activated │
│ • WHMCS_Order_ID__c │
│ =(WHMCS ID) │
├─────────────────────┤
│ OPPORTUNITY: │
│ • Stage=Active │
│ • WHMCS_Service_ │
│ ID__c=(service ID)│
└─────────────────────┘
11. Customer Has Active Service
└─► Service visible in GET /subscriptions (read only)
portal dashboard
```
### 2. SIM Customer Journey
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ SIM CUSTOMER JOURNEY │
└─────────────────────────────────────────────────────────────────────────────────┘
CUSTOMER ACTION SYSTEM BEHAVIOR SALESFORCE CHANGES
═══════════════ ═══════════════ ══════════════════
1. Browse SIM Plans
└─► Catalog loads GET /api/catalog/sim (none - read only)
Family plans shown if
user has existing SIM
2. Click "Select Plan"
└─► Redirect to login if /auth/login?returnTo=... (none - auth required)
unauthenticated Standard auth flow creates
SF Account + WHMCS Client
3. Configure & Checkout (Authenticated)
└─► AccountCheckoutContainer /account/shop/sim/configure (cart stored locally)
handles full flow /account/order
4. Upload Residence Card (ID Verification)
└─► File upload POST /verification/ ┌─────────────────────┐
residence-card │ ACCOUNT: │
│ • Id_Verification_ │
│ Status__c= │
│ Submitted │
│ • Id_Verification_ │
│ Submitted_Date_ │
│ Time__c=NOW() │
├─────────────────────┤
│ CONTENT VERSION: │
│ • File uploaded │
│ • FirstPublish │
│ LocationId= │
│ Account │
└─────────────────────┘
⏳ CUSTOMER WAITS (manual review)
═════════════════════════════════
5. Agent Reviews ID (MANUAL AGENT WORK) ┌─────────────────────┐
└─► Verify document │ ACCOUNT: │
└─► Update status │ • Id_Verification_ │
│ Status__c= │
│ Verified/Rejected │
│ • Id_Verification_ │
│ Verified_Date_ │
│ Time__c=NOW() │
│ • Id_Verification_ │
│ Rejection_ │
│ Message__c= │
│ (if rejected) │
└─────────────────────┘
6. Customer Returns (If Verified)
└─► Can proceed to payment Verification status checked (none)
7-11. (Same as Internet steps 7-11)
```
### 3. Opportunity Lifecycle State Machine
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ OPPORTUNITY STAGE TRANSITIONS │
└─────────────────────────────────────────────────────────────────────────────────┘
┌───────────────────┐
│ POST PROCESSING │ ◄─── Created at ORDER PLACEMENT
│ (75% prob) │ (Not at eligibility request)
└─────────┬─────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────────┐ ┌─────────────┐
│ VOID │ │ ACTIVE │ │ PENDING │
│ (Closed, │ │ (90% prob) │ │ (On hold) │
│ 0% prob) │ └───────┬───────┘ └─────────────┘
└───────────┘ │
Failed │ Set when:
provisioning │ • Service provisioned in WHMCS
│ • WHMCS_Service_ID__c populated
│
▼
┌───────────────┐
│ △CANCELLING │ ◄─── Set when:
│ (100% prob) │ • Customer submits cancellation
└───────┬───────┘ • ScheduledCancellationDateAndTime__c set
│ • CancellationNotice__c = 有
│ • LineReturn__c = NotYet
▼
┌───────────────┐
│ 〇CANCELLED │ ◄─── Set when:
│ (Closed,Won) │ • Service terminated
└───────────────┘ • Equipment returned (if applicable)
NOTE: Introduction/Ready stages may be used by agents for pre-order tracking,
but portal creates Opportunities starting at Post Processing.
```
---
## Detailed Behavior Analysis
### Shop/Catalog Module
**Location:** `apps/bff/src/modules/catalog/`
**Key Services:**
- `InternetCatalogService` - Plans, installations, addons
- `SimCatalogService` - Plans, activation fees, addons
- `VpnCatalogService` - Plans
**Caching Strategy:**
- Catalog items cached via `CatalogCacheService`
- Cache keys built by product type + item type
- Cache invalidation on product updates
**Eligibility-Filtered Plans:**
```typescript
// InternetCatalogService.getPlansForUser()
// Filters plans based on Account.Internet_Eligibility__c value
// e.g., if eligibility = "Home 1G", only Home 1G plans shown
```
**Family Discount Logic (SIM):**
```typescript
// SimCatalogService.getPlansForUser()
// Checks WHMCS for existing active SIM services
// Shows family discount plans only if user has existing SIM
```
### Eligibility Validation Module
**Location:** `apps/bff/src/modules/catalog/services/internet-catalog.service.ts`
**Flow Summary:**
1. Customer requests eligibility check
2. System creates Case for agent to process
3. System updates Account eligibility fields to "Pending"
4. **Manual Agent Work Required** - Agent checks NTT serviceability
5. Agent updates Account with eligibility result
6. Salesforce Flow sends email notification to customer
7. **Note:** Opportunity **is created/reused during eligibility** (Stage = Introduction) so the Case can link to it (`Case.OpportunityId`) and the journey can be reused at order placement.
**Account Fields Updated:**
| Field | Value Set | When |
|-------|-----------|------|
| `Internet_Eligibility_Status__c` | "Pending" | On request |
| `Internet_Eligibility_Request_Date_Time__c` | NOW() | On request |
| `Internet_Eligibility_Case_Id__c` | Case ID | On request |
| `Internet_Eligibility__c` | Result value | By agent |
| `Internet_Eligibility_Checked_Date_Time__c` | NOW() | By agent |
### ID Verification Module
**Location:** `apps/bff/src/modules/verification/residence-card.service.ts`
**Flow Summary:**
1. Customer uploads residence card image
2. File stored as Salesforce ContentVersion (linked to Account)
3. Account verification status updated to "Submitted"
4. **Manual Agent Work Required**
5. Agent reviews document and updates status
**Account Fields Updated:**
| Field | Value Set | When |
|-------|-----------|------|
| `Id_Verification_Status__c` | "Submitted" | On upload |
| `Id_Verification_Submitted_Date_Time__c` | NOW() | On upload |
| `Id_Verification_Rejection_Message__c` | null | Cleared on resubmit |
| `Id_Verification_Note__c` | null | Cleared on resubmit |
| `Id_Verification_Status__c` | "Verified"/"Rejected" | By agent |
| `Id_Verification_Verified_Date_Time__c` | NOW() | By agent |
**Supported File Types:**
- PDF
- PNG
- JPG/JPEG
### User Registration Flow
**IMPORTANT: Guest checkout has been removed.** All checkout flows now require authentication first.
**Authentication-First Checkout Flow:**
1. User browses public catalog at `/shop`
2. When proceeding to checkout, unauthenticated users are redirected to `/auth/login`
3. After login/registration, users continue checkout at `/account/order`
4. Checkout is handled by `AccountCheckoutContainer` (single-page flow)
**Registration Location:** `apps/portal/src/app/auth/register/` (standard auth flow)
**Benefits of Auth-First Approach:**
- Simpler code: Removed `checkout-registration` module entirely
- Better UX: Users complete registration once, then shop freely
- Cleaner architecture: No multi-step guest registration with partial rollback
- Consistent: All users have accounts before interacting with Salesforce/WHMCS
### Opportunity Management Module
**Location (current code paths):**
- `apps/bff/src/modules/catalog/services/internet-catalog.service.ts` (eligibility request creates/reuses Opportunity + Case)
- `apps/bff/src/modules/orders/services/order-orchestrator.service.ts` (order placement resolves Opportunity)
- `apps/bff/src/integrations/salesforce/services/salesforce-opportunity.service.ts` (Salesforce query/create/update)
**Matching Rules:**
| Scenario | Action |
|----------|--------|
| Order has `opportunityId` | Use it directly |
| Internet order without Opp | Find Introduction/Ready stage or create new |
| SIM order without Opp | Find Introduction/Ready stage or create new |
| VPN order | Always create new Opportunity |
**Stage Transitions by Trigger:**
| Trigger | From Stage(s) | To Stage |
|---------|---------------|----------|
| Eligibility Request | (new) | Introduction |
| Eligibility Confirmed | Introduction | Ready |
| Eligibility Denied | Introduction | Void |
| Order Placed | Introduction, Ready | Post Processing |
| Service Provisioned | Post Processing | Active |
| Cancellation Requested | Active | △Cancelling |
| Cancellation Complete | △Cancelling | 〇Cancelled |
---
## Salesforce Field Changes Reference
### Complete Field Map by Object
#### Account Object
| Field API Name | Label | Type | Who Updates | When |
| ------------------------------------------- | --------------------- | -------- | ------------ | ------------- |
| `SF_Account_No__c` | Customer Number | Text | Portal | Registration |
| `Portal_Status__c` | Portal Status | Picklist | Portal | Registration |
| `Portal_Registration_Source__c` | Registration Source | Text | Portal | Registration |
| `Portal_Last_SignIn__c` | Last Sign In | DateTime | Portal | Each login |
| `WH_Account__c` | WHMCS Account | Text | Portal | Registration |
| `Internet_Eligibility__c` | Internet Eligibility | Text | **Agent** | After check |
| `Internet_Eligibility_Status__c` | Eligibility Status | Picklist | Portal/Agent | Request/Check |
| `Internet_Eligibility_Request_Date_Time__c` | Eligibility Requested | DateTime | Portal | Request |
| `Internet_Eligibility_Checked_Date_Time__c` | Eligibility Checked | DateTime | **Agent** | After check |
| `Internet_Eligibility_Notes__c` | Eligibility Notes | Text | **Agent** | After check |
| `Internet_Eligibility_Case_Id__c` | Eligibility Case | Lookup | Portal | Request |
| `Id_Verification_Status__c` | ID Status | Picklist | Portal/Agent | Upload/Review |
| `Id_Verification_Submitted_Date_Time__c` | ID Submitted | DateTime | Portal | Upload |
| `Id_Verification_Verified_Date_Time__c` | ID Verified | DateTime | **Agent** | Review |
| `Id_Verification_Note__c` | ID Notes | Text | **Agent** | Review |
| `Id_Verification_Rejection_Message__c` | Rejection Reason | Text | **Agent** | If rejected |
#### Opportunity Object
| Field API Name | Label | Type | Who Updates | When |
| ------------------------------------- | ---------------------- | -------- | ------------ | -------------------- |
| `StageName` | Stage | Picklist | Portal/Agent | Throughout lifecycle |
| `CommodityType` | Commodity Type | Picklist | Portal | Creation |
| `Application_Stage__c` | Application Stage | Picklist | Portal | Creation (INTRO-1) |
| `Opportunity_Source__c` | Opportunity Source | Picklist | Portal | Creation |
| `WHMCS_Service_ID__c` | WHMCS Service ID | Number | Portal | After provisioning |
| `CancellationNotice__c` | Cancellation Notice | Picklist | Portal | Cancellation request |
| `ScheduledCancellationDateAndTime__c` | Scheduled Cancellation | DateTime | Portal | Cancellation request |
| `LineReturn__c` | Line Return Status | Picklist | **Agent** | Equipment tracking |
#### Order Object
| Field API Name | Label | Type | Who Updates | When |
| ----------------------------- | ----------------- | -------- | ------------ | ------------------ |
| `OpportunityId` | Opportunity | Lookup | Portal | Order creation |
| `Status` | Status | Picklist | Portal/Agent | Throughout |
| `Activation_Status__c` | Activation Status | Picklist | Portal | Fulfillment |
| `Activation_Error_Code__c` | Error Code | Text | Portal | If failed |
| `Activation_Error_Message__c` | Error Message | Text | Portal | If failed |
| `WHMCS_Order_ID__c` | WHMCS Order ID | Text | Portal | After provisioning |
#### Case Object
| Field API Name | Label | Type | Who Updates | When |
| --------------- | ----------- | -------- | ----------- | ------------------ |
| `OpportunityId` | Opportunity | Lookup | Portal | Eligibility/Cancel |
| `Origin` | Origin | Picklist | Portal | "Portal" |
| `Status` | Status | Picklist | **Agent** | Processing |
| `Priority` | Priority | Picklist | Portal | Creation |
---
## Agent Workflow & Checklist
### Internet Eligibility Processing
**Queue:** Cases with Subject = "Internet availability check request (Portal)"
**Agent Checklist:**
- [ ] **1. Open the Case**
- Note the OpportunityId (related Opportunity)
- Review Description for address details
- [ ] **2. Perform NTT Serviceability Check**
- Check FLET'S光 availability for the address
- Determine offering type (Home 1G, Mansion 1G, etc.)
- [ ] **3. Update Account Fields**
```
Internet_Eligibility__c = "[Offering Type]" (e.g., "Home 1G", "Mansion 1G")
Internet_Eligibility_Status__c = "Eligible" or "Ineligible"
Internet_Eligibility_Checked_Date_Time__c = NOW()
Internet_Eligibility_Notes__c = [Any relevant notes]
```
- [ ] **4. Close the Case**
- Status = "Closed"
- Resolution notes
**ℹ️ Automatic Actions:**
- Salesforce Flow automatically sends email to customer when eligibility fields are updated
- Portal polls Account for eligibility changes (customer sees result on next visit)
- Opportunity is created/reused at eligibility request (Stage = Introduction) and then reused at order placement when possible
---
### ID Verification Processing
**Queue:** Accounts with `Id_Verification_Status__c = "Submitted"`
**Agent Checklist:**
- [ ] **1. Find the Account**
- Filter by `Id_Verification_Status__c = "Submitted"`
- [ ] **2. Download & Review Document**
- Go to Account → Files → Most Recent
- Verify: Name matches account, document is valid, not expired
- [ ] **3. Update Account (Approved)**
```
Id_Verification_Status__c = "Verified"
Id_Verification_Verified_Date_Time__c = NOW()
Id_Verification_Note__c = "Verified by [Agent Name]"
```
- [ ] **3. Update Account (Rejected)**
```
Id_Verification_Status__c = "Rejected"
Id_Verification_Verified_Date_Time__c = NOW()
Id_Verification_Rejection_Message__c = "[Specific reason - customer will see this]"
```
**⚠️ Critical:** Rejection message is shown to customer. Be specific but professional.
---
### Order Approval Processing
**Queue:** Orders with `Status = "Pending Review"` or triggered via automation
**Agent Checklist:**
- [ ] **1. Verify Customer Prerequisites**
- Internet: `Account.Internet_Eligibility__c` is set
- SIM: `Account.Id_Verification_Status__c = "Verified"`
- [ ] **2. Review Order Details**
- Check order items are correct
- Verify pricing
- [ ] **3. Approve Order**
- Set `Order.Status = "Approved"`
- This triggers CDC event → BFF provisioning
- [ ] **4. Monitor Activation**
- Check `Activation_Status__c` updates to "Activated"
- If "Failed", check error code/message
---
### Cancellation Processing
**Queue:** Cases with Subject = "Cancellation Request - ..."
**Agent Checklist:**
- [ ] **1. Open the Case**
- Note the OpportunityId
- Review cancellation month and service details
- [ ] **2. Verify the 25th Rule**
- If requested before 25th: Can cancel THIS month
- If requested on/after 25th: Must be NEXT month
- [ ] **3. Check Opportunity Fields** (portal sets these)
- `ScheduledCancellationDateAndTime__c` = End of cancellation month
- `CancellationNotice__c` = "有"
- `LineReturn__c` = "NotYet"
- [ ] **4. Process Equipment Return** (if Internet)
- Send return kit
- Update `LineReturn__c` = "SentKit"
- Track return: "Returned1", "Returned2"
- [ ] **5. Terminate Service in WHMCS**
- On the scheduled date
- [ ] **6. Complete Cancellation**
- `Opportunity.Stage = "〇Cancelled"`
---
## Critical Issues & Recommendations
### 🔴 Critical Issues
#### 1. Internet Eligibility Has No SLA Visibility
**Problem:** Customers submit eligibility requests and see "Pending" indefinitely. No estimated time, no progress indicator.
**Impact:** High abandonment rate, customer frustration, support inquiries.
**Recommendation:**
```
SHORT TERM:
- Add expected timeframe messaging: "Usually completed within 2-3 business days"
- Send email when eligibility is updated
LONG TERM:
- Implement automated NTT API check where possible
- Add SLA tracking on Cases with escalation rules
```
#### 2. ID Verification Rejection Lacks Guidance
**Problem:** When rejected, customers see the rejection message but no clear next steps.
**Impact:** Customers don't know how to fix the issue, leading to repeated failures.
**Recommendation:**
```
- Create structured rejection reasons with remediation steps
- Add "Re-submit" button that clears previous submission
- Show example of correct document format
```
#### 3. ~~Salesforce Fields Not Created~~ (RESOLVED)
**Status:** ✅ Confirmed fields exist:
- `Opportunity_Source__c` - Picklist with portal values
- `WHMCS_Service_ID__c` - Number field for WHMCS linking
**Note:** Emails for eligibility and ID verification status changes are sent automatically from Salesforce (via Flow/Process Builder).
### 🟡 Medium Issues
#### 4. No Internet ID Verification Requirement
**Problem:** Internet orders don't require ID verification, but SIM orders do. This may be intentional but creates inconsistency.
**Recommendation:**
```
- Confirm business requirement
- If ID needed for Internet, add gating step in checkout
- Document the decision either way
```
#### 5. WHMCS Rollback is Manual
**Problem:** If checkout registration fails after WHMCS client creation, the WHMCS client cannot be auto-deleted.
**Impact:** Orphaned WHMCS accounts require manual cleanup.
**Recommendation:**
```
- Add monitoring/alerting for failed registrations
- Create weekly cleanup process for orphaned WHMCS clients
- Consider delayed WHMCS creation (after all validations pass)
```
#### 6. Opportunity Matching Could Create Duplicates
**Problem:** The matching query only looks for open Opportunities. If two eligibility requests happen quickly, two Opportunities could be created.
**Recommendation:**
```
- Add optimistic locking or unique constraint
- Consider using Salesforce duplicate rules
```
### 🟢 Minor Issues
#### 7. Cache Invalidation on Eligibility Update
**Problem:** After agent updates eligibility, customer might see cached "Pending" status.
**Current:** Cache key includes account ID, TTL-based expiry.
**Recommendation:**
```
- Reduce eligibility cache TTL during "Pending" status
- Consider CDC-triggered cache invalidation
```
---
## Customer Experience Analysis
### Current CX Pain Points (Ranked)
| Rank | Issue | User Impact | Frequency |
| ---- | -------------------------------- | ---------------- | ----------------------- |
| 1 | No eligibility timeline | High frustration | Every Internet customer |
| 2 | Unclear ID rejection reasons | High frustration | ~10% of SIM customers |
| 3 | No email notifications | Medium annoyance | All customers |
| 4 | Must return to check status | Medium annoyance | All customers |
| 5 | Address entry before eligibility | Low friction | Internet customers |
### Recommended CX Improvements
#### Tier 1: Quick Wins (Days)
1. **Add Timeline Messaging**
```tsx
// AvailabilityStep.tsx
Last checked: {formatRelativeTime(lastCheckedAt)}
``` #### Tier 2: Medium Effort (Weeks) 1. **Email Notifications** - Eligibility confirmed/denied - ID verification approved/rejected - Order status changes 2. **Progress Indicators** ```tsx // Visual progress for Internet checkout