ERP-node/popdocs/archive/BUGFIX_CANVAS_ROWS.md

5.6 KiB

POP 레이아웃 canvasGrid.rows 버그 수정

문제점

1. 데이터 불일치

  • DB에 저장된 데이터: canvasGrid.rowHeight: 20 (고정 픽셀)
  • 코드에서 기대하는 데이터: canvasGrid.rows: 24 (비율 기반)
  • 결과: rowsundefined로 인한 렌더링 오류

2. 타입 정의 불일치

  • PopCanvas.tsx 타입: { columns: number; rowHeight: number; gap: number }
  • 실제 사용: canvasGrid.rows로 계산
  • 결과: 타입 안정성 저하

3. 렌더링 오류

  • 디자이너: rowHeight = resolution.height / undefinedNaN
  • 뷰어: gridTemplateRows: repeat(undefined, 1fr) → CSS 무효
  • 결과: 섹션이 매우 작게 표시됨

수정 내용

1. ensureV2Layout 강화

파일: frontend/components/pop/designer/types/pop-layout.ts

export const ensureV2Layout = (data: PopLayoutData): PopLayoutDataV2 => {
  let result: PopLayoutDataV2;
  
  if (isV2Layout(data)) {
    result = data;
  } else if (isV1Layout(data)) {
    result = migrateV1ToV2(data);
  } else {
    console.warn("알 수 없는 레이아웃 버전, 빈 v2 레이아웃 생성");
    result = createEmptyPopLayoutV2();
  }
  
  // ✅ canvasGrid.rows 보장 (구버전 데이터 호환)
  if (!result.settings.canvasGrid.rows) {
    console.warn("canvasGrid.rows 없음, 기본값 24로 설정");
    result.settings.canvasGrid = {
      ...result.settings.canvasGrid,
      rows: DEFAULT_CANVAS_GRID.rows, // 24
    };
  }
  
  return result;
};

효과: DB에서 로드한 구버전 데이터도 자동으로 rows: 24 보장


2. PopCanvas.tsx 타입 수정 및 fallback

파일: frontend/components/pop/designer/PopCanvas.tsx

타입 정의 수정:

interface DeviceFrameProps {
  canvasGrid: { columns: number; rows: number; gap: number }; // rowHeight → rows
  // ...
}

fallback 추가:

// ✅ rows가 없으면 24 사용
const rows = canvasGrid.rows || 24;
const rowHeight = Math.floor(resolution.height / rows);

효과:

  • 타입 일관성 확보
  • NaN 방지

3. PopLayoutRenderer.tsx fallback

파일: frontend/components/pop/designer/renderers/PopLayoutRenderer.tsx

style={{
  display: "grid",
  gridTemplateColumns: `repeat(${canvasGrid.columns}, 1fr)`,
  // ✅ fallback 추가
  gridTemplateRows: `repeat(${canvasGrid.rows || 24}, 1fr)`,
  gap: `${canvasGrid.gap}px`,
  padding: `${canvasGrid.gap}px`,
}}

효과: 뷰어에서도 안전하게 렌더링


4. 백엔드 저장 로직 강화

파일: backend-node/src/services/screenManagementService.ts

if (isV2) {
  dataToSave = {
    ...layoutData,
    version: "pop-2.0",
  };
  
  // ✅ canvasGrid.rows 검증 및 보정
  if (dataToSave.settings?.canvasGrid) {
    if (!dataToSave.settings.canvasGrid.rows) {
      console.warn("canvasGrid.rows 없음, 기본값 24로 설정");
      dataToSave.settings.canvasGrid.rows = 24;
    }
    // ✅ 구버전 rowHeight 필드 제거
    if (dataToSave.settings.canvasGrid.rowHeight) {
      console.warn("구버전 rowHeight 필드 제거");
      delete dataToSave.settings.canvasGrid.rowHeight;
    }
  }
}

효과: 앞으로 저장되는 모든 데이터는 올바른 구조 보장


원칙 준수 여부

1. 데스크톱과 완전 분리

  • POP 전용 파일만 수정
  • 데스크톱 코드 0% 영향

2. 4모드 반응형 디자인

  • 변경 없음

3. 비율 기반 그리드 시스템

  • 오히려 원칙을 바로잡는 수정
  • 고정 픽셀(rowHeight) → 비율(rows) 강제

해결된 문제

문제 수정 전 수정 후
섹션 크기 매우 작게 표시 정상 크기 (24x24 그리드)
디자이너 렌더링 NaN 오류 정상 계산
뷰어 렌더링 CSS 무효 비율 기반 렌더링
타입 안정성 rowHeight vs rows 불일치 rows로 통일
구버전 데이터 호환 불가 자동 보정

테스트 방법

1. 기존 화면 확인 (screen_id: 3884)

# 디자이너 접속
http://localhost:9771/screen-management/pop-designer/3884

# 저장 후 뷰어 확인
http://localhost:9771/pop/screens/3884

기대 결과:

  • 섹션이 화면 전체 크기로 정상 표시
  • 가로/세로 모드 전환 시 비율 유지

2. 새로운 화면 생성

  • POP 디자이너에서 새 화면 생성
  • 섹션 추가 및 배치
  • 저장 후 DB 확인

DB 확인:

SELECT 
  screen_id,
  layout_data->'settings'->'canvasGrid' as canvas_grid
FROM screen_layouts_pop 
WHERE screen_id = 3884;

기대 결과:

{
  "gap": 4,
  "rows": 24,
  "columns": 24
}

추가 조치 사항

1. 기존 DB 데이터 마이그레이션 (선택)

만약 프론트엔드 자동 보정이 아닌 DB 마이그레이션을 원한다면:

UPDATE screen_layouts_pop
SET layout_data = jsonb_set(
  jsonb_set(
    layout_data,
    '{settings,canvasGrid,rows}',
    '24'
  ),
  '{settings,canvasGrid}',
  (layout_data->'settings'->'canvasGrid') - 'rowHeight'
)
WHERE layout_data->'settings'->'canvasGrid'->>'rows' IS NULL
  AND layout_data->>'version' = 'pop-2.0';

2. 모드별 컴포넌트 위치 반대 문제

별도 이슈: activeModeKey 상태 관리 점검 필요

  • DeviceFrame 클릭 시 모드 전환
  • 저장 시 올바른 modeKey 전달 확인

결론

원칙 준수: 데스크톱 분리, 4모드 반응형 유지
비율 기반 강제: 고정 픽셀 제거
하위 호환: 구버전 데이터 자동 보정
안정성 향상: 타입 일관성 확보