Support Module Feature List
Support inquiries, support tickets, feedback, realtime chat, and admin operations.
Support Module - Feature List
1. Feature Overview
The support module owns customer communication and operational follow-up across three related surfaces:
- support inquiries for homepage/live-chat style conversations, including guests and authenticated customers
- support requests for authenticated customer tickets that are tied to a verified customer record
- feedback submissions for app/product feedback that should be reviewed by admins but does not become a live conversation
Support now uses a mixed interaction model:
- synchronous REST for creating, listing, identifying, verifying, assigning, closing, linking, and reading records
- websocket delta events for live support request and inquiry messages
- scheduled maintenance for inactive inquiry closing
- existing notification queue for support inquiry email verification
The support inquiry flow is intentionally safe for guest users. A guest can provide an email address, but an email match with an existing customer is never revealed to the frontend and never links the inquiry to that customer until the email is verified or the customer logs in.
2. Route Ownership and Surfaces
| Surface | Route prefix | Owner |
|---|---|---|
| Public/customer support inquiries | /api/support-inquiries | SupportInquiriesCustomerController |
| Admin support inquiries | /api/admin/support-inquiries | SupportInquiriesAdminController |
| Mobile support requests | /api/mobile/support-requests | MobileModule composition of SupportRequestsMobileModule |
| Admin support requests | /api/admin/support-requests | SupportRequestsAdminController |
| Mobile feedback | /api/mobile/feedback | MobileModule composition of FeedbackMobileModule |
| Admin feedback | /api/admin/feedback | FeedbackAdminController |
| Realtime websocket namespace | configured by WS_NAMESPACE | RealtimeGateway + SupportRealtimeModule |
Swagger tags used by support controllers:
Support InquiriesSupport Inquiries (Admin)Support RequestsSupport Requests (Admin)FeedbackFeedback (Admin)
Notes:
- Support inquiry customer routes are mounted directly at
/api/support-inquiriesbecause they are intended for website/homepage chat, including unauthenticated guests. - Existing authenticated mobile support requests remain mounted through the mobile composition layer at
/api/mobile/support-requests. - Feedback is not a chat surface. It is a one-way submission plus admin review workflow.
3. Admin Feature Matrix
| Capability | Endpoint | AuthZ |
|---|---|---|
| List support inquiries | GET /api/admin/support-inquiries | SupportInquiries_READ |
| Support inquiry detail | GET /api/admin/support-inquiries/:id | SupportInquiries_READ |
| Add admin reply to inquiry | POST /api/admin/support-inquiries/:id/messages | SupportInquiries_UPDATE |
| Assign/unassign inquiry | PATCH /api/admin/support-inquiries/:id/assign | SupportInquiries_UPDATE |
| Update inquiry status | PATCH /api/admin/support-inquiries/:id/status | SupportInquiries_UPDATE |
| Link inquiry to existing support request | POST /api/admin/support-inquiries/:id/link-support-request | SupportInquiries_UPDATE |
| Create support request from verified inquiry | POST /api/admin/support-inquiries/:id/link-support-request | SupportInquiries_UPDATE |
| List support requests | GET /api/admin/support-requests | SupportRequests_READ |
| Support request detail | GET /api/admin/support-requests/:id | SupportRequests_READ |
| Update support request status | PATCH /api/admin/support-requests/:id/status | SupportRequests_UPDATE |
| Assign/unassign support request | PATCH /api/admin/support-requests/:id/assign | SupportRequests_UPDATE |
| Add admin reply to support request | POST /api/admin/support-requests/:id/messages | SupportRequests_UPDATE |
| List feedback submissions | GET /api/admin/feedback | Feedback_READ |
| Feedback submission detail | GET /api/admin/feedback/:id | Feedback_READ |
| Mark feedback reviewed | PATCH /api/admin/feedback/:id/review | Feedback_UPDATE |
Admin mutations record activity logs for support inquiry operations, support request operations, and feedback review operations. The audit context includes the request-derived metadata provided by SupportAdminSharedService.buildAuditContext(...).
4. Customer / Guest / Mobile Feature Matrix
| Capability | Endpoint | Runtime mode | Auth model |
|---|---|---|---|
| Create support inquiry | POST /api/support-inquiries | Synchronous create + greeting | Optional customer JWT or guest |
| List own customer inquiries | GET /api/support-inquiries | Synchronous read | Customer JWT only |
| Get inquiry detail | GET /api/support-inquiries/:id | Synchronous read | Customer JWT or guest inquiry token |
| Get inquiry messages | GET /api/support-inquiries/:id/messages | Synchronous read | Customer JWT or guest inquiry token |
| Add inquiry message | POST /api/support-inquiries/:id/messages | Synchronous write + websocket event | Customer JWT or guest inquiry token |
| Identify guest contact | PATCH /api/support-inquiries/:id/identify | Synchronous write | Customer JWT or guest inquiry token |
| Request inquiry email verification | POST /api/support-inquiries/:id/verify-email/request | Synchronous OTP enqueue | Customer JWT or guest inquiry token |
| Confirm inquiry email verification | POST /api/support-inquiries/:id/verify-email/confirm | Synchronous verify/link | Customer JWT or guest inquiry token |
| Create mobile support request | POST /api/mobile/support-requests | Synchronous create + first message | Customer JWT |
| List mobile support requests | GET /api/mobile/support-requests | Synchronous read | Customer JWT |
| Mobile support request detail | GET /api/mobile/support-requests/:id | Synchronous read | Customer JWT |
| Add mobile support request reply | POST /api/mobile/support-requests/:id/messages | Synchronous write + websocket event | Customer JWT |
| Submit feedback | POST /api/mobile/feedback | Synchronous create | Customer JWT |
5. Key Product Rules
- A support inquiry is a lightweight chat-style record that can exist before the visitor is known.
- A support request is a customer ticket and requires a real
customer_id. - A guest email does not prove identity. It is stored as contact data only until verification succeeds.
- If a guest email matches an existing customer, the backend silently sends verification and does not expose whether the email exists.
- A verified guest inquiry can be linked to a customer and then converted to a normal support request.
- A guest inquiry can still be handled by admins even when it never becomes a support request.
- Closing or resolving an inquiry changes status only; messages are retained for admin history.
- Inactive inquiries are automatically closed by scheduled maintenance after the configured inactivity window.
- Customer-facing APIs never expose raw token hashes.
- Guest inquiry access uses
Authorization: Bearer si_..., not a customer JWT. - Websocket rooms are additive. REST remains the source of truth for initial state and full history.
- Feedback submissions are reviewed, not replied to. They do not have message threads.
6. Domain Surfaces
6.1 Support inquiries
Support inquiries are for live chat and homepage inquiry capture. They support:
- guest creation
- authenticated customer creation
- tracking codes
- first system greeting message
- guest name/email/phone capture
- guest access token
- silent customer email lookup
- OTP verification before customer linking
- admin assignment
- admin replies
- status management
- linking to an existing support request
- creating a new support request after verified identity
- websocket rooms for live message deltas
- scheduled inactive close
6.2 Support requests
Support requests are the existing authenticated ticket system. They support:
- mobile customer ticket creation
- mobile customer replies
- admin listing/filtering/search
- admin detail view with full message history
- admin assignment
- admin replies
- status changes
- resolution notes
- websocket rooms for message deltas
- customer reply reopen behavior for resolved tickets
6.3 Feedback submissions
Feedback submissions are one-way app feedback records. They support:
- authenticated mobile submission
- admin listing/filtering/search
- admin detail view
- admin review marker
- activity log on review
7. State Models
7.1 Support inquiry status lifecycle
Typical path:
open -> active -> waiting -> resolved -> closed
Conversion path:
open -> active -> linked
Moderation path:
open -> spam
State notes:
openmeans inquiry exists and may have only system/visitor messages.activemeans staff or visitor conversation is ongoing.waitingmeans the team is waiting on the visitor/customer.linkedmeans the inquiry is tied to asupport_request.resolvedmeans the conversation is resolved but not necessarily hard-closed.closedmeans no more visitor/admin messages are accepted.spamis terminal-like and recordsclosedAt.
7.2 Support request status lifecycle
Typical path:
open -> in_progress -> resolved -> closed
Reply behavior:
- Mobile/customer reply on a resolved request reopens it to
open. - Closed support requests reject both customer and admin replies.
- Resolution notes are only valid for
resolvedandclosed.
7.3 Feedback status lifecycle
new -> reviewed
Review state requires:
reviewedByAdminIdreviewedAt
New state requires both fields to be null.
8. Identity, Security, and Privacy
8.1 Guest access token
Guest support inquiries return an inquiryAccessToken only at creation time. The token:
- starts with
si_ - is used as
Authorization: Bearer si_... - is hashed with SHA-256 before storage
- is stored in
support_inquiry_tokens.token_hash - expires using the inquiry token expiry policy
- can be revoked by setting
revoked_at - is accepted by REST inquiry endpoints and websocket inquiry room joins
8.2 Optional auth behavior
Support inquiry public routes use an optional auth guard:
- normal customer JWTs are parsed as customer identity
Bearer si_...is treated as guest inquiry token- invalid or missing customer JWT does not automatically become an admin identity
- guest token access is validated against the target inquiry
8.3 Email verification and customer linking
Production-safe flow:
- Guest creates inquiry.
- System creates inquiry and a system greeting message.
- Guest adds or updates email using create or identify endpoint.
- If the email matches a customer, backend does not reveal the match.
- Backend sends OTP/magic verification to the email.
- Guest confirms OTP.
- Backend links inquiry to
customerIdonly after successful verification. - Admin can create or link a support request after identity is verified.
Security constraints:
- No account enumeration response.
- No customer support request is created from email alone.
- Guest cannot read customer ticket data without a verified customer link.
- Admin can still handle the guest inquiry without converting it.
9. Tracking Codes
Each support inquiry has a customer-safe trackingCode, independent from the serial database id.
Example:
INQ-8K4P2XUsage:
- returned on inquiry creation
- shown to guest/customer as the inquiry ID
- available in admin list/detail/search
- included in websocket inquiry message payloads
- remains visible if the inquiry later links to a support request
When linked, both identifiers remain useful:
| Identifier | Meaning |
|---|---|
trackingCode | Public inquiry tracking reference |
supportRequestId | Internal/customer ticket reference |
10. Realtime Features
Realtime support uses websocket rooms and event history.
Room types:
| Room | Pattern |
|---|---|
| Support request messages | support:request:{supportRequestId}:messages |
| Support inquiry messages | support:inquiry:{supportInquiryId}:messages |
Client events:
support:join_request_messagessupport:leave_request_messagessupport:sync_request_messagessupport:join_inquiry_messagessupport:leave_inquiry_messagessupport:sync_inquiry_messages
Server events:
support.request_message.createdsupport.inquiry_message.created
Realtime rules:
- REST is used for initial full history.
- Websocket events are deltas only.
- Clients dedupe by
eventId. - Clients call sync with
sinceEventIdafter reconnect. - If a gap is detected, clients refetch REST detail/messages.
- Admins can join any support request/inquiry room if they have read permission.
- Customers can join only their own support request/inquiry rooms.
- Guests can join only inquiry rooms for which they hold a valid
si_...token.
11. Search and Filtering
11.1 Admin support inquiry list
Admin inquiry list supports:
statuscategorycustomerIdassignedAdminIdsupportRequestIdsearch- pagination
- sort by
createdAtorupdatedAt
Search matches:
- tracking code
- subject
- guest email
- guest name
- guest phone
11.2 Customer support inquiry list
Customer inquiry list supports:
- current customer only
statuscategory- pagination
- sort by
createdAtorupdatedAt
Guest users do not use list; they fetch a specific inquiry with the inquiry token.
11.3 Admin support request list
Admin request list supports:
statuscategorycustomerIdassignedAdminIdsearchby subject- pagination
- sort
11.4 Mobile support request list
Mobile request list supports:
- current customer only
statuscategory- pagination
- sort
11.5 Admin feedback list
Admin feedback list supports:
statuscategorycustomerIdsearch- pagination
- sort by
createdAtorupdatedAt
12. Rate Limiting
Support inquiry public write flows use IpThrottlerGuard:
- create inquiry
- add inquiry message
- identify guest contact
- request email verification
- confirm email verification
The guard protects unauthenticated homepage chat surfaces where there is no stable customer identity. Authenticated mobile support request and feedback routes use the existing authenticated API guards and global request controls.
Rate-limit errors use the project standard RateLimitExceededException path and return the shared rate-limit error contract.
13. Notifications and Email
Support inquiry verification uses existing notification infrastructure:
VerificationTokenServicecreates the OTP.QueueName.NOTIFICATIONSreceives an email job.NotificationJob.SEND_EMAILis used to send the verification email.
The inquiry verification email is sent without revealing whether the email belongs to an existing customer. The response remains generic.
Support request replies use the existing SupportNotificationService path where applicable for customer notification of admin replies.
14. Maintenance Features
Support inquiries include scheduled inactive-close behavior:
| Runtime | Env |
|---|---|
| Cron expression | SUPPORT_INQUIRIES_INACTIVE_CLOSE_CRON |
| Inactivity days | SUPPORT_INQUIRIES_INACTIVE_CLOSE_DAYS |
Default behavior:
- cron:
0 * * * * - inactivity window:
7days
The scheduler marks stale open, active, waiting, or resolved inquiries as closed and sets closedAt. It does not delete inquiry messages.
15. Business Flow Diagrams
15.1 Guest live inquiry with verification
15.2 Live message realtime path
15.3 Existing mobile support request flow
16. Error UX Mapping
| errorCode | Typical HTTP | UX action |
|---|---|---|
SUPPORT_INQUIRY_NOT_FOUND | 404 | Show not-found state and offer to start a new inquiry |
SUPPORT_INQUIRY_ACCESS_DENIED | 403 | Ask user to log in or use the original inquiry link/token |
SUPPORT_INQUIRY_TOKEN_INVALID | 403 | Treat guest session as expired; create a new inquiry |
SUPPORT_INQUIRY_CLOSED | 400 | Disable reply UI and show closed/resolved state |
SUPPORT_INQUIRY_LINK_INVALID | 400 | Ask admin to verify customer/link target before converting |
SUPPORT_INQUIRY_EMAIL_VERIFICATION_INVALID | 400 | Ask visitor to request a new code |
SUPPORT_INQUIRY_SUPPORT_REQUEST_REQUIRED | 400 | Require verified customer before creating a ticket |
RATE_LIMIT_EXCEEDED | 429 | Backoff and retry later |
Existing support request and feedback paths may also return standard validation, not-found, forbidden, and unauthorized errors from the shared exception layer.
17. Release/QA Checklist
- Guest inquiry creation returns
id,trackingCode, messages with system greeting, andinquiryAccessToken. - Authenticated inquiry creation links directly to the customer without returning guest token.
- Guest token can fetch detail/messages only for the matching inquiry.
- Customer JWT can list only that customer's linked inquiries.
- Guest email identify flow stores normalized email and does not reveal customer existence.
- Email verification request sends a generic response for existing and non-existing email states.
- Email verification confirm links
customerIdonly after valid OTP. - Admin can list/search inquiries by tracking code, subject, guest email, guest name, and guest phone.
- Admin can reply, assign, update status, and link/create support request from inquiry.
- Linked inquiry preserves both
trackingCodeandsupportRequestId. - Closed/spam inquiries do not accept new visitor/admin messages.
- Inactive-close scheduler closes stale inquiries without deleting messages.
- Existing mobile support request create/list/detail/reply still works.
- Existing admin support request list/detail/status/assign/reply still works.
- Feedback create/list/detail/review still works.
- Websocket request rooms enforce customer/admin authorization.
- Websocket inquiry rooms enforce customer/admin/guest-token authorization.
- Reconnect sync returns replay events or
gapDetectedso clients can REST refetch. - Admin permissions include
SupportInquiries_READandSupportInquiries_UPDATE. - Permission seed includes
SupportInquiries.
18. Integration Flows
18.1 Homepage guest chat
- Frontend calls
POST /api/support-inquirieswith subject, optional category, optional first message, and optional guest contact fields. - Backend creates
support_inquiries,support_inquiry_tokens, and system greeting message. - Frontend stores the returned
inquiryAccessTokensecurely for the browser session. - Frontend displays
trackingCode. - Frontend joins
support:inquiry:{id}:messagesusing websocket authBearer si_.... - Guest posts messages through REST and receives admin replies through websocket.
- If guest leaves email, frontend calls identify and verification endpoints.
- Admin can continue handling the inquiry even if the guest never verifies.
18.2 Authenticated customer inquiry
- Customer is logged in and calls
POST /api/support-inquirieswith customer JWT. - Backend creates inquiry linked to
customerId. - No guest inquiry token is returned.
- Customer can list inquiries using
GET /api/support-inquiries. - Customer can join the websocket inquiry room with the normal customer JWT.
- Admin can create a support request from the inquiry because customer identity is already known.
18.3 Inquiry to support request conversion
- Admin opens an inquiry detail.
- Admin verifies the inquiry has
customerId. - Admin calls
POST /api/admin/support-inquiries/:id/link-support-request. - If
supportRequestIdis omitted, backend creates a newsupport_requestfor the verified customer. - Non-system inquiry messages are copied into
support_request_messages. - Inquiry status becomes
linked. - Admin support request workflow continues from
/api/admin/support-requests/:id.
18.4 Feedback review
- Mobile customer submits
POST /api/mobile/feedback. - Admin lists new feedback with
GET /api/admin/feedback?status=new. - Admin opens detail with
GET /api/admin/feedback/:id. - Admin marks reviewed with
PATCH /api/admin/feedback/:id/review. - Backend records reviewer and review timestamp.
See Also
- API Reference: See Support - API & Integration Guide for request/response contracts and websocket payloads.
- Backend Reference: See Support - Backend Documentation for schema, services, scheduler, and data model details.