summaryrefslogtreecommitdiff
path: root/app/api/swp
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/swp')
-rw-r--r--app/api/swp/upload/route.ts57
1 files changed, 42 insertions, 15 deletions
diff --git a/app/api/swp/upload/route.ts b/app/api/swp/upload/route.ts
index d17fcff7..b38c4ff4 100644
--- a/app/api/swp/upload/route.ts
+++ b/app/api/swp/upload/route.ts
@@ -26,7 +26,8 @@ interface InBoxFileInfo {
}
/**
- * 파일명 파싱: [OWN_DOC_NO]_[REV_NO]_[STAGE]_[YYYYMMDDhhmmss].[확장자]
+ * 파일명 파싱: [DOC_NO]_[REV_NO]_[STAGE]_[자유-파일명].[확장자]
+ * 자유 파일명에는 언더스코어가 포함될 수 있음
*/
function parseFileName(fileName: string) {
const lastDotIndex = fileName.lastIndexOf(".");
@@ -35,23 +36,38 @@ function parseFileName(fileName: string) {
const parts = nameWithoutExt.split("_");
- if (parts.length !== 4) {
+ // 최소 4개 파트 필요: docNo, revNo, stage, fileName
+ if (parts.length < 4) {
throw new Error(
`잘못된 파일명 형식입니다: ${fileName}. ` +
- `형식: [OWN_DOC_NO]_[REV_NO]_[STAGE]_[YYYYMMDDhhmmss].확장자`
+ `형식: [DOC_NO]_[REV_NO]_[STAGE]_[파일명].확장자 (언더스코어 최소 3개 필요)`
);
}
- const [ownDocNo, revNo, stage, timestamp] = parts;
+ // 앞에서부터 3개는 고정: docNo, revNo, stage
+ const ownDocNo = parts[0];
+ const revNo = parts[1];
+ const stage = parts[2];
+
+ // 나머지는 자유 파일명 (언더스코어 포함 가능)
+ const customFileName = parts.slice(3).join("_");
- if (!/^\d{14}$/.test(timestamp)) {
- throw new Error(
- `잘못된 타임스탬프 형식입니다: ${timestamp}. ` +
- `YYYYMMDDhhmmss 형식이어야 합니다.`
- );
- }
+ return { ownDocNo, revNo, stage, fileName: customFileName, extension };
+}
- return { ownDocNo, revNo, stage, timestamp, extension };
+/**
+ * 현재 시간을 YYYYMMDDhhmmss 형식으로 반환
+ */
+function generateTimestamp(): string {
+ const now = new Date();
+ const year = now.getFullYear().toString();
+ const month = (now.getMonth() + 1).toString().padStart(2, "0");
+ const day = now.getDate().toString().padStart(2, "0");
+ const hours = now.getHours().toString().padStart(2, "0");
+ const minutes = now.getMinutes().toString().padStart(2, "0");
+ const seconds = now.getSeconds().toString().padStart(2, "0");
+
+ return `${year}${month}${day}${hours}${minutes}${seconds}`;
}
/**
@@ -171,6 +187,10 @@ export async function POST(request: NextRequest) {
const inBoxFileInfos: InBoxFileInfo[] = [];
const swpMountDir = process.env.SWP_MOUNT_DIR || "/mnt/swp-smb-dir/";
+
+ // 업로드 시점의 timestamp 생성 (모든 파일에 동일한 timestamp 사용)
+ const uploadTimestamp = generateTimestamp();
+ console.log(`[upload] 업로드 타임스탬프 생성: ${uploadTimestamp}`);
for (const file of files) {
try {
@@ -178,8 +198,8 @@ export async function POST(request: NextRequest) {
const parsed = parseFileName(file.name);
console.log(`[upload] 파일명 파싱:`, parsed);
- // 네트워크 경로 생성
- const networkPath = path.join(swpMountDir, projNo, cpyCd, parsed.timestamp, file.name);
+ // 네트워크 경로 생성 (timestamp를 경로에만 사용)
+ const networkPath = path.join(swpMountDir, projNo, cpyCd, uploadTimestamp, file.name);
// 파일 중복 체크
try {
@@ -245,8 +265,8 @@ export async function POST(request: NextRequest) {
matchesOriginal: buffer.slice(0, 20).equals(verifyBuffer.slice(0, 20))
});
- // InBox 파일 정보 준비
- const fldPath = `\\\\${projNo}\\\\${cpyCd}\\\\${parsed.timestamp}`;
+ // InBox 파일 정보 준비 (FLD_PATH에 업로드 timestamp 사용)
+ const fldPath = `\\\\${projNo}\\\\${cpyCd}\\\\${uploadTimestamp}`;
inBoxFileInfos.push({
CPY_CD: cpyCd,
@@ -339,12 +359,19 @@ export async function POST(request: NextRequest) {
console.log(`[upload] 완료:`, { success, message, result });
+ // 동기화 완료 정보 추가
+ const syncCompleted = result.successCount > 0;
+ const syncTimestamp = new Date().toISOString();
+
return NextResponse.json({
success,
message,
successCount: result.successCount,
failedCount: result.failedCount,
details: result.details,
+ syncCompleted,
+ syncTimestamp,
+ affectedVndrCd: vndrCd,
});
} catch (error) {
console.error("[upload] 오류:", error);