- Added new modules for SIM management, internet management, and call history to the BFF, improving service organization and modularity. - Updated environment validation schema to reflect changes in Salesforce event channels, ensuring accurate configuration. - Refactored router configuration to include new subscription-related modules, enhancing API routing clarity. - Cleaned up Salesforce integration by removing unused service files and optimizing event handling logic. - Improved support service by adding cache invalidation logic for case comments, ensuring real-time updates for users. - Updated domain schemas to remove deprecated fields and enhance validation for residence card verification, promoting data integrity. - Enhanced utility functions in the portal for better address formatting and confirmation prompts, improving user experience.
113 lines
4.6 KiB
Markdown
113 lines
4.6 KiB
Markdown
# Support Cases
|
|
|
|
How the portal surfaces and creates support cases for customers.
|
|
|
|
## Data Source & Scope
|
|
|
|
- Cases are read and written directly in Salesforce. Origin is set to "Portal Support."
|
|
- The portal only shows cases for the customer's mapped Salesforce Account to avoid leakage across customers.
|
|
|
|
## Creating a Case
|
|
|
|
- Required inputs: subject and description. Optional: category/type and priority.
|
|
- The portal creates the case in Salesforce with Status = New and Priority mapped to Salesforce values.
|
|
- If a Contact ID is available it is used; otherwise the Account ID is set on the case.
|
|
|
|
## Viewing Cases
|
|
|
|
- Cases are fetched from Salesforce with Redis caching (see Caching section below).
|
|
- The portal summarizes open vs. closed counts and highlights high-priority cases.
|
|
|
|
## Real-Time Updates via Platform Events
|
|
|
|
Support cases use Platform Events for real-time cache invalidation:
|
|
|
|
**Platform Event:** `Case_Status_Update__e`
|
|
|
|
| Field | API Name | Description |
|
|
| ---------- | --------------- | --------------------- |
|
|
| Account ID | `Account_Id__c` | Salesforce Account ID |
|
|
| Case ID | `Case_Id__c` | Salesforce Case ID |
|
|
|
|
**Flow Trigger:** Record update on Case when Status changes (and Origin = "Portal Support")
|
|
|
|
**BFF Behavior:**
|
|
|
|
1. Invalidates `support:cases:{accountId}` cache
|
|
2. Invalidates `support:messages:{caseId}` cache
|
|
3. Sends SSE `support.case.changed` to connected portals
|
|
4. Portal refetches case data automatically
|
|
|
|
See `docs/integrations/salesforce/platform-events.md` for full Platform Event documentation.
|
|
|
|
## Caching Strategy
|
|
|
|
We use Redis TTL-based caching to reduce Salesforce API calls:
|
|
|
|
| Cache Key | TTL | Invalidated On |
|
|
| --------------------------- | --------- | -------------- |
|
|
| `support:cases:{accountId}` | 2 minutes | Case created |
|
|
| `support:messages:{caseId}` | 1 minute | Comment added |
|
|
|
|
Features:
|
|
|
|
- **Request coalescing**: Prevents thundering herd on cache miss
|
|
- **Write-through invalidation**: Cache cleared after customer writes
|
|
- **Metrics tracking**: Hits, misses, and invalidations are tracked
|
|
|
|
## Customer-Friendly Status Mapping
|
|
|
|
Salesforce uses internal workflow statuses that may not be meaningful to customers. We map them to simplified, customer-friendly labels:
|
|
|
|
| Salesforce Status (API) | Portal Display | Meaning |
|
|
| ----------------------- | ----------------- | ------------------------------------- |
|
|
| 新規 (New) | New | New case, not yet reviewed |
|
|
| 対応中 (In Progress) | In Progress | Support is working on it |
|
|
| Awaiting Approval | In Progress | Internal workflow (hidden) |
|
|
| VPN Pending | In Progress | Internal workflow (hidden) |
|
|
| Pending | In Progress | Internal workflow (hidden) |
|
|
| 完了済み (Replied) | Awaiting Customer | Support replied, waiting for customer |
|
|
| Closed | Closed | Case is closed |
|
|
|
|
**Rationale:**
|
|
|
|
- Internal workflow statuses are hidden from customers and shown as "In Progress"
|
|
- "Replied/完了済み" means support has responded and is waiting for the customer
|
|
- Only 4 statuses visible to customers: New, In Progress, Awaiting Customer, Closed
|
|
|
|
## Case Conversation (Messages)
|
|
|
|
The case detail view shows a unified conversation timeline composed of:
|
|
|
|
1. **EmailMessages** - Email exchanges attached to the case
|
|
2. **CaseComments** - Portal comments added by customer or agent
|
|
|
|
### Features
|
|
|
|
- **Date grouping**: Messages are grouped by date (Today, Yesterday, Mon Dec 30, etc.)
|
|
- **Attachment indicators**: Messages with attachments show a paperclip icon
|
|
- **Clean email bodies**: Quoted reply chains are stripped (see below)
|
|
|
|
### Email Body Cleaning
|
|
|
|
Emails often contain quoted reply chains that pollute the conversation view. We automatically clean email bodies to show only the latest reply by stripping:
|
|
|
|
**Single-line patterns:**
|
|
|
|
- Lines starting with `>` (quoted text)
|
|
- `From:`, `To:`, `Subject:`, `Sent:` headers
|
|
- Japanese equivalents (送信者:, 件名:, etc.)
|
|
|
|
**Multi-line patterns:**
|
|
|
|
- "On Mon, Dec 29, 2025 at 18:43 ... wrote:" (Gmail style, spans multiple lines)
|
|
- "-------- Original Message --------" blocks
|
|
- Forwarded message headers
|
|
|
|
This ensures each message bubble shows only the new content, not the entire email history.
|
|
|
|
## If something goes wrong
|
|
|
|
- Salesforce unavailable: we show "support system unavailable, please try again later."
|
|
- Case not found or belongs to another account: we respond with "case not found" to avoid leaking information.
|