);
}
```
### 5.2 렌더링 결과 예시
**데스크톱 (lg: 1024px+)**:
```
┌─────────────────────────────────────────────────────────┐
│ [분리] [저장] [수정] [삭제] │ ← 버튼들 오른쪽 정렬
├─────────────────────────────────────────────────────────┤
│ │
│ 테이블 컴포넌트 │
│ │
└─────────────────────────────────────────────────────────┘
```
**태블릿 (md: 768px ~ 1024px)**:
```
┌───────────────────────────────┐
│ [분리] [저장] [수정] [삭제] │ ← 버튼들 2개씩
├───────────────────────────────┤
│ │
│ 테이블 컴포넌트 │
│ │
└───────────────────────────────┘
```
**모바일 (sm: < 768px)**:
```
┌─────────────────┐
│ [분리] │
│ [저장] │
│ [수정] │ ← 세로 스택
│ [삭제] │
├─────────────────┤
│ 테이블 컴포넌트 │
│ (스크롤) │
└─────────────────┘
```
---
## 6. 마이그레이션 계획
### 6.1 데이터 마이그레이션 스크립트
```sql
-- 기존 데이터를 V3 구조로 변환하는 함수
CREATE OR REPLACE FUNCTION migrate_layout_to_v3(layout_data JSONB)
RETURNS JSONB AS $$
DECLARE
result JSONB;
component JSONB;
new_components JSONB := '[]'::JSONB;
grid_col INT;
grid_row INT;
col_span INT;
row_span INT;
BEGIN
-- 각 컴포넌트 변환
FOR component IN SELECT * FROM jsonb_array_elements(layout_data->'components')
LOOP
-- 픽셀 → 그리드 변환 (160px = 1컬럼, 80px = 1행)
grid_col := GREATEST(1, LEAST(12, ROUND((component->'position'->>'x')::NUMERIC / 160) + 1));
grid_row := GREATEST(1, ROUND((component->'position'->>'y')::NUMERIC / 80) + 1);
col_span := GREATEST(1, LEAST(13 - grid_col, ROUND((component->'size'->>'width')::NUMERIC / 160)));
row_span := GREATEST(1, ROUND((component->'size'->>'height')::NUMERIC / 80));
-- 새 컴포넌트 구조 생성
component := component || jsonb_build_object(
'grid', jsonb_build_object(
'col', grid_col,
'row', grid_row,
'colSpan', col_span,
'rowSpan', row_span
),
'responsive', jsonb_build_object(
'sm', jsonb_build_object('col', 1, 'colSpan', 12),
'md', jsonb_build_object('col', GREATEST(1, ROUND(grid_col / 2.0)), 'colSpan', LEAST(col_span * 2, 12)),
'lg', jsonb_build_object('col', grid_col, 'colSpan', col_span)
)
);
-- position, size 필드 제거 (선택사항 - 호환성 위해 유지 가능)
-- component := component - 'position' - 'size';
new_components := new_components || component;
END LOOP;
-- 결과 생성
result := jsonb_build_object(
'version', '3.0',
'layoutMode', 'grid',
'components', new_components,
'gridSettings', COALESCE(layout_data->'gridSettings', '{"columns": 12, "rowHeight": 80, "gap": 16}'::JSONB)
);
RETURN result;
END;
$$ LANGUAGE plpgsql;
-- 마이그레이션 실행
UPDATE screen_layouts_v2
SET layout_data = migrate_layout_to_v3(layout_data)
WHERE (layout_data->>'version') = '2.0';
```
### 6.2 백워드 호환성
V2 ↔ V3 호환을 위한 변환 레이어:
```typescript
// frontend/lib/utils/layoutVersionConverter.ts
export function normalizeLayout(layout: any): NormalizedLayout {
const version = layout.version || "2.0";
if (version === "2.0") {
// V2 → V3 변환 (렌더링 시)
return {
...layout,
version: "3.0",
layoutMode: "grid",
components: layout.components.map((comp: any) => ({
...comp,
grid: pixelToGrid(comp.position, comp.size),
responsive: getDefaultResponsive(pixelToGrid(comp.position, comp.size)),
})),
};
}
return layout; // V3는 그대로
}
```
---
## 7. 디자인 모드 수정
### 7.1 그리드 편집 UI
디자인 모드에서 그리드 셀 선택 방식 추가:
```tsx
// 기존: 픽셀 좌표 입력
updatePosition({ x })}
/>
// 변경: 그리드 셀 선택
{Array.from({ length: 12 }).map((_, col) => (
setGridCol(col + 1)}
/>
))}
```
### 7.2 반응형 미리보기
```tsx
// 화면 크기 미리보기 버튼
// 미리보기 컨테이너
```
---
## 8. 작업 목록
### Phase 1: 핵심 유틸리티 (1일)
| 작업 | 파일 | 상태 |
|------|------|------|
| 그리드 변환 함수 | `lib/utils/gridConverter.ts` | ⬜ |
| 클래스 생성 함수 | `lib/utils/gridClassGenerator.ts` | ⬜ |
| Tailwind safelist 설정 | `tailwind.config.js` | ⬜ |
### Phase 2: 렌더링 수정 (1일)
| 작업 | 파일 | 상태 |
|------|------|------|
| ResponsiveGridLayout 생성 | `lib/registry/layouts/responsive-grid/` | ⬜ |
| 레이아웃 버전 분기 처리 | `lib/registry/DynamicComponentRenderer.tsx` | ⬜ |
### Phase 3: 저장 로직 수정 (1일)
| 작업 | 파일 | 상태 |
|------|------|------|
| 저장 시 그리드 변환 | `components/screen/ScreenDesigner.tsx` | ⬜ |
| V3 레이아웃 변환기 | `lib/utils/layoutV3Converter.ts` | ⬜ |
### Phase 4: 디자인 모드 UI (1일)
| 작업 | 파일 | 상태 |
|------|------|------|
| 그리드 셀 편집 UI | `components/screen/panels/V2PropertiesPanel.tsx` | ⬜ |
| 반응형 미리보기 | `components/screen/ScreenDesigner.tsx` | ⬜ |
### Phase 5: 마이그레이션 (0.5일)
| 작업 | 파일 | 상태 |
|------|------|------|
| 마이그레이션 스크립트 | `db/migrations/xxx_migrate_to_v3.sql` | ⬜ |
| 백워드 호환성 테스트 | - | ⬜ |
---
## 9. 예상 일정
| 단계 | 기간 | 완료 기준 |
|------|------|-----------|
| Phase 1 | 1일 | 유틸리티 함수 테스트 통과 |
| Phase 2 | 1일 | 그리드 렌더링 정상 동작 |
| Phase 3 | 1일 | 저장/로드 정상 동작 |
| Phase 4 | 1일 | 디자인 모드 UI 완성 |
| Phase 5 | 0.5일 | 기존 데이터 마이그레이션 완료 |
| 테스트 | 0.5일 | 모든 화면 반응형 테스트 |
| **합계** | **5일** | |
---
## 10. 리스크 및 대응
| 리스크 | 영향 | 대응 방안 |
|--------|------|-----------|
| 기존 레이아웃 깨짐 | 높음 | position/size 필드 유지하여 폴백 |
| Tailwind 동적 클래스 | 중간 | safelist로 모든 클래스 사전 정의 |
| 디자인 모드 혼란 | 낮음 | 그리드 가이드라인 시각화 |
---
## 11. 참고 자료
- [COMPONENT_LAYOUT_V2_ARCHITECTURE.md](./COMPONENT_LAYOUT_V2_ARCHITECTURE.md) - V2 아키텍처
- [Tailwind CSS Grid](https://tailwindcss.com/docs/grid-template-columns) - 그리드 시스템
- [shadcn/ui](https://ui.shadcn.com/) - 컴포넌트 라이브러리