ERP-node/popdocs/CHANGELOG.md

67 KiB

POP 변경 이력

형식: Keep a Changelog


[미출시]

  • Phase 0: 공통 인프라 구현 (useDataSource, usePopEvent) 완료
  • Phase 2: pop-button, pop-icon 구현
  • Phase 3: pop-table 구현
  • Phase 4: pop-search, pop-field, pop-lookup 구현
  • Phase 5: pop-table 카드 템플릿, 차트, 게이지
  • Phase 6: pop-system 구현
  • 워크플로우 연동

[2026-02-11] Phase 0 공통 인프라: usePopEvent + useDataSource 훅 구현

배경

모든 데이터 연동 POP 컴포넌트(pop-button, pop-table, pop-search 등)가 공유하는 2개 핵심 훅을 구현. 기존 대시보드 dataFetcher.ts의 조회 로직과 dataApi CRUD를 공통 훅으로 래핑하는 작업.

Added

  • usePopEvent (frontend/hooks/pop/usePopEvent.ts)

    • screenId 기반 이벤트 버스 (publish/subscribe/sharedData)
    • 전역 Map 2개 (screenBuses, sharedDataStore) - 모듈 스코프, SSR 가드
    • cleanupScreen(screenId) 유틸 (화면 언마운트 시 메모리 정리)
  • popSqlBuilder 유틸 (frontend/hooks/pop/popSqlBuilder.ts)

    • dataFetcher.ts에서 SQL 빌더 로직 5개 함수 추출 (로직 변경 없이 복사)
    • escapeSQL, sanitizeIdentifier, validateDataSourceConfig, buildWhereClause, buildAggregationSQL
  • useDataSource (frontend/hooks/pop/useDataSource.ts)

    • DataSourceConfig 기반 DB 테이블 CRUD 통합
    • 조회 분기: 집계/조인 → SQL 빌더 + executeQuery, 단순 → dataApi.getTableData
    • CRUD: save/update/remove → dataApi 래핑
    • 자동 새로고침 (refreshInterval, 최소 5초)
    • refetch 필터 병합 (overrideFilters + config.filters)
  • 배럴 파일 (frontend/hooks/pop/index.ts)

    • usePopEvent, cleanupScreen, useDataSource, MutationResult, DataSourceResult, buildAggregationSQL, validateDataSourceConfig re-export

검수 결과

  • 린트 에러: 0건
  • 중복 정의: 0건 (20개 함수/타입 전수 Grep)
  • 미사용 import: 0건
  • 가상 시뮬레이션 8시나리오: 전부 정상
  • 기존 대시보드 dataFetcher.ts: 미수정 (안정성 우선)

수정 파일

파일 변경 내용
frontend/hooks/pop/usePopEvent.ts 신규 - 이벤트 버스 훅 (190줄)
frontend/hooks/pop/popSqlBuilder.ts 신규 - SQL 빌더 유틸 (195줄)
frontend/hooks/pop/useDataSource.ts 신규 - 데이터 CRUD 훅 (383줄)
frontend/hooks/pop/index.ts 신규 - 배럴 파일 (15줄)

Git

브랜치 커밋 작업
ksh-button 300542d9 feat(pop): usePopEvent, useDataSource 공통 훅 구현
ksh-v2-work fast-forward merge ksh-button 병합
origin/ksh-v2-work push 완료 원격 동기화

[2026-02-11] 브랜치 병합: ksh-dashboard -> ksh-v2-work (pop-icon + pop-dashboard 통합)

배경

ksh-v2-work 브랜치에서 pop-icon 컴포넌트를, ksh-dashboard 브랜치에서 pop-dashboard 컴포넌트를 각각 독립 개발. 두 브랜치가 공통 확장 포인트(타입 정의, 팔레트, 렌더러, 에디터 패널)를 동시에 수정하여 병합 충돌 발생.

병합 통계

  • 충돌 파일: 7개 / 17개 충돌 지점
  • 해결 전략: 양쪽 기능 통합(union) 14건, ksh-dashboard 채택 2건, ksh-v2-work 채택 1건
  • 의존성 순서 해결: pop-layout.ts -> index.ts -> pop-text.tsx -> ComponentPalette.tsx -> PopRenderer.tsx -> ComponentEditorPanel.tsx -> PopDesigner.tsx

Merged (양쪽 통합)

  • PopComponentType: "pop-icon" | "pop-dashboard" 양쪽 타입 통합 (pop-layout.ts)
  • DEFAULT_COMPONENT_GRID_SIZE: pop-icon(1x2) + pop-dashboard(6x3) 기본 크기 추가
  • COMPONENT_TYPE_LABELS: PopRenderer, ComponentEditorPanel 양쪽에 4개 항목 완비
  • PALETTE_ITEMS: 아이콘(MousePointer) + 대시보드(BarChart3) 팔레트 항목 추가
  • PopRendererProps: currentScreenId(아이콘용) + previewPageIndex(대시보드용) props 통합
  • ComponentEditorPanelProps: previewPageIndex + onPreviewPage props 통합
  • 컴포넌트 등록: ./pop-icon + ./pop-dashboard import 통합 (index.ts)
  • lucide-react import: MousePointer + BarChart3 통합 (ComponentPalette.tsx)
  • ComponentContent 렌더링: pop-icon pointer-events 허용 + previewPageIndex 전달 통합

Adopted from ksh-dashboard

  • pop-text isRealtime: isRealtime 조건부 interval로 변경 (불필요한 timer 방지)
  • handleUpdateComponent: 함수적 setLayout(prev => ...) 업데이트 (stale closure 방지)

Adopted from ksh-v2-work

  • ComponentEditorPanel CSS: overflow-hidden, min-h-0, m-0 방어적 CSS (스크롤 안정성)

검증 결과

  • 충돌 마커 잔여: 0건
  • TypeScript 에러 (병합 파일): 0건
  • 프론트엔드 빌드: 성공
  • 백엔드 빌드 에러: 0건 (기존 2건은 패키지 미설치)
  • 린트 에러: 0건

[2026-02-11] 대시보드 스타일 정리 + 페이지 미리보기 + 차트 디자인 개선

배경

이전 작업에서 구현한 글자 크기 3그룹 커스텀이 @container 반응형 자동 크기와 충돌하여 정보 잘림 발생. 또한 handleUpdateComponent의 stale closure 버그로 빠른 연속 설정 변경 시 값 유실. 추가로 디자이너 캔버스에서 페이지별 미리보기 기능 부재.

Changed

  • 글자 크기 커스텀 제거 (types.ts, KpiCard, StatCard, GaugeItem, ChartItem)

    • FONT_SIZE_PX 상수 삭제
    • ItemStyleConfig{ labelAlign?: TextAlign } 으로 단순화
    • 기존 @container 반응형 자동 크기 복원 (text-xs @[250px]:text-sm 등)
  • 라벨 정렬 기능 (4개 아이템 + PopDashboardConfig.tsx)

    • TEXT_ALIGN_CLASSES[itemStyle?.labelAlign ?? "center"] 로 라벨만 정렬
    • 값/보조 텍스트는 항상 가운데 정렬 고정
    • ItemStyleEditor 컴포넌트에 접기/펼치기(Collapsible) 지원
  • 페이지 미리보기 (PopDashboardComponent, PopDashboardConfig, PopDesigner, PopCanvas, PopRenderer, ComponentEditorPanel)

    • 각 페이지 옆에 Eye 버튼 → 클릭 시 해당 페이지만 디자이너 캔버스에 렌더링
    • previewPageIndex prop 전달 체인: PopDesigner → PopCanvas → PopRenderer → ComponentContent → PopDashboardComponent
    • 스타일 변경 시 자동으로 해당 페이지 미리보기 활성화
  • 차트 디자인 개선 (ChartItem.tsx)

    • CartesianGrid 추가 (얇은 격자선)
    • abbreviateNumber 적용 (Y축 + 파이 라벨 + 툴팁)
    • X축 라벨 7자 이상 시 대각선 표시 (angle: -45)
    • 긴 라벨 시 하단 여백 자동 확보

Fixed

  • stale closure 버그 (PopDesigner.tsx)

    • handleUpdateComponent에서 layout 직접 참조 → setLayout(prev => ...) 함수적 업데이트
    • 의존성 배열에서 layout 제거 → [saveToHistory]만 유지
  • 불필요 코드 제거 (PopDashboardComponent.tsx)

    • setRenderTick state + itemStyleKey 변수 + 관련 useEffect 삭제
  • 디버그 console.log 전량 제거 (8개)

    • PopDashboardComponent(3), PopDesigner(3), ChartItem(1), PopDashboardConfig(1)
  • .next 빌드 캐시 꼬임 (Docker)

    • Docker 익명 볼륨에 캐시된 .next가 호스트 삭제와 독립적인 문제
    • docker-compose down -v로 볼륨 포함 삭제 후 --build 재시작

[2026-02-10] 디자이너 캔버스 UX 개선 (헤더 제거 + 실제 데이터 렌더링 + 컴포넌트 목록)

배경

디자이너 캔버스와 실제 뷰어 간의 시각적 차이 해소 요청:

  • 디자이너에서 각 컴포넌트마다 5px 헤더 바가 표시되어 실제 뷰어와 다름
  • 대시보드가 더미 아이콘(PreviewComponent)으로만 표시됨
  • 헤더 제거 후 컴포넌트 식별 수단 필요

Changed

  • 디자인모드 실제 데이터 렌더링 (PopRenderer.tsx)

    • 헤더(5px) + 위치 정보 div 완전 삭제
    • PreviewComponent 대신 ActualComp(실제 컴포넌트)로 렌더링
    • pointer-events-none으로 내부 클릭 차단 (그리드 선택은 정상 작동)
  • 컴포넌트 목록 UI (ComponentEditorPanel.tsx)

    • "위치" 탭에 "배치된 컴포넌트" 목록 추가 (Layers 아이콘 + 카운트)
    • 목록에서 클릭하면 해당 컴포넌트 선택 (그리드 클릭과 동일 효과)
    • COMPONENT_TYPE_LABELSpop-sample, pop-text, pop-dashboard 키 추가
  • Props 연결 (PopDesigner.tsx)

    • allComponents, onSelectComponent, selectedComponentId 3개 props 전달

