diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-26 18:09:18 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-26 18:09:18 +0900 |
| commit | 8547034e6d82e4d1184f35af2dbff67180d89dc8 (patch) | |
| tree | 2e1835040f39adc7d0c410a108ebb558f9971a8b /db/schema | |
| parent | 3131dce1f0c90d960f53bd384045b41023064bc4 (diff) | |
(김준회) dolce: 동기화 기능 추가, 로컬 다운로드, 삭제 추가, 동기화 dialog 개선 등
Diffstat (limited to 'db/schema')
| -rw-r--r-- | db/schema/dolce/dolce.ts | 89 | ||||
| -rw-r--r-- | db/schema/index.ts | 2 |
2 files changed, 91 insertions, 0 deletions
diff --git a/db/schema/dolce/dolce.ts b/db/schema/dolce/dolce.ts new file mode 100644 index 00000000..378d29d2 --- /dev/null +++ b/db/schema/dolce/dolce.ts @@ -0,0 +1,89 @@ +import { pgSchema, varchar, timestamp, jsonb, text, index, serial, boolean, uuid, integer } from "drizzle-orm/pg-core"; + +export const dolceSchema = pgSchema("dolce"); + +/** + * 돌체 스키마: 동기화 기능을 만들기 위해, 로컬에 임시 저장을 위한 퍼시스턴스 레이어를 구성 + * + * 전체적인 설명: + * 외부 시스템인 돌체는 문서관리 시스템임. + * 우리 시스템은 돌체와 API 를 통해, 벤더가 문서를 넣어줄 수 있게 하는 역할을 함. + * + * 특정 프로젝트에 B3, B4 라는 타입으로 문서를 관리함 + * B3는 일반 벤더, B4는 GTT 라는 특정 벤더에 대한 타입임. + * + * 전체적인 구조는 B3, B4가 유사함 + * - 도면리스트: 외부시스템에서 관리하므로, 우리는 받기만 함 + * + * - 상세도면리스트: 특정 도면에 소속된 개별 도면임. + * Revision을 관리하기 위해 생긴 레이어이며, 개별 도면에 연결된, 파일이 첨부된 실제 수발신하는 도면 단위라고 보면 됨. + * 외부시스템(DOLCE)에서 리스트를 API로 응답함. 개별 도면별로 응답함. + * 우리 시스템에서 벤더가 생성한다. (생성 API를 호출함) 단, 외부 시스템 측에서도 작업해 응답 결과를 다르게 줄 수도 있음. + * 우리 시스템에서 벤더가 수정할 수 있다. (수정 API를 호출함) 수정시에도 로컬 측에 저장하고, 동기화시 수정된 내용을 외부시스템에 전송한다. + * 우리 시스템에서 벤더가 상세도면을 생성했을 때, 우선 우리 시스템 DB에만 생성하고, API 응답 리스트에 로컬DB 임시저장값을 추가해서 보여줄 것임. + * + * - 파일리스트: 외부시스템에서 관리하며, 개별 상세도면에 첨부된 파일 리스트임. + * 외부시스템(DOLCE)에서 특정 상세도면의 파일 리스트를 API로 조회할 수 있음. 개별 상세도면에 할당된 uploadId 별로 파일리스트를 응답함. + * 우리 시스템에서 벤더가 파일을 추가하기도 함. 이 경우, 우선 우리 시스템 DB에 추가한 파일 정보를 임시 저장하고, API 응답 리스트에 로컬DB 임시저장값을 추가해서 보여줄 것임. + * + * 동기화 기능 + * - 우리 시스템에서 상세도면 추가 및 첨부파일을 추가했던 건들을 외부시스템에 전송해주는 기능임 + * - 임시 저장시 dolce에 생성/수정 요청을 할 수 있도록 필요한 정보를 저장해야 함. 이것은 스키마의 작성 기준임 + * - 동기화 하기 이전에, 우리 시스템에서 임시로 저장한 건들은 삭제할 수 있도록 함. (soft 삭제가 아니고 hard 삭제) + * + * 동기화 목록 구성 방법 + * - isSynced==false 인 건들로 목록을 구성한다. + * - 상세도면 추가 작업 건은, 상세도면+첨부파일을 하나의 동기화 건으로 구성한다. + * - 파일 추가 작업 건은, 개별 파일들을 동기화 건으로 구성한다. + * - B4 Bulk 업로드 건은, 개별 파일들을 동기화 건으로 구성한다. + * - 사용자는 본인이 임시 저장한 건들만을 선택해서 동기화할 수 있도록 한다. + * + * 사용자가 로컬에 파일 업로드하는 부분의 구현 + * 1. 환경변수 DOLCE_LOCAL_UPLOAD_ABSOLUTE_DIRECTORY="/evcp/data/dolce" 가 설정되어 있음. (없으면 경로 만들기) + * 2. 로컬에서 저장할 때는 파일 메타데이터를 별도로 저장 (로컬 파일 경로는 API 호출시 사용하지 않으나, 로컬 건들도 조회 및 다운로드가 가능해야 하므로) + * 3. 동기화되지 않아 로컬에만 있는 건들은 파일 다운로드시 로컬에서 다운로드 + * 4. 동기화 성공한 경우, 로컬에 저장된 파일은 삭제 + */ + +export const dolceSyncList = dolceSchema.table("dolce_sync_list", { + id: uuid("id").primaryKey().defaultRandom(), + + // [필수] 작업 유형 + // "ADD_DETAIL": 상세도면 추가 (메타데이터 + 파일) + // "MOD_DETAIL": 상세도면 수정 (메타데이터) + // "ADD_FILE": 기존 상세도면에 파일 추가 (파일) + // "B4_BULK": B4 일괄 업로드 + type: varchar("type", { length: 50 }).notNull(), + + // [중요] 조회 성능 및 필터링을 위한 메타데이터 컬럼 (JSONB에서 자주 쓰는 값 추출) + projectNo: varchar("project_no", { length: 50 }).notNull(), // 프로젝트별 조회용 + drawingNo: varchar("drawing_no", { length: 100 }), // 특정 도면 조회용 + uploadId: varchar("upload_id", { length: 100 }), // 업로드ID 기준 조회용 + + userId: varchar("user_id", { length: 50 }).notNull(), // 내 작업만 보기용 + userName: varchar("user_name", { length: 100 }), // [추가] UI 표시용 + vendorCode: varchar("vendor_code", { length: 50 }), // [추가] 벤더별 필터링용 + + // [데이터] + // 실제 API 호출에 필요한 Body 데이터 + 로컬 파일 경로 정보 포함 + // 예: { meta: { ...API Body... }, files: [{ localPath: "...", originalName: "..." }] } + payload: jsonb("payload").notNull(), + + // [상태] + isSynced: boolean("is_synced").default(false).notNull(), + syncAttempts: integer("sync_attempts").default(0).notNull(), + lastError: text("last_error"), // 실패 사유 + + // [응답] + responseCode: varchar("response_code", { length: 50 }), + response: text("response"), + + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").defaultNow().notNull(), +}, (table) => ({ + // 인덱스 설정: 프로젝트별 미동기화 건 조회 속도 향상 + projectIdx: index("dolce_sync_project_idx").on(table.projectNo, table.isSynced), + userIdx: index("dolce_sync_user_idx").on(table.userId, table.isSynced), + // [추가] 벤더별 조회 인덱스 + vendorIdx: index("dolce_sync_vendor_idx").on(table.projectNo, table.vendorCode, table.isSynced), +})); diff --git a/db/schema/index.ts b/db/schema/index.ts index 1155740b..df4ca424 100644 --- a/db/schema/index.ts +++ b/db/schema/index.ts @@ -85,3 +85,5 @@ export * from './avl/vendor-pool'; // === Email Logs 스키마 === export * from './emailLogs'; export * from './emailWhitelist'; +// Dolce 로컬 저장용 스키마 +export * from './dolce/dolce';
\ No newline at end of file |
