import { varchar, timestamp, serial, uniqueIndex, index, pgEnum, pgSchema, } from "drizzle-orm/pg-core"; // ============================================================================ // 스키마 // ============================================================================ export const swpSchema = pgSchema("swp"); // ============================================================================ // ENUMS // ============================================================================ export const syncStatusEnum = pgEnum("swp_sync_status", [ "synced", "pending", "error", ]); // ============================================================================ // 문서 마스터 (GetVDRDocumentList) // 컬럼명: API 필드명과 동일하게 유지 (UPPER_SNAKE_CASE) // ============================================================================ export const swpDocuments = swpSchema.table( "swp_documents", { // Composite Primary Key: DOC_NO + PROJ_NO DOC_NO: varchar("DOC_NO", { length: 1000 }).notNull(), PROJ_NO: varchar("PROJ_NO", { length: 1000 }).notNull(), // 문서 기본 정보 DOC_TITLE: varchar("DOC_TITLE", { length: 1000 }).notNull(), DOC_GB: varchar("DOC_GB", { length: 1000 }), DOC_TYPE: varchar("DOC_TYPE", { length: 1000 }), OWN_DOC_NO: varchar("OWN_DOC_NO", { length: 1000 }), SHI_DOC_NO: varchar("SHI_DOC_NO", { length: 1000 }), // 프로젝트 정보 PROJ_NM: varchar("PROJ_NM", { length: 1000 }), PKG_NO: varchar("PKG_NO", { length: 1000 }), // 자재/기술 정보 MAT_CD: varchar("MAT_CD", { length: 1000 }), MAT_NM: varchar("MAT_NM", { length: 1000 }), DISPLN: varchar("DISPLN", { length: 1000 }), CTGRY: varchar("CTGRY", { length: 1000 }), // 업체 정보 VNDR_CD: varchar("VNDR_CD", { length: 1000 }), CPY_CD: varchar("CPY_CD", { length: 1000 }), CPY_NM: varchar("CPY_NM", { length: 1000 }), // 담당자 정보 PIC_NM: varchar("PIC_NM", { length: 1000 }), PIC_DEPTCD: varchar("PIC_DEPTCD", { length: 1000 }), PIC_DEPTNM: varchar("PIC_DEPTNM", { length: 1000 }), // 최신 리비전 정보 (빠른 조회용) LTST_REV_NO: varchar("LTST_REV_NO", { length: 1000 }), LTST_REV_SEQ: varchar("LTST_REV_SEQ", { length: 1000 }), LTST_ACTV_STAT: varchar("LTST_ACTV_STAT", { length: 1000 }), // 기타 STAGE: varchar("STAGE", { length: 1000 }), SKL_CD: varchar("SKL_CD", { length: 1000 }), MOD_TYPE: varchar("MOD_TYPE", { length: 1000 }), ACT_TYPE_NM: varchar("ACT_TYPE_NM", { length: 1000 }), USE_YN: varchar("USE_YN", { length: 1000 }), // 이력 정보 (SWP) CRTER: varchar("CRTER", { length: 1000 }), CRTE_DTM: varchar("CRTE_DTM", { length: 1000 }), CHGR: varchar("CHGR", { length: 1000 }), CHG_DTM: varchar("CHG_DTM", { length: 1000 }), REV_DTM: varchar("REV_DTM", { length: 1000 }), // 동기화 메타데이터 sync_status: syncStatusEnum("sync_status").default("synced").notNull(), last_synced_at: timestamp("last_synced_at").defaultNow().notNull(), created_at: timestamp("created_at").defaultNow().notNull(), updated_at: timestamp("updated_at").defaultNow().notNull(), }, (table) => ({ // Composite Primary Key pk: uniqueIndex("swp_documents_pk").on(table.DOC_NO, table.PROJ_NO), // Indexes projNoIdx: index("swp_documents_proj_no_idx").on(table.PROJ_NO), vndrCdIdx: index("swp_documents_vndr_cd_idx").on(table.VNDR_CD), pkgNoIdx: index("swp_documents_pkg_no_idx").on(table.PKG_NO), syncStatusIdx: index("swp_documents_sync_status_idx").on(table.sync_status), }) ); // ============================================================================ // 문서 리비전 (GetExternalInboxList에서 추출) // 컬럼명: API 필드명과 동일하게 유지 (UPPER_SNAKE_CASE) // ============================================================================ export const swpDocumentRevisions = swpSchema.table( "swp_document_revisions", { // Primary Key id: serial("id").primaryKey(), // Document Reference (NO FK - 외래키 제거) DOC_NO: varchar("DOC_NO", { length: 1000 }).notNull(), // 리비전 정보 REV_NO: varchar("REV_NO", { length: 1000 }).notNull(), STAGE: varchar("STAGE", { length: 1000 }).notNull(), // Activity 정보 ACTV_NO: varchar("ACTV_NO", { length: 1000 }), ACTV_SEQ: varchar("ACTV_SEQ", { length: 1000 }), BOX_SEQ: varchar("BOX_SEQ", { length: 1000 }), OFDC_NO: varchar("OFDC_NO", { length: 1000 }), // 프로젝트/패키지 정보 (파일 API에서만 제공) PROJ_NO: varchar("PROJ_NO", { length: 1000 }), PKG_NO: varchar("PKG_NO", { length: 1000 }), VNDR_CD: varchar("VNDR_CD", { length: 1000 }), CPY_CD: varchar("CPY_CD", { length: 1000 }), // 동기화 메타데이터 sync_status: syncStatusEnum("sync_status").default("synced").notNull(), last_synced_at: timestamp("last_synced_at").defaultNow().notNull(), created_at: timestamp("created_at").defaultNow().notNull(), updated_at: timestamp("updated_at").defaultNow().notNull(), }, (table) => ({ // Unique constraint: 문서당 리비전은 유일 docRevUnique: uniqueIndex("swp_doc_rev_unique_idx").on( table.DOC_NO, table.REV_NO ), docNoIdx: index("swp_revisions_doc_no_idx").on(table.DOC_NO), revNoIdx: index("swp_revisions_rev_no_idx").on(table.REV_NO), stageIdx: index("swp_revisions_stage_idx").on(table.STAGE), }) ); // ============================================================================ // 첨부파일 (GetExternalInboxList) // 컬럼명: API 필드명과 동일하게 유지 (UPPER_SNAKE_CASE) // ============================================================================ export const swpDocumentFiles = swpSchema.table( "swp_document_files", { // Primary Key id: serial("id").primaryKey(), // Foreign Key revision_id: serial("revision_id") .notNull() .references(() => swpDocumentRevisions.id, { onDelete: "cascade" }), // 파일 정보 FILE_NM: varchar("FILE_NM", { length: 1000 }).notNull(), FILE_SEQ: varchar("FILE_SEQ", { length: 1000 }).notNull(), FILE_SZ: varchar("FILE_SZ", { length: 1000 }), FLD_PATH: varchar("FLD_PATH", { length: 1000 }), // 문서 참조 (조회 편의용, 비정규화) DOC_NO: varchar("DOC_NO", { length: 1000 }).notNull(), // 상태 정보 STAT: varchar("STAT", { length: 1000 }), STAT_NM: varchar("STAT_NM", { length: 1000 }), IDX: varchar("IDX", { length: 1000 }), // Activity 정보 ACTV_NO: varchar("ACTV_NO", { length: 1000 }), // 이력 정보 (SWP) CRTER: varchar("CRTER", { length: 1000 }), CRTE_DTM: varchar("CRTE_DTM", { length: 1000 }), CHGR: varchar("CHGR", { length: 1000 }), CHG_DTM: varchar("CHG_DTM", { length: 1000 }), // 동기화 메타데이터 sync_status: syncStatusEnum("sync_status").default("synced").notNull(), last_synced_at: timestamp("last_synced_at").defaultNow().notNull(), created_at: timestamp("created_at").defaultNow().notNull(), updated_at: timestamp("updated_at").defaultNow().notNull(), }, (table) => ({ // Unique constraint: 리비전당 파일 시퀀스는 유일 revFileUnique: uniqueIndex("swp_rev_file_unique_idx").on( table.revision_id, table.FILE_SEQ ), revisionIdIdx: index("swp_files_revision_id_idx").on(table.revision_id), docNoIdx: index("swp_files_doc_no_idx").on(table.DOC_NO), fileNmIdx: index("swp_files_file_nm_idx").on(table.FILE_NM), }) ); // ============================================================================ // TYPES // ============================================================================ export type SwpDocument = typeof swpDocuments.$inferSelect; export type SwpDocumentInsert = typeof swpDocuments.$inferInsert; export type SwpDocumentRevision = typeof swpDocumentRevisions.$inferSelect; export type SwpDocumentRevisionInsert = typeof swpDocumentRevisions.$inferInsert; export type SwpDocumentFile = typeof swpDocumentFiles.$inferSelect; export type SwpDocumentFileInsert = typeof swpDocumentFiles.$inferInsert;