summaryrefslogtreecommitdiff
path: root/db/seeds/seedRevision.ts
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-03-25 15:55:45 +0900
committerjoonhoekim <26rote@gmail.com>2025-03-25 15:55:45 +0900
commit1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch)
tree8a5587f10ca55b162d7e3254cb088b323a34c41b /db/seeds/seedRevision.ts
initial commit
Diffstat (limited to 'db/seeds/seedRevision.ts')
-rw-r--r--db/seeds/seedRevision.ts173
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