2025-11-26 16:36:06 +09:00
|
|
|
/**
|
|
|
|
|
* Support Domain - Salesforce Provider Mapper
|
|
|
|
|
*
|
|
|
|
|
* Transform functions to convert raw Salesforce Case records to domain types.
|
|
|
|
|
*/
|
|
|
|
|
|
2025-12-10 15:22:10 +09:00
|
|
|
import { supportCaseSchema, type SupportCase } from "../../schema.js";
|
|
|
|
|
import type { SalesforceCaseRecord } from "./raw.types.js";
|
2025-11-26 16:36:06 +09:00
|
|
|
import {
|
|
|
|
|
getStatusDisplayLabel,
|
|
|
|
|
getPriorityDisplayLabel,
|
|
|
|
|
SALESFORCE_CASE_STATUS,
|
|
|
|
|
SALESFORCE_CASE_PRIORITY,
|
2025-12-10 15:22:10 +09:00
|
|
|
} from "./raw.types.js";
|
2025-11-26 16:36:06 +09:00
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Helper Functions
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Safely coerce a value to string or return undefined
|
|
|
|
|
*/
|
|
|
|
|
function ensureString(value: unknown): string | undefined {
|
|
|
|
|
if (typeof value === "string" && value.length > 0) {
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get current ISO timestamp
|
|
|
|
|
*/
|
|
|
|
|
function nowIsoString(): string {
|
|
|
|
|
return new Date().toISOString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Transform Functions
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transform a raw Salesforce Case record to a portal SupportCase.
|
|
|
|
|
*
|
|
|
|
|
* Converts Salesforce API values (often in Japanese) to portal display labels (English).
|
|
|
|
|
*
|
|
|
|
|
* @param record - Raw Salesforce Case record from SOQL query
|
|
|
|
|
* @returns Validated SupportCase domain object
|
|
|
|
|
*/
|
2025-12-25 17:30:02 +09:00
|
|
|
export function transformSalesforceCaseToSupportCase(record: SalesforceCaseRecord): SupportCase {
|
2025-11-26 16:36:06 +09:00
|
|
|
// Get raw values
|
|
|
|
|
const rawStatus = ensureString(record.Status) ?? SALESFORCE_CASE_STATUS.NEW;
|
|
|
|
|
const rawPriority = ensureString(record.Priority) ?? SALESFORCE_CASE_PRIORITY.MEDIUM;
|
|
|
|
|
|
|
|
|
|
return supportCaseSchema.parse({
|
|
|
|
|
id: record.Id,
|
|
|
|
|
caseNumber: record.CaseNumber,
|
|
|
|
|
subject: ensureString(record.Subject) ?? "",
|
|
|
|
|
// Convert Japanese SF values to English display labels
|
|
|
|
|
status: getStatusDisplayLabel(rawStatus),
|
|
|
|
|
priority: getPriorityDisplayLabel(rawPriority),
|
|
|
|
|
category: ensureString(record.Type) ?? null,
|
|
|
|
|
description: ensureString(record.Description) ?? "",
|
|
|
|
|
createdAt: ensureString(record.CreatedDate) ?? nowIsoString(),
|
|
|
|
|
updatedAt: ensureString(record.LastModifiedDate) ?? nowIsoString(),
|
|
|
|
|
closedAt: ensureString(record.ClosedDate) ?? null,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transform multiple Salesforce Case records to SupportCase array.
|
|
|
|
|
*
|
|
|
|
|
* @param records - Array of raw Salesforce Case records
|
|
|
|
|
* @returns Array of validated SupportCase domain objects
|
|
|
|
|
*/
|
|
|
|
|
export function transformSalesforceCasesToSupportCases(
|
|
|
|
|
records: SalesforceCaseRecord[]
|
|
|
|
|
): SupportCase[] {
|
|
|
|
|
return records.map(transformSalesforceCaseToSupportCase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build the SOQL SELECT fields for Case queries.
|
|
|
|
|
*
|
|
|
|
|
* Standard Salesforce Case fields based on org configuration.
|
|
|
|
|
* Note: Type field is not accessible via API in this org.
|
|
|
|
|
*
|
|
|
|
|
* @param additionalFields - Optional additional fields to include
|
|
|
|
|
* @returns Array of field names for SOQL SELECT clause
|
|
|
|
|
*/
|
|
|
|
|
export function buildCaseSelectFields(additionalFields: string[] = []): string[] {
|
|
|
|
|
const baseFields = [
|
|
|
|
|
// Core identifiers
|
|
|
|
|
"Id",
|
|
|
|
|
"CaseNumber",
|
|
|
|
|
|
|
|
|
|
// Case content
|
|
|
|
|
"Subject",
|
|
|
|
|
"Description",
|
|
|
|
|
|
|
|
|
|
// Picklist fields
|
|
|
|
|
"Status",
|
|
|
|
|
"Priority",
|
|
|
|
|
"Origin",
|
|
|
|
|
|
|
|
|
|
// Relationships
|
|
|
|
|
"AccountId",
|
|
|
|
|
"ContactId",
|
|
|
|
|
"OwnerId",
|
|
|
|
|
|
|
|
|
|
// Timestamps
|
|
|
|
|
"CreatedDate",
|
|
|
|
|
"LastModifiedDate",
|
|
|
|
|
"ClosedDate",
|
|
|
|
|
|
|
|
|
|
// Flags
|
|
|
|
|
"IsEscalated",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return [...new Set([...baseFields, ...additionalFields])];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a SOQL query for fetching cases for an account.
|
|
|
|
|
*
|
|
|
|
|
* @param accountId - Salesforce Account ID
|
|
|
|
|
* @param origin - Case origin to filter by (e.g., "Portal Website")
|
|
|
|
|
* @param additionalFields - Optional additional fields to include
|
|
|
|
|
* @returns SOQL query string
|
|
|
|
|
*/
|
|
|
|
|
export function buildCasesForAccountQuery(
|
|
|
|
|
accountId: string,
|
|
|
|
|
origin: string,
|
|
|
|
|
additionalFields: string[] = []
|
|
|
|
|
): string {
|
|
|
|
|
const fields = buildCaseSelectFields(additionalFields).join(", ");
|
|
|
|
|
return `
|
|
|
|
|
SELECT ${fields}
|
|
|
|
|
FROM Case
|
|
|
|
|
WHERE AccountId = '${accountId}' AND Origin = '${origin}'
|
|
|
|
|
ORDER BY CreatedDate DESC
|
|
|
|
|
LIMIT 100
|
|
|
|
|
`.trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build a SOQL query for fetching a single case by ID.
|
|
|
|
|
*
|
|
|
|
|
* @param caseId - Salesforce Case ID
|
|
|
|
|
* @param accountId - Salesforce Account ID (for ownership validation)
|
|
|
|
|
* @param origin - Case origin to filter by
|
|
|
|
|
* @param additionalFields - Optional additional fields to include
|
|
|
|
|
* @returns SOQL query string
|
|
|
|
|
*/
|
|
|
|
|
export function buildCaseByIdQuery(
|
|
|
|
|
caseId: string,
|
|
|
|
|
accountId: string,
|
|
|
|
|
origin: string,
|
|
|
|
|
additionalFields: string[] = []
|
|
|
|
|
): string {
|
|
|
|
|
const fields = buildCaseSelectFields(additionalFields).join(", ");
|
|
|
|
|
return `
|
|
|
|
|
SELECT ${fields}
|
|
|
|
|
FROM Case
|
|
|
|
|
WHERE Id = '${caseId}' AND AccountId = '${accountId}' AND Origin = '${origin}'
|
|
|
|
|
LIMIT 1
|
|
|
|
|
`.trim();
|
|
|
|
|
}
|