import { pool } from "../database/db"; import logger from "../utils/logger"; export interface DigitalTwinLayoutTemplate { id: string; company_code: string; name: string; description?: string | null; external_db_connection_id: number; layout_type: string; config: any; created_by: string; created_at: Date; updated_by: string; updated_at: Date; } interface ServiceResponse { success: boolean; data?: T; message?: string; error?: string; } export class DigitalTwinTemplateService { static async listTemplates( companyCode: string, options: { externalDbConnectionId?: number; layoutType?: string } = {}, ): Promise> { try { const params: any[] = [companyCode]; let paramIndex = 2; let query = ` SELECT * FROM digital_twin_layout_template WHERE company_code = $1 `; if (options.layoutType) { query += ` AND layout_type = $${paramIndex++}`; params.push(options.layoutType); } if (options.externalDbConnectionId) { query += ` AND external_db_connection_id = $${paramIndex++}`; params.push(options.externalDbConnectionId); } query += ` ORDER BY updated_at DESC, name ASC `; const result = await pool.query(query, params); logger.info("디지털 트윈 매핑 템플릿 목록 조회", { companyCode, count: result.rowCount, }); return { success: true, data: result.rows as DigitalTwinLayoutTemplate[], }; } catch (error: any) { logger.error("디지털 트윈 매핑 템플릿 목록 조회 실패", error); return { success: false, error: error.message, message: "매핑 템플릿 목록 조회 중 오류가 발생했습니다.", }; } } static async getTemplateById( companyCode: string, id: string, ): Promise> { try { const query = ` SELECT * FROM digital_twin_layout_template WHERE id = $1 AND company_code = $2 `; const result = await pool.query(query, [id, companyCode]); if (result.rowCount === 0) { return { success: false, message: "매핑 템플릿을 찾을 수 없습니다.", }; } return { success: true, data: result.rows[0] as DigitalTwinLayoutTemplate, }; } catch (error: any) { logger.error("디지털 트윈 매핑 템플릿 조회 실패", error); return { success: false, error: error.message, message: "매핑 템플릿 조회 중 오류가 발생했습니다.", }; } } static async createTemplate( companyCode: string, userId: string, payload: { name: string; description?: string; externalDbConnectionId: number; layoutType?: string; config: any; }, ): Promise> { try { const query = ` INSERT INTO digital_twin_layout_template ( company_code, name, description, external_db_connection_id, layout_type, config, created_by, created_at, updated_by, updated_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), $7, NOW()) RETURNING * `; const values = [ companyCode, payload.name, payload.description || null, payload.externalDbConnectionId, payload.layoutType || "yard-3d", JSON.stringify(payload.config), userId, ]; const result = await pool.query(query, values); logger.info("디지털 트윈 매핑 템플릿 생성", { companyCode, templateId: result.rows[0].id, externalDbConnectionId: payload.externalDbConnectionId, }); return { success: true, data: result.rows[0] as DigitalTwinLayoutTemplate, }; } catch (error: any) { logger.error("디지털 트윈 매핑 템플릿 생성 실패", error); return { success: false, error: error.message, message: "매핑 템플릿 생성 중 오류가 발생했습니다.", }; } } }