ERP-node/popdocs/sessions/2026-02-09.md

12 KiB

2026-02-09 작업 기록

요약

POP 컴포넌트 정의서 v8.0 완성, 모달 화면 설계 방식 확정, 기존 시스템 호환성 검증, POP 뷰어 실제 컴포넌트 렌더링 버그 수정, POP 뷰어 스크롤 수정


완료

POP 컴포넌트 정의서 작성 (POPUPDATE_2.md)

  • 9개 컴포넌트 정의 (pop-text, pop-dashboard, pop-table, pop-button, pop-icon, pop-search, pop-field, pop-lookup, pop-system)
  • POP 헌법 8조 작성 (공통 규칙)
  • 공통 인프라 설계 (DataSourceConfig, ColumnBinding, JoinConfig, useDataSource, usePopEvent, PopActionConfig)
  • 컴포넌트 간 통신 시퀀스 다이어그램 5개 작성
  • 구현 우선순위 6단계(Phase 0~6) 정리
  • v7.0 POPUPDATE_2.md 생성 및 커밋/푸시 (ksh-v2-work)

모달 화면 설계 방식 확정 (v8.0)

  • pop-lookup 모달 화면 두 가지 방식 정의
    • 방식 A (인라인 모달): DataSourceConfig 기반, 단순 목록 선택용
    • 방식 B (외부 화면 참조): 별도 screen_id 연결, 복잡한 화면/재사용 목적
  • POP 헌법 제9조 추가 (모달 화면의 설계)
  • PopActionConfig의 modal 타입 구체화
  • 인라인 vs 외부 참조 시퀀스 다이어그램 추가

기존 시스템 호환성 검증

  • DB 스키마 확인 (screen_layouts_v2, screen_layouts_pop)
    • layout_data JSONB 유연 구조 -> modalConfig 저장 가능
    • DB 마이그레이션 불필요
  • 백엔드 API 확인 (saveLayoutPop, getLayoutPop)
    • 기존 API 그대로 사용 가능
    • 새로운 API 불필요
  • 프론트엔드 참조 패턴 확인 (TabsWidget)
    • 탭의 screenId 참조 방식을 모달에 차용 가능
    • 디자이너 탭 내부 컴포넌트 편집 패턴 존재

대화 핵심

컴포넌트 설계 토론 (이전 세션 연속)

주요 결정들:

  1. 컴포넌트 9개 확정: 기존 7개에서 pop-lookup, pop-system 추가
  2. 역할 분리 원칙: 조회용(pop-search) vs 저장용(pop-field), 이동(pop-icon) vs 값 선택(pop-lookup)
  3. 시스템 설정도 컴포넌트: pop-system으로 통합 (디자이너가 배치 여부 결정)
  4. 모달 화면 이중 방식: 인라인(설정만으로 완결) + 외부 참조(별도 화면)

모달 설계 방식 결정

사용자 관심사:

참조 화면에서 검색 -> 거래처 모달 -> 거래처 선택 -> 품목 출력, 이런 연결 구조를 어떻게 만들지?

결론:

  • 단순 선택: pop-lookup 인라인 모달 (설정만으로 완결)
  • 복잡한 화면: 별도 POP 화면을 만들어 screenId로 참조

호환성 검증

사용자 요청:

반영하기 전에 실제 백엔드나 프론트엔드 로직상 가능한지, DB 스키마나 컬럼 형식도 맞는지 확인해줘

검증 결과:

항목 결과
DB screen_layouts_v2 JSONB -> 유연하게 확장 가능
DB screen_layouts_pop 동일 구조, 모달 화면도 별도 screen_id로 저장 가능
백엔드 saveLayoutPop/getLayoutPop 기존 API 그대로 사용 가능
프론트 TabsWidget screenId 참조 패턴 이미 존재 (차용 가능)
프론트 detectLinkedModals 화면 간 참조 관계 추적에 활용 가능

변경 파일

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

중단점

다음 작업: Phase 0 공통 인프라 구현

  • ColumnBinding, JoinConfig, DataSourceConfig 타입 정의
  • useDataSource 훅 (CRUD 포함)
  • usePopEvent 훅 (데이터 전달 포함)
  • PopActionConfig 타입 정의
  • POPUPDATE_2.md의 "구현 우선순위" 섹션 참조

