Assist_Design/apps/bff/src/modules/support/support.service.ts
barsa 8c89109213 Update worktree setup and enhance BFF with SupportModule integration
- 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.
2025-11-18 14:06:27 +09:00

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,
};
}
}