Fixed

  • 미사용 import 제거 (ComponentEditorPanel.tsx)
    • COMPONENT_TYPE_LABELS 타입 변경 후 PopComponentType import 누락 정리

[2026-02-10] pop-dashboard 차트/게이지/UI 디자인 개선

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 파이 차트(Chart 7)가 표시되지 않음 (fetch 기반 API 간헐 실패 + bigint 문자열 타입 문제)
  • 파이 차트 슬라이스에 카테고리명/레전드 없어 의미 파악 불가
  • 게이지 최소/최대/목표 값 변경이 적용되지 않음 (스프레드 연산자 순서 버그)
  • 게이지가 가로 레이아웃에서 너무 작게 표시됨 (고정 max-width 제한)
  • 좌우 버튼/인디케이터가 별도 영역 차지해서 콘텐츠 공간 부족 + 상하 마진 불균형
  • KPI 카드/통계 카드만 왼쪽 정렬 (게이지/차트는 가운데)
  • 차트 설정에서 "X축 컬럼"과 "그룹핑(X축)" 중복으로 혼동

Fixed

  • 파이 차트 미표시 (dataFetcher.ts)

    • fetch 기반 API가 iframe에서 간헐 실패 -> apiClient(axios) 우선 사용, fetch 폴백
    • PostgreSQL bigint 반환값이 문자열("79") -> Number() 변환 추가
  • 파이 차트 라벨 없음 (ChartItem.tsx)

    • Legend 컴포넌트 추가, label 커스텀 포맷 (name value (percent%))
    • Tooltip formatter로 이름+값 표시
  • gaugeConfig 값 변경 안 됨 (PopDashboardConfig.tsx)

    • 스프레드 연산자 순서 버그: { max: newValue, ...item.gaugeConfig } -> { ...item.gaugeConfig, max: newValue }
    • min/max/target 3개 모두 동일 패턴 수정
  • 게이지 가로 레이아웃 비율 (GaugeItem.tsx)

    • max-w-[200px] 고정 -> h-full w-auto max-w-full 높이 기반 스케일링
    • SVG 래퍼를 flex-1 min-h-0으로 변경해 가용 높이 최대 활용

Changed

  • 좌우 버튼/인디케이터 오버레이 (ArrowsMode.tsx, AutoSlideMode.tsx)

    • 버튼: px-12 패딩 제거, 콘텐츠 위에 겹침 (absolute, bg-background/70 backdrop-blur-sm)
    • 인디케이터: 별도 영역 -> absolute bottom-1로 콘텐츠 하단 오버레이
    • 상하 마진 불균형 해소
  • KPI/통계 카드 가운데 정렬 (KpiCard.tsx, StatCard.tsx)

    • KPI: items-center 추가
    • 통계: items-center justify-center 추가
    • 4개 아이템 모드(KPI/Chart/Gauge/Stat) 정렬 통일
  • 차트 X/Y축 입력 필드 제거 (PopDashboardConfig.tsx)

    • "X축 컬럼"/"Y축 컬럼" 수동 입력 제거 (groupBy와 중복, 혼동 유발)
    • "X축: 그룹핑(X축)에서 선택한 컬럼 자동 적용 / Y축: 집계 결과(value) 자동 적용" 안내 텍스트로 교체

수정 파일

파일 변경 내용
PopDashboardConfig.tsx gaugeConfig 스프레드 순서 수정, X/Y축 입력 제거 + 안내 텍스트
utils/dataFetcher.ts apiClient 우선 사용, bigint 문자열 -> 숫자 변환
items/ChartItem.tsx PieChart Legend/custom label 추가
items/GaugeItem.tsx SVG 스케일링 높이 기반 변경
items/KpiCard.tsx items-center 추가
items/StatCard.tsx items-center justify-center 추가
modes/ArrowsMode.tsx 좌우 버튼 + 인디케이터 오버레이
modes/AutoSlideMode.tsx 인디케이터 오버레이

[2026-02-10] pop-dashboard 아이템 모드 완성 + SQL 방어 로직 + 레이아웃/라벨 수정

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 대시보드 아이템 4개 모드(KPI, Chart, Gauge, Stat Card)가 실제 데이터와 연동되어 동작하려면 설정 UI가 부족함
  • Chart에 groupBy(X축) 설정 UI 없음, StatCard에 카테고리 편집 UI 없음
  • 설정 폼 중간 상태(집계 유형만 선택, 컬럼 미선택)에서 SUM(), COUNT() 같은 잘못된 SQL이 백엔드로 전송되어 장애 유발
  • 2열 설정이 1열로 렌더링되고, 라벨/단위가 잘려서 안 보임

Added

  • groupBy(X축) 설정 Combobox (PopDashboardConfig.tsx)

    • DataSourceEditor에 "그룹핑(X축)" Popover Combobox 추가
    • 집계 활성화 시 표시, 차트 X축 카테고리 컬럼 선택
  • 차트 xAxisColumn / yAxisColumn 입력 UI (PopDashboardConfig.tsx)

    • Chart 아이템 전용 X축/Y축 컬럼 입력 필드
  • StatCard 카테고리 인라인 편집기 (PopDashboardConfig.tsx)

    • 카테고리별 라벨, 필터 조건(컬럼/연산자/값), 색상 편집
    • 카테고리 추가/삭제
  • validateDataSourceConfig() 함수 (dataFetcher.ts)

    • 테이블/컬럼/조인 미완료 상태 검증
    • 미완료 시 SQL 생성 차단, 에러 메시지 반환

Changed

  • Chart xAxisColumn 자동 보정 (PopDashboardComponent.tsx)

    • groupBy 설정 있지만 xAxisColumn 미설정 시 첫 번째 groupBy 컬럼 자동 적용
  • StatCard 카테고리별 독립 데이터 필터링 (PopDashboardComponent.tsx)

    • 전체 rows를 카테고리 filter 조건으로 각각 필터링하여 개별 건수 계산
  • useEffect 의존성 안정화 (PopDashboardComponent.tsx)

    • visibleItems 배열 참조 -> visibleItemIds JSON 문자열로 교체
    • 매 렌더마다 새 배열 참조 생성으로 인한 불필요한 재호출 방지
  • refreshInterval 최소 5초 강제 (PopDashboardComponent.tsx)

    • 5초 미만 설정 시 5초로 강제
  • fetchTableColumns API 우선순위 (dataFetcher.ts)

    • tableManagementApi(axios) 우선, dashboardApi(fetch) 폴백
  • buildWhereClause 빈 필터 무시 (dataFetcher.ts)

    • 컬럼명이 빈 필터 조건 건너뜀 (설정 중간 상태 방어)
  • buildAggregationSQL COUNT(*) 처리 (dataFetcher.ts)

    • COUNT는 컬럼 없이도 COUNT(*)로 처리, 불완전한 조인 건너뜀

Fixed

  • 2열 설정이 1열로 렌더링 (GridMode.tsx)

    • MIN_CELL_WIDTH 160px -> 80px
    • 초기 containerWidth=300에서 (300-8)/2=146 < 160이라 1열로 축소되던 문제
  • 라벨/단위 잘림 (KpiCard, GaugeItem, StatCard, ChartItem)

    • truncate 클래스 제거 (text-overflow: ellipsis 비활성)
    • hidden @[120px]:inline 등 조건부 숨김 제거
    • 기본 폰트 크기 text-[10px] -> text-xs (12px)
    • 내부 패딩 p-2 -> p-3 (여유 공간 확보)
  • 백엔드 unhealthy 유발하는 잘못된 SQL (dataFetcher.ts)

    • 설정 중간 상태에서 SUM(), COUNT() 같은 빈 괄호 SQL 전송 차단
    • validateDataSourceConfig()으로 사전 검증

수정 파일

파일 변경 내용
PopDashboardConfig.tsx groupBy Combobox, 차트 축 입력, 통계 카테고리 편집기
PopDashboardComponent.tsx 차트 자동 보정, StatCard 필터링, useEffect 안정화, refreshInterval 최소값
utils/dataFetcher.ts validateDataSourceConfig, buildWhereClause/buildAggregationSQL 방어, fetchTableColumns API 우선순위
modes/GridMode.tsx MIN_CELL_WIDTH 160 -> 80
items/KpiCard.tsx truncate 제거, hidden 제거, 폰트/패딩 상향
items/GaugeItem.tsx truncate 제거, hidden 제거, 폰트/패딩 상향
items/StatCard.tsx truncate 제거, hidden 제거, 폰트/패딩 상향
items/ChartItem.tsx truncate 제거, 폰트/패딩 상향

[2026-02-10] pop-dashboard 페이지(슬라이드) 구조 재설계

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 기존 대시보드는 아이템이 평면 리스트 -> 슬라이드 하나에 아이템 하나만 표시 가능
  • "한 화면에 4개 차트, 다음 화면에 1개 차트" 같은 구성 불가
  • useGridLayout 옵션은 전체 아이템을 하나의 그리드에 넣는 것만 가능

해결 방향:

  • DashboardPage 개념 도입: 각 페이지가 독립적인 그리드 레이아웃(열/행/셀 배치) 보유
  • 표시 모드(arrows/auto-slide/scroll)는 페이지 간 전환 방식을 결정
  • 기존 useGridLayout, gridCells, gridColumns, gridRows 속성 폐기 -> pages 배열로 대체