다음 작업자 참고

  1. POPUPDATE_2.md가 컴포넌트 정의서의 최신본 (v8.0)
  2. 기존 popdocs/components-spec.md는 v4 기준이라 갱신 필요
  3. 구현 순서: Phase 0 (공통 인프라) -> Phase 1 (pop-dashboard) -> Phase 2 (pop-button, pop-icon) -> ...
  4. 모달 구현 시: TabsWidget의 screenId 참조 패턴을 참고할 것

pop-dashboard 토의를 위한 사전 정보

다음 세션에서 대시보드 컴포넌트를 토의할 때 이 섹션을 먼저 읽으세요.

정의서 위치

  • POPUPDATE_2.md 240~255행: pop-dashboard 정의 (서브타입, 이벤트, 설정)
  • 서브타입: kpi-card, chart, gauge, stat-card
  • Phase 1에서 KPI 카드 서브타입부터 구현 예정

기존 대시보드 코드 (이미 존재함 - 반드시 확인)

POP 대시보드 프로토타입과 관리자 대시보드가 이미 구현되어 있음. 재사용/참고 판단 필요.

POP 대시보드 (프로토타입 - 하드코딩):

파일 역할 핵심 내용
frontend/components/pop/dashboard/PopDashboard.tsx POP 대시보드 메인 테마(dark/light), 헤더/KPI/메뉴/활동/공지/푸터 조합
frontend/components/pop/dashboard/KpiBar.tsx KPI 게이지 바 SVG 원형 게이지 + 퍼센트 + 값 + 단위 (목표달성률, 생산실적, 불량률, 가동설비)
frontend/components/pop/dashboard/types.ts 타입 정의 KpiItem(label, value, unit, percentage, color), MenuItem, ActivityItem 등
frontend/components/pop/dashboard/data.ts 샘플 데이터 KPI 4종(목표달성률 83%, 생산실적 1250EA, 불량률 0.8%, 가동설비 8/10)
frontend/components/pop/dashboard/MenuGrid.tsx 메뉴 그리드 생산/자재/품질/설비/안전 5개 메뉴 카드
frontend/components/pop/dashboard/DashboardHeader.tsx 헤더 회사명, 사용자, 날씨, 시간, 테마 토글
frontend/components/pop/dashboard/DashboardFooter.tsx 푸터 회사명, 버전, 긴급연락처
frontend/components/pop/dashboard/dashboard.css 스타일 CSS 전용 (Tailwind 아님), dark/light 테마

현재 상태: 하드코딩 샘플 데이터. API 연동 없음. 컴포넌트 시스템과 미연결.

관리자 대시보드 (별도 시스템):

파일 역할
frontend/lib/api/dashboard.ts 대시보드 CRUD API (dashboardApi)
frontend/contexts/DashboardContext.tsx 위젯 간 데이터 공유 (selectedDate)
frontend/components/admin/dashboard/DashboardCanvas.tsx 관리자용 대시보드 캔버스
frontend/components/admin/dashboard/DashboardSaveModal.tsx 대시보드 저장 모달
frontend/components/dashboard/DashboardViewer.tsx 대시보드 뷰어
frontend/lib/registry/components/DashboardRenderer.tsx 대시보드 렌더러 (기존 위젯 시스템)
frontend/components/screen/config-panels/DashboardConfigPanel.tsx 대시보드 설정 패널

dashboardApi 제공 기능: CRUD(create/get/update/delete), executeQuery(SQL 실행), getTableSchema(스키마 조회)

토의 시 결정해야 할 것

  1. 기존 KpiBar.tsx 재사용 여부: SVG 게이지 UI를 pop-dashboard kpi-card에 그대로 쓸지, 새로 만들지
  2. 기존 dashboardApi 활용 여부: executeQuery/getTableSchema를 useDataSource에서 쓸지, 별도 API를 만들지
  3. 하드코딩 -> DataSourceConfig 전환: 기존 data.ts 샘플을 DB 연동으로 어떻게 바꿀지
  4. 기존 dashboard.css -> Tailwind 전환: POP 대시보드 스타일을 Tailwind/shadcn으로 전환할지
  5. 관리자 대시보드와의 관계: 별도 시스템으로 유지할지, POP 컴포넌트 시스템으로 통합할지


POP 뷰어 실제 컴포넌트 렌더링 버그 수정

문제

설계 화면(디자이너)에서는 이미지/텍스트/타이틀이 정상 표시되지만, 뷰어(/pop/screens/4114)에 접속하면 "pop-text 1", "pop-text 2" 같은 라벨만 보이는 플레이스홀더 상태.

원인 (2가지)

