- Changed worktree setup command from npm to pnpm for improved package management. - Added SupportModule to app.module.ts and router.config.ts for better support case handling. - Refactored OrderEventsService to utilize OrderUpdateEventPayload for improved type safety. - Updated InvoicesList component to use INVOICE_STATUS for status filtering and improved type definitions. - Enhanced SimActions and SimDetailsCard components to utilize SimStatus for better state management. - Refactored Subscription components to leverage new utility functions for status handling and billing cycle labels. - Improved SupportCasesView with better state management and error handling. - Updated API query keys to include support cases for better data retrieval.
141 lines
4.6 KiB
TypeScript
141 lines
4.6 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import {
|
|
SUPPORT_CASE_CATEGORY,
|
|
SUPPORT_CASE_PRIORITY,
|
|
SUPPORT_CASE_STATUS,
|
|
supportCaseFilterSchema,
|
|
supportCaseListSchema,
|
|
type SupportCase,
|
|
type SupportCaseFilter,
|
|
type SupportCaseList,
|
|
type SupportCasePriority,
|
|
type SupportCaseStatus,
|
|
} from "@customer-portal/domain/support";
|
|
|
|
const OPEN_STATUSES: SupportCaseStatus[] = [
|
|
SUPPORT_CASE_STATUS.OPEN,
|
|
SUPPORT_CASE_STATUS.IN_PROGRESS,
|
|
SUPPORT_CASE_STATUS.WAITING_ON_CUSTOMER,
|
|
];
|
|
|
|
const RESOLVED_STATUSES: SupportCaseStatus[] = [
|
|
SUPPORT_CASE_STATUS.RESOLVED,
|
|
SUPPORT_CASE_STATUS.CLOSED,
|
|
];
|
|
|
|
const HIGH_PRIORITIES: SupportCasePriority[] = [
|
|
SUPPORT_CASE_PRIORITY.HIGH,
|
|
SUPPORT_CASE_PRIORITY.CRITICAL,
|
|
];
|
|
|
|
@Injectable()
|
|
export class SupportService {
|
|
// Placeholder dataset until Salesforce integration is ready
|
|
private readonly cases: SupportCase[] = [
|
|
{
|
|
id: 12001,
|
|
subject: "VPS Performance Issues",
|
|
status: SUPPORT_CASE_STATUS.IN_PROGRESS,
|
|
priority: SUPPORT_CASE_PRIORITY.HIGH,
|
|
category: SUPPORT_CASE_CATEGORY.TECHNICAL,
|
|
createdAt: "2025-08-14T10:30:00Z",
|
|
updatedAt: "2025-08-15T14:20:00Z",
|
|
lastReply: "2025-08-15T14:20:00Z",
|
|
description: "Experiencing slow response times on VPS server, CPU usage appears high.",
|
|
assignedTo: "Technical Support Team",
|
|
},
|
|
{
|
|
id: 12002,
|
|
subject: "Billing Question - Invoice #12345",
|
|
status: SUPPORT_CASE_STATUS.WAITING_ON_CUSTOMER,
|
|
priority: SUPPORT_CASE_PRIORITY.MEDIUM,
|
|
category: SUPPORT_CASE_CATEGORY.BILLING,
|
|
createdAt: "2025-08-13T16:45:00Z",
|
|
updatedAt: "2025-08-14T09:30:00Z",
|
|
lastReply: "2025-08-14T09:30:00Z",
|
|
description: "Need clarification on charges in recent invoice.",
|
|
assignedTo: "Billing Department",
|
|
},
|
|
{
|
|
id: 12003,
|
|
subject: "SSL Certificate Installation",
|
|
status: SUPPORT_CASE_STATUS.RESOLVED,
|
|
priority: SUPPORT_CASE_PRIORITY.LOW,
|
|
category: SUPPORT_CASE_CATEGORY.TECHNICAL,
|
|
createdAt: "2025-08-12T08:15:00Z",
|
|
updatedAt: "2025-08-12T15:45:00Z",
|
|
lastReply: "2025-08-12T15:45:00Z",
|
|
description: "Request assistance with SSL certificate installation on shared hosting.",
|
|
assignedTo: "Technical Support Team",
|
|
},
|
|
{
|
|
id: 12004,
|
|
subject: "Feature Request: Control Panel Enhancement",
|
|
status: SUPPORT_CASE_STATUS.OPEN,
|
|
priority: SUPPORT_CASE_PRIORITY.LOW,
|
|
category: SUPPORT_CASE_CATEGORY.FEATURE_REQUEST,
|
|
createdAt: "2025-08-11T13:20:00Z",
|
|
updatedAt: "2025-08-11T13:20:00Z",
|
|
description: "Would like to see improved backup management in the control panel.",
|
|
assignedTo: "Development Team",
|
|
},
|
|
{
|
|
id: 12005,
|
|
subject: "Server Migration Assistance",
|
|
status: SUPPORT_CASE_STATUS.CLOSED,
|
|
priority: SUPPORT_CASE_PRIORITY.MEDIUM,
|
|
category: SUPPORT_CASE_CATEGORY.TECHNICAL,
|
|
createdAt: "2025-08-10T11:00:00Z",
|
|
updatedAt: "2025-08-11T17:30:00Z",
|
|
lastReply: "2025-08-11T17:30:00Z",
|
|
description: "Need help migrating website from old server to new VPS.",
|
|
assignedTo: "Migration Team",
|
|
},
|
|
];
|
|
|
|
async listCases(rawFilters?: SupportCaseFilter): Promise<SupportCaseList> {
|
|
const filters = supportCaseFilterSchema.parse(rawFilters ?? {});
|
|
const filteredCases = this.applyFilters(this.cases, filters);
|
|
const result = {
|
|
cases: filteredCases,
|
|
summary: this.buildSummary(filteredCases),
|
|
};
|
|
return supportCaseListSchema.parse(result);
|
|
}
|
|
|
|
private applyFilters(cases: SupportCase[], filters: SupportCaseFilter): SupportCase[] {
|
|
const search = filters.search?.toLowerCase().trim();
|
|
return cases.filter(supportCase => {
|
|
if (filters.status && supportCase.status !== filters.status) {
|
|
return false;
|
|
}
|
|
if (filters.priority && supportCase.priority !== filters.priority) {
|
|
return false;
|
|
}
|
|
if (filters.category && supportCase.category !== filters.category) {
|
|
return false;
|
|
}
|
|
if (search) {
|
|
const haystack = `${supportCase.subject} ${supportCase.description} ${supportCase.id}`.toLowerCase();
|
|
if (!haystack.includes(search)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
private buildSummary(cases: SupportCase[]): SupportCaseList["summary"] {
|
|
const open = cases.filter(c => OPEN_STATUSES.includes(c.status)).length;
|
|
const highPriority = cases.filter(c => HIGH_PRIORITIES.includes(c.priority)).length;
|
|
const resolved = cases.filter(c => RESOLVED_STATUSES.includes(c.status)).length;
|
|
|
|
return {
|
|
total: cases.length,
|
|
open,
|
|
highPriority,
|
|
resolved,
|
|
};
|
|
}
|
|
}
|