feat: Phase 2.1 Stage 2 complete - 레이아웃 관리 전환 (12/46)

Stage 2 완료: 레이아웃 관리 Raw Query 전환

 전환 완료 (4개 Prisma 호출):
9. saveLayout() - 레이아웃 저장
   - 권한 확인 쿼리
   - 기존 레이아웃 삭제 (DELETE)
   - 메타데이터 INSERT (격자 설정, 해상도)
   - 컴포넌트 루프 INSERT (JSON properties)

10. getLayout() - 레이아웃 조회
   - 권한 확인 쿼리
   - 레이아웃 조회 (ORDER BY display_order)

📊 진행률: 12/46 (26.1%)
🎯 다음: Stage 3 템플릿 & 메뉴 관리 전환

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kjs 2025-09-30 16:29:59 +09:00
parent 0e8d1d496d
commit 67dced74bd
1 changed files with 62 additions and 45 deletions

View File

@ -1116,7 +1116,7 @@ export class ScreenManagementService {
// ========================================
/**
*
* ( Raw Query )
*/
async saveLayout(
screenId: number,
@ -1130,22 +1130,26 @@ export class ScreenManagementService {
console.log(`해상도 설정:`, layoutData.screenResolution);
// 권한 확인
const existingScreen = await prisma.screen_definitions.findUnique({
where: { screen_id: screenId },
});
const screens = await query<{ company_code: string | null }>(
`SELECT company_code FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
[screenId]
);
if (!existingScreen) {
if (screens.length === 0) {
throw new Error("화면을 찾을 수 없습니다.");
}
const existingScreen = screens[0];
if (companyCode !== "*" && existingScreen.company_code !== companyCode) {
throw new Error("이 화면의 레이아웃을 저장할 권한이 없습니다.");
}
// 기존 레이아웃 삭제 (컴포넌트와 메타데이터 모두)
await prisma.screen_layouts.deleteMany({
where: { screen_id: screenId },
});
await query(
`DELETE FROM screen_layouts WHERE screen_id = $1`,
[screenId]
);
// 1. 메타데이터 저장 (격자 설정과 해상도 정보)
if (layoutData.gridSettings || layoutData.screenResolution) {
@ -1154,20 +1158,24 @@ export class ScreenManagementService {
screenResolution: layoutData.screenResolution,
};
await prisma.screen_layouts.create({
data: {
screen_id: screenId,
component_type: "_metadata", // 특별한 타입으로 메타데이터 식별
component_id: `_metadata_${screenId}`,
parent_id: null,
position_x: 0,
position_y: 0,
width: 0,
height: 0,
properties: metadata,
display_order: -1, // 메타데이터는 맨 앞에 배치
},
});
await query(
`INSERT INTO screen_layouts (
screen_id, component_type, component_id, parent_id,
position_x, position_y, width, height, properties, display_order
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
[
screenId,
"_metadata", // 특별한 타입으로 메타데이터 식별
`_metadata_${screenId}`,
null,
0,
0,
0,
0,
JSON.stringify(metadata),
-1, // 메타데이터는 맨 앞에 배치
]
);
console.log(`메타데이터 저장 완료:`, metadata);
}
@ -1185,7 +1193,7 @@ export class ScreenManagementService {
title: (component as any).title,
});
// Prisma JSON 필드에 맞는 타입으로 변환
// JSON 필드에 맞는 타입으로 변환
const properties: any = {
...componentData,
position: {
@ -1199,26 +1207,30 @@ export class ScreenManagementService {
},
};
await prisma.screen_layouts.create({
data: {
screen_id: screenId,
component_type: component.type,
component_id: component.id,
parent_id: component.parentId || null,
position_x: component.position.x,
position_y: component.position.y,
width: component.size.width,
height: component.size.height,
properties: properties,
},
});
await query(
`INSERT INTO screen_layouts (
screen_id, component_type, component_id, parent_id,
position_x, position_y, width, height, properties
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
screenId,
component.type,
component.id,
component.parentId || null,
component.position.x,
component.position.y,
component.size.width,
component.size.height,
JSON.stringify(properties),
]
);
}
console.log(`=== 레이아웃 저장 완료 ===`);
}
/**
*
* ( Raw Query )
*/
async getLayout(
screenId: number,
@ -1228,22 +1240,27 @@ export class ScreenManagementService {
console.log(`화면 ID: ${screenId}`);
// 권한 확인
const existingScreen = await prisma.screen_definitions.findUnique({
where: { screen_id: screenId },
});
const screens = await query<{ company_code: string | null }>(
`SELECT company_code FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
[screenId]
);
if (!existingScreen) {
if (screens.length === 0) {
return null;
}
const existingScreen = screens[0];
if (companyCode !== "*" && existingScreen.company_code !== companyCode) {
throw new Error("이 화면의 레이아웃을 조회할 권한이 없습니다.");
}
const layouts = await prisma.screen_layouts.findMany({
where: { screen_id: screenId },
orderBy: { display_order: "asc" },
});
const layouts = await query<any>(
`SELECT * FROM screen_layouts
WHERE screen_id = $1
ORDER BY display_order ASC NULLS LAST, layout_id ASC`,
[screenId]
);
console.log(`DB에서 조회된 레이아웃 수: ${layouts.length}`);