summaryrefslogtreecommitdiff
path: root/db/schema/techSales.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-20 11:37:31 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-20 11:37:31 +0000
commitaa86729f9a2ab95346a2851e3837de1c367aae17 (patch)
treeb601b18b6724f2fb449c7fa9ea50cbd652a8077d /db/schema/techSales.ts
parent95bbe9c583ff841220da1267630e7b2025fc36dc (diff)
(대표님) 20250620 작업사항
Diffstat (limited to 'db/schema/techSales.ts')
-rw-r--r--db/schema/techSales.ts85
1 files changed, 85 insertions, 0 deletions
diff --git a/db/schema/techSales.ts b/db/schema/techSales.ts
index 334bf6bb..744d22cc 100644
--- a/db/schema/techSales.ts
+++ b/db/schema/techSales.ts
@@ -34,6 +34,8 @@ import {
integer,
numeric,
date,
+ json,
+ index,
} from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import { biddingProjects } from "./projects";
@@ -60,6 +62,7 @@ export const TECH_SALES_QUOTATION_STATUSES = {
SUBMITTED: "Submitted",
REVISED: "Revised",
ACCEPTED: "Accepted",
+ REJECTED: "Rejected",
} as const;
export type TechSalesQuotationStatus = typeof TECH_SALES_QUOTATION_STATUSES[keyof typeof TECH_SALES_QUOTATION_STATUSES];
@@ -90,6 +93,12 @@ export const TECH_SALES_QUOTATION_STATUS_CONFIG = {
description: "승인된 견적서",
color: "text-green-600",
},
+ [TECH_SALES_QUOTATION_STATUSES.REJECTED]: {
+ label: "거절됨",
+ variant: "destructive" as const,
+ description: "거절된 견적서",
+ color: "text-red-600",
+ },
} as const;
// ===== 스키마 정의 =====
@@ -241,6 +250,37 @@ export const techSalesVendorQuotations = pgTable(
}
);
+// 기술영업 벤더 견적서 revision 히스토리 테이블 (이전 버전 스냅샷 저장)
+export const techSalesVendorQuotationRevisions = pgTable(
+ "tech_sales_vendor_quotation_revisions",
+ {
+ id: serial("id").primaryKey(),
+ quotationId: integer("quotation_id")
+ .notNull()
+ .references(() => techSalesVendorQuotations.id, { onDelete: "cascade" }),
+
+ // 버전 정보
+ version: integer("version").notNull(),
+
+ // 이전 데이터 JSON 스냅샷
+ snapshot: json("snapshot").notNull(),
+
+ // 변경 사유
+ changeReason: text("change_reason"),
+ revisionNote: text("revision_note"),
+
+ // 변경자 정보
+ revisedBy: integer("revised_by"),
+ revisedAt: timestamp("revised_at").defaultNow().notNull(),
+ },
+ (table) => ({
+ quotationVersionIdx: index("tech_sales_quotation_revisions_quotation_version_idx").on(
+ table.quotationId,
+ table.version
+ ),
+ })
+);
+
export const techSalesRfqComments = pgTable(
"tech_sales_rfq_comments",
{
@@ -299,6 +339,28 @@ export const techSalesRfqCommentAttachments = pgTable("tech_sales_rfq_comment_at
uploadedAt: timestamp("uploaded_at").defaultNow().notNull(),
});
+// 기술영업 벤더 견적서 첨부파일 테이블
+export const techSalesVendorQuotationAttachments = pgTable("tech_sales_vendor_quotation_attachments", {
+ id: serial("id").primaryKey(),
+ quotationId: integer("quotation_id")
+ .notNull()
+ .references(() => techSalesVendorQuotations.id, { onDelete: "cascade" }),
+ fileName: varchar("file_name", { length: 255 }).notNull(),
+ originalFileName: varchar("original_file_name", { length: 255 }).notNull(),
+ fileSize: integer("file_size").notNull(),
+ fileType: varchar("file_type", { length: 100 }),
+ filePath: varchar("file_path", { length: 500 }).notNull(),
+ description: text("description"), // 파일 설명
+ uploadedBy: integer("uploaded_by").references(() => users.id, {
+ onDelete: "set null",
+ }),
+ vendorId: integer("vendor_id").references(() => techVendors.id, {
+ onDelete: "set null",
+ }),
+ isVendorUpload: boolean("is_vendor_upload").default(true), // 벤더가 업로드한 파일인지
+ createdAt: timestamp("created_at").defaultNow().notNull(),
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
+});
// 타입 정의
export type TechSalesVendorQuotations =
@@ -390,6 +452,7 @@ export const techSalesVendorQuotationsRelations = relations(techSalesVendorQuota
// 첨부파일 관계
attachments: many(techSalesRfqCommentAttachments),
+ quotationAttachments: many(techSalesVendorQuotationAttachments),
}));
export const techSalesAttachmentsRelations = relations(techSalesAttachments, ({ one }) => ({
@@ -474,4 +537,26 @@ export const techSalesRfqCommentAttachmentsRelations = relations(techSalesRfqCom
fields: [techSalesRfqCommentAttachments.vendorId],
references: [techVendors.id],
}),
+}));
+
+// 기술영업 벤더 견적서 첨부파일 relations
+export const techSalesVendorQuotationAttachmentsRelations = relations(techSalesVendorQuotationAttachments, ({ one }) => ({
+ // 견적서 관계
+ quotation: one(techSalesVendorQuotations, {
+ fields: [techSalesVendorQuotationAttachments.quotationId],
+ references: [techSalesVendorQuotations.id],
+ }),
+
+ // 업로드한 사용자 관계
+ uploadedByUser: one(users, {
+ fields: [techSalesVendorQuotationAttachments.uploadedBy],
+ references: [users.id],
+ relationName: "techSalesQuotationAttachmentUploadedBy",
+ }),
+
+ // 벤더 관계
+ vendor: one(techVendors, {
+ fields: [techSalesVendorQuotationAttachments.vendorId],
+ references: [techVendors.id],
+ }),
})); \ No newline at end of file