Added

  • DashboardPage 인터페이스 (types.ts)

    • id, label, gridColumns, gridRows, gridCells 속성
    • 각 페이지가 독립적 그리드 레이아웃 보유
  • migrateConfig() 함수 (PopDashboardComponent.tsx)

    • 레거시 config(displayMode="grid", useGridLayout=true)를 pages 기반으로 런타임 변환
    • 저장된 config는 변경하지 않고 런타임에서만 적용
  • PageEditor 컴포넌트 (PopDashboardConfig.tsx)

    • 페이지별 열/행/셀 배치 편집 UI
    • 기존 GridLayoutEditor 재사용
  • 아이템 라벨 인라인 편집 (PopDashboardConfig.tsx)

    • ItemEditor 헤더에서 직접 라벨 편집 가능 (접힌 상태에서도)

Changed

  • PopDashboardConfig 타입 구조 변경 (types.ts)

    • 삭제: useGridLayout, gridCells, gridColumns, gridRows
    • 추가: pages?: DashboardPage[]
  • "레이아웃" 탭 -> "페이지" 탭 (PopDashboardConfig.tsx)

    • 페이지 추가/삭제 UI
    • 페이지별 독립 그리드 편집
  • 렌더링 로직 전면 교체 (PopDashboardComponent.tsx)

    • migrateConfig() -> pages 기반 -> 각 모드 컴포넌트에 페이지 단위 전달
    • GridModeComponent를 페이지 내부 렌더링에 재사용
  • 미리보기 로직 변경 (PopDashboardPreview.tsx)

    • 첫 번째 페이지의 그리드 미리보기 + "N페이지" 배지 표시
  • defaultProps 업데이트 (index.tsx)

    • useGridLayout: false 제거, pages: [] 추가

Fixed

  • 설정 탭 세로 스크롤 불가 (ComponentEditorPanel.tsx)
    • Flexbox min-height: auto 문제로 overflow-auto 미작동
    • Tabs/TabsContentmin-h-0 추가, TabsListshrink-0 추가

수정 파일

파일 변경 내용
types.ts DashboardPage 추가, PopDashboardConfig 구조 변경
PopDashboardComponent.tsx migrateConfig() 추가, 페이지 기반 렌더링
PopDashboardPreview.tsx migrateConfig 적용, 페이지 미리보기
PopDashboardConfig.tsx "페이지" 탭, PageEditor, 인라인 라벨 편집
pop-dashboard/index.tsx defaultProps 업데이트
ComponentEditorPanel.tsx Tabs/TabsContent min-h-0 추가 (스크롤 수정)
popdocs/PROBLEMS.md 스크롤 버그 상세 기록

[2026-02-09] POP 뷰어 스크롤 수정

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 설계 화면(디자이너)에서 컴포넌트를 화면 높이 아래로 배치하면 스크롤로 볼 수 있음
  • 뷰어(/pop/screens/4114)에서는 화면 높이를 초과하는 컴포넌트가 잘려서 안 보임
  • 스크롤 자체가 불가능한 상태

Fixed

  • 최외곽 컨테이너 overflow-hidden 제거 (page.tsx 185행)

    • overflow-hidden이 뷰포트를 넘는 모든 콘텐츠를 잘라내고 있었음
    • 제거하여 자식 요소의 스크롤을 허용
  • overflow-auto 공통 적용 (page.tsx 266행)

    • 기존: 프리뷰 모드에서만 overflow-auto 적용
    • 수정: 조건문 밖으로 이동하여 일반 뷰어 모드에서도 스크롤 가능
  • min-h-full 추가 (page.tsx 275행)

    • 일반 뷰어 모드에서 짧은 콘텐츠일 때 백색 배경이 전체 높이를 채우도록 보장

수정 파일

파일 변경 내용
frontend/app/(pop)/pop/screens/[screenId]/page.tsx CSS 클래스 3곳 수정 (overflow-hidden 제거, overflow-auto 공통 적용, min-h-full 추가)

[2026-02-09] POP 뷰어 실제 컴포넌트 렌더링 수정

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 설계 화면(디자이너)에서는 이미지/텍스트/타이틀이 정상 표시
  • 뷰어(/pop/screens/4114)에 접속하면 "pop-text 1" 같은 라벨만 보이는 플레이스홀더 상태
  • renderActualComponent() 함수가 레지스트리의 실제 컴포넌트를 무시하고 라벨 문자열만 반환
  • 뷰어 페이지에서 컴포넌트 레지스트리 초기화 import 누락

Fixed

  • 뷰어 컴포넌트 레지스트리 미초기화 (page.tsx)

    • import "@/lib/registry/pop-components" 추가
    • PopRenderer import 앞에 배치 (순서 중요)
  • renderActualComponent() 플레이스홀더만 반환 (PopRenderer.tsx)

    • PopComponentRegistry.getComponent()로 실제 컴포넌트 조회
    • 등록된 컴포넌트가 있으면 config/label props 전달하여 실제 렌더링
    • 미등록 컴포넌트는 기존 플레이스홀더를 fallback으로 유지

발견된 추가 문제 (미수정)

  • datetime 실시간 업데이트 기본값 불일치
    • 설정 패널: config?.isRealtime ?? true (기본 켜짐)
    • 뷰어 컴포넌트: if (!config?.isRealtime) return (undefined = 꺼짐)
    • DB에 isRealtime 미저장 시 시간이 멈춰 보임
    • 별도 작업으로 수정 예정

수정 파일

파일 변경 내용
frontend/app/(pop)/pop/screens/[screenId]/page.tsx 레지스트리 초기화 import 추가 (+2줄)
frontend/components/pop/designer/renderers/PopRenderer.tsx renderActualComponent() 실제 컴포넌트 렌더링으로 교체 (-8줄 +19줄)

[2026-02-09] pop-dashboard 상세 설계 토의

배경 (왜 이 작업이 필요했는가)

상황:

  • 컴포넌트 정의서 v8.0에서 pop-dashboard가 "숫자를 집계해서 보여줌"으로 정의되어 있으나, 구체적인 데이터 구조/표시 모드/설정 패널 등 상세 설계가 필요
  • Phase 0 공통 인프라와 Phase 1 pop-dashboard를 실제 구현하기 위한 세부 사항 결정 필요
  • 기존 POP 대시보드 프로토타입(frontend/components/pop/dashboard/)과의 관계 정리 필요

토의에서 결정된 사항

# 결정 항목 결정 내용 근거
1 컴포넌트 구조 1개 pop-dashboard = 여러 DashboardItem 묶음 (멀티 아이템 컨테이너) 시스템 옵션에서 각 아이템별 보이기/숨기기 가능해야 함
2 서브타입 범위 4개 전부 Phase 1에서 구현 (kpi-card, chart, gauge, stat-card) "시간이 걸리겠지만 4개 결국 전부 필요"
3 표시 모드 arrows, auto-slide, grid, scroll 4가지 전부 가능하게, 디자이너가 옵션으로 선택
4 그리드 배치 디자이너가 아이템별 행/열 위치 직접 지정 "행열 그리드 배치"에서 수동 지정
5 계산식 formula 지원 (값A/값B, A+B, A/B*100 등) "생산량/총재고량" 같은 복합 표현 필요
6 설정 패널 드롭다운 기반 쉬운 집계 설정 (SQL 불필요) "집계 및 계산 설정이 쉽게 이루어져야 함"
7 백엔드 호환성 기존 API만 사용, 신규 백엔드 개발 불필요 dataApi, dashboardApi, entityJoinApi 호환 확인 완료
8 POP/데스크탑 분리 POP 전용 훅은 frontend/hooks/pop/ 에 완전 분리 "분리 명확하게 해야해"
9 기존 대시보드 frontend/components/pop/dashboard/ 폐기 정적 하드코딩된 홈 화면, 새 컴포넌트로 완전 대체
10 표시 형태 value, fraction(1,234/5,678), percent(21.7%), ratio(1,234:5,678) 계산식 결과 다양한 표현

보류/미결 사항

항목 상태 비고
Recharts 라이브러리 확인 필요 chart 서브타입에 필요, 프로젝트에 이미 있는지 확인 후 추가
자동 슬라이드 터치 재개 시간 미정 구현 시 결정 (3~5초 추천)
그리드 모드 겹침 검사 미정 설정 패널 구현 시 상세 설계

변경 파일

파일 변경 내용
POPUPDATE_2.md pop-dashboard 섹션 전면 개편 (멀티 아이템, 표시 모드, 계산식, 백엔드 API, 훅 분리)
popdocs/PLAN.md Phase 1 상세 업데이트, 파일 경로, 백엔드 API, 함정 경고
popdocs/STATUS.md 토의 결과 반영, 다음 작업 업데이트
popdocs/README.md 마지막 대화 요약 업데이트
popdocs/CHANGELOG.md 본 항목 추가
.cursor/plans/pop-dashboard_*.plan.md 상세 설계 plan 파일 (별도 유지)

[2026-02-09] POP 컴포넌트 정의서 v8.0 확정

배경 (왜 이 작업이 필요했는가)

상황:

  • POP 시스템에 넣을 컴포넌트의 역할, 데이터 흐름, 통신 방식을 사전에 정의해야 함
  • 영업팀으로부터 받은 참조 화면(HTML 샘플)을 기반으로 필요한 컴포넌트 목록 도출
  • 모달 화면 설계 방식에 대한 결정 필요

