summaryrefslogtreecommitdiff
path: root/lib/sedp/sync-object-class.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sedp/sync-object-class.ts')
-rw-r--r--lib/sedp/sync-object-class.ts257
1 files changed, 245 insertions, 12 deletions
diff --git a/lib/sedp/sync-object-class.ts b/lib/sedp/sync-object-class.ts
index 1cf0c23b..0a76c592 100644
--- a/lib/sedp/sync-object-class.ts
+++ b/lib/sedp/sync-object-class.ts
@@ -40,7 +40,12 @@ interface SyncResult {
count?: number;
error?: string;
}
-
+interface TagType {
+ TYPE_ID: string;
+ DESC: string;
+ PROJ_NO: string;
+ // 기타 필드들...
+}
// 오브젝트 클래스 데이터 가져오기
async function getObjectClasses(projectCode: string, token:string): Promise<ObjectClass[]> {
try {
@@ -55,7 +60,8 @@ async function getObjectClasses(projectCode: string, token:string): Promise<Obje
'ProjectNo': projectCode
},
body: JSON.stringify({
- ContainDeleted: true
+ ProjectNo:projectCode,
+ ContainDeleted: false
})
}
);
@@ -95,11 +101,171 @@ async function verifyTagTypes(projectId: number, tagTypeCodes: string[]): Promis
}
}
-// 데이터베이스에 오브젝트 클래스 저장 (upsert 사용)
-async function saveObjectClassesToDatabase(projectId: number, classes: ObjectClass[]): Promise<number> {
+async function saveTagTypesToDatabase(allTagTypes: TagType[], projectCode: string): Promise<void> {
+ try {
+ if (allTagTypes.length === 0) {
+ console.log(`프로젝트 ${projectCode}에 저장할 태그 타입이 없습니다.`);
+ return;
+ }
+
+ // 프로젝트 코드로 프로젝트 ID 조회
+ const projectResult = await db.select({ id: projects.id })
+ .from(projects)
+ .where(eq(projects.code, projectCode))
+ .limit(1);
+
+ if (projectResult.length === 0) {
+ throw new Error(`프로젝트 코드 ${projectCode}에 해당하는 프로젝트를 찾을 수 없습니다.`);
+ }
+
+ const projectId = projectResult[0].id;
+
+ // 현재 프로젝트의 모든 태그 타입 조회
+ const existingTagTypes = await db.select()
+ .from(tagTypes)
+ .where(eq(tagTypes.projectId, projectId));
+
+ // 코드 기준으로 맵 생성
+ const existingTagTypeMap = new Map(
+ existingTagTypes.map(type => [type.code, type])
+ );
+
+ // API에 있는 코드 목록
+ const apiTagTypeCodes = new Set(allTagTypes.map(type => type.TYPE_ID));
+
+ // 삭제할 코드 목록
+ const codesToDelete = existingTagTypes
+ .map(type => type.code)
+ .filter(code => !apiTagTypeCodes.has(code));
+
+ // 새로 추가할 항목
+ const toInsert = [];
+
+ // 업데이트할 항목
+ const toUpdate = [];
+
+ // 태그 타입 데이터 처리
+ for (const tagType of allTagTypes) {
+ // 데이터베이스 레코드 준비
+ const record = {
+ code: tagType.TYPE_ID,
+ projectId: projectId,
+ description: tagType.DESC,
+ updatedAt: new Date()
+ };
+
+ // 이미 존재하는 코드인지 확인
+ if (existingTagTypeMap.has(tagType.TYPE_ID)) {
+ // 업데이트 항목에 추가
+ toUpdate.push(record);
+ } else {
+ // 새로 추가할 항목에 추가 (createdAt 필드 추가)
+ toInsert.push({
+ ...record,
+ createdAt: new Date()
+ });
+ }
+ }
+
+ // 트랜잭션 실행
+
+ // 1. 새 항목 삽입
+ if (toInsert.length > 0) {
+ await db.insert(tagTypes).values(toInsert);
+ console.log(`프로젝트 ID ${projectId}에 ${toInsert.length}개의 새 태그 타입 추가 완료`);
+ }
+
+ // 2. 기존 항목 업데이트
+ for (const item of toUpdate) {
+ await db.update(tagTypes)
+ .set({
+ description: item.description,
+ updatedAt: item.updatedAt
+ })
+ .where(
+ and(
+ eq(tagTypes.code, item.code),
+ eq(tagTypes.projectId, item.projectId)
+ )
+ );
+ }
+
+ if (toUpdate.length > 0) {
+ console.log(`프로젝트 ID ${projectId}의 ${toUpdate.length}개 태그 타입 업데이트 완료`);
+ }
+
+ // 3. 더 이상 존재하지 않는 항목 삭제
+ if (codesToDelete.length > 0) {
+ for (const code of codesToDelete) {
+ await db.delete(tagTypes)
+ .where(
+ and(
+ eq(tagTypes.code, code),
+ eq(tagTypes.projectId, projectId)
+ )
+ );
+ }
+ console.log(`프로젝트 ID ${projectId}에서 ${codesToDelete.length}개의 태그 타입 삭제 완료`);
+ }
+
+ console.log(`프로젝트 ${projectCode}(ID: ${projectId})의 태그 타입 동기화 완료`);
+ } catch (error) {
+ console.error(`태그 타입 저장 실패 (프로젝트: ${projectCode}):`, error);
+ throw error;
+ }
+}
+
+async function getAllTagTypes(projectCode: string, token: string): Promise<TagType[]> {
+ try {
+ console.log(`프로젝트 ${projectCode}의 모든 태그 타입 가져오기 시작`);
+
+ const response = await fetch(
+ `${SEDP_API_BASE_URL}/TagType/Get`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'accept': '*/*',
+ 'ApiKey': token,
+ 'ProjectNo': projectCode
+ },
+ body: JSON.stringify({
+ ProjectNo: projectCode,
+ ContainDeleted: false
+ })
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error(`태그 타입 요청 실패: ${response.status} ${response.statusText}`);
+ }
+
+ const data = await response.json();
+
+ // 결과가 배열인지 확인
+ if (Array.isArray(data)) {
+ return data;
+ } else {
+ // 단일 객체인 경우 배열로 변환
+ return [data];
+ }
+ } catch (error) {
+ console.error('태그 타입 목록 가져오기 실패:', error);
+ throw error;
+ }
+}
+
+// 4. 기존 함수 수정 - saveObjectClassesToDatabase
+async function saveObjectClassesToDatabase(
+ projectId: number,
+ classes: ObjectClass[],
+ projectCode: string,
+ token: string,
+ skipTagTypeSync: boolean = false // 태그 타입 동기화를 건너뛸지 여부
+): Promise<number> {
try {
// null이 아닌 TAG_TYPE_ID만 필터링
- const validClasses = classes.filter(cls => cls.TAG_TYPE_ID !== null);
+ const validClasses = classes.filter(cls => cls.TAG_TYPE_ID !== null && cls.TAG_TYPE_ID !== "") ;
if (validClasses.length === 0) {
console.log(`프로젝트 ID ${projectId}에 저장할 유효한 오브젝트 클래스가 없습니다.`);
@@ -109,6 +275,25 @@ async function saveObjectClassesToDatabase(projectId: number, classes: ObjectCla
// 모든 태그 타입 ID 목록 추출
const tagTypeCodes = validClasses.map(cls => cls.TAG_TYPE_ID!);
+ // skipTagTypeSync가 true인 경우 태그 타입 동기화 단계 건너뜀
+ if (!skipTagTypeSync) {
+ // 태그 타입이 없는 경우를 대비해 태그 타입 정보 먼저 가져와서 저장
+ console.log(`프로젝트 ID ${projectId}의 태그 타입 동기화 시작...`);
+
+ try {
+ // 프로젝트의 모든 태그 타입 가져오기
+ const allTagTypes = await getAllTagTypes(projectCode, token);
+
+ // 태그 타입 저장
+ await saveTagTypesToDatabase(allTagTypes, projectCode);
+ } catch (error) {
+ console.error(`프로젝트 ${projectCode}의 태그 타입 동기화 실패:`, error);
+ // 에러가 발생해도 계속 진행
+ }
+
+ console.log(`프로젝트 ID ${projectId}의 태그 타입 동기화 완료`);
+ }
+
// 존재하는 태그 타입 확인
const existingTagTypeCodes = await verifyTagTypes(projectId, tagTypeCodes);
@@ -122,6 +307,7 @@ async function saveObjectClassesToDatabase(projectId: number, classes: ObjectCla
return 0;
}
+ // 이하 기존 코드와 동일
// 현재 프로젝트의 오브젝트 클래스 코드 가져오기
const existingClasses = await db.select()
.from(tagClasses)
@@ -223,7 +409,7 @@ async function saveObjectClassesToDatabase(projectId: number, classes: ObjectCla
}
}
-// 메인 동기화 함수
+// 5. 메인 동기화 함수 수정
export async function syncObjectClasses() {
try {
console.log('오브젝트 클래스 동기화 시작:', new Date().toISOString());
@@ -234,15 +420,55 @@ export async function syncObjectClasses() {
// 2. 모든 프로젝트 가져오기
const allProjects = await db.select().from(projects);
- // 3. 각 프로젝트에 대해 오브젝트 클래스 동기화
+ // 3. 모든 프로젝트에 대해 먼저 태그 타입 동기화 (바로 이 부분이 추가됨)
+ console.log('모든 프로젝트의 태그 타입 동기화 시작...');
+
+ const tagTypeResults = await Promise.allSettled(
+ allProjects.map(async (project: Project) => {
+ try {
+ console.log(`프로젝트 ${project.code}의 태그 타입 동기화 시작...`);
+ // 프로젝트의 모든 태그 타입 가져오기
+ const allTagTypes = await getAllTagTypes(project.code, token);
+
+ // 태그 타입 저장
+ await saveTagTypesToDatabase(allTagTypes, project.code);
+ console.log(`프로젝트 ${project.code}의 태그 타입 동기화 완료`);
+
+ return {
+ project: project.code,
+ success: true,
+ count: allTagTypes.length
+ };
+ } catch (error) {
+ console.error(`프로젝트 ${project.code}의 태그 타입 동기화 실패:`, error);
+ return {
+ project: project.code,
+ success: false,
+ error: error instanceof Error ? error.message : String(error)
+ };
+ }
+ })
+ );
+
+ // 태그 타입 동기화 결과 집계
+ const tagTypeSuccessCount = tagTypeResults.filter(
+ result => result.status === 'fulfilled' && result.value.success
+ ).length;
+
+ const tagTypeFailCount = tagTypeResults.length - tagTypeSuccessCount;
+
+ console.log(`모든 프로젝트의 태그 타입 동기화 완료: ${tagTypeSuccessCount}개 성공, ${tagTypeFailCount}개 실패`);
+
+ // 4. 각 프로젝트에 대해 오브젝트 클래스 동기화 (태그 타입 동기화는 건너뜀)
const results = await Promise.allSettled(
allProjects.map(async (project: Project) => {
try {
// 오브젝트 클래스 데이터 가져오기
const objectClasses = await getObjectClasses(project.code, token);
- // 데이터베이스에 저장
- const count = await saveObjectClassesToDatabase(project.id, objectClasses);
+ // 데이터베이스에 저장 (skipTagTypeSync를 true로 설정하여 태그 타입 동기화 건너뜀)
+ const count = await saveObjectClassesToDatabase(project.id, objectClasses, project.code, token, true);
+
return {
project: project.code,
success: true,
@@ -291,10 +517,17 @@ export async function syncObjectClasses() {
console.log(`오브젝트 클래스 동기화 완료: ${successCount}개 프로젝트 성공 (총 ${totalItems}개 항목), ${failCount}개 프로젝트 실패`);
+ // 전체 결과에 태그 타입 동기화 결과도 포함
return {
- success: successCount,
- failed: failCount,
- items: totalItems,
+ tagTypeSync: {
+ success: tagTypeSuccessCount,
+ failed: tagTypeFailCount
+ },
+ objectClassSync: {
+ success: successCount,
+ failed: failCount,
+ items: totalItems
+ },
timestamp: new Date().toISOString()
};
} catch (error) {