85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import type { DredgingSaveGroup } from "./types";
|
|
import { createDredgingClientUuid } from "../lib/uuid";
|
|
|
|
/** 공통 첨부 업로드가 완료된 사진의 서버 식별자다. */
|
|
export type AttachmentReference = { atflCd: string; atflId: string };
|
|
|
|
/** 화면 draft에서 기존 등록 DTO에 해당하는 필드만 명시적으로 추출한다. */
|
|
const buildRegistrationBody = (
|
|
groups: DredgingSaveGroup[],
|
|
attachments: Map<string, AttachmentReference>,
|
|
requireAttachments: boolean,
|
|
) => ({
|
|
dredgingDate: groups[0]?.dredgingDate,
|
|
groups: groups.map((group, groupIndex) => ({
|
|
groupSn: groupIndex + 1,
|
|
registrationMode: group.registrationMode,
|
|
location: {
|
|
source: group.locationSource,
|
|
longitude: group.location.longitude,
|
|
latitude: group.location.latitude,
|
|
},
|
|
expectedPipe: group.pipe ? {
|
|
fid: group.pipe.fid,
|
|
mngInstCd: group.pipe.mngInstCd,
|
|
fcltMngNo: group.pipe.fcltMngNo,
|
|
} : null,
|
|
photos: group.photos.map((photo) => {
|
|
const attachment = attachments.get(photo.key);
|
|
if (!attachment && requireAttachments) {
|
|
throw new Error(`${photo.file.name}의 첨부 식별자가 없습니다.`);
|
|
}
|
|
return {
|
|
atflCd: attachment?.atflCd,
|
|
atflId: attachment?.atflId,
|
|
originalFileName: photo.file.name,
|
|
clientCapturedAt: photo.metadata.capturedAt,
|
|
clientLongitude: photo.metadata.location?.longitude ?? null,
|
|
clientLatitude: photo.metadata.location?.latitude ?? null,
|
|
};
|
|
}),
|
|
})),
|
|
});
|
|
|
|
/** 기존 POST /v1/dredging/registrations의 요청 body를 그대로 표현한다. */
|
|
export type DredgingRegistrationRequest = ReturnType<
|
|
typeof buildRegistrationBody
|
|
> & {
|
|
clientRequestId: string;
|
|
};
|
|
|
|
/**
|
|
* 모달을 연 한 번의 등록 세션이 전송 payload별 중복방지 ID를 소유한다.
|
|
* 응답 유실 후 같은 입력 재시도와 수정 후 원래 입력 복원은 같은 ID를 쓴다.
|
|
* 날짜·관로·위치·사진 등 실제 전송값이 바뀌면 새 ID를 발급한다.
|
|
* 화면 그룹 ID, 관경 표시값, 선택 탭 등 비전송 상태는 등록 의도를 바꾸지 않는다.
|
|
*/
|
|
export const createDredgingRegistrationSession = (
|
|
createId: () => string = createDredgingClientUuid,
|
|
) => {
|
|
// 세션 밖으로 공유하지 않으며 모달을 다시 열 때 새 Map으로 교체한다.
|
|
const requestIds = new Map<string, string>();
|
|
return {
|
|
/** 첨부 식별자까지 확정된 동일 payload에 항상 같은 요청 ID를 부여한다. */
|
|
prepare: (
|
|
groups: DredgingSaveGroup[],
|
|
attachments: Map<string, AttachmentReference>,
|
|
// FE 선행 모의 모드만 첨부 업로드 없이 payload 구성 검증을 허용한다.
|
|
requireAttachments = true,
|
|
): DredgingRegistrationRequest => {
|
|
const body = buildRegistrationBody(
|
|
groups,
|
|
attachments,
|
|
requireAttachments,
|
|
);
|
|
const signature = JSON.stringify(body);
|
|
let clientRequestId = requestIds.get(signature);
|
|
if (!clientRequestId) {
|
|
clientRequestId = createId();
|
|
requestIds.set(signature, clientRequestId);
|
|
}
|
|
return { clientRequestId, ...body };
|
|
},
|
|
};
|
|
};
|