Project

General

Profile

Bug #11925 ยป Ecommerce_Customer_Support_Representative_Gap_Analysis_and_Implementation_Guide.md

Yalavarthi Thriveni, 11/02/2026 04:14 AM

 

E-Commerce Customer Support System: Gap Analysis & Developer Action Guide

Scope: E-Commerce Customer (Client) $\longleftrightarrow$ Company Level (Company Admin & Customer Support Representative)

Exclusion: Platform Tenant to SaaS SuperAdmin tier is strictly excluded.

Standard: 2026 Enterprise E-Commerce Standard (Shopify Inbox, Gorgias, Zendesk, Freshdesk Omnichannel)


1. Executive Summary & New Requirements

This guide provides an end-to-end technical gap analysis, real-world case simulations, and an actionable developer implementation plan for the Company-Level E-Commerce Support Ticket Ecosystem.

Four Core Upgrades Introduced:

  1. Multi-Channel Push Notifications (FCM + Email + SMS):
    Trigger instant Firebase Cloud Messaging (FCM) push notifications to customers (mobile web/PWA/app) and support representatives (admin browser web push) simultaneously with transactional emails and SMS alerts.
  2. Global UI Rebranding:
    Update all occurrences of "Customer Support Manager" to "Customer Support Representative" (CSR) across all admin panel views, role guards, headers, modals, and export reports.
  3. Customer Support Representative Performance & Live Status Dashboard:
    A dedicated admin analytics screen displaying real-time representative availability (Online, Busy, Offline), active workloads, resolved ticket tallies, First Response Time (FRT), Average Resolution Time (ART), and historical CSAT ratings.
  4. Post-Resolution Customer Feedback Loop (CSAT):
    Automated delivery of 1-click 1โ€“5 star rating surveys (with emoji/sentiment scale) upon ticket resolution. Ratings are linked directly to both the ticket and the assigned representative's permanent performance record.

2. Global Role Architecture & Permission Hierarchy

graph TD
    Cust[E-Commerce Customer / Client] <-->|Public Comments, Attachments, CSAT| CSR[Customer Support Representative]
    CSR <-->|Internal Notes, Escalation| Admin[Company Admin / Store Owner]

    subgraph "Customer Actions"
        Cust -->|Raise Ticket with Order Context| C1[Order Details / Help Portal]
        Cust -->|Inbound Replies| C2[Storefront Chat & Email]
        Cust -->|Post-Resolution Rating| C3[1-Click CSAT Survey]
    end

    subgraph "Representative Actions"
        CSR -->|Live Status| R1[Online / Busy / Offline Toggle]
        CSR -->|Resolution| R2[Public Response + 1-Click Order Actions]
        CSR -->|Collaboration| R3[Private Internal Notes - Staff Only]
    end

    subgraph "Admin Supervisory Actions"
        Admin -->|Monitor| A1[Live CSR Performance Dashboard]
        Admin -->|Configure| A2[Auto-Assignment & SLA Rules]
        Admin -->|Audit| A3[Representative Feedback Reports]
    end

Role Matrix:

  • E-Commerce Customer (Client):
    • Authenticated via storefront JWT.
    • Can create tickets with attached orderId, product SKUs, and photo proof.
    • Can view and reply only to public comments.
    • Receives FCM web push and email notifications on replies.
    • Submits post-resolution CSAT ratings (1 to 5 stars).
  • Customer Support Representative (NurseryUser with role CustomerSupportRepresentative):
    • Authenticated via admin JWT.
    • Manages ticket queue, sets live status (Online, Busy, Offline).
    • Publishes public replies (sends email + FCM to customer) or logs private internal notes (isInternal: true, visible only to staff).
    • Executes 1-click order resolutions: replacement orders, partial refunds, store credit.
    • Evaluated on personal FRT, resolution count, and average CSAT score.
  • Company Admin / Store Owner (NurseryUser with role Admin):
    • Full visibility across all representative queues and performance metrics.
    • Can reassign tickets, override SLAs, and review CSR feedback reports.
    • Manages automated routing rules and notification integrations (FCM, SMTP, Twilio/SMS).

3. Comprehensive Codebase Gap Analysis

