diff options
Diffstat (limited to 'app/api')
| -rw-r--r-- | app/api/basicContract/create-revision/route.ts | 75 | ||||
| -rw-r--r-- | app/api/files/[...path]/route.ts | 9 | ||||
| -rw-r--r-- | app/api/upload/basicContract/complete/route.ts | 25 |
3 files changed, 94 insertions, 15 deletions
diff --git a/app/api/basicContract/create-revision/route.ts b/app/api/basicContract/create-revision/route.ts new file mode 100644 index 00000000..69dc4c8f --- /dev/null +++ b/app/api/basicContract/create-revision/route.ts @@ -0,0 +1,75 @@ +// app/api/basicContract/create-revision/route.ts +import { NextRequest, NextResponse } from "next/server"; +import { unstable_noStore } from "next/cache"; +import { z } from "zod"; +import { getErrorMessage } from "@/lib/handle-error"; +import { createBasicContractTemplateRevision } from "@/lib/basic-contract/service"; + +// 리비전 생성 스키마 +const createRevisionSchema = z.object({ + baseTemplateId: z.string().uuid(), + templateName: z.string().min(1), + revision: z.number().int().min(1), + legalReviewRequired: z.boolean(), + shipBuildingApplicable: z.boolean(), + windApplicable: z.boolean(), + pcApplicable: z.boolean(), + nbApplicable: z.boolean(), + rcApplicable: z.boolean(), + gyApplicable: z.boolean(), + sysApplicable: z.boolean(), + infraApplicable: z.boolean(), + fileName: z.string().min(1), + filePath: z.string().min(1), +}); + +export async function POST(request: NextRequest) { + unstable_noStore(); + + try { + // 요청 본문 파싱 + const body = await request.json(); + const validatedData = createRevisionSchema.parse(body); + + // 같은 템플릿 이름에 대해 리비전이 이미 존재하는지 확인하는 로직은 + // 서비스 함수에서 처리됨 + + // 새 리비전 생성 + const { data: newRevision, error } = await createBasicContractTemplateRevision(validatedData); + + if (error) { + return NextResponse.json( + { success: false, error }, + { status: 400 } + ); + } + + return NextResponse.json({ + success: true, + data: newRevision, + message: `${validatedData.templateName} v${validatedData.revision} 리비전이 성공적으로 생성되었습니다.` + }); + + } catch (error) { + console.error("Create revision API error:", error); + + if (error instanceof z.ZodError) { + return NextResponse.json( + { + success: false, + error: "입력 데이터가 올바르지 않습니다.", + details: error.errors + }, + { status: 400 } + ); + } + + return NextResponse.json( + { + success: false, + error: getErrorMessage(error) + }, + { status: 500 } + ); + } +}
\ No newline at end of file diff --git a/app/api/files/[...path]/route.ts b/app/api/files/[...path]/route.ts index a3bd67af..c9d530de 100644 --- a/app/api/files/[...path]/route.ts +++ b/app/api/files/[...path]/route.ts @@ -36,7 +36,14 @@ const isAllowedPath = (requestedPath: string): boolean => { 'vendorFormReportSample', 'vendorFormData', 'uploads', - 'tech-sales' + 'tech-sales', + 'techsales-rfq', + 'tech-vendors', + 'vendor-investigation', + 'vendor-responses', + 'vendor-evaluation', + 'vendor-evaluation-submit', + 'vendor-attachments', ]; return allowedPaths.some(allowed => diff --git a/app/api/upload/basicContract/complete/route.ts b/app/api/upload/basicContract/complete/route.ts index 6398c5eb..b22e99f1 100644 --- a/app/api/upload/basicContract/complete/route.ts +++ b/app/api/upload/basicContract/complete/route.ts @@ -1,27 +1,24 @@ import { NextRequest, NextResponse } from 'next/server'; import { createBasicContractTemplate } from '@/lib/basic-contract/service'; import { revalidatePath ,revalidateTag} from 'next/cache'; +import { createBasicContractTemplateSchema } from '@/lib/basic-contract/validations'; export async function POST(request: NextRequest) { try { - const { templateName,validityPeriod, status, fileName, filePath } = await request.json(); + const json = await request.json(); + const parsed = createBasicContractTemplateSchema.safeParse(json); - if (!templateName || !fileName || !filePath) { - return NextResponse.json({ success: false, error: '필수 정보가 누락되었습니다' }, { status: 400 }); + if (!parsed.success) { + return NextResponse.json( + { success: false, error: parsed.error.flatten() }, + { status: 400 } + ); } - - // DB에 저장 - const { data, error } = await createBasicContractTemplate({ - templateName, - validityPeriod, - status, - fileName, - filePath - }); - + + const { data, error } = await createBasicContractTemplate(parsed.data); + revalidatePath('/evcp/basic-contract-templates'); - revalidatePath('/'); // 루트 경로 무효화도 시도 revalidateTag("basic-contract-templates"); if (error) { |
