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