/** * seedVendorRevisions.ts * - revisions 테이블에 vendor 업로더 타입의 테스트 데이터 삽입 * - issueStageId + revision 조합이 유니크해야 함 */ import db from "@/db/db" import { faker } from "@faker-js/faker" import { issueStages, revisions } from "../schema/vendorDocu" import { eq } from "drizzle-orm" // 하나의 스테이지당 리비전 개수 범위 const REV_MIN = 1 const REV_MAX = 2 // 가능한 리비전 코드 목록 const POSSIBLE_REVISIONS = ["A", "B", "C", "D", "E", "0", "1", "2", "3", "4"]; // 가능한 상태 목록 (vendor 타입에 적합한 상태들) const POSSIBLE_STATUSES = ["submitted", "in_review", "approved", "rejected"]; async function seedVendorRevisions() { try { console.log("Seeding vendor revisions started...") // 먼저 issueStages 테이블에서 모든 스테이지 정보 가져오기 const allStages = await db.select({ id: issueStages.id, }).from(issueStages) console.log(`Found ${allStages.length} stages to create vendor revisions for.`) if (allStages.length === 0) { console.warn("No stages found. Run seedIssueStages.ts first.") return } // 각 스테이지에 대해 리비전 생성 및 삽입 let totalRevisionsCreated = 0 // 배치 처리를 위한 설정 const BATCH_SIZE = 50 // 작은 배치 사이즈로 조정 (유니크 제약조건 때문에) let revisionBatch = [] // 각 스테이지 ID별로 이미 사용된 리비전 코드를 추적 const usedRevisions = new Map(); for (const stage of allStages) { // 이 스테이지에 사용할 수 있는 리비전 코드들 const availableRevisions = [...POSSIBLE_REVISIONS]; // 이미 사용된 리비전 코드들 가져오기 (DB에 저장된 것 확인) const existingRevs = await db.select({ revision: revisions.revision }) .from(revisions) .where(eq(revisions.issueStageId, stage.id)); // 이미 사용된 리비전 코드 제외 existingRevs.forEach(rev => { const index = availableRevisions.indexOf(rev.revision); if (index !== -1) { availableRevisions.splice(index, 1); } }); // 리비전 개수 계산 (가용 리비전 코드 수에 제한) const revCount = Math.min( faker.number.int({ min: REV_MIN, max: REV_MAX }), availableRevisions.length ); // 리비전 코드가 더 이상 없으면 스킵 if (revCount === 0) { console.warn(`No available revision codes for stage ${stage.id}, skipping...`); continue; } // 사용할 리비전 코드 무작위 선택 const selectedRevisions = faker.helpers.arrayElements(availableRevisions, revCount); for (const revisionCode of selectedRevisions) { // 랜덤 업체명 생성 const companyNames = ["ABC Engineering", "XYZ Construction", "Global Tech Solutions", "Mega Builders"]; const uploaderName = faker.helpers.maybe(() => { const name = faker.person.fullName(); const company = faker.helpers.arrayElement(companyNames); return `${name} (${company})`; }, { probability: 0.7 }); // 랜덤 코멘트 생성 const comment = faker.helpers.maybe(() => { return faker.helpers.arrayElement([ "문서 초안 업로드입니다.", "수정 사항이 반영된 버전입니다.", "최신 규격에 맞게 업데이트했습니다.", "요청하신 변경사항 적용했습니다.", "검토 후 피드백 부탁드립니다." ]); }, { probability: 0.6 }); // 상태 설정 const status = faker.helpers.arrayElement(POSSIBLE_STATUSES); // 리비전 객체 생성 revisionBatch.push({ issueStageId: stage.id, revision: revisionCode, uploaderType: "vendor", // 업로더 타입을 vendor로 설정 uploaderName, comment, status, approvedDate: status === "approved" ? faker.date.recent({ days: 10 }) : null, createdAt: faker.date.recent({ days: 30 }), updatedAt: new Date(), }); // 배치 크기에 도달하면 DB에 삽입 if (revisionBatch.length >= BATCH_SIZE) { try { await db.insert(revisions).values(revisionBatch); totalRevisionsCreated += revisionBatch.length; console.log(`Created ${totalRevisionsCreated} vendor revisions so far...`); revisionBatch = []; // 배치 초기화 } catch (error) { console.error(`Error inserting revision batch:`, error); // 유니크 제약조건 충돌 시 개별 삽입 시도 console.log("Trying to insert revisions one by one..."); for (const rev of revisionBatch) { try { await db.insert(revisions).values([rev]); totalRevisionsCreated++; } catch (singleError) { console.warn(`Skipping duplicate revision: Stage ${rev.issueStageId}, Rev ${rev.revision}`); } } revisionBatch = []; } } } } // 마지막 배치 처리 if (revisionBatch.length > 0) { try { await db.insert(revisions).values(revisionBatch); totalRevisionsCreated += revisionBatch.length; } catch (error) { console.error(`Error inserting final revision batch:`, error); // 유니크 제약조건 충돌 시 개별 삽입 시도 console.log("Trying to insert remaining revisions one by one..."); for (const rev of revisionBatch) { try { await db.insert(revisions).values([rev]); totalRevisionsCreated++; } catch (singleError) { console.warn(`Skipping duplicate revision: Stage ${rev.issueStageId}, Rev ${rev.revision}`); } } } } console.log(`Seeding vendor revisions completed successfully. Total created: ${totalRevisionsCreated}`); } catch (err) { console.error("Seeding vendor revisions error:", err); process.exit(1); } } // 스크립트 직접 실행 시 seedVendorRevisions() .then(() => process.exit(0)) .catch(() => process.exit(1));