diff options
| author | joonhoekim <26rote@gmail.com> | 2025-10-23 18:44:19 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-10-23 18:44:19 +0900 |
| commit | 04bd1965c3699a4b29ed9c9627574bfeedd3d6c6 (patch) | |
| tree | 691b9a6e844a788937a240d47e77e8cfa848a88a /db/schema | |
| parent | 535e234dbd674bf2e5ecf344e03ed8ae5b2cbd6c (diff) | |
(김준회) SWP 문서 업로드 (Submisssion) 초기 개발건
Diffstat (limited to 'db/schema')
| -rw-r--r-- | db/schema/SWP/swp-documents.ts | 219 | ||||
| -rw-r--r-- | db/schema/index.ts | 5 |
2 files changed, 223 insertions, 1 deletions
diff --git a/db/schema/SWP/swp-documents.ts b/db/schema/SWP/swp-documents.ts new file mode 100644 index 00000000..2c7d06b0 --- /dev/null +++ b/db/schema/SWP/swp-documents.ts @@ -0,0 +1,219 @@ +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", + { + // Primary Key + DOC_NO: varchar("DOC_NO", { length: 1000 }).primaryKey(), + + // 문서 기본 정보 + 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_NO: varchar("PROJ_NO", { length: 1000 }).notNull(), + 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) => ({ + 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(), + + // Foreign Key + DOC_NO: varchar("DOC_NO", { length: 1000 }) + .notNull() + .references(() => swpDocuments.DOC_NO, { onDelete: "cascade" }), + + // 리비전 정보 + 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; + diff --git a/db/schema/index.ts b/db/schema/index.ts index dbbb90a1..ea39ae8c 100644 --- a/db/schema/index.ts +++ b/db/schema/index.ts @@ -83,4 +83,7 @@ export * from './avl/avl'; export * from './avl/vendor-pool'; // === Email Logs 스키마 === export * from './emailLogs'; -export * from './emailWhitelist';
\ No newline at end of file +export * from './emailWhitelist'; + +// SWP 문서/첨부파일 테이블 및 뷰 스키마 +export * from './SWP/swp-documents';
\ No newline at end of file |
