diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-29 13:31:40 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-29 13:31:40 +0000 |
| commit | 4614210aa9878922cfa1e424ce677ef893a1b6b2 (patch) | |
| tree | 5e7edcce05fbee207230af0a43ed08cd351d7c4f /db/schema/project-doc-templates.ts | |
| parent | e41e3af4e72870d44a94b03e0f3246d6ccaaca48 (diff) | |
(대표님) 구매 권한설정, data room 등
Diffstat (limited to 'db/schema/project-doc-templates.ts')
| -rw-r--r-- | db/schema/project-doc-templates.ts | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/db/schema/project-doc-templates.ts b/db/schema/project-doc-templates.ts new file mode 100644 index 00000000..6ec9500a --- /dev/null +++ b/db/schema/project-doc-templates.ts @@ -0,0 +1,124 @@ +// 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<DocTemplateVariable[]>().notNull().default([]), + requiredVariables: jsonb("required_variables").$type<string[]>().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<Record<string, any>>(), + + // 프로젝트 정보 + 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;
\ No newline at end of file |
