summaryrefslogtreecommitdiff
path: root/db/schema/gtc.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-24 11:06:32 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-24 11:06:32 +0000
commit1dc24d48e52f2e490f5603ceb02842586ecae533 (patch)
tree8fca2c5b5b52cc10557b5ba6e55b937ae3c57cf6 /db/schema/gtc.ts
parented0d6fcc98f671280c2ccde797b50693da88152e (diff)
(대표님) 정기평가 피드백 반영, 설계 피드백 반영, (최겸) 기술영업 피드백 반영
Diffstat (limited to 'db/schema/gtc.ts')
-rw-r--r--db/schema/gtc.ts110
1 files changed, 110 insertions, 0 deletions
diff --git a/db/schema/gtc.ts b/db/schema/gtc.ts
new file mode 100644
index 00000000..a4052d61
--- /dev/null
+++ b/db/schema/gtc.ts
@@ -0,0 +1,110 @@
+import {
+ pgTable,
+ serial,
+ varchar,
+ text,
+ integer,
+ timestamp,
+ pgEnum,
+ boolean,
+ index,
+ uniqueIndex
+ } from "drizzle-orm/pg-core"
+ import { relations } from "drizzle-orm"
+import { projects } from "./projects"
+import { users } from "./users"
+
+ // GTC 구분 enum
+ export const gtcTypeEnum = pgEnum("gtc_type", ["standard", "project"])
+
+ // GTC 문서 테이블
+ export const gtcDocuments = pgTable("gtc_documents", {
+ id: serial("id").primaryKey(),
+
+ // 구분 (표준/프로젝트)
+ type: gtcTypeEnum("type").notNull(),
+
+ // 프로젝트 참조 (프로젝트 타입인 경우만)
+ projectId: integer("project_id").references(() => projects.id, {
+ onDelete: "cascade"
+ }),
+
+ // 리비전 번호
+ revision: integer("revision").notNull().default(0),
+
+ // 파일 정보
+ fileName: varchar("file_name", { length: 255 }),
+ filePath: varchar("file_path", { length: 500 }),
+ fileSize: integer("file_size"), // bytes
+
+ // 최초 등록 정보
+ createdAt: timestamp("created_at", { withTimezone: true })
+ .defaultNow()
+ .notNull(),
+ createdById: integer("created_by_id")
+ .references(() => users.id, { onDelete: "set null" })
+ .notNull(),
+
+ // 최종 수정 정보
+ updatedAt: timestamp("updated_at", { withTimezone: true })
+ .defaultNow()
+ .notNull(),
+ updatedById: integer("updated_by_id")
+ .references(() => users.id, { onDelete: "set null" }),
+
+ // 편집 사유
+ editReason: text("edit_reason"),
+
+ // 활성 상태
+ isActive: boolean("is_active").default(true).notNull(),
+
+ }, (table) => {
+ return {
+ // 프로젝트별 리비전 유니크 (표준의 경우 projectId가 null)
+ projectRevisionIdx: uniqueIndex("gtc_project_revision_idx")
+ .on(table.projectId, table.revision, table.type),
+
+ // 조회 성능을 위한 인덱스들
+ typeIdx: index("gtc_type_idx").on(table.type),
+ projectIdx: index("gtc_project_idx").on(table.projectId),
+ createdAtIdx: index("gtc_created_at_idx").on(table.createdAt),
+ updatedAtIdx: index("gtc_updated_at_idx").on(table.updatedAt),
+ }
+ })
+
+ // 관계 정의 (필요한 경우)
+ export const gtcDocumentsRelations = relations(gtcDocuments, ({ one }) => ({
+ project: one(projects, {
+ fields: [gtcDocuments.projectId],
+ references: [projects.id],
+ }),
+ createdBy: one(users, {
+ fields: [gtcDocuments.createdById],
+ references: [users.id],
+ }),
+ updatedBy: one(users, {
+ fields: [gtcDocuments.updatedById],
+ references: [users.id],
+ }),
+ }))
+
+ // 타입 정의
+ export type GtcDocument = typeof gtcDocuments.$inferSelect
+ export type NewGtcDocument = typeof gtcDocuments.$inferInsert
+
+ // 조인된 결과를 위한 타입
+ export type GtcDocumentWithRelations = GtcDocument & {
+ project?: {
+ id: number
+ code: string
+ name: string
+ }
+ createdBy?: {
+ id: number
+ name: string
+ }
+ updatedBy?: {
+ id: number
+ name: string
+ }
+ } \ No newline at end of file