Support & Help Desk
Last updated August 2, 2026
Classgrid's Support module provides a full-featured help desk with public ticket creation (no login required), authenticated ticket management, file attachments, admin reply system, ticket lifecycle management, and email + push notifications. All ticket data is stored in MongoDB via the SupportTicket model.
Two Access Modes
1. Public Endpoints (No Login Required)
For marketing site visitors at classgrid.in/support. Users are identified by email only (similar to Zendesk/Brevo).
2. Authenticated Endpoints (Logged-in Platform Users)
For students, faculty, and admins within the platform.
Strict Session Enforcement
All public endpoints pass through enforceStrictSession middleware that prevents:
-
Session Mismatch — If a user is logged in but provides a different email, returns HTTP 403:
JSON -
Registered User Without Login — If the email belongs to a registered platform user and they're NOT logged in, blocks access to existing tickets:
JSONException: Creating NEW tickets is always allowed.
Public Ticket Creation
API: POST /api/support/public/tickets
Auth: None (public)
Upload: Up to 5 files via multipleUploads("files", 5)
Body (multipart):
Two ticket types based on institution field:
- If
institutionis provided → General Inquiry (Classgrid Talk) — open to anyone - If
institutionis empty → Technical Support Ticket — requires registered email with an organization:JSONJSON
Ticket creation workflow:
- Validates email, subject (max 200 chars), message
- Looks up user in MongoDB for profile picture, role, org info
- Uploads files to Supabase storage bucket
support-attachments(path:support_tickets/public/{email}/) - Creates
SupportTicketwith:messages[]— initial message with author info, avatar, org name, org logoevents[]—{ type: 'ticketCreated', label: 'Ticket submitted' }lastComment— timestamp for sorting
- Sends confirmation email:
- Technical:
notifyUserOfTicketCreation() - Inquiry:
notifyUserOfTalkRequestCreation()
- Technical:
- Notifies all
super_adminusers viabulkDispatchNotificationwith push notification
Public Ticket Viewing & Replies
List My Tickets
API: GET /api/support/public/tickets?email=xxx
Auth: Public (with strict session enforcement)
Returns all tickets for the email with:
replyCount— number of messages minus 1 (excludes initial message)lastComment— timestamp of most recent activityisPlatformUser— boolean indicating if email is registeredhasOrganization— boolean indicating if user has an org
View Single Ticket
API: GET /api/support/public/tickets/:id?email=xxx
Auth: Public
Email must match ticket.submitterEmail. Returns full ticket with all messages and events.
Reply to Ticket
API: POST /api/support/public/tickets/:id/reply
Auth: Public (email verified against ticket owner)
Upload: Up to 5 files
Body: { "email": "...", "message": "...", "name": "..." }
Workflow:
- Validates ticket is not
closed - Verifies email matches ticket owner
- Uploads any attachments to Supabase
- Fetches user's current profile, role, org info from MongoDB
- Pushes to both
ticket.replies[]andticket.messages[](dual format for compatibility) - Adds event:
{ type: 'userReply', label: '[Role] replied' } - Updates
lastCommentandlastUserReplyAt - If ticket was
resolved, reopens it (status →reopened) - Otherwise sets status to
open - Notifies all super admins
Close Ticket
API: POST /api/support/public/tickets/:id/close
Auth: Public (email verified)
Sets status: closed. Adds event: { type: 'statusChanged', label: 'User closed ticket' }.
Authenticated Ticket Creation
API: POST /api/support/tickets
Roles: Any authenticated user with an organization
Upload: Up to 5 files
Same as public creation but:
- Uses
req.user._idassubmittedBy(ObjectId reference) - Requires
organization_id— blocks orgless accounts:JSON - Attaches user's profile picture, role, org name, org logo to the initial message
View My Tickets
API: GET /api/support/tickets
Roles: Any authenticated user
Returns tickets with stats:
View Ticket Detail
API: GET /api/support/tickets/:id
Roles: Any authenticated user
Returns full ticket with populated submittedBy and assignedTo fields.
Ticket Lifecycle
Message Format
Each message in ticket.messages[] contains:
Event Timeline
Each ticket tracks events in ticket.events[]:
File Attachments
- Storage: Supabase bucket
support-attachments - Path:
support_tickets/{userId}/(authenticated) orsupport_tickets/public/{email}/(public) - Max files per request: 5
- Each attachment stores:
id,name,url(storage_path),mimeType,size,uploadedAt
Email Notifications
All via support-ticket-email.service.js
Push Notifications to Super Admins
Every ticket action sends push notifications to all super_admin users:
- New ticket: "New Support Ticket: [subject]"
- New inquiry: "New Inquiry: [subject]"
- User reply: "New Reply (Public): [subject]"
- Link:
/superadmin/support/view/{ticketId}
Key Models
SupportTicket Schema Key Fields
subject, message, category, priority, status, submitterEmail, submitterName, submitterRole, submittedBy (ObjectId), organization_id, assignedTo (ObjectId), messages[], replies[], events[], attachments[], lastComment, lastUserReplyAt, institution