From 64b16282fea10ed94dc1c4f1b81703c4875d9f7e Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Mon, 10 Nov 2025 17:57:27 +0900 Subject: (김준회) taxId 필수값에서 제거 (MDG에서 사업자번호(세금번호) 없는 벤더가 들어오기 때문) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/auth/signup-with-vendor/route.ts | 25 ++++++++++++++----------- app/api/vendors/route.ts | 30 ++++++++++++++++-------------- db/schema/vendors.ts | 6 ++++-- lib/soap/mdg/mapper/vendor-mapper.ts | 20 +++++++++----------- 4 files changed, 43 insertions(+), 38 deletions(-) diff --git a/app/api/auth/signup-with-vendor/route.ts b/app/api/auth/signup-with-vendor/route.ts index 4585778c..f8c2c6ee 100644 --- a/app/api/auth/signup-with-vendor/route.ts +++ b/app/api/auth/signup-with-vendor/route.ts @@ -408,17 +408,20 @@ export async function POST(request: NextRequest) { ) } - const existingVendor = await db - .select({ id: vendors.id }) - .from(vendors) - .where(eq(vendors.taxId, vendor.taxId)) - .limit(1) - - if (existingVendor.length > 0) { - return NextResponse.json( - { error: '이미 등록된 사업자등록번호입니다.' }, - { status: 400 } - ) + // Check for existing taxId (only if taxId is provided) + if (vendor.taxId && vendor.taxId.trim()) { + const existingVendor = await db + .select({ id: vendors.id }) + .from(vendors) + .where(eq(vendors.taxId, vendor.taxId)) + .limit(1) + + if (existingVendor.length > 0) { + return NextResponse.json( + { error: '이미 등록된 사업자등록번호입니다.' }, + { status: 400 } + ) + } } // 클라이언트 정보 추출 diff --git a/app/api/vendors/route.ts b/app/api/vendors/route.ts index 760f183e..27b79385 100644 --- a/app/api/vendors/route.ts +++ b/app/api/vendors/route.ts @@ -162,20 +162,22 @@ export async function POST(request: NextRequest) { ) } - // Check for existing taxId - const existingVendor = await db - .select({ id: vendors.id }) - .from(vendors) - .where(eq(vendors.taxId, vendorData.taxId)) - .limit(1) - - if (existingVendor.length > 0) { - return NextResponse.json( - { - error: `이미 등록된 사업자등록번호입니다. (Tax ID ${vendorData.taxId} already exists in the system)` - }, - { status: 400 } - ) + // Check for existing taxId (only if taxId is provided) + if (vendorData.taxId && vendorData.taxId.trim()) { + const existingVendor = await db + .select({ id: vendors.id }) + .from(vendors) + .where(eq(vendors.taxId, vendorData.taxId)) + .limit(1) + + if (existingVendor.length > 0) { + return NextResponse.json( + { + error: `이미 등록된 사업자등록번호입니다. (Tax ID ${vendorData.taxId} already exists in the system)` + }, + { status: 400 } + ) + } } // Create vendor and handle files in transaction diff --git a/db/schema/vendors.ts b/db/schema/vendors.ts index fbf094cc..25255379 100644 --- a/db/schema/vendors.ts +++ b/db/schema/vendors.ts @@ -21,7 +21,8 @@ export const vendors = pgTable("vendors", { // 벤더 코드 유니크 아니어도 괜찮은지? vendorCode: varchar("vendor_code", { length: 100 }), //사업자번호이고, 법인등록번호는 corporateRegistrationNumber - taxId: varchar("tax_id", { length: 100 }).notNull(), + // MDG에서 taxId 없이 수신되는 벤더도 저장 가능하도록 nullable로 변경 + taxId: varchar("tax_id", { length: 100 }), address: text("address"), addressDetail: text("address_detail"), postalCode: varchar("postal_code", { length: 20 }), @@ -233,7 +234,8 @@ export const vendorCandidates = pgTable("vendor_candidates", { contactEmail: varchar("contact_email", { length: 255 }), contactPhone: varchar("contact_phone", { length: 50 }), - taxId: varchar("tax_id", { length: 100 }).notNull(), + // 후보 업체는 사업자번호가 없을 수 있으므로 nullable로 변경 + taxId: varchar("tax_id", { length: 100 }), address: text("address"), country: varchar("country", { length: 100 }), diff --git a/lib/soap/mdg/mapper/vendor-mapper.ts b/lib/soap/mdg/mapper/vendor-mapper.ts index 1bb542e0..c9824785 100644 --- a/lib/soap/mdg/mapper/vendor-mapper.ts +++ b/lib/soap/mdg/mapper/vendor-mapper.ts @@ -307,7 +307,7 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise * - id: serial (자동) * - vendorName: varchar (필수) * - vendorCode: varchar - * - taxId: varchar (필수) + * - taxId: varchar (nullable - MDG에서 없이 수신될 수 있음) * - address: text * - addressDetail: text * - postalCode: varchar @@ -342,15 +342,6 @@ function mapMDGToVendor(mdgVendorData: MDGVendorData): VendorData | null { return null; } - // taxId가 없으면 처리하지 않음 (vendors 테이블에서 필수) - if (!mdgVendorData.BIZ_PTNR_TX_NO) { - debugError('BIZ_PTNR_TX_NO가 없는 벤더 데이터', { - vndrCode: mdgVendorData.VNDRCD, - reason: '필수 필드 누락: taxId' - }); - return null; - } - // vendorName이 없으면 처리하지 않음 (vendors 테이블에서 필수) if (!mdgVendorData.VNDRNM_1) { debugError('VNDRNM_1이 없는 벤더 데이터', { @@ -360,10 +351,17 @@ function mapMDGToVendor(mdgVendorData: MDGVendorData): VendorData | null { return null; } + // taxId가 없는 경우 경고 로그만 출력 (nullable이므로 처리 계속) + if (!mdgVendorData.BIZ_PTNR_TX_NO) { + debugWarn('BIZ_PTNR_TX_NO가 없는 벤더 데이터 - taxId null로 저장됨', { + vndrCode: mdgVendorData.VNDRCD + }); + } + debugSuccess('필수 필드 검증 통과', { vndrCode: mdgVendorData.VNDRCD, vendorName: mdgVendorData.VNDRNM_1, - taxId: mdgVendorData.BIZ_PTNR_TX_NO + taxId: mdgVendorData.BIZ_PTNR_TX_NO || 'null' }); // 주소 상세 정보 결합 -- cgit v1.2.3