// db/schema/project-doc-templates.ts import { pgTable, serial, varchar, text, timestamp, boolean, integer, jsonb, AnyPgColumn } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; import { projects } from "./projects"; import { users } from "./users"; // 프로젝트 문서 템플릿 테이블 export const projectDocTemplates = pgTable("project_doc_templates", { id: serial("id").primaryKey(), // 템플릿 기본 정보 templateName: varchar("template_name", { length: 255 }).notNull(), templateCode: varchar("template_code", { length: 100 }).unique().notNull(), description: text("description"), // 프로젝트 정보 (선택적 - 전사 템플릿인 경우 null) projectId: integer("project_id").references(() => projects.id), projectCode: varchar("project_code", { length: 50 }), projectName: varchar("project_name", { length: 255 }), // 템플릿 타입 templateType: varchar("template_type", { length: 50 }).notNull().default("PROJECT"), // PROJECT, COMPANY_WIDE documentType: varchar("document_type", { length: 100 }).notNull(), // CONTRACT, SPECIFICATION, REPORT, etc. // 파일 정보 filePath: text("file_path").notNull(), fileName: varchar("file_name", { length: 255 }).notNull(), fileSize: integer("file_size"), mimeType: varchar("mime_type", { length: 100 }), // 버전 관리 version: integer("version").notNull().default(1), isLatest: boolean("is_latest").notNull().default(true), parentTemplateId: integer("parent_template_id").references((): AnyPgColumn => projectDocTemplates.id), // 변수 정보 variables: jsonb("variables").$type().notNull().default([]), requiredVariables: jsonb("required_variables").$type().notNull().default([]), // 사용 권한 및 상태 status: varchar("status", { length: 20 }).notNull().default("ACTIVE"), // ACTIVE, INACTIVE, DRAFT, ARCHIVED isPublic: boolean("is_public").notNull().default(false), // 다른 프로젝트에서도 사용 가능 여부 requiresApproval: boolean("requires_approval").notNull().default(false), // 감사 필드 createdBy: integer('created_by').references(() => users.id), // 생성자 createdByName: varchar("created_by_name", { length: 50 }), // 생성자 updatedBy: integer('updated_by').references(() => users.id), // 수정자 updatedByName: varchar("updated_by_name", { length: 50 }), // 생성자 createdAt: timestamp("created_at").notNull().defaultNow(), updatedAt: timestamp("updated_at").notNull().defaultNow(), deletedAt: timestamp("deleted_at"), }); // 템플릿 변수 타입 export type DocTemplateVariable = { name: string; displayName: string; type: "text" | "number" | "date" | "select"; required: boolean; defaultValue?: string; options?: string[]; // select 타입인 경우 description?: string; validation?: { pattern?: string; min?: number; max?: number; }; }; // 템플릿 사용 이력 테이블 export const projectDocTemplateUsage = pgTable("project_doc_template_usage", { id: serial("id").primaryKey(), templateId: integer("template_id").notNull().references(() => projectDocTemplates.id), // 생성된 문서 정보 generatedDocumentId: varchar("generated_document_id", { length: 100 }).unique(), generatedFilePath: text("generated_file_path"), generatedFileName: varchar("generated_file_name", { length: 255 }), // 사용된 변수 값 usedVariables: jsonb("used_variables").$type>(), // 프로젝트 정보 usedInProjectId: integer("used_in_project_id"), usedInProjectCode: varchar("used_in_project_code", { length: 50 }), // 사용자 정보 usedBy: varchar("used_by", { length: 100 }), usedAt: timestamp("used_at").notNull().defaultNow(), // 추가 메타데이터 metadata: jsonb("metadata"), }); // Relations export const projectDocTemplatesRelations = relations(projectDocTemplates, ({ one, many }) => ({ project: one(projects, { fields: [projectDocTemplates.projectId], references: [projects.id], }), parentTemplate: one(projectDocTemplates, { fields: [projectDocTemplates.parentTemplateId], references: [projectDocTemplates.id], }), childTemplates: many(projectDocTemplates), usageHistory: many(projectDocTemplateUsage), })); export const projectDocTemplateUsageRelations = relations(projectDocTemplateUsage, ({ one }) => ({ template: one(projectDocTemplates, { fields: [projectDocTemplateUsage.templateId], references: [projectDocTemplates.id], }), })); // 타입 정의 export type ProjectDocTemplate = typeof projectDocTemplates.$inferSelect; export type NewProjectDocTemplate = typeof projectDocTemplates.$inferInsert; export type ProjectDocTemplateUsage = typeof projectDocTemplateUsage.$inferSelect; export type NewProjectDocTemplateUsage = typeof projectDocTemplateUsage.$inferInsert;