Added

  • POP 컴포넌트 정의서 v8.0 (POPUPDATE_2.md)

    • 9개 컴포넌트 정의: pop-text(완성), pop-dashboard, pop-table, pop-button, pop-icon, pop-search, pop-field, pop-lookup, pop-system
    • POP 헌법 9조 (공통 규칙)
    • 공통 인프라 설계: DataSourceConfig, ColumnBinding, JoinConfig, useDataSource, usePopEvent, PopActionConfig
    • 컴포넌트 간 통신 시퀀스 다이어그램 5개
    • 구현 우선순위 7단계 (Phase 0~6)
  • 모달 화면 설계 방식 (v8.0 추가)

    • 방식 A (인라인 모달): DataSourceConfig 기반 단순 목록 선택
    • 방식 B (외부 화면 참조): 별도 screen_id 연결, 복잡한 화면/재사용
    • POP 헌법 제9조: 모달 화면의 설계 원칙
    • PopActionConfig modal 타입 구체화
  • 기존 시스템 호환성 검증 결과 (v8.0 추가)

    • DB: layout_data JSONB로 modalConfig 저장 가능 (마이그레이션 불필요)
    • 백엔드: saveLayoutPop/getLayoutPop API 그대로 사용 가능
    • 프론트: TabsWidget의 screenId 참조 패턴 차용 가능

주요 설계 결정

결정 내용
컴포넌트 9개 확정 pop-text~pop-system
역할 분리 조회용(search) vs 저장용(field), 이동(icon) vs 값 선택(lookup)
시스템 설정 = 컴포넌트 pop-system으로 통합
모달 이중 방식 인라인 + 외부 참조
이벤트 격리 화면 단위 (같은 화면 내 자유 통신)
컬럼별 CRUD read/write/readwrite/hidden 개별 설정

수정 파일

파일 변경 내용
POPUPDATE_2.md v7.0 -> v8.0 (모달 설계, 헌법 제9조, 호환성 검증)

[2026-02-09] origin/main 병합 (ksh-v2-work-merge-test)

배경 (왜 이 작업이 필요했는가)

