diff options
| author | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
| commit | 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch) | |
| tree | 8a5587f10ca55b162d7e3254cb088b323a34c41b /db/seeds/seedRevision.ts | |
initial commit
Diffstat (limited to 'db/seeds/seedRevision.ts')
| -rw-r--r-- | db/seeds/seedRevision.ts | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/db/seeds/seedRevision.ts b/db/seeds/seedRevision.ts new file mode 100644 index 00000000..c41fa333 --- /dev/null +++ b/db/seeds/seedRevision.ts @@ -0,0 +1,173 @@ +/** + * 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));
\ No newline at end of file |
