barsa 465a62a3e8 Refactor Domain Mappings and Update Import Paths
- Removed the domain mappings module, consolidating related types and schemas into the id-mappings feature.
- Updated import paths across the BFF to reflect the new structure, ensuring compliance with import hygiene rules.
- Cleaned up unused files and optimized the codebase for better maintainability and clarity.
2025-12-26 17:27:22 +09:00

127 lines
3.7 KiB
TypeScript

/**
* ID Mapping Domain - Validation
*
* Pure business validation functions for ID mappings.
* These functions contain no infrastructure dependencies (no DB, no HTTP, no logging).
*/
import type {
CreateMappingRequest,
UpdateMappingRequest,
UserIdMapping,
MappingValidationResult,
} from "./contract.js";
/**
* Check if a mapping request has optional Salesforce account ID
* This is used for warnings, not validation errors
*/
export function checkMappingCompleteness(request: CreateMappingRequest | UserIdMapping): string[] {
const warnings: string[] = [];
if (!request.sfAccountId) {
warnings.push("Salesforce account ID not provided - mapping will be incomplete");
}
return warnings;
}
/**
* Validate no conflicts exist with existing mappings
* Business rule: Each userId, whmcsClientId should be unique
*
* Note: This assumes the request has already been validated by schema.
* Use createMappingRequestSchema.parse() before calling this function.
*/
export function validateNoConflicts(
request: CreateMappingRequest,
existingMappings: UserIdMapping[]
): MappingValidationResult {
const errors: string[] = [];
const warnings: string[] = [];
// Check for conflicts
const duplicateUser = existingMappings.find(m => m.userId === request.userId);
if (duplicateUser) {
errors.push(`User ${request.userId} already has a mapping`);
}
const duplicateWhmcs = existingMappings.find(m => m.whmcsClientId === request.whmcsClientId);
if (duplicateWhmcs) {
errors.push(
`WHMCS client ${request.whmcsClientId} is already mapped to user ${duplicateWhmcs.userId}`
);
}
if (request.sfAccountId) {
const duplicateSf = existingMappings.find(m => m.sfAccountId === request.sfAccountId);
if (duplicateSf) {
warnings.push(
`Salesforce account ${request.sfAccountId} is already mapped to user ${duplicateSf.userId}`
);
}
}
return { isValid: errors.length === 0, errors, warnings };
}
/**
* Validate deletion constraints
* Business rule: Warn about data access impacts
*
* Note: This assumes the mapping has already been validated.
* This function adds business warnings about the impact of deletion.
*/
export function validateDeletion(
mapping: UserIdMapping | null | undefined
): MappingValidationResult {
const errors: string[] = [];
const warnings: string[] = [];
if (!mapping) {
errors.push("Cannot delete non-existent mapping");
return { isValid: false, errors, warnings };
}
warnings.push("Deleting this mapping will prevent access to WHMCS/Salesforce data for this user");
if (mapping.sfAccountId) {
warnings.push(
"This mapping includes Salesforce integration - deletion will affect case management"
);
}
return { isValid: true, errors, warnings };
}
/**
* Sanitize and normalize a create mapping request
*
* Note: This performs basic string trimming before validation.
* The schema handles validation; this is purely for data cleanup.
*/
export function sanitizeCreateRequest(request: CreateMappingRequest): CreateMappingRequest {
return {
userId: request.userId?.trim(),
whmcsClientId: request.whmcsClientId,
sfAccountId: request.sfAccountId?.trim() || undefined,
};
}
/**
* Sanitize and normalize an update mapping request
*
* Note: This performs basic string trimming before validation.
* The schema handles validation; this is purely for data cleanup.
*/
export function sanitizeUpdateRequest(request: UpdateMappingRequest): UpdateMappingRequest {
const sanitized: Partial<UpdateMappingRequest> = {};
if (request.whmcsClientId !== undefined) {
sanitized.whmcsClientId = request.whmcsClientId;
}
if (request.sfAccountId !== undefined) {
sanitized.sfAccountId = request.sfAccountId?.trim() || undefined;
}
return sanitized;
}