Component / File Current Implementation in Codebase Required 2026 Enterprise Implementation Gap Severity
Data Model[SupportTickets-model.js](file:///c:/thriveni/folder%20f/POS/EGF_POS/evergreen_pos_be/src/models/SupportTickets/SupportTickets-model.js) Only supports createdBy: ref 'NurseryUser'. Comments lack privacy flags (isInternal). No order binding, no SLA fields, no CSAT subdocument. Polymorphic creatorType: ['Client', 'NurseryUser'], isInternal: Boolean per comment, order reference, sla tracking, csat subdocument. CRITICAL
Representative Performance[NurseryUser-model.js](file:///c:/thriveni/folder%20f/POS/EGF_POS/evergreen_pos_be/src/models/NurseryUser/NurseryUser-model.js) Stores basic user profile and static role. No live status or performance tracking. Add availabilityStatus: ['Online', 'Busy', 'Offline'], lastActiveAt: Date, and performanceMetrics (resolved count, avg FRT, avg CSAT). HIGH
Push Notificationssrc/services/notifications/ Only basic email triggers exist in disconnected controllers. No mobile/web push. Firebase Cloud Messaging (FCM) dispatcher sending multi-channel alerts (FCM + Email + SMS) to customer and representative. HIGH
Controller Endpoints[SupportTickets.controller.js](file:///c:/thriveni/folder%20f/POS/EGF_POS/evergreen_pos_be/src/controllers/SupportTickets/SupportTickets.controller.js) Only staff CRUD endpoints exist. All requests require staff verifyToken. Add customer endpoints (createCustomerTicket, getCustomerTickets, addCustomerReply, submitCsat) and representative analytics. CRITICAL
Routing & Auth[tickets-route.js](file:///c:/thriveni/folder%20f/POS/EGF_POS/evergreen_pos_be/src/routes/SupportTickets/tickets-route.js) All routes guarded by staff verifyToken. Segregate /api/v1/customer/tickets (using verifyClientToken) from /api/v1/tickets (using staff verifyToken). CRITICAL
Admin UI View[adminManagementTickets.tsx](file:///c:/thriveni/folder%20f/POS/EGF_POS/evergreen_pos_fe/src/supportTickets/adminManagementTickets.tsx) Label says "Customer Support Manager". Single reply box. No CSR status header or Customer 360 view. Rebrand to "Customer Support Representative", add Internal Note switch, Customer 360 sidebar, and Representative Live Status bar. HIGH
CSR Dashboardsrc/supportTickets/CsrPerformanceDashboard.tsx Non-existent in admin panel. New dedicated screen listing all representatives with live status, resolved counts, avg resolution time, and CSAT breakdown. HIGH
Storefront Portalevergreenpos_E-commerce_new Only generic Contact Us form (submit-contact). No customer ticket tracking or order-help modal. Add /account/tickets view, contextual "Need Help?" button in OrderDetails.tsx, and 1-click CSAT survey landing page. CRITICAL

4. Multi-Channel Push Notification Architecture (FCM + Email + SMS)

Notification Dispatch Matrix:

Event Trigger Recipient Channels Fired Payload & Content Summary
New Ticket Created Customer Email + FCM Web Push "Support Request Received [TC-XXXX]. Target response: 4h. Track online."
New Ticket Created Assigned CSR & Admin Email + FCM Admin Push "New Ticket [TC-XXXX] from John Doe (Order #1042). Urgency: High."
Urgent Escalation (Score 4-5) Head of Support & Admin Email + FCM High-Priority + SMS "๐Ÿšจ URGENT: High Escalation Risk on Ticket [TC-XXXX]. Immediate review needed."
Ticket Assigned to CSR Assigned CSR FCM Admin Push + Email "You have been assigned Ticket [TC-XXXX] regarding Damaged Goods."
CSR Public Reply Customer FCM Push + Email + SMS "New reply from Sarah at Evergreen: We've dispatched your replacement..."
Customer Reply Assigned CSR FCM Admin Push + Sound Alert "Customer replied on [TC-XXXX]: Photo uploaded as requested."
Ticket Solved (CSAT Prompt) Customer Email (1-Click Widget) + FCM Push "Your ticket is resolved! How was your experience with Sarah? (1-5 Stars)"
48-Hour Inactivity Warning Customer Email + FCM Push "We haven't heard from you regarding [TC-XXXX]. Do you still need assistance?"
72-Hour Auto-Closure Customer Email + FCM Push "Ticket [TC-XXXX] has been closed due to inactivity. Reopen anytime with 1 click."

5. Support Team Performance & Status Dashboard

Dashboard Specifications:

  • Real-Time CSR Status Switcher: Representatives can toggle their live state at the top of their workspace:
    • ๐ŸŸข Online: Ready to receive automated ticket assignments.
    • ๐ŸŸก Busy: Working on complex ticket / in call; no auto-assignments.
    • ๐Ÿ”ด Offline: Shift ended; tickets route to backup representative.
  • Representative Performance Table:
Representative Name Current Status Active Tickets Resolved Today / Month Avg First Response (FRT) Avg Resolution Time CSAT Rating (1-5) Positive Rating % Actions
Sarah Jenkins ๐ŸŸข Online 4 18 / 240 14 mins 3.2 hrs โญ 4.9 (182 reviews) 98.2% [View Reviews] [Audit Queue]
Rahul Sharma ๐ŸŸก Busy 7 12 / 195 28 mins 4.8 hrs โญ 4.6 (140 reviews) 92.1% [View Reviews] [Audit Queue]
Amit Patel ๐Ÿ”ด Offline 0 0 / 160 45 mins 6.5 hrs โญ 4.2 (98 reviews) 85.0% [View Reviews] [Audit Queue]
  • Feedback Report Drawer: Clicking [View Reviews] opens a slide-over panel displaying all customer feedback comments, star distributions (5โ˜… to 1โ˜…), and ticket links associated with that representative.

6. Post-Resolution Customer Feedback Loop (CSAT)

1-Click Interactive Rating Flow:

  1. When a CSR sets a ticket status to Resolved, the system automatically captures sla.resolutionAt and dispatches the CSAT prompt.
  2. The customer receives an email and push notification containing 5 interactive rating buttons:
    • ๐Ÿ˜ 5 - Excellent | ๐Ÿ˜Š 4 - Good | ๐Ÿ˜ 3 - Average | ๐Ÿ™ 2 - Poor | ๐Ÿ˜ก 1 - Terrible
  3. Clicking any rating opens https://store.evergreen.com/support/rate-ticket?id=...&rating=5.
  4. The page instantly acknowledges the score and provides an optional text area: "What did we do well, or how can we improve?"
  5. The submission updates SupportTicket.csat and recalculates the assigned representative's cumulative rating.

7. Real-Time E-Commerce Case Studies & Walkthroughs

Case 1: Perishable Live Plant Damaged in Transit

  • Context: Customer orders an expensive Fiddle Leaf Fig (Order #EG-9842, โ‚น3,499). The courier took 5 days; leaves arrived brown, wilted, and stem cracked.
  • Customer Action: Goes to Storefront $\rightarrow$ My Orders $\rightarrow$ Clicks "Need Help with this Order?". Pre-selected SKU, uploads 3 photos of cracked stem and damaged packaging.
  • AI Triage: Gemini parses description + tags: Urgency = 4/5, Category = Damaged / Defective Plant, Sentiment = frustrated. Suggests immediate replacement draft.
  • Representative Action:
    1. CSR Sarah receives high-urgency FCM web push on admin dashboard.
    2. Reviews uploaded photos in ticket preview.
    3. Adds an Internal Note: "Verified photos. Plant dehydrated and main stem snapped. Carrier claim to be filed with Delhivery. Approved 100% free nursery replacement."
    4. Clicks 1-Click Action: "Create Replacement Order" (auto-generates Order #EG-9842-R in POS backend).
    5. Sends Public Reply: "Dear Customer, We sincerely apologize for the damaged plant. A healthy fresh replacement has been booked under order #EG-9842-R with priority express shipping."
  • Outcome: Customer receives Email 5 + FCM push with replacement tracking link. Customer rates 5โ˜… on CSAT survey.

Case 2: Live Plant Courier Delay & Stagnation

  • Context: Bonsai tree in transit for 4 days; tracking shows package stationary at regional hub for 48 hours without update.
  • Customer Action: Submits ticket "Plant stuck at hub, will die in dark box!".
  • Representative Action:
    1. CSR sees ticket in Waiting on Staff queue.
    2. Adds an Internal Note: "Called BlueDart hub manager (Rajesh, Hub ID 412). Package located, marked for priority morning delivery run tomorrow."
    3. Sends Public Reply: "We have escalated directly with the hub manager. Your plant is prioritized for morning delivery tomorrow before 11 AM."
    4. Status set to In Progress.
  • Outcome: Package delivered next morning. CSR follows up, customer confirms plant is healthy, ticket resolved with 5โ˜… rating.

Case 3: Missing Item in Split Shipment

  • Context: Customer ordered 3 Ceramic Planters + 2 Succulent Packs. Box arrives containing only succulents.
  • Customer Action: Raises ticket "Order incomplete! Where are the 3 ceramic planters?".
  • Representative Action:
    1. CSR opens ticket, clicks Customer 360 drawer to inspect order fulfillment records.
    2. Discovers fulfillment was split into two packages due to weight: Package 1 (Plants, Delivered) and Package 2 (Ceramics, In Transit with tracking AWB #BLU-8841).
    3. Sends Public Reply: "Your order was dispatched in two separate packages to protect the plants. Your 3 planters are currently out for delivery today with BlueDart tracking #BLU-8841."
  • Outcome: Avoids unnecessary refund or panic. Customer tracks second package, receives planters, rates 5โ˜….

Case 4: Payment Deducted but Order Failed (Gateway Timeout)

  • Context: Customer attempted โ‚น4,200 purchase via UPI. Payment gateway timed out, amount debited from bank, but storefront shows "Cart empty / Order Not Found".
  • Customer Action: Panicked customer submits ticket with bank SMS screenshot and UTR transaction reference #4289103819.
  • AI Triage: Recognizes financial distress; urgency flagged as 5/5 (Escalation Risk).
  • Representative Action:
    1. CSR receives high-priority FCM push alert.
    2. Checks Razorpay/Stripe dashboard using UTR #; finds payment was captured as "Unclaimed Webhook".
    3. Clicks POS action: "Convert Captured Payment to Order".
    4. Sends Public Reply: "Your payment was successfully received! We have confirmed Order #EG-9912. Tax invoice and tracking details attached below."
  • Outcome: Resolves severe customer frustration within 15 minutes, preventing bank chargeback or dispute.

Case 5: Return / Replacement with Photo Proof & Reverse Pickup

  • Context: Customer received a 10-inch terracotta pot instead of the 14-inch variant ordered.
  • Customer Action: Submits ticket with tape-measure photo showing 10-inch diameter.
  • Representative Action:
    1. CSR validates photo proof against order invoice.
    2. Clicks "Generate Reverse Pickup" (creates reverse courier AWB via Shiprocket/Delhivery API).
    3. Logs Internal Note: "Warehouse picked wrong SKU. Notified inventory lead. Reverse pickup scheduled for tomorrow."
    4. Sends Public Reply: "We apologize for the fulfillment mix-up. Courier will collect the 10-inch pot tomorrow. We have already dispatched the correct 14-inch pot under AWB #SHP-9921."
  • Outcome: Seamless reverse exchange; customer praises fast resolution.

Case 6: High Escalation Risk / Impending Chargeback

  • Context: High-value wholesale customer (LTV: โ‚น1,80,000) whose delivery was delayed 72 hours without response. Customer emails: "Unacceptable! Cancel order immediately, refund my card or I am filing a bank chargeback and consumer forum complaint today."
  • AI Triage: Classifies sentiment = escalation_risk, Urgency = 5/5.
  • Representative Action:
    1. Urgent Escalation email + FCM push instantly alerts both CSR and Admin.
    2. CSR immediately dials customer phone number (from Customer 360 card) to offer personal apology and compensation.
    3. Agrees to express courier delivery + 15% refund credit for delay.
    4. Logs Internal Note: "Spoke to customer Mr. Verma. Calm now. Issued 15% partial refund (โ‚น4,500) and waived shipping."
  • Outcome: Retained high-LTV account, avoided merchant payment gateway dispute fee and chargeback penalty.

Case 7: Post-Delivery Horticultural Care Guidance

  • Context: 2 weeks post-delivery, customer submits ticket: "My Calathea leaves are curling and tips turning brown. Is it dying?".
  • Customer Action: Selects category Plant Care Advice, uploads photo of leaf.
  • Representative Action:
    1. Ticket routes to CSR horticultural specialist.
    2. CSR diagnoses low humidity and tap water mineral sensitivity.
    3. Sends Public Reply: "Calatheas are sensitive to chlorine in tap water and low humidity. We recommend using filtered water and misting leaves twice daily. Link to our complete Calathea care guide: [evergreen.com/care/calathea]".
    4. Marks status as Resolved.
  • Outcome: Builds customer loyalty and trust; customer leaves 5โ˜… rating and subsequently purchases a plant humidifier from the store.

8. Detailed Developer Implementation Plan

Step 1: Database Schema Enhancements (evergreen_pos_be)

1. Modify src/models/SupportTickets/SupportTickets-model.js:

Add polymorphic creator, internal notes, SLA timers, FCM message tracking, and CSAT subdocument.

const mongoose = require('mongoose');

const commentSchema = new mongoose.Schema({
  authorType: { type: String, enum: ['NurseryUser', 'Client'], required: true },
  authorUser: { type: mongoose.Schema.Types.ObjectId, ref: 'NurseryUser', default: null },
  authorClient: { type: mongoose.Schema.Types.ObjectId, ref: 'Client', default: null },
  authorName: { type: String, required: true },
  message: { type: String, required: true, trim: true },
  isInternal: { type: Boolean, default: false }, // Staff-only private note
  attachments: [{ fileName: String, fileUrl: String, fileType: String }],
  createdAt: { type: Date, default: Date.now }
});

const supportTicketSchema = new mongoose.Schema({
  nurseryId: { type: mongoose.Schema.Types.ObjectId, ref: 'Nursery', required: true, index: true },
  ticketNumber: { type: String, unique: true, required: true, index: true },

  // Polymorphic Creator: Storefront Customer or Staff
  creatorType: { type: String, enum: ['Client', 'NurseryUser'], default: 'Client', required: true },
  client: { type: mongoose.Schema.Types.ObjectId, ref: 'Client', default: null, index: true },
  staffCreator: { type: mongoose.Schema.Types.ObjectId, ref: 'NurseryUser', default: null },

  customerName: { type: String, required: true },
  customerEmail: { type: String, required: true, index: true },
  customerPhone: { type: String, default: '' },

  // E-Commerce Order Reference
  order: { type: mongoose.Schema.Types.ObjectId, ref: 'Order', default: null, index: true },
  orderNumber: { type: String, default: null },
  trackingNumber: { type: String, default: null },
  affectedItems: [{
    productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' },
    productName: String,
    sku: String,
    quantity: Number
  }],

  subject: { type: String, required: true, trim: true },
  description: { type: String, required: true },
  category: {
    type: String,
    enum: [
      'Order & Shipping',
      'Damaged / Defective Plant',
      'Return & Refund',
      'Payment & Billing',
      'Plant Care Advice',
      'General Inquiry'
    ],
    default: 'General Inquiry'
  },
  priority: { type: String, enum: ['Low', 'Medium', 'High', 'Urgent'], default: 'Medium' },
  status: {
    type: String,
    enum: ['Open', 'In Progress', 'Waiting on Customer', 'Waiting on Staff', 'Resolved', 'Closed'],
    default: 'Open',
    index: true
  },

  // Assigned Customer Support Representative
  assignedTo: { type: mongoose.Schema.Types.ObjectId, ref: 'NurseryUser', default: null, index: true },

  // SLA Tracking
  sla: {
    firstResponseDue: { type: Date, required: true },
    firstResponseAt: { type: Date, default: null },
    resolutionDue: { type: Date, required: true },
    resolutionAt: { type: Date, default: null },
    isFirstResponseBreached: { type: Boolean, default: false },
    isResolutionBreached: { type: Boolean, default: false }
  },

  // Post-Resolution CSAT
  csat: {
    rating: { type: Number, min: 1, max: 5, default: null },
    feedbackComment: { type: String, default: null },
    ratedAt: { type: Date, default: null }
  },

  // AI Triage
  aiTriage: {
    urgencyScore: { type: Number, min: 1, max: 5, default: 3 },
    sentiment: { type: String, enum: ['positive', 'neutral', 'frustrated', 'escalation_risk'], default: 'neutral' },
    suggestedDraftReply: String,
    triageTimestamp: Date
  },

  comments: [commentSchema]
}, { timestamps: true });

module.exports = mongoose.model('SupportTicket', supportTicketSchema);

2. Modify src/models/NurseryUser/NurseryUser-model.js:

Add live representative status, FCM device tokens, and performance evaluation metrics.

// Add to NurseryUser Schema:
availabilityStatus: {
  type: String,
  enum: ['Online', 'Busy', 'Offline'],
  default: 'Offline',
  index: true
},
lastActiveAt: {
  type: Date,
  default: Date.now
},
fcmTokens: [{
  token: String,
  deviceType: { type: String, enum: ['web', 'android', 'ios'], default: 'web' },
  updatedAt: { type: Date, default: Date.now }
}],
performanceMetrics: {
  totalResolved: { type: Number, default: 0 },
  averageFirstResponseMinutes: { type: Number, default: 0 },
  averageResolutionHours: { type: Number, default: 0 },
  averageCsat: { type: Number, default: 5.0 },
  totalRatingsCount: { type: Number, default: 0 }
}

Step 2: Multi-Channel Notification Service (evergreen_pos_be)

Create src/services/notifications/notificationDispatcher.service.js:

Coordinates Firebase Cloud Messaging (FCM), Nodemailer, and SMS.

const admin = require('firebase-admin'); // Initialize Firebase Admin SDK with credentials
const nodemailer = require('nodemailer');

exports.dispatchMultiChannelNotification = async ({
  recipientType, // 'Client' or 'NurseryUser'
  recipientDoc,  // Document containing fcmTokens, email, phone
  title,
  body,
  dataPayload = {},
  emailHtml = null,
  sendSms = false
}) => {
  const promises = [];

  // 1. Firebase Cloud Messaging (FCM) Push
  if (recipientDoc.fcmTokens && recipientDoc.fcmTokens.length > 0) {
    const tokens = recipientDoc.fcmTokens.map(t => t.token);
    const fcmMessage = {
      notification: { title, body },
      data: { ...dataPayload, click_action: 'FLUTTER_NOTIFICATION_CLICK' },
      tokens
    };
    promises.push(
      admin.messaging().sendEachForMulticast(fcmMessage).catch(err => console.error('FCM error:', err))
    );
  }

  // 2. Transactional Email
  if (recipientDoc.email && emailHtml) {
    // Dispatch email using nodemailer transporter...
  }

  // 3. SMS Gateway (Twilio / Fast2SMS) for Urgent Escalations
  if (sendSms && recipientDoc.phone) {
    // Dispatch SMS...
  }

  return Promise.allSettled(promises);
};

Step 3: Support Representative Performance Controller & APIs (evergreen_pos_be)

Add to src/controllers/SupportTickets/SupportTickets.controller.js:

  1. Representative Status Toggle (PATCH /api/v1/csr/status): Updates representative's live availability (Online, Busy, Offline).
  2. Support Team Performance Overview (GET /api/v1/csr/performance-dashboard): Aggregates live counts of active tickets, resolved counts, and average CSAT for each representative.
  3. Representative Feedback Reports (GET /api/v1/csr/:id/feedback-reports): Returns all tickets with customer CSAT comments and star ratings for a specific representative.

Step 4: Admin UI Enhancements (evergreen_pos_fe)

  1. Global Rebranding: Search and replace "Customer Support Manager" $\longrightarrow$ "Customer Support Representative" across:
    • Sidebar navigation: Customer Support Representatives
    • Table columns: Assigned Representative
    • Filter dropdowns: Filter by Representative
    • Modal headers: Representative Action & Notes
  2. Dual-Mode Reply Component: Implement tab switcher between Public Reply to Customer (triggers Email + FCM) and Internal Private Note (amber styling, saves without customer notification).
  3. New Dedicated Dashboard Component:
    Create src/supportTickets/CsrPerformanceDashboard.tsx displaying the live status board, resolved ticket tallies, FRT/ART meters, and CSAT breakdown.

Step 5: Storefront Customer Portal (evergreenpos_E-commerce_new)

  1. Contextual Order Help Button: Add to src/pages/Orders/OrderDetails.tsx:
    • Clicking "Need Help with this Order?" launches ticket modal with order number and product items pre-populated.
  2. Customer Ticket Tracking View: Create src/pages/Account/CustomerTickets.tsx:
    • Displays conversational thread between customer and representative.
    • Shows public comments only (internal notes completely hidden).
    • Allows uploading additional photo proof.
  3. 1-Click CSAT Landing Page: Create src/pages/Support/TicketRating.tsx to handle post-resolution feedback clicks from emails and push notifications.

9. Developer Verification & Testing Checklist

  • [ ] FCM Push Notification: Customer receives push alert on their device when representative posts a public reply.
  • [ ] CSR Web Push: Representative receives browser notification when customer submits a ticket or posts a reply.
  • [ ] Label Rebranding: Verify zero occurrences of "Customer Support Manager" remain in the admin frontend; all displays show "Customer Support Representative".
  • [ ] Internal Note Leak Test: Submit an internal note (isInternal: true) from admin; verify storefront API GET /customer/tickets/:id strips it completely.
  • [ ] Live Status Switcher: Toggle CSR status from Online to Busy; verify status reflects immediately on the team dashboard.
  • [ ] 1-Click CSAT Loop: Mark ticket as Resolved; verify email/push survey arrives; clicking 5โ˜… records rating in ticket and updates representative's profile.
  • [ ] Perishable Plant Case Test: Create ticket with order number and image; verify AI triage flags high urgency and drafts replacement response.
(2-2/2)