상황:

  • ksh-v2-work 브랜치에서 POP 디자이너 개발이 진행되는 동안, main 브랜치에서 데스크톱 ScreenDesigner 관련 대규모 업데이트(feature/v2-unified-renewal PR #386)가 병합됨
  • 두 브랜치가 ScreenDesigner.tsx를 동시에 수정하여 병합 충돌 발생
  • 안전한 병합을 위해 ksh-v2-work-merge-test 테스트 브랜치에서 작업

병합 통계:

  • 소스: origin/main (86 커밋)
  • 대상: ksh-v2-work-merge-test (ksh-v2-work에서 분기, 14 커밋)
  • 분기점: 3fca677f (feat: V2Media 컴포넌트 추가)
  • 변경 파일: 207개 (43,535줄 추가, 3,547줄 삭제)
  • 충돌 파일: 1개 (ScreenDesigner.tsx)

Merged (origin/main에서 가져온 주요 변경)

  • ScreenDesigner 데스크톱 기능 강화

    • 그룹 정렬/분배/크기 맞춤 (handleGroupAlign, handleGroupDistribute, handleMatchSize)
    • 라벨 토글 (handleToggleAllLabels)
    • 단축키 도움말 모달 (showShortcutsModal)
    • 디버그 console.log 정리
  • 백엔드 신규 기능

    • 스케줄 관리 API (scheduleController, scheduleRoutes, scheduleService)
    • 파일 관리 개선 (fileController, fileRoutes)
    • 테이블 관리 확장 (tableManagementController)
    • 넘버링 규칙 개선 (numberingRuleController)
  • 프론트엔드 신규/수정

    • 레이어 매니저 패널, 레이어 조건 패널
    • 화면 복사 모달, 편집 모달
    • InteractiveDataTable, InteractiveScreenViewer
    • 넘버링 규칙 디자이너
    • 화면 그룹 트리뷰, 화면 관계 플로우

충돌 해결 (ScreenDesigner.tsx)

3건의 충돌을 수동 해결:

충돌 영역 해결 방식
1. 함수 시그니처 isPop, defaultDevicePreview props 추가 ksh-v2-work 유지 (POP 모드 지원), 중복 usePanelState 제거
2. 저장 로직 POP/V2/Legacy 3단계 분기 ksh-v2-work 유지 (3단계 분기), console.log 제거
3. 툴바 props 정렬/분배/크기맞춤/라벨토글/단축키 origin/main 채택 (데스크톱 신규 기능 모두 포함)

검증 결과

항목 결과
충돌 마커 잔존 없음
TypeScript 컴파일 신규 에러 없음 (기존 에러만)
프론트엔드 빌드 성공
백엔드 빌드 신규 에러 없음 (docx/bwip-js 기존 이슈만)
시맨틱 충돌 없음
린트 기능 에러 없음 (들여쓰기 차이만)

주의사항

  • Conflict 3 영역 들여쓰기: origin/main에서 가져온 툴바 JSX(L5745~6631)의 들여쓰기가 ksh-v2-work와 2칸 차이. 기능에는 영향 없으나, 추후 포매팅 정리 권장
  • 기존 타입 에러: GridSettings/GridUtilSettings 불일치, SCREEN_RESOLUTIONS export type 문제 등은 병합 이전부터 존재하던 기술 부채

수정 파일

파일 변경 내용
ScreenDesigner.tsx 3건 충돌 수동 해결 (함수 시그니처, 저장 로직, 툴바 props)
외 207개 파일 origin/main에서 자동 병합

[2026-02-06] v5.2.1 그리드 셀 크기 강제 고정

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 4칸 모드에서 특정 행의 가이드 셀이 다른 행보다 작게 표시됨
  • gridAutoRows는 최소 높이만 보장하여, 컴포넌트 콘텐츠가 행 높이를 밀어내면 인접 빈 셀도 영향받음
  • "셀의 크기 = 컴포넌트의 크기"라는 핵심 설계 원칙이 시각적으로 깨짐

Changed

  • gridAutoRows → gridTemplateRows (PopRenderer.tsx)

    // 변경 전: 최소 높이만 보장 (콘텐츠에 따라 늘어남)
    gridAutoRows: `${breakpoint.rowHeight}px`
    
    // 변경 후: 행 높이 강제 고정
    gridTemplateRows: `repeat(${dynamicRowCount}, ${breakpoint.rowHeight}px)`
    gridAutoRows: `${breakpoint.rowHeight}px`  // 동적 추가행 대비 유지
    
  • dynamicRowCount 분리 (PopRenderer.tsx)

    • gridCells 내부 → 독립 useMemo로 분리
    • gridStyle과 gridCells에서 공유
  • 컴포넌트 overflow 변경 (PopRenderer.tsx)

    • overflow-visibleoverflow-hidden
    • 컴포넌트 콘텐츠가 셀 경계를 벗어나지 않도록 강제

Fixed

  • PopRenderer dynamicRowCount에서 숨김 컴포넌트 포함 문제

    • PopCanvas는 숨김 제외하여 높이 계산, PopRenderer는 포함하여 계산 → 기준 불일치
    • PopRenderer에도 숨김 필터 추가, 여유행 +5 → +3으로 통일
  • 디버깅 console.log 잔존 (PopCanvas.tsx)

    • reviewComponents useMemo 내 console.log 2개 삭제
  • 뷰어 viewportWidth 선언 순서 (page.tsx)

    • currentModeKey보다 뒤에 선언되어 있던 viewportWidth를 앞으로 이동

수정 파일

파일 변경 내용
PopRenderer.tsx gridTemplateRows 강제 고정, dynamicRowCount 분리, overflow-hidden, 숨김 필터 추가
PopCanvas.tsx 디버깅 console.log 삭제
page.tsx (뷰어) viewportWidth 선언 순서 수정

[2026-02-06] v5.2 브레이크포인트 재설계 + 세로 자동 확장

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 뷰어에서 브라우저 수동 리사이즈 시 768~839px 구간에서 모드 불일치
  • useResponsiveMode 훅과 GRID_BREAKPOINTS 상수 간 기준 불일치
  • 기존 브레이크포인트가 실제 기기 뷰포트와 맞지 않음

사용자 요구사항:

  • "현장 모바일 기기 8~14인치, 핸드폰은 아이폰 미니 ~ 갤럭시 울트라"
  • "세로는 신경쓸 필요 없고 무한 스크롤 가능해야 함"

Changed

  • 브레이크포인트 재설계 (pop-layout.ts)

    모드 변경 전 변경 후 근거
    mobile_portrait ~599px ~479px 스마트폰 세로 최대 440px
    mobile_landscape 600~839px 480~767px 스마트폰 가로
    tablet_portrait 840~1023px 768~1023px iPad Mini 768px 포함
    tablet_landscape 1024px+ 동일 -
  • detectGridMode() 조건 수정 (pop-layout.ts)

    if (viewportWidth < 480) return "mobile_portrait";   // was 600
    if (viewportWidth < 768) return "mobile_landscape";  // was 840
    if (viewportWidth < 1024) return "tablet_portrait";
    
  • BREAKPOINTS.TABLET_MIN 변경 (useDeviceOrientation.ts)

    • 768 (was 840)
  • VIEWPORT_PRESETS에서 height 제거 (PopCanvas.tsx)

    • width만 유지, 세로는 무한 스크롤

Added

  • 세로 자동 확장 (PopCanvas.tsx)

    • MIN_CANVAS_HEIGHT = 600: 최소 캔버스 높이
    • CANVAS_EXTRA_ROWS = 3: 항상 유지되는 여유 행 수
    • dynamicCanvasHeight: 컴포넌트 배치 기반 동적 계산
  • 격자 셀 동적 계산 (PopRenderer.tsx)

    • 고정 20행 → maxRowEnd + 5 동적 계산
  • 뷰어 일관성 확보 (page.tsx)

    • 프리뷰 모드: useResponsiveModeWithOverride 유지
    • 일반 모드: detectGridMode(viewportWidth) 직접 사용

Fixed

  • 뷰어 반응형 모드 불일치

    • 768~839px 구간에서 6칸/8칸 모드 불일치 해결
  • hiddenComponentIds 중복 정의 에러

    • 라인 410-412 중복 useMemo 제거

Technical Details

브레이크포인트 재설계 근거 (실제 기기 CSS 뷰포트):

| 기기 | CSS 뷰포트 너비 |
|------|----------------|
| iPhone SE | 375px |
| iPhone 16 Pro | 402px |
| Galaxy S25 Ultra | 440px |
| iPad Mini 7 | 768px |
| iPad Pro 11 | 834px (세로), 1194px (가로) |
| iPad Pro 13 | 1024px (세로), 1366px (가로) |

→ 768px, 1024px가 업계 표준 (Tailwind, Bootstrap 동일)
세로 자동 확장 로직:

const dynamicCanvasHeight = useMemo(() => {
  const maxRowEnd = visibleComps.reduce((max, comp) => {
    return Math.max(max, comp.row + comp.rowSpan);
  }, 1);
  
  const totalRows = maxRowEnd + CANVAS_EXTRA_ROWS;  // +3행 여유
  const height = totalRows * (rowHeight + gap) + padding * 2;
  
  return Math.max(MIN_CANVAS_HEIGHT, height);  // 최소 600px
}, [...]);

수정 파일

파일 변경 내용
pop-layout.ts GRID_BREAKPOINTS 값 수정, detectGridMode() 조건 수정
useDeviceOrientation.ts BREAKPOINTS.TABLET_MIN = 768
PopCanvas.tsx VIEWPORT_PRESETS height 제거, dynamicCanvasHeight 추가
PopRenderer.tsx gridCells 동적 행 수 계산
page.tsx (뷰어) detectGridMode() 사용

[2026-02-06] v5.1 자동 줄바꿈 + 검토 필요 시스템

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 12칸에서 배치한 컴포넌트가 4칸 모드로 전환하면 "화면 밖" 패널로 이동하여 뷰어에서 안 보임
  • 사용자가 모든 모드를 수동으로 편집해야 하는 부담
  • "화면 밖" 개념이 실제로는 "검토 필요" 알림 역할이었음

해결 방향:

  • 자동 줄바꿈: col > maxCol인 컴포넌트를 자동으로 맨 아래에 배치
  • 정보 손실 방지: 모든 컴포넌트가 항상 그리드 안에 표시됨
  • 검토 필요 알림: 오버라이드 없으면 "검토 필요" 표시 (자동 배치 상태)

Added

  • 자동 줄바꿈 로직 (gridUtils.ts)

    • convertAndResolvePositions() 수정
    • 원본 col 보존 로직 추가
    • 정상 컴포넌트 vs 초과 컴포넌트 분리
    • 초과 컴포넌트를 맨 아래에 순차 배치 (col=1, row=맨아래+1)
    • colSpan 자동 축소 (targetColumns 초과 방지)
  • 검토 필요 판별 함수 (gridUtils.ts)

    • needsReview() 신규 함수
    • 기준: 12칸 아니고 + 오버라이드 없으면 → 검토 필요
    • 간단한 로직: "이 모드에서 편집했냐 안 했냐"
  • 검토 필요 패널 (PopCanvas.tsx)

    • ReviewPanel: "화면 밖" → "검토 필요"로 이름 변경
    • ReviewItem: 클릭 시 해당 컴포넌트 선택 (드래그 없음)
    • 자동 배치 뱃지 표시
    • 파란색 테마 (경고 아닌 안내 느낌)

Changed

  • isOutOfBounds() Deprecated (gridUtils.ts)

    • @deprecated 주석 추가
    • needsReview()로 대체 권장
    • 하위 호환을 위해 함수는 유지
  • "화면 밖" 패널 역할 변경 (PopCanvas.tsx)

    • 기존: col > maxCol → 화면 밖 (드래그로 복원)
    • 변경: 오버라이드 없음 → 검토 필요 (클릭으로 선택)
    • 숨김 기능과 완전히 분리 (별도 유지)

Fixed

  • 정보 손실 문제 해결
    • 모든 컴포넌트가 항상 그리드 안에 배치됨
    • 뷰어에서도 자동 배치가 적용되어 모두 표시됨

Technical Details

자동 줄바꿈 로직:

1. convertAndResolvePositions() 호출
   components: [ {id: "A", position: {col:1, ...}}, {id: "B", position: {col:5, ...}} ]
   targetMode: "mobile_portrait" (4칸)

2. 비율 변환 + 원본 col 보존
   converted: [
     {id: "A", position: {col:1, ...}, originalCol: 1},
     {id: "B", position: {col:2, ...}, originalCol: 5}  // col은 변환됨, 원본은 5
   ]

3. 정상 vs 초과 분리
   normalComponents: [A]  // originalCol ≤ 4
   overflowComponents: [B]  // originalCol > 4

4. 맨 아래 배치
   maxRow = A의 (row + rowSpan - 1) = 1
   B: col=1, row=2 (맨 아래에 자동 배치)

5. 겹침 해결
   resolveOverlaps([A, B], 4)  // 최종 위치 확정

6. 검토 필요 판별
   needsReview("mobile_portrait", false)  // 오버라이드 없음 → true
   → ReviewPanel에 B 표시
검토 필요 vs 숨김:

구분          | 검토 필요              | 숨김
------------- | ---------------------- | -------------------
역할          | 자동 배치 알림         | 의도적 숨김
뷰어에서      | 보임 (자동 배치)       | 안 보임
디자이너에서  | ReviewPanel 표시       | HiddenPanel 표시
판단 기준     | 오버라이드 없음        | hidden 배열에 ID
색상 테마     | 파란색 (안내)          | 회색 (제외)

수정 파일

파일 변경 내용
gridUtils.ts convertAndResolvePositions 자동 줄바꿈, needsReview 추가, isOutOfBounds deprecated
PopCanvas.tsx OutOfBoundsPanel → ReviewPanel 변경, needsReview 필터링
PopRenderer.tsx isOutOfBounds import 제거 (사용 안 함)
README.md v5.1 버전 표시, 최신 기능 요약
CHANGELOG.md v5.1 항목 추가

[2026-02-05 심야] 반응형 레이아웃 + 숨김 기능 완성

배경 (왜 이 작업이 필요했는가)

문제 상황:

  • 12칸 모드에서 배치한 컴포넌트가 4칸 모드에서 초과됨
  • 모드별로 컴포넌트 위치/크기를 다르게 설정할 방법 없음
  • 특정 모드에서만 컴포넌트를 숨길 방법 없음

해결 방향:

  • 모드별 오버라이드 시스템으로 위치/크기 개별 저장
  • 화면 밖 컴포넌트를 별도 패널에 표시하고 드래그로 재배치
  • 숨김 기능으로 특정 모드에서 컴포넌트 제외

Added

  • 모드별 오버라이드 시스템 (PopDesigner.tsx, pop-layout.ts)

    • PopModeOverrideV5.positions: 모드별 컴포넌트 위치 저장
    • PopModeOverrideV5.hidden: 모드별 숨김 컴포넌트 ID 배열
    • getEffectiveComponentPosition(): 오버라이드된 위치 반환
    • 드래그/리사이즈 시 자동으로 오버라이드 저장
  • 화면 밖 컴포넌트 패널 (PopCanvas.tsx)

    • OutOfBoundsPanel: 현재 모드에서 초과하는 컴포넌트 표시
    • OutOfBoundsItem: 드래그 가능한 회색 컴포넌트 카드
    • isOutOfBounds(): 컴포넌트가 현재 모드 칸 수 초과 여부 판단
    • 클릭하면 숨김 패널로 이동
  • 숨김 기능 (PopDesigner.tsx, PopCanvas.tsx)

    • HiddenPanel: 숨김 처리된 컴포넌트 표시
    • HiddenItem: 드래그로 숨김 해제 가능
    • handleHideComponent(): 컴포넌트 숨김 처리
    • handleUnhideComponent(): 숨김 해제 (handleMoveComponent에 통합)
    • 숨김 방법 3가지:
      1. 그리드 → 숨김패널 드래그
      2. H키 단축키
      3. 화면밖 컴포넌트 클릭
  • 리사이즈 겹침 검사 (PopRenderer.tsx)

    • checkResizeOverlap(): 리사이즈 시 다른 컴포넌트와 겹침 검사
    • 겹치면 리사이즈 취소 및 toast 알림
  • 원본으로 되돌리기 (PopDesigner.tsx)

    • handleResetToDefault(): 현재 모드 오버라이드 삭제
    • 자동 위치 계산으로 복원

Fixed

  • 숨김 컴포넌트 드래그 안됨 버그

    • 원인: onUnhideComponentonMoveComponent가 별도로 호출되어 상태 충돌
    • 해결: handleMoveComponent에서 숨김 해제 로직 통합 (단일 상태 업데이트)
  • 그리드 범위 초과 에러

    • 원인: 드롭 위치 + colSpan이 칸 수 초과
    • 해결: 드롭 시 adjustedCol 계산하여 자동으로 왼쪽으로 밀어서 배치
  • getAllEffectivePositions에 숨김 컴포넌트 포함

    • 해결: 숨김 및 화면밖 컴포넌트를 결과에서 제외
  • Expected drag drop context 에러 (뷰어 페이지)

    • 원인: DraggableComponent에서 useDrag 훅이 DndProvider 없이 호출됨
    • 해결: isDesignMode=false일 때 DraggableComponent 대신 일반 div로 렌더링

Changed

  • PopModeOverrideV5 타입 확장

    interface PopModeOverrideV5 {
      positions?: Record<string, Partial<PopGridPosition>>;  // 위치 오버라이드
      hidden?: string[];  // 숨김 컴포넌트 ID 배열
    }
    
  • 12칸 모드(tablet_landscape) 제한

    • 기본 모드이므로 숨김 기능 비활성화
    • 화면밖 패널 표시 안함
    • 위치 변경은 기본 position에 직접 저장
  • 패널 레이아웃 재구성 (PopCanvas.tsx)

    • 오른쪽에 화면밖 패널 + 숨김 패널 세로 배치
    • 12칸 모드에서는 패널 숨김

Technical Details

오버라이드 데이터 흐름:

1. 컴포넌트 드래그/리사이즈
   ↓
2. currentMode 확인
   ↓
3-a. tablet_landscape → layout.components[id].position 직접 수정
3-b. 다른 모드 → layout.overrides[mode].positions[id]에 저장
   ↓
4. getEffectiveComponentPosition()이 우선순위대로 반환
   우선순위: overrides > autoResolved > 기본 position

숨김 기능 흐름:

1. 숨김 요청 (드래그/H키/클릭)
   ↓
2. layout.overrides[mode].hidden 배열에 ID 추가
   ↓
3. PopRenderer에서 hidden 체크 → 렌더링 제외
   ↓
4. HiddenPanel에서 표시
   ↓
5. 드래그로 그리드에 복원 → hidden 배열에서 제거 + 위치 업데이트 (단일 상태 업데이트)

수정 파일

파일 변경 내용
pop-layout.ts PopModeOverrideV5.hidden 추가
PopDesigner.tsx handleHideComponent, handleUnhideComponent 통합, 오버라이드 저장
PopCanvas.tsx OutOfBoundsPanel, HiddenPanel 추가, 드롭 위치 자동 조정
PopRenderer.tsx 숨김 필터링, 리사이즈 겹침 검사
gridUtils.ts getAllEffectivePositions에서 숨김/화면밖 제외, isOutOfBounds 함수

[2026-02-05 저녁] 드래그앤드롭 완전 수정

배경 (왜 좌표 계산이 틀렸는가)

문제 상황:

  • 컴포넌트를 아래로 드래그해도 위로 올라감
  • Row 92 같은 비정상적인 좌표로 배치됨
  • 드래그 이동/리사이즈가 전혀 작동하지 않음

핵심 원인: 캔버스에 transform: scale(0.8) 적용 시 좌표 계산 불일치

문제:
- getBoundingClientRect() → 스케일 적용된 크기 반환 (예: 1024px → 819px)
- getClientOffset() → 뷰포트 기준 실제 마우스 좌표
- 이 둘을 그대로 계산하면 좌표가 완전히 틀림

해결: 단순한 상대 좌표 + 스케일 보정

// 캔버스 내 상대 좌표 (스케일 보정)
const relX = (마우스X - 캔버스left) / canvasScale;
const relY = (마우스Y - 캔버스top) / canvasScale;
calcGridPosition(relX, relY, customWidth, ...);  // 실제 캔버스 크기 사용

Added

  • calcGridPosition() 함수 (PopCanvas.tsx)

    • 캔버스 내 상대 좌표를 그리드 좌표로 변환
    • 패딩, gap, 셀 너비를 고려한 정확한 계산
  • 공통 DND 상수 (constants/dnd.ts)

    • DND_ITEM_TYPES.COMPONENT: 팔레트에서 새 컴포넌트
    • DND_ITEM_TYPES.MOVE_COMPONENT: 기존 컴포넌트 이동
    • 3개 파일에서 중복 정의되던 것을 통합

Fixed

  • 스케일 보정 누락

    • 캔버스 줌(scale)이 적용된 상태에서 좌표 계산 오류
    • (offset - rect.left) / scale로 보정
  • DND 타입 상수 불일치

    • PopCanvas: "component", "MOVE_COMPONENT"
    • PopRenderer: "MOVE_COMPONENT" (하드코딩)
    • ComponentPalette: "component" (로컬 정의)
    • 모두 공통 상수로 통합
  • 컴포넌트 중첩(겹침) 문제

    • 원인: toast import 누락으로 겹침 감지 로직이 실행 안됨
    • 해결: sonner에서 toast import 추가
    • 겹침 시 findNextEmptyPosition()으로 자동 재배치
  • 리사이즈 핸들 작동 안됨

    • 원인: useDrop 훅 2개가 같은 canvasRef에 중복 적용
    • 해결: 단일 useDrop으로 통합 (COMPONENT + MOVE_COMPONENT 모두 처리)
  • 불필요한 toast 메시지 제거

    • "컴포넌트가 이동되었습니다" 알림 삭제

Changed

  • mouseToGridPosition 단순화
    • 복잡한 DOMRect 전달 대신 필요한 값만 직접 전달
    • gridUtils.ts의 함수는 유지 (다른 곳에서 사용)

Technical Details

좌표 변환 흐름 (수정 후):

1. 마우스 드롭
   offset = monitor.getClientOffset()  // 뷰포트 기준 {x: 500, y: 300}

2. 캔버스 위치
   canvasRect = canvasRef.getBoundingClientRect()  // {left: 250, top: 100}

3. 스케일 보정된 상대 좌표
   relX = (500 - 250) / 0.8 = 312.5  // 캔버스 내 실제 X
   relY = (300 - 100) / 0.8 = 250    // 캔버스 내 실제 Y

4. 그리드 좌표 계산
   calcGridPosition(312.5, 250, 1024, 12, 48, 16, 24)
   → { col: 5, row: 4 }

수정 파일

파일 변경 내용
PopCanvas.tsx calcGridPosition 추가, 스케일 보정 적용
PopDesigner.tsx toast 메시지 제거
PopRenderer.tsx DND 상수 import
ComponentPalette.tsx DND 상수 import
constants/dnd.ts 새 파일 (DND 타입 상수)
constants/index.ts 새 파일 (export)

[2026-02-05 오후] 그리드 가이드 CSS Grid 통합

배경 (왜 재설계했는가)

문제 상황:

  • GridGuide.tsx(SVG 기반)와 PopRenderer.tsx(CSS Grid)가 좌표계 불일치
  • 격자선과 컴포넌트가 정렬되지 않음 ("무늬가 따로 논다")
  • 행/열 라벨이 4부터 시작하는 등 오류

핵심 원칙:

"격자선은 컴포넌트와 같은 좌표계에서 태어나야 한다"

결정: SVG 격자 삭제, CSS Grid 기반 통합 → 상세: decisions/004-grid-guide-integration.md

Breaking Changes

  • GridGuide.tsx 삭제 (SVG 기반 격자)

Added

  • CSS Grid 기반 격자 셀 (PopRenderer.tsx)

    • gridCells: 12x20 = 240개 실제 DOM 셀
    • border-dashed border-blue-300/40 스타일
    • 컴포넌트는 z-index:10으로 위에 표시
    • showGridGuide prop으로 ON/OFF
  • 행/열 라벨 (PopCanvas.tsx)

    • 열 라벨: 1~12 (캔버스 상단)
    • 행 라벨: 1~20 (캔버스 좌측)
    • absolute positioning으로 정확한 정렬
    • 줌/패닝에 연동
  • 그리드 토글 버튼 (PopCanvas.tsx)

    • "그리드 ON/OFF" 버튼 추가
    • 격자 표시 상태 관리

Changed

  • 컴포넌트 타입 단순화
    • PopComponentType: pop-sample 1개로 단순화
    • DEFAULT_COMPONENT_GRID_SIZE: pop-sample 전용
    • ComponentPalette.tsx: 샘플 박스 1개만 표시
    • PopRenderer.tsx: 샘플 박스 렌더링으로 단순화

Technical Details

역할 분담:
- PopRenderer: 격자 셀(div) + 컴포넌트 (같은 CSS Grid 좌표계)
- PopCanvas: 라벨 + 줌/패닝 + 토글
- GridGuide: 삭제

격자 셀 구조:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│1,1│2,1│3,1│4,1│5,1│6,1│7,1│8,1│9,1│10│11│12 │ ← col
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│1,2│...                                     │
└───┴───────────────────────────────────────────┘
  ↑ row

[2026-02-05] v5 그리드 시스템 완전 통합

배경 (왜 v5로 전환했는가)

문제 상황:

  • v4 Flexbox로 반응형 구현 시도 → 배치가 예측 불가능
  • 캔버스에 "그리듯이" 배치하면 화면 크기별로 깨짐

상급자 피드백:

"이런 식이면 나중에 문제가 생긴다." "스크린의 픽셀 규격과 마진 간격 규칙을 설정해라. 큰 화면 디자인의 전체 프레임 규격과 사이즈 간격 규칙을 정한 다음에 거기에 컴포넌트를 끼워 맞추듯 우리의 규칙 내로 움직이게 바탕을 잡아라."

연구 내용:

  • Softr: 블록 기반, 제약 기반 레이아웃
  • Ant Design: 24열 그리드, 8px 간격
  • Material Design: 4/8/12열, 반응형 브레이크포인트

결정: CSS Grid 기반 그리드 시스템 (v5) 채택 → 상세: decisions/003-v5-grid-system.md

popdocs 문서 구조 재정비

배경: 문서가 AI 에이전트 진입점 역할을 못함, 컨텍스트 효율화 필요

적용 기법: Progressive Disclosure (점진적 공개), Token as Currency

추가된 파일:

  • SAVE_RULES.md: AI 저장/조회 규칙, 템플릿
  • STATUS.md: 현재 진행 상태, 중단점
  • PROBLEMS.md: 문제-해결 색인
  • INDEX.md: 기능별 색인
  • sessions/: 날짜별 작업 기록

문서 계층:

  • Layer 1 (진입점): README, STATUS, SAVE_RULES
  • Layer 2 (상세): CHANGELOG, PROBLEMS, INDEX, FILES, ARCHITECTURE
  • Layer 3 (심화): decisions/, sessions/, archive/

Breaking Changes

  • v1, v2, v3, v4 레이아웃 완전 삭제
  • 기존 POP 화면 데이터 전체 초기화 필요
  • 레거시 컴포넌트 및 타입 삭제

Added

  • CSS Grid 기반 그리드 시스템 (v5)

    • 4개 모드별 칸 수: 4/6/8/12칸
    • 명시적 위치 지정 (col, row, colSpan, rowSpan)
    • 모드별 오버라이드 지원
    • 자동 위치 변환 (12칸 기준 → 다른 모드)
  • 통합된 파일 구조

    • PopCanvas.tsx: 그리드 캔버스 (DnD + 줌 + 모드 전환)
    • PopRenderer.tsx: 그리드 렌더링
    • ComponentEditorPanel.tsx: 속성 편집
    • pop-layout.ts: v5 전용 타입 정의
    • gridUtils.ts: 그리드 유틸리티 함수

Removed

  • PopCanvasV4.tsx, PopCanvas.tsx (v3)
  • PopFlexRenderer.tsx, PopLayoutRenderer.tsx
  • ComponentEditorPanelV4.tsx, PopPanel.tsx
  • v1, v2, v3, v4 타입 정의 및 유틸리티 함수
  • test-v4 테스트 페이지

Changed

  • screenManagementService.ts: v5 전용으로 단순화
  • screen_layouts_pop 테이블: 기존 데이터 삭제, v5 전용
  • PopDesigner.tsx: v5 전용으로 리팩토링
  • 뷰어 페이지: v5 렌더러 전용

Technical Details

// v5 그리드 모드
type GridMode = "mobile_portrait" | "mobile_landscape" | "tablet_portrait" | "tablet_landscape";

// 그리드 설정
const GRID_BREAKPOINTS = {
  mobile_portrait: { columns: 4, rowHeight: 48, gap: 8, padding: 12 },
  mobile_landscape: { columns: 6, rowHeight: 44, gap: 8, padding: 16 },
  tablet_portrait: { columns: 8, rowHeight: 52, gap: 12, padding: 20 },
  tablet_landscape: { columns: 12, rowHeight: 56, gap: 12, padding: 24 },
};

// 컴포넌트 위치
interface PopGridPosition {
  col: number;      // 시작 열 (1부터)
  row: number;      // 시작 행 (1부터)
  colSpan: number;  // 열 크기
  rowSpan: number;  // 행 크기
}

[2026-02-04] Phase 2.1 완료 - 배치 고정 기능

Added

  • 현재 모드 추적 (PopDesigner.tsx)

    • currentViewportMode 상태 추가
    • PopCanvasV4와 양방향 동기화
    • 모드 변경 시 자동 업데이트
  • 배치 고정 기능

    • "고정" 버튼 추가 (기본 모드 제외)
    • handleLockLayoutV4() - 현재 배치를 오버라이드에 저장
    • 배치 정보: direction, wrap, gap, alignItems, justifyContent, children 순서
  • 오버라이드 초기화 기능

    • handleResetOverrideV4() - 오버라이드 삭제
    • "자동으로 되돌리기" 버튼 (편집된 모드만 표시)
    • 자동 계산으로 되돌림

Changed

  • PopCanvasV4 Props 구조 변경

    • currentMode prop 추가 (외부에서 제어)
    • onModeChange 콜백 추가
    • onLockLayout 콜백 추가
    • 내부 activeViewport 상태 제거 (부모가 관리)
  • 프리셋 버튼 동작

    • 클릭 시 부모 상태 업데이트 (onModeChange)
    • currentMode prop 기반으로 활성 상태 표시

Technical Details

// 고정 로직
const handleLockLayoutV4 = () => {
  const newLayout = {
    ...layoutV4,
    overrides: {
      ...layoutV4.overrides,
      [currentViewportMode]: {
        containers: {
          root: {
            direction: layoutV4.root.direction,
            wrap: layoutV4.root.wrap,
            gap: layoutV4.root.gap,
            children: layoutV4.root.children, // 순서 고정
            // ... 기타 배치 속성
          }
        }
      }
    }
  };
};

// 초기화 로직
const handleResetOverrideV4 = (mode) => {
  const newOverrides = { ...layoutV4.overrides };
  delete newOverrides[mode];
  // overrides가 비면 undefined로 설정
};

UI 변경

툴바:
[모바일↕] [모바일↔] [태블릿↕] [태블릿↔(기본)] [고정] [자동으로 되돌리기]

조건부 표시:
- "고정" 버튼: 기본 모드가 아닐 때
- "자동으로 되돌리기": 오버라이드가 있을 때

주의사항

  • 크기는 고정하지 않음 (여전히 자동 스케일링)
  • 배치만 오버라이드 (순서, 방향, 정렬)
  • 최소/최대값 기능은 별도 구현 필요

[2026-02-04] Phase 2 시작 - 오버라이드 UI 표시

Added

  • 오버라이드 데이터 구조 (pop-layout.ts)

    • PopModeOverride 인터페이스 추가
    • PopLayoutDataV4.overrides 필드 추가
    • 3개 모드 오버라이드 지원 (mobile_portrait, mobile_landscape, tablet_portrait)
  • 프리셋 버튼 상태 표시 (PopCanvasV4.tsx)

    • 기본 모드: "(기본)" 텍스트 표시
    • 편집된 모드: "(편집)" 텍스트 + 노란색 강조
    • 자동 모드: 기본 스타일

Changed

  • hasOverride 함수 구현
    • layout.overrides 필드 체크
    • 컴포넌트/컨테이너 오버라이드 존재 여부 확인

[2026-02-04] 비율 스케일링 시스템 구현

Added

  • 비율 스케일링 시스템 (업계 표준 Scale with Fixed Aspect Ratio)

    • 기준 너비: 1024px (10인치 태블릿 가로)
    • 최대 너비: 1366px (12인치 태블릿)
    • 8~12인치 화면에서 배치 유지, 크기만 비례 조정
  • 뷰포트 감지 (page.tsx)

    • viewportWidth state 추가
    • resize 이벤트 리스너로 실시간 감지
    • Math.min(window.innerWidth, 1366) 최대값 제한

Changed

  • PopFlexRenderer.tsx

    • BASE_VIEWPORT_WIDTH = 1024 상수 추가
    • scale = viewportWidth / BASE_VIEWPORT_WIDTH 계산
    • calculateSizeStyle() 함수에 scale 파라미터 추가
    • 컴포넌트 크기 (fixedWidth, fixedHeight) 스케일 적용
    • 컨테이너 gap, padding 스케일 적용
    • 디자인 모드: scale = 1 (원본), 뷰어 모드: 실제 scale 적용
  • ComponentRendererV4

    • viewportWidth prop 추가
    • 내부에서 scale 계산하여 sizeStyle에 적용
  • ContainerRenderer

    • scaledGap, scaledPadding 계산하여 containerStyle에 적용

Technical Details

비율 스케일링 계산:
scale = 실제 화면 너비 / 기준 너비 (1024px)

예시:
- 800px (8인치): scale = 0.78 → 200px 컴포넌트 → 156px
- 1024px (10인치): scale = 1.00 → 200px 컴포넌트 → 200px (기준)
- 1366px (12인치): scale = 1.33 → 200px 컴포넌트 → 266px
- 1920px (데스크톱): max-width 1366px 적용 → 12인치와 동일 + 여백

Fixed

  • DndProvider 에러 (뷰어 페이지)
    • 원인: isDesignMode=false일 때 useDrag/useDrop 훅 호출
    • 해결: DraggableComponentWrapper에서 isDesignMode 체크 후 early return

[2026-02-04] Flexbox 가로 배치 + Spacer + Undo/Redo 개선

Added

  • Spacer 컴포넌트 (pop-spacer)

    • 빈 공간을 차지하여 레이아웃 정렬에 사용
    • 기본 크기: width: fill, height: 48px
    • 디자인 모드에서 점선 배경으로 표시
    • 실제 모드에서는 투명 (공간만 차지)
  • 컴포넌트 순서 변경 (드래그 앤 드롭)

    • 같은 컨테이너 내에서 컴포넌트 순서 변경 가능
    • 드래그 중인 컴포넌트는 반투명하게 표시
    • 드롭 위치는 파란색 테두리로 표시
    • handleReorderComponentV4 핸들러 추가

Changed

  • 기본 레이아웃 방향 변경 (Flexbox 가로 배치)

    • direction: "vertical"direction: "horizontal"
    • wrap: falsewrap: true (자동 줄바꿈)
    • alignItems: "stretch"alignItems: "start"
    • 컴포넌트가 가로로 나열되고, 공간 부족 시 다음 줄로 이동
  • 컴포넌트 기본 크기 타입별 설정

    • 필드: 200x48px (fixed)
    • 버튼: 120x48px (fixed)
    • 리스트: fill x 200px
    • 인디케이터: 120x80px (fixed)
    • 스캐너: 200x48px (fixed)
    • 숫자패드: 200x280px (fixed)
    • Spacer: fill x 48px
  • Undo/Redo 방식 개선 (데스크탑 모드와 동일)

    • useLayoutHistory 훅 제거
    • 별도 history[], historyIndex 상태로 관리
    • saveToHistoryV4() 함수로 명시적 히스토리 저장
    • 컴포넌트 추가/삭제/수정/순서변경 시 히스토리 저장
  • 디바이스 스크린 스크롤

    • overflow: auto 추가 (컴포넌트가 넘치면 스크롤)
    • heightminHeight 변경 (컨텐츠에 따라 높이 증가)

Technical Details

업계 표준 레이아웃 방식 (Figma, Webflow, FlutterFlow):
1. Flexbox 기반 Row/Column 배치
2. 크기 제어: Fill / Fixed / Hug
3. Spacer 컴포넌트로 정렬 조정
4. 화면 크기별 조건 분기 (반응형)

사용 예시:
[버튼A] [Spacer(fill)] [버튼B]  → 버튼B가 오른쪽 끝으로
[Spacer] [컴포넌트] [Spacer]   → 컴포넌트가 가운데로

[2026-02-04] 드래그 리사이즈 + Undo/Redo 기능

Added

  • useLayoutHistory.ts - Undo/Redo 히스토리 훅

    • 최대 50개 히스토리 저장
    • undo(), redo(), canUndo, canRedo
    • reset() - 새 레이아웃 로드 시 히스토리 초기화
  • 드래그 리사이즈 핸들 (PopFlexRenderer)

    • 오른쪽 핸들: 너비 조정 (cursor: ew-resize)
    • 아래쪽 핸들: 높이 조정 (cursor: ns-resize)
    • 오른쪽 아래 핸들: 너비+높이 동시 조정 (cursor: nwse-resize)
    • 선택된 컴포넌트에만 표시
    • 최소 크기 보장 (너비 48px, 높이 touchTargetMin)

Changed

  • PopDesigner.tsx

    • useLayoutHistory 훅 통합 (v3, v4 각각 독립적)
    • Undo/Redo 버튼 추가 (툴바 오른쪽)
    • 단축키 등록:
      • Ctrl+Z / Cmd+Z: 실행 취소
      • Ctrl+Shift+Z / Cmd+Shift+Z / Ctrl+Y: 다시 실행
    • handleResizeComponentV4 핸들러 추가
  • PopCanvasV4.tsx

    • onResizeComponent prop 추가
    • PopFlexRenderer에 전달
  • PopFlexRenderer.tsx

    • onComponentResize prop 추가
    • ComponentRendererV4에 리사이즈 핸들 추가
    • 드래그 이벤트 처리 (mousemove, mouseup)

단축키 목록

단축키 기능
Delete / Backspace 선택된 컴포넌트 삭제
Ctrl+Z / Cmd+Z 실행 취소 (Undo)
Ctrl+Shift+Z / Ctrl+Y 다시 실행 (Redo)
Space + 드래그 캔버스 패닝
Ctrl + 휠 줌 인/아웃

[2026-02-04] v4 통합 설계 모드 Phase 1 완료

목표

v4를 기본 레이아웃 모드로 통합하고, 새 화면은 자동으로 v4로 시작

Added

  • ComponentPaletteV4.tsx - v4 전용 컴포넌트 팔레트
    • 6개 컴포넌트 (필드, 버튼, 리스트, 인디케이터, 스캐너, 숫자패드)
    • 드래그 앤 드롭 지원

Changed

  • PopDesigner.tsx - v3/v4 통합 디자이너로 리팩토링

    • v3/v4 탭 제거 (자동 판별)
    • 새 화면 → v4로 시작
    • 기존 v3 화면 → v3로 로드 (하위 호환)
    • 빈 레이아웃 → v4로 시작 (컴포넌트 유무로 판별)
    • 레이아웃 버전 텍스트 표시 ("자동 레이아웃 (v4)" / "4모드 레이아웃 (v3)")
  • PopCanvasV4.tsx - 4개 프리셋으로 변경

    • 기존: [모바일] [태블릿] [데스크톱]
    • 변경: [모바일↕] [모바일↔] [태블릿↕] [태블릿↔]
    • 기본 프리셋: 태블릿 가로 (1024x768)
    • 슬라이더 범위: 320~1200px
    • 비율 유지: 슬라이더 조절 시 높이도 비율에 맞게 자동 조정

Fixed

  • 새 화면이 v3로 열리는 문제
    • 원인: 백엔드가 빈 v2 레이아웃 반환 (version 필드 있음)
    • 해결: 컴포넌트 유무로 빈 레이아웃 판별 → v4로 시작

Technical Details

레이아웃 로드 로직:
1. version 필드 확인
2. components 존재 여부 확인
3. version 있고 components 있음 → 해당 버전으로 로드
4. version 없거나 components 없음 → v4로 새로 시작

[2026-02-04] Phase 2.1 완료 - 배치 고정 기능 (버그 수정)

🔥 주요 버그 수정

  • layoutV4.root 오염 문제 해결: 다른 모드에서 편집 시 기본 레이아웃이 변경되던 버그 수정
  • tempLayout 도입: 고정 전 임시 배치를 별도 상태로 관리하여 root를 보호
  • 렌더러 병합 로직: PopFlexRenderer에 오버라이드 자동 병합 기능 추가

데이터 흐름 개선

  1. 기본 모드 (태블릿 가로)

    • 드래그/속성 변경 → layoutV4.root 직접 수정
    • 모든 다른 모드의 기본값으로 사용
  2. 다른 모드 (모바일 세로 등)

    • 드래그 → tempLayout 임시 저장 (화면에만 표시)
    • "고정" 버튼 → layoutV4.overrides[mode]에 저장
    • 속성 패널 → 비활성화 + 안내 메시지
  3. 렌더링

    • tempLayout 있으면 최우선 표시 (고정 전 미리보기)
    • 오버라이드 있으면 root와 병합
    • 없으면 root 그대로 표시

수정 파일

  • PopDesigner.tsx: tempLayout 상태 추가, 핸들러 수정
  • PopFlexRenderer.tsx: 병합 로직 추가 (getMergedRoot)
  • PopCanvasV4.tsx: tempLayout props 전달
  • ComponentEditorPanelV4.tsx: 속성 패널 비활성화 로직

[2026-02-04] Phase 3 완료 - visibility + 줄바꿈 컴포넌트

추가 기능

  • visibility 속성: 모드별 컴포넌트 표시/숨김 제어
  • pop-break 컴포넌트: 강제 줄바꿈 (flex-basis: 100%)
  • 컴포넌트 오버라이드 병합: 모드별 컴포넌트 설정 변경 가능

타입 정의

interface PopComponentDefinitionV4 {
  // 기존 속성...
  
  // 🆕 모드별 표시/숨김
  visibility?: {
    tablet_landscape?: boolean;
    tablet_portrait?: boolean;
    mobile_landscape?: boolean;
    mobile_portrait?: boolean;
  };
}

// 🆕 줄바꿈 컴포넌트
type PopComponentType = 
  | "pop-field"
  | "pop-button"
  | "pop-list"
  | "pop-indicator"
  | "pop-scanner"
  | "pop-numpad"
  | "pop-spacer"
  | "pop-break";  // 새로 추가

렌더러 개선

  • isComponentVisible(): visibility 체크 로직
  • getMergedComponent(): 컴포넌트 오버라이드 병합
  • pop-break 전용 렌더링 (디자인 모드: 점선, 실제: 높이 0)

삭제 함수 개선

  • cleanupOverridesAfterDelete(): 컴포넌트 삭제 시 모든 오버라이드 정리
  • containers.root.children 정리
  • components 오버라이드 정리
  • 빈 오버라이드 자동 제거

UI 개선

  • 속성 패널에 "표시" 탭 추가 (Eye 아이콘)
  • 모드별 체크박스 UI
  • 반응형 숨김 (hideBelow) 유지
  • 팔레트에 "줄바꿈" 컴포넌트 추가

사용 예시

태블릿 가로:
[A] [B] [C] [D] [E]  ← 한 줄

모바일 세로:
[A] [B]
───────  ← 줄바꿈 (visibility: mobile만 true)
[C] [D] [E]

수정 파일

  • pop-layout.ts: 타입 추가, 삭제 함수 수정
  • PopFlexRenderer.tsx: visibility, 병합, pop-break 렌더링
  • ComponentEditorPanelV4.tsx: 표시 탭 추가
  • ComponentPaletteV4.tsx: 줄바꿈 추가

[2026-02-04] v4 타입 및 렌더러

Added

  • v4 타입 정의 (간결 버전)

    • PopLayoutDataV4 - 단일 소스 레이아웃
    • PopContainerV4 - 스택 컨테이너 (direction, wrap, gap, alignItems)
    • PopComponentDefinitionV4 - 크기 제약 기반 (size: fixed/fill/hug)
    • PopSizeConstraintV4 - 크기 규칙
    • PopResponsiveRuleV4 - 반응형 규칙 (breakpoint별 변경)
    • PopGlobalSettingsV4 - 전역 설정
    • createEmptyPopLayoutV4() - 생성 함수
    • isV4Layout() - 타입 가드
    • CRUD 함수들 (add, remove, update, find)
  • PopFlexRenderer.tsx - v4 Flexbox 렌더러

    • 컨테이너 재귀 렌더링
    • 반응형 규칙 적용
    • 크기 제약 → CSS 변환
  • ComponentEditorPanelV4.tsx - v4 속성 편집 패널

    • 크기 제약 편집 UI
    • 컨테이너 설정 UI
  • PopCanvasV4.tsx - v4 전용 캔버스

    • 뷰포트 프리셋
    • 너비 슬라이더
    • 줌/패닝

[2026-02-04] (earlier)

Added

  • 저장/조회 시스템 구축
    • rangraph: AI 장기 기억 (시맨틱 검색, 요약)
    • popdocs: 상세 기록 (파일 기반, 히스토리)
    • 이중 저장 체계로 검색 + 기록 분리

Changed

  • popdocs 문서 구조 정리
    • README.md: 저장/조회 규칙 추가
    • 기존 문서 archive/로 이동
  • 문서 관리 전략 확정
    • 저장 시: 파일 형식 자동 파악 → 형식 맞춰 추가 → rangraph 요약
    • 조회 시: rangraph 시맨틱 검색

Removed

  • .cursorrules 변경 계획 철회 (Git 커밋 영향)

[2026-02-03]

Added

  • v4 제약조건 기반 레이아웃 계획
    • 단일 소스 + 자동 적응
    • 3가지 규칙 (크기, 배치, 반응형)
    • ADR: decisions/001-v4-constraint-based.md

[2026-02-02]

Fixed

  • 캔버스 rowSpan 문제
    • 원인: gridTemplateRows 고정 px
    • 해결: 1fr 사용

[2026-02-01]

Fixed

  • 4모드 자동 전환 문제
    • 해결: useResponsiveMode 훅 추가

[2026-01-31]

Added

  • v3 섹션 제거, 순수 그리드 구조
  • 4개 모드 독립 그리드

[2026-01-30]

Added

  • POP 디자이너 기본 구조
  • PopDesigner, PopCanvas 컴포넌트

[2026-01-29]

Added

  • screen_layouts_pop 테이블
  • POP 레이아웃 API (CRUD)

최신이 위, 시간순 역순