Re_Figma_Code/src/pages/CreateRequest/utils/payloadBuilders.ts

114 lines
3.3 KiB
TypeScript

/**
* Utility functions for building API payloads
* Simplified: Backend auto-generates participants from approvers and spectators
*/
import { FormData, RequestTemplate } from '@/hooks/useCreateRequestForm';
import {
CreateWorkflowPayload,
UpdateWorkflowPayload,
} from '../types/createRequest.types';
import { buildApprovalLevels } from './approvalLevelBuilders';
/**
* Build create workflow payload
* Backend will auto-generate participants array from approvers and spectators
*/
export function buildCreatePayload(
formData: FormData,
selectedTemplate: RequestTemplate | null,
user: any
): CreateWorkflowPayload {
// Filter out spectators who are also approvers (backend will handle validation)
const approverEmails = new Set(
(formData.approvers || []).map((a: any) => a?.email?.toLowerCase()).filter(Boolean)
);
const filteredSpectators = (formData.spectators || []).filter(
(s: any) => s?.email && !approverEmails.has(s.email.toLowerCase())
);
return {
templateId: selectedTemplate?.id || null,
templateType: selectedTemplate?.id === 'custom' ? 'CUSTOM' : 'TEMPLATE',
title: formData.title,
description: formData.description,
priorityUi: formData.priority === 'express' ? 'express' : 'standard',
approverCount: formData.approverCount || 1,
approvers: (formData.approvers || []).map((a: any) => ({
userId: a?.userId || '',
email: a?.email || '',
name: a?.name,
tat: a?.tat || '',
tatType: a?.tatType || 'hours',
})),
spectators: filteredSpectators.map((s) => ({
email: s?.email || '',
})),
// Note: participants array is auto-generated by backend
// No need to send it from frontend
};
}
/**
* Build update workflow payload
* Backend will auto-generate participants array from approvalLevels
*/
export function buildUpdatePayload(
formData: FormData,
user: any,
documentsToDelete: string[]
): UpdateWorkflowPayload {
const approvalLevels = buildApprovalLevels(
formData.approvers || [],
formData.approverCount || 1
);
return {
title: formData.title,
description: formData.description,
priority: formData.priority === 'express' ? 'EXPRESS' : 'STANDARD',
approvalLevels,
// Note: participants array is auto-generated by backend
deleteDocumentIds: documentsToDelete.length > 0 ? documentsToDelete : undefined,
};
}
/**
* Validate approvers before submission
* Simplified: Only check for valid emails (backend handles user lookup)
*/
export function validateApproversForSubmission(
approvers: any[],
approverCount: number
): { valid: boolean; message?: string } {
const approversToCheck = approvers.slice(0, approverCount);
// Check if all approvers have valid emails
const hasMissingEmails = approversToCheck.some(
(a: any) => !a?.email || !a.email.trim()
);
if (hasMissingEmails) {
return {
valid: false,
message: 'Please provide email addresses for all approvers.',
};
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const hasInvalidEmails = approversToCheck.some(
(a: any) => !emailRegex.test(a?.email || '')
);
if (hasInvalidEmails) {
return {
valid: false,
message: 'Please provide valid email addresses for all approvers.',
};
}
return { valid: true };
}