# 원인 파일 라인
A renderActualComponent() 함수가 레지스트리의 실제 컴포넌트를 사용하지 않고 라벨만 반환 PopRenderer.tsx 555-564
B 뷰어 페이지에서 import "@/lib/registry/pop-components" 누락으로 레지스트리 초기화 안 됨 page.tsx (없음)

수정 내용

파일 변경
frontend/app/(pop)/pop/screens/[screenId]/page.tsx import "@/lib/registry/pop-components" 추가 (PopRenderer import 앞에 배치)
frontend/components/pop/designer/renderers/PopRenderer.tsx renderActualComponent() 함수를 레지스트리에서 실제 컴포넌트를 조회하여 렌더링하도록 교체

검증

  • 린트 에러 0건
  • 자체 검증 5항목 전부 통과 (중복 정의, import 일치, props 일치 등)

미해결: datetime 실시간 업데이트 기본값 문제

  • DateTimeDisplay 컴포넌트의 isRealtime 기본값이 true가 아닌 문제 발견
  • 설정 패널 UI는 ?? true로 기본 "켜짐" 표시하나, 실제 컴포넌트는 !config?.isRealtime으로 undefined를 "꺼짐"으로 처리
  • DB에 isRealtime 필드가 저장되지 않은 기존 데이터에서 시간이 멈춰 보임
  • 별도 작업으로 수정 예정

이번 작업에서 배운 것

side-effect import 순서의 중요성

import "@/lib/registry/pop-components"와 같은 side-effect import는 반드시 해당 레지스트리를 사용하는 컴포넌트(PopRenderer) import보다 앞에 위치해야 한다. JavaScript 모듈은 import 순서대로 실행되므로, 순서가 뒤바뀌면 빈 레지스트리를 참조할 수 있다.

UI 기본값과 로직 기본값의 불일치 패턴

설정 패널에서 config?.isRealtime ?? true로 UI를 "켜짐"으로 보여주지만, 실제 컴포넌트에서 !config?.isRealtime으로 체크하면 undefinedfalse로 평가되어 동작하지 않는다. UI 기본값과 로직 기본값은 반드시 동일한 패턴(?? true)을 사용해야 한다.

다음에 비슷한 작업할 때 주의할 점

  • 새 POP 컴포넌트를 레지스트리에 등록할 때, 뷰어 페이지(page.tsx)에도 해당 컴포넌트의 초기화 import가 포함되는지 반드시 확인
  • optional config 필드의 기본값은 "정의하는 곳(설정 패널)"과 "사용하는 곳(렌더 컴포넌트)" 모두에서 동일하게 처리


POP 뷰어 스크롤 수정

문제

뷰어(/pop/screens/4114)에서 화면 높이를 초과하는 컴포넌트가 잘려서 안 보임. 설계(디자이너)에서는 스크롤되지만 뷰어에서는 스크롤 불가.

원인

# 컨테이너 (라인) 현재 클래스 문제
1 최외곽 (185) h-screen ... overflow-hidden 넘치는 콘텐츠를 잘라냄
2 컨텐츠 영역 (266) 프리뷰 모드에만 overflow-auto 일반 모드에서 스크롤 불가
3 백색 배경 (275) 일반 모드에 min-h-full 없음 짧은 콘텐츠 시 배경 불완전

수정 내용

라인 변경 전 변경 후
185 overflow-hidden 포함 overflow-hidden 제거
266 프리뷰 모드에만 overflow-auto overflow-auto 공통 적용
275 일반 모드 w-full w-full min-h-full

검증

  • 린트 에러 0건
  • 새 변수/함수/타입 추가 없음 (CSS 클래스만 변경)

이번 작업에서 배운 것 (스크롤 수정)

Flexbox + overflow 조합에서 스크롤 동작 원리

  • 부모에 overflow-hidden이 있으면, 자식에 아무리 overflow-auto를 넣어도 스크롤이 작동하지 않음
  • h-screen + overflow-hidden은 뷰포트 높이로 잘라내는 "뚜껑" 역할
  • 스크롤을 허용하려면 부모의 overflow-hidden을 제거하고, 실제 스크롤이 필요한 자식에 overflow-auto를 넣어야 함

프리뷰 모드와 일반 모드의 CSS 분기 주의

  • 조건부 클래스(isPreviewMode ? "overflow-auto" : "")로 특정 모드에만 스크롤을 넣으면, 다른 모드에서 스크롤이 빠지는 문제가 발생
  • 공통으로 필요한 속성은 조건문 밖에 배치해야 함

관련 링크