Skip to main content

Support Ticket Data Model Analysis

Current State Comparison

Backoffice Code (seeding & API)

FieldSeeding ScriptAPI RouteStatus
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 requesterId and requesterEmail
  • Firestore Rules: Uses userId (not requesterId)
  • Dashboard Page: Uses userId and userEmail (not requesterId/requesterEmail)
  • Impact: Firestore rules won't work correctly! Rules check resource.data.userId but model stores requesterId
  • Question: Should we use userId or requesterId?
  • 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_tickets to 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 userId and userEmail (matches Firestore rules)
  • Option B: Use requesterId and requesterEmail (more descriptive)
  • Recommendation: Use userId and userEmail to match existing Firestore rules

4. Requester ID vs Email

  • Current: requesterId is required, but API allows creation with just requesterEmail
  • Validation: API checks requesterId || requesterEmail (at least one required)
  • Question: Should requesterId be optional if requesterEmail is provided?
  • Recommendation: Make requesterId optional, require at least one of requesterId or requesterEmail

5. Denormalized Names

  • Current: assignedToName and requesterName are stored (denormalized)
  • Question: Should we keep denormalized names or fetch from users collection?
  • Recommendation: Keep denormalized for performance (similar to case updates)
  • Current: No field to link ticket to a specific case or guardian
  • Question: Should tickets be linkable to cases/guardians?
  • Recommendation: Add optional caseId and guardianId fields for case-related tickets

7. No Message/Thread System

  • Current: Single description field, 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 userId or userEmail
  • Validate in API: if (!userId && !userEmail)

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

  1. CRITICAL: Field Names: Should we use userId/userEmail or requesterId/requesterEmail?

    • My recommendation: userId/userEmail (matches Firestore rules)
  2. Collection Name: Should we use support_tickets or supportTickets?

    • My recommendation: support_tickets (matches backoffice)
  3. User ID: Should userId be optional if userEmail is provided?

    • My recommendation: Yes, make optional, require at least one
  4. Related Entities: Should tickets be linkable to cases/guardians?

    • My recommendation: Yes, add optional caseId and guardianId
  5. Status: Should we keep 'cancelled' status?

    • My recommendation: Yes, it's already in code
  6. Tags: Should tags have specific types or stay flexible?

    • My recommendation: Keep flexible for now
  7. Message Thread: Should tickets support message threads?

    • My recommendation: Keep simple for now, can add later