Support Ticket Data Model Analysis
Current State Comparison
Backoffice Code (seeding & API)
| Field | Seeding Script | API Route | Status |
|---|---|---|---|
id | ✅ Required | ✅ Required | ✅ Match |
ticketNumber | ✅ Required | ✅ Required | ✅ Match |
title | ✅ Required | ✅ Required | ✅ Match |
description | ✅ Required | ✅ Required | ✅ Match |
status | ✅ Required | ✅ Required | ✅ Match |
priority | ✅ Required | ✅ Required | ✅ Match |
category | ✅ Required | ✅ Required | ✅ Match |
assignedTo | ✅ Optional | ✅ Optional | ✅ Match |
assignedToName | ✅ Optional | ✅ Optional | ✅ Match |
requesterId | ✅ Required | ✅ Required | ✅ Match |
requesterEmail | ✅ Required | ✅ Required | ✅ Match |
requesterName | ✅ Optional | ✅ Optional | ✅ Match |
createdAt | ✅ Required | ✅ Required | ✅ Match |
updatedAt | ✅ Required | ✅ Required | ✅ Match |
dueDate | ✅ Optional | ✅ Optional | ✅ Match |
resolvedAt | ✅ Optional | ✅ Optional | ✅ Match |
closedAt | ✅ Optional | ✅ Optional | ✅ Match |
tags | ✅ Optional | ✅ Optional | ✅ Match |
attachments | ✅ Optional | ✅ Optional | ✅ Match |
internalNotes | ✅ Optional | ✅ Optional | ✅ Match |
Status Values
Seeding & API:
'open' | 'in_progress' | 'resolved' | 'closed' | 'cancelled'
Documentation:
'open' | 'in_progress' | 'resolved' | 'closed'(missing'cancelled')
Priority Values
Seeding & API:
'low' | 'medium' | 'high' | 'urgent'
Documentation:
'low' | 'medium' | 'high' | 'urgent'✅ Match
Category Values
Seeding & API:
'technical' | 'billing' | 'general' | 'bug_report' | 'feature_request' | 'case_related' | 'guardian_onboarding'
Documentation:
- Not specified in detail
Issues Identified
1. CRITICAL: Field Name Inconsistency ⚠️⚠️⚠️
- Model/API: Uses
requesterIdandrequesterEmail - Firestore Rules: Uses
userId(notrequesterId) - Dashboard Page: Uses
userIdanduserEmail(notrequesterId/requesterEmail) - Impact: Firestore rules won't work correctly! Rules check
resource.data.userIdbut model storesrequesterId - Question: Should we use
userIdorrequesterId? - Recommendation: Standardize on
userId(matches Firestore rules and dashboard)
2. Collection Name Inconsistency ⚠️
- Backoffice: Uses
support_tickets(snake_case) - App Firestore Rules: Uses
supportTickets(camelCase) - Impact: Potential mismatch if app tries to access tickets
- Question: Which collection name should be used?
- Recommendation: Standardize on one name (likely
support_ticketsto match backoffice)
2. Missing cancelled Status in Documentation
- Code: Includes
'cancelled'status - Documentation: Missing
'cancelled'status - Recommendation: Update documentation to include
'cancelled'
3. Field Name Standardization
CRITICAL: Need to decide on field names:
- Option A: Use
userIdanduserEmail(matches Firestore rules) - Option B: Use
requesterIdandrequesterEmail(more descriptive) - Recommendation: Use
userIdanduserEmailto match existing Firestore rules
4. Requester ID vs Email
- Current:
requesterIdis required, but API allows creation with justrequesterEmail - Validation: API checks
requesterId || requesterEmail(at least one required) - Question: Should
requesterIdbe optional ifrequesterEmailis provided? - Recommendation: Make
requesterIdoptional, require at least one ofrequesterIdorrequesterEmail
5. Denormalized Names
- Current:
assignedToNameandrequesterNameare stored (denormalized) - Question: Should we keep denormalized names or fetch from users collection?
- Recommendation: Keep denormalized for performance (similar to case updates)
6. No Related Case/Guardian Reference
- Current: No field to link ticket to a specific case or guardian
- Question: Should tickets be linkable to cases/guardians?
- Recommendation: Add optional
caseIdandguardianIdfields for case-related tickets
7. No Message/Thread System
- Current: Single
descriptionfield, no conversation thread - Question: Should tickets support message threads (like conversations)?
- Recommendation: For now, keep simple. Can add thread system later if needed.
8. Tags Array
- Current:
tags?: string[](optional array) - Question: Should tags have a specific type/enum?
- Recommendation: Keep as flexible string array for now
Recommendations
1. CRITICAL: Fix Field Name Inconsistency
Recommendation: Use userId and userEmail instead of requesterId and requesterEmail
- Update model interfaces
- Update API routes
- Update seeding scripts
- Keep Firestore rules as-is (they already use
userId)
2. Standardize Collection Name
Recommendation: Use support_tickets everywhere
- Update app Firestore rules to use
support_tickets - Or update backoffice to use
supportTickets(less likely)
3. Update Status Type
Recommendation: Include 'cancelled' in all type definitions
type TicketStatus = 'open' | 'in_progress' | 'resolved' | 'closed' | 'cancelled';
4. Make userId Optional
Recommendation: Make userId optional
- Require at least one of
userIdoruserEmail - Validate in API:
if (!userId && !userEmail)
5. Add Related Entity References
Recommendation: Add optional fields for related entities
caseId?: string; // If ticket is related to a case
guardianId?: string; // If ticket is related to a guardian
6. Keep Denormalized Names
Recommendation: Keep assignedToName and userName (or requesterName if keeping that naming)
- Better performance for listing/displaying tickets
- Update when user name changes (if needed)
Questions for User
-
CRITICAL: Field Names: Should we use
userId/userEmailorrequesterId/requesterEmail?- My recommendation:
userId/userEmail(matches Firestore rules)
- My recommendation:
-
Collection Name: Should we use
support_ticketsorsupportTickets?- My recommendation:
support_tickets(matches backoffice)
- My recommendation:
-
User ID: Should
userIdbe optional ifuserEmailis provided?- My recommendation: Yes, make optional, require at least one
-
Related Entities: Should tickets be linkable to cases/guardians?
- My recommendation: Yes, add optional
caseIdandguardianId
- My recommendation: Yes, add optional
-
Status: Should we keep
'cancelled'status?- My recommendation: Yes, it's already in code
-
Tags: Should tags have specific types or stay flexible?
- My recommendation: Keep flexible for now
-
Message Thread: Should tickets support message threads?
- My recommendation: Keep simple for now, can add later