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/schema/vendorData.ts | |
initial commit
Diffstat (limited to 'db/schema/vendorData.ts')
| -rw-r--r-- | db/schema/vendorData.ts | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/db/schema/vendorData.ts b/db/schema/vendorData.ts new file mode 100644 index 00000000..f7baa883 --- /dev/null +++ b/db/schema/vendorData.ts @@ -0,0 +1,205 @@ +import { + pgTable, + text, + varchar, + timestamp, + integer, numeric, date, unique, serial, jsonb, uniqueIndex +} from "drizzle-orm/pg-core" +import { contractItems } from "./contract" + +export const forms = pgTable("forms", { + id: integer("id").primaryKey().generatedAlwaysAsIdentity(), + contractItemId: integer("contract_item_id") + .notNull() + .references(() => contractItems.id, { onDelete: "cascade" }), + formCode: varchar("form_code", { length: 100 }).notNull(), + formName: varchar("form_name", { length: 255 }).notNull(), + // tagType: varchar("tag_type", { length: 50 }).notNull(), + // class: varchar("class", { length: 100 }).notNull(), + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").defaultNow().notNull(), +}, (table) => { + return { + // contractItemId와 formCode의 조합을 유니크하게 설정 + contractItemFormCodeUnique: uniqueIndex("contract_item_form_code_unique").on( + table.contractItemId, + table.formCode + ), + } +}) + +export const rfqAttachments = pgTable("form_templates", { + id: serial("id").primaryKey(), + formId: integer("form_id").references(() => forms.id), + fileName: varchar("file_name", { length: 255 }).notNull(), + filePath: varchar("file_path", { length: 1024 }).notNull(), + + createdAt: timestamp("created_at").defaultNow().notNull(), + udpatedAt: timestamp("updated_at").defaultNow().notNull(), + +}); + + +export const formMetas = pgTable("form_metas", { + id: serial("id").primaryKey(), + formCode: varchar("form_code", { length: 50 }).notNull(), + formName: varchar("form_name", { length: 255 }).notNull(), + columns: jsonb("columns").notNull(), + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}) + +export const formEntries = pgTable("form_entries", { + id: serial("id").primaryKey(), + formCode: varchar("form_code", { length: 50 }).notNull(), + data: jsonb("data").notNull(), + contractItemId: integer("contract_item_id") + .notNull() + .references(() => contractItems.id, { onDelete: "cascade" }), + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}) + + +// ============ tags (각 계약 아이템에 대한 Tag) ============ +// "어느 계약의 어느 아이템에 대한 태그"임을 나타내려면 contract_items를 참조 +export const tags = pgTable("tags", { + id: integer("id").primaryKey().generatedAlwaysAsIdentity(), + + // 이 Tag가 속한 "계약 내 아이템" (즉 contract_items.id) + contractItemId: integer("contract_item_id") + .notNull() + .references(() => contractItems.id, { onDelete: "cascade" }), + + formId: integer("form_id") + .references(() => forms.id, { onDelete: "set null" }), + + tagNo: varchar("tag_no", { length: 100 }).notNull(), + tagType: varchar("tag_type", { length: 50 }).notNull(), + class: varchar("class", { length: 100 }).notNull(), + description: text("description"), + + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").defaultNow().notNull(), +}) + +export type Tag = typeof tags.$inferSelect +export type Form = typeof forms.$inferSelect +export type NewTag = typeof tags.$inferInsert + +export const tagTypes = pgTable("tag_types", { + code: varchar("code", { length: 50 }).primaryKey(), + description: text("description").notNull(), + + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}) + +export const tagSubfields = pgTable("tag_subfields", { + id: serial("id").primaryKey(), + + // 외래키: tagTypeCode -> tagTypes.code + tagTypeCode: varchar("tag_type_code", { length: 50 }) + .notNull() + .references(() => tagTypes.code, { onDelete: "cascade" }), + + /** + * 나머지 필드 + */ + // tagTypeDescription: -> 이제 불필요. tagTypes.description로 join + attributesId: varchar("attributes_id", { length: 50 }).notNull(), + attributesDescription: text("attributes_description").notNull(), + + expression: text("expression"), + delimiter: varchar("delimiter", { length: 10 }), + + sortOrder: integer("sort_order").default(0).notNull(), + + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}, (table) => { + return { + uniqTagTypeAttribute: unique("uniq_tag_type_attribute").on( + table.tagTypeCode, + table.attributesId + ), + }; +}); + +export const tagSubfieldOptions = pgTable("tag_subfield_options", { + id: serial("id").primaryKey(), + + // 어떤 subfield에 속하는 옵션인지 + attributesId: varchar("attributes_id", { length: 50 }) + .notNull() + .references(() => tagSubfields.attributesId, { onDelete: "cascade" }), + + /** + * 실제 코드 (예: "PM", "AA", "VB", "VAR", "01", "02" ...) + */ + code: varchar("code", { length: 50 }).notNull(), + + /** + * 사용자에게 보여줄 레이블 (예: "Pump", "Pneumatic Motor", "Ball Valve", ...) + */ + label: text("label").notNull(), + + /** + * 생성/수정 시각 (선택) + */ + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}) + +export const tagClasses = pgTable("tag_classes", { + id: integer("id").primaryKey().generatedAlwaysAsIdentity(), + + // 기존 code/label + code: varchar("code", { length: 100 }).notNull(), + label: text("label").notNull(), + + // 새 필드: tagTypeCode -> references tagTypes.code + tagTypeCode: varchar("tag_type_code", { length: 50 }) + .notNull() + .references(() => tagTypes.code, { onDelete: "cascade" }), + + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").defaultNow().notNull(), +}) + +export const tagTypeClassFormMappings = pgTable("tag_type_class_form_mappings", { + id: serial("id").primaryKey(), + + tagTypeLabel: varchar("tag_type_label", { length: 255 }).notNull(), + classLabel: varchar("class_label", { length: 255 }).notNull(), + + formCode: varchar("form_code", { length: 50 }).notNull(), + formName: varchar("form_name", { length: 255 }).notNull(), + + createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), +}) + +export type TagTypeClassFormMappings = typeof tagTypeClassFormMappings.$inferSelect +export type TagSubfields = typeof tagSubfields.$inferSelect +export type TagSubfieldOption = typeof tagSubfieldOptions.$inferSelect +export type TagClasses = typeof tagClasses.$inferSelect + + +export const viewTagSubfields = pgTable("view_tag_subfields", { + id: integer("id").primaryKey(), + + tagTypeCode: varchar("tag_type_code", { length: 50 }).notNull(), + tagTypeDescription: text("tag_type_description"), + attributesId: varchar("attributes_id", { length: 50 }).notNull(), + attributesDescription: text("attributes_description").notNull(), + + expression: text("expression"), + delimiter: varchar("delimiter", { length: 10 }), + sortOrder: integer("sort_order").default(0).notNull(), + + createdAt: timestamp("created_at", { withTimezone: true }), + updatedAt: timestamp("updated_at", { withTimezone: true }), +}) + +export type ViewTagSubfields = typeof viewTagSubfields.$inferSelect |
