summaryrefslogtreecommitdiff
path: root/db/schema/gtc.ts
diff options
context:
space:
mode:
Diffstat (limited to 'db/schema/gtc.ts')
-rw-r--r--db/schema/gtc.ts174
1 files changed, 171 insertions, 3 deletions
diff --git a/db/schema/gtc.ts b/db/schema/gtc.ts
index a4052d61..281b6af9 100644
--- a/db/schema/gtc.ts
+++ b/db/schema/gtc.ts
@@ -8,9 +8,9 @@ import {
pgEnum,
boolean,
index,
- uniqueIndex
+ uniqueIndex, pgView
} from "drizzle-orm/pg-core"
- import { relations } from "drizzle-orm"
+ import { relations ,sql, eq} from "drizzle-orm"
import { projects } from "./projects"
import { users } from "./users"
@@ -107,4 +107,172 @@ import { users } from "./users"
id: number
name: string
}
- } \ No newline at end of file
+ }
+
+
+ export const gtcDocumentsView = pgView('gtc_documents_view').as((qb) =>
+ qb
+ .select({
+ // GTC 문서 기본 필드
+ id: gtcDocuments.id,
+ type: gtcDocuments.type,
+ projectId: gtcDocuments.projectId,
+ revision: gtcDocuments.revision,
+ fileName: gtcDocuments.fileName,
+ filePath: gtcDocuments.filePath,
+ fileSize: gtcDocuments.fileSize,
+ createdAt: gtcDocuments.createdAt,
+ createdById: gtcDocuments.createdById,
+ updatedAt: gtcDocuments.updatedAt,
+ updatedById: gtcDocuments.updatedById,
+ editReason: gtcDocuments.editReason,
+ isActive: gtcDocuments.isActive,
+
+ // 프로젝트 정보
+ projectCode: projects.code,
+ projectName: projects.name,
+
+ // 생성자 정보
+ createdByName: sql<string>`created_by_user.name`.as('created_by_name'),
+ createdByEmail: sql<string>`created_by_user.email`.as('created_by_email'),
+
+ // 수정자 정보
+ updatedByName: sql<string>`updated_by_user.name`.as('updated_by_name'),
+ updatedByEmail: sql<string>`updated_by_user.email`.as('updated_by_email'),
+
+ // 집계 필드들
+ // 같은 타입/프로젝트의 총 문서 수
+ totalDocumentsInGroup: sql<number>`
+ (
+ SELECT count(*)
+ FROM gtc_documents gd2
+ WHERE gd2.type = ${gtcDocuments.type}
+ AND gd2.is_active = true
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd2.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd2.project_id IS NULL)
+ )
+ )
+ `.as('total_documents_in_group'),
+
+ // 최신 리비전 번호
+ latestRevision: sql<number>`
+ (
+ SELECT max(revision)
+ FROM gtc_documents gd3
+ WHERE gd3.type = ${gtcDocuments.type}
+ AND gd3.is_active = true
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd3.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd3.project_id IS NULL)
+ )
+ )
+ `.as('latest_revision'),
+
+ // 현재 문서가 최신인지 여부
+ isLatestRevision: sql<boolean>`
+ ${gtcDocuments.revision} = (
+ SELECT max(revision)
+ FROM gtc_documents gd4
+ WHERE gd4.type = ${gtcDocuments.type}
+ AND gd4.is_active = true
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd4.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd4.project_id IS NULL)
+ )
+ )
+ `.as('is_latest_revision'),
+
+ // 이전 리비전 ID (있다면)
+ previousRevisionId: sql<number>`
+ (
+ SELECT id
+ FROM gtc_documents gd5
+ WHERE gd5.type = ${gtcDocuments.type}
+ AND gd5.is_active = true
+ AND gd5.revision < ${gtcDocuments.revision}
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd5.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd5.project_id IS NULL)
+ )
+ ORDER BY gd5.revision DESC
+ LIMIT 1
+ )
+ `.as('previous_revision_id'),
+
+ // 다음 리비전 ID (있다면)
+ nextRevisionId: sql<number>`
+ (
+ SELECT id
+ FROM gtc_documents gd6
+ WHERE gd6.type = ${gtcDocuments.type}
+ AND gd6.is_active = true
+ AND gd6.revision > ${gtcDocuments.revision}
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd6.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd6.project_id IS NULL)
+ )
+ ORDER BY gd6.revision ASC
+ LIMIT 1
+ )
+ `.as('next_revision_id'),
+
+ // 파일 크기 (사람이 읽기 쉬운 형태)
+ fileSizeFormatted: sql<string>`
+ CASE
+ WHEN ${gtcDocuments.fileSize} IS NULL THEN NULL
+ WHEN ${gtcDocuments.fileSize} < 1024 THEN ${gtcDocuments.fileSize} || ' B'
+ WHEN ${gtcDocuments.fileSize} < 1024 * 1024 THEN round(${gtcDocuments.fileSize} / 1024.0, 1) || ' KB'
+ WHEN ${gtcDocuments.fileSize} < 1024 * 1024 * 1024 THEN round(${gtcDocuments.fileSize} / (1024.0 * 1024), 1) || ' MB'
+ ELSE round(${gtcDocuments.fileSize} / (1024.0 * 1024 * 1024), 1) || ' GB'
+ END
+ `.as('file_size_formatted'),
+
+ // 프로젝트가 있는 경우, 해당 프로젝트의 총 GTC 문서 수
+ projectTotalDocuments: sql<number>`
+ CASE
+ WHEN ${gtcDocuments.projectId} IS NOT NULL THEN (
+ SELECT count(*)
+ FROM gtc_documents gd7
+ WHERE gd7.project_id = ${gtcDocuments.projectId}
+ AND gd7.is_active = true
+ )
+ ELSE NULL
+ END
+ `.as('project_total_documents'),
+
+ // 리비전 히스토리 (배열로 반환)
+ revisionHistory: sql<number[]>`
+ (
+ SELECT array_agg(revision ORDER BY revision)
+ FROM gtc_documents gd8
+ WHERE gd8.type = ${gtcDocuments.type}
+ AND gd8.is_active = true
+ AND (
+ (${gtcDocuments.type} = 'project' AND gd8.project_id = ${gtcDocuments.projectId}) OR
+ (${gtcDocuments.type} = 'standard' AND gd8.project_id IS NULL)
+ )
+ )
+ `.as('revision_history'),
+
+ // 수정 이력이 있는지 여부
+ hasEditHistory: sql<boolean>`
+ ${gtcDocuments.createdById} != ${gtcDocuments.updatedById} OR
+ ${gtcDocuments.createdAt} != ${gtcDocuments.updatedAt}
+ `.as('has_edit_history'),
+ })
+ .from(gtcDocuments)
+ .leftJoin(projects, sql`${gtcDocuments.projectId} = ${projects.id}`)
+ .leftJoin(
+ sql`users created_by_user`,
+ sql`${gtcDocuments.createdById} = created_by_user.id`
+ )
+ .leftJoin(
+ sql`users updated_by_user`,
+ sql`${gtcDocuments.updatedById} = updated_by_user.id`
+ )
+ );
+
+ export type GtcDocumentView = typeof gtcDocumentsView.$inferSelect;
+
+ \ No newline at end of file