summaryrefslogtreecommitdiff
path: root/db/schema/bRfq.ts
diff options
context:
space:
mode:
Diffstat (limited to 'db/schema/bRfq.ts')
-rw-r--r--db/schema/bRfq.ts132
1 files changed, 97 insertions, 35 deletions
diff --git a/db/schema/bRfq.ts b/db/schema/bRfq.ts
index 5e211448..115d2c6e 100644
--- a/db/schema/bRfq.ts
+++ b/db/schema/bRfq.ts
@@ -168,52 +168,114 @@ export const bRfqsAttachments = pgTable(
"b_rfq_attachments",
{
id: serial("id").primaryKey(),
- attachmentType: varchar("attachment_type", { length: 50 }).notNull(), // '구매', '설계'
+ attachmentType: varchar("attachment_type", { length: 50 }).notNull(),
serialNo: varchar("serial_no", { length: 50 }).notNull(),
rfqId: integer("rfq_id")
- .notNull()
- .references(() => bRfqs.id),
+ .notNull()
+ .references(() => bRfqs.id),
+
+ // 현재 리비전 정보 (빠른 접근용)
+ currentRevision: varchar("current_revision", { length: 10 }).notNull().default("Rev.0"),
+ latestRevisionId: integer("latest_revision_id"), // self-reference to bRfqAttachmentRevisions
+
+ // 메타 정보
+ description: varchar("description", { length: 500 }),
+ createdBy: integer("created_by")
+ .references(() => users.id, { onDelete: "set null" })
+ .notNull(),
+ createdAt: timestamp("created_at").defaultNow().notNull(),
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
+ }
+ )
+
+ // 리비전 테이블 (모든 파일 버전 관리)
+ export const bRfqAttachmentRevisions = pgTable(
+ "b_rfq_attachment_revisions",
+ {
+ id: serial("id").primaryKey(),
+ attachmentId: integer("attachment_id")
+ .notNull()
+ .references(() => bRfqsAttachments.id, { onDelete: "cascade" }),
+
+ // 리비전 정보
+ revisionNo: varchar("revision_no", { length: 10 }).notNull(), // "Rev.0", "Rev.1", "Rev.2"
+ revisionComment: text("revision_comment"),
+ isLatest: boolean("is_latest").notNull().default(true),
+
+ // 파일 정보
fileName: varchar("file_name", { length: 255 }).notNull(),
originalFileName: varchar("original_file_name", { length: 255 }).notNull(),
filePath: varchar("file_path", { length: 512 }).notNull(),
fileSize: integer("file_size"),
fileType: varchar("file_type", { length: 100 }),
- description: varchar("description", { length: 500 }),
+
+ // 리비전 생성 정보
createdBy: integer("created_by")
.references(() => users.id, { onDelete: "set null" })
.notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
- },
- );
-// 1. 첨부파일 리비전 관리 테이블
-export const bRfqAttachmentRevisions = pgTable(
- "b_rfq_attachment_revisions",
- {
- id: serial("id").primaryKey(),
- attachmentId: integer("attachment_id")
- .notNull()
- .references(() => bRfqsAttachments.id, { onDelete: "cascade" }),
-
- revisionNo: varchar("revision_no", { length: 10 }).notNull(), // "Rev.0", "Rev.1", "Rev.2"
- fileName: varchar("file_name", { length: 255 }).notNull(),
- originalFileName: varchar("original_file_name", { length: 255 }).notNull(),
- filePath: varchar("file_path", { length: 512 }).notNull(),
- fileSize: integer("file_size"),
- fileType: varchar("file_type", { length: 100 }),
-
- isLatest: boolean("is_latest").notNull().default(true),
- revisionComment: text("revision_comment"),
-
- createdBy: integer("created_by")
- .references(() => users.id, { onDelete: "set null" })
- .notNull(),
- createdAt: timestamp("created_at").defaultNow().notNull(),
- }, (t) => ({
- latestRevisionIdx: uniqueIndex('latest_revision_idx').on(
- t.attachmentId.asc(),
- t.isLatest.asc(),
- ),
- }));
+ },
+ (t) => ({
+ // 첨부파일당 하나의 최신 리비전만 허용
+ latestRevisionIdx: uniqueIndex('latest_revision_idx')
+ .on(t.attachmentId, t.isLatest)
+ .where(eq(t.isLatest, true)),
+
+ // 첨부파일 + 리비전 번호 유니크
+ attachmentRevisionIdx: uniqueIndex('attachment_revision_idx')
+ .on(t.attachmentId, t.revisionNo),
+ })
+ )
+
+ // 첨부파일 + 최신 리비전 뷰
+ export const attachmentsWithLatestRevisionView = pgView("attachments_with_latest_revision", {
+ // 메인 첨부파일 정보
+ attachmentId: integer("attachment_id"),
+ attachmentType: varchar("attachment_type", { length: 50 }),
+ serialNo: varchar("serial_no", { length: 50 }),
+ rfqId: integer("rfq_id"),
+ description: varchar("description", { length: 500 }),
+ currentRevision: varchar("current_revision", { length: 10 }),
+
+ // 최신 리비전 파일 정보
+ revisionId: integer("revision_id"),
+ fileName: varchar("file_name", { length: 255 }),
+ originalFileName: varchar("original_file_name", { length: 255 }),
+ filePath: varchar("file_path", { length: 512 }),
+ fileSize: integer("file_size"),
+ fileType: varchar("file_type", { length: 100 }),
+ revisionComment: text("revision_comment"),
+
+ // 생성/수정 정보
+ createdBy: integer("created_by"),
+ createdByName: varchar("created_by_name", { length: 255 }),
+ createdAt: timestamp("created_at"),
+ updatedAt: timestamp("updated_at"),
+ }).as(sql`
+ SELECT
+ a.id as attachment_id,
+ a.attachment_type,
+ a.serial_no,
+ a.rfq_id,
+ a.description,
+ a.current_revision,
+
+ r.id as revision_id,
+ r.file_name,
+ r.original_file_name,
+ r.file_path,
+ r.file_size,
+ r.file_type,
+ r.revision_comment,
+
+ a.created_by,
+ u.name as created_by_name,
+ a.created_at,
+ a.updated_at
+ FROM b_rfq_attachments a
+ LEFT JOIN b_rfq_attachment_revisions r ON a.latest_revision_id = r.id
+ LEFT JOIN users u ON a.created_by = u.id
+ `)
// 2. 벤더별 첨부파일 응답 현황 관리
export const vendorAttachmentResponses = pgTable(