ERP-node/.cursor/agents/pipeline-common-rules.md

8.1 KiB

WACE ERP 파이프라인 공통 룰 (모든 에이전트 필수 준수)

1. 화면 유형 구분 (절대 규칙!)

이 시스템은 관리자 메뉴사용자 메뉴가 완전히 다른 방식으로 동작한다. 기능 구현 시 반드시 어느 유형인지 먼저 판단하라.

관리자 메뉴 (Admin)

  • 구현 방식: React 코드 기반 페이지 (.tsx 파일)
  • 경로: frontend/app/(main)/admin/{기능명}/page.tsx
  • 메뉴 등록: menu_info 테이블에 INSERT 필수 (코드만 만들고 메뉴 등록 안 하면 미완성!)
  • 대상: 시스템 설정, 사용자 관리, 결재 관리, 코드 관리 등
  • 특징: 하드코딩된 UI, 관리자만 접근

사용자 메뉴 (User/Screen) - 절대 하드코딩 금지!!!

  • 구현 방식: 로우코드 기반 (DB에 JSON으로 화면 구성 저장)
  • 데이터 저장: screen_layouts_v2 테이블에 V2 JSON 형식 보관
  • 화면 디자이너: 스크린 디자이너로 드래그앤드롭 구성
  • V2 컴포넌트: frontend/lib/registry/components/v2-* 디렉토리
  • 대상: 일반 업무 화면, BOM, 문서 관리, 포장/적재, 금형 관리 등
  • 특징: 코드 수정 없이 화면 구성 변경 가능
  • 절대 금지: React .tsx 페이지 파일로 직접 UI를 하드코딩하는 것!

판단 기준

질문 관리자 메뉴 사용자 메뉴
누가 쓰나? 시스템 관리자 일반 사용자
화면 구조 고정? 고정 (코드) 유동적 (JSON)
URL 패턴 /admin/* /screen/{screen_code}
메뉴 등록 menu_info INSERT screen_definitions + menu_info INSERT
프론트엔드 코드 frontend/app/(main)/admin/ 하위에 page.tsx 작성 코드 작성 금지! DB에 스크린 정의만 등록

사용자 메뉴 구현 방법 (반드시 이 방식으로!)

절대 규칙: 사용자 메뉴는 React 페이지(.tsx)를 직접 만들지 않는다! 이미 /screen/[screenCode]/page.tsx/screens/[screenId]/page.tsx 렌더링 시스템이 존재한다. 새 화면이 필요하면 DB에 등록만 하면 자동으로 렌더링된다.

Step 1: screen_definitions에 화면 등록

INSERT INTO screen_definitions (screen_name, screen_code, table_name, company_code, is_active)
VALUES ('포장/적재정보 관리', 'COMPANY_7_PKG', 'pkg_unit', 'COMPANY_7', 'Y')
RETURNING screen_id;
  • screen_code: {company_code}_{기능약어} 형식 (예: COMPANY_7_PKG)
  • table_name: 메인 테이블명 (V2 컴포넌트가 이 테이블 기준으로 동작)
  • company_code: 대상 회사 코드

Step 2: screen_layouts_v2에 V2 레이아웃 JSON 등록

INSERT INTO screen_layouts_v2 (screen_id, company_code, layer_id, layer_name, layout_data)
VALUES (
  {screen_id},
  'COMPANY_7',
  1,
  '기본 레이어',
  '{
    "version": "2.0",
    "components": [
      {
        "id": "comp_split_1",
        "url": "@/lib/registry/components/v2-split-panel-layout",
        "position": {"x": 0, "y": 0},
        "size": {"width": 1200, "height": 800},
        "displayOrder": 0,
        "overrides": {
          "leftTitle": "포장단위 목록",
          "rightTitle": "상세 정보",
          "splitRatio": 40,
          "leftTableName": "pkg_unit",
          "rightTableName": "pkg_unit",
          "tabs": [
            {"id": "basic", "label": "기본정보"},
            {"id": "items", "label": "매칭품목"}
          ]
        }
      }
    ]
  }'::jsonb
);
  • V2 컴포넌트 목록: v2-split-panel-layout, v2-table-list, v2-table-search-widget, v2-repeater, v2-button-primary, v2-tabs-widget 등
  • 상세 컴포넌트 가이드: .cursor/rules/component-development-guide.mdc 참조

Step 3: menu_info에 메뉴 등록

-- 먼저 부모 메뉴 objid 조회
-- SELECT objid, menu_name_kor FROM menu_info WHERE company_code = '{회사코드}' AND menu_name_kor LIKE '%물류%';

INSERT INTO menu_info (objid, menu_type, parent_obj_id, menu_name_kor, seq, menu_url, screen_code, company_code, status)
VALUES (
  (SELECT COALESCE(MAX(objid), 0) + 1 FROM menu_info),
  2,                          -- 2 = 메뉴 항목
  {부모_objid},               -- 상위 메뉴의 objid
  '포장/적재정보',
  10,                         -- 정렬 순서
  '/screen/COMPANY_7_PKG',   -- /screen/{screen_code} 형식 (절대!)
  'COMPANY_7_PKG',           -- screen_definitions.screen_code와 일치
  'COMPANY_7',
  'Y'
);

핵심: menu_url은 반드시 /screen/{screen_code} 형식이어야 한다! 프론트엔드가 이 URL을 받아 screen_definitions에서 screen_id를 찾고, screen_layouts_v2에서 레이아웃을 로드한다.

2. 관리자 메뉴 등록 (코드 구현 후 필수!)

관리자 기능을 코드로 만들었으면 반드시 menu_info에 등록해야 한다.

-- 예시: 결재 템플릿 관리 메뉴 등록
INSERT INTO menu_info (objid, menu_type, parent_obj_id, menu_name_kor, seq, menu_url, company_code, status)
VALUES (
  (SELECT COALESCE(MAX(objid), 0) + 1 FROM menu_info),
  2, {부모_objid}, '결재 템플릿', 40, '/admin/approvalTemplate', '대상회사코드', 'Y'
);
  • 기존 메뉴 구조를 먼저 조회해서 parent_obj_id, seq 등을 맞춰라
  • company_code 별로 등록이 필요할 수 있다
  • menu_auth_group 권한 매핑도 필요하면 추가

3. 하드코딩 금지 / 범용성 필수

  • 특정 회사에만 동작하는 코드 금지
  • 특정 사용자 ID에 의존하는 로직 금지
  • 매직 넘버 사용 금지 (상수 또는 설정 파일로 관리)
  • 하드코딩 색상 금지 (CSS 변수 사용: bg-primary, text-destructive 등)
  • 하드코딩 URL 금지 (환경 변수 또는 API 클라이언트 사용)

4. 테스트 환경 정보

  • 테스트 계정: userId=wace, password=qlalfqjsgh11
  • 역할: SUPER_ADMIN (company_code = "*")
  • 개발 프론트엔드: http://localhost:9771
  • 개발 백엔드 API: http://localhost:8080
  • 개발 DB: postgresql://postgres:ph0909!!@39.117.244.52:11132/plm

5. 기능 구현 완성 체크리스트

기능 하나를 "완성"이라고 말하려면 아래를 전부 충족해야 한다:

공통

  • DB: 마이그레이션 작성 + 실행 완료
  • DB: company_code 컬럼 + 인덱스 존재
  • BE: API 엔드포인트 구현 + 라우트 등록 (app.ts에 import + use 추가!)
  • BE: company_code 필터링 적용
  • 빌드 통과: 백엔드 tsc + 프론트엔드 tsc

관리자 메뉴인 경우

  • FE: frontend/app/(main)/admin/{기능}/page.tsx 작성
  • FE: API 클라이언트 함수 작성 (lib/api/)
  • DB: menu_info INSERT (menu_url = /admin/{기능})

사용자 메뉴인 경우 (코드 작성 금지!)

  • DB: screen_definitions INSERT (screen_code, table_name, company_code)
  • DB: screen_layouts_v2 INSERT (V2 레이아웃 JSON)
  • DB: menu_info INSERT (menu_url = /screen/{screen_code})
  • BE: 필요한 경우 전용 API 작성 (범용 table-management API로 커버 안 되는 경우만)
  • FE: .tsx 페이지 파일 만들지 않음 (이미 /screens/[screenId]/page.tsx가 렌더링)

6. 절대 하지 말 것

  1. 페이지 파일만 만들고 메뉴 등록 안 하기 (미완성!)
  2. fetch() 직접 사용 (lib/api/ 클라이언트 필수)
  3. company_code 필터링 빠뜨리기
  4. 하드코딩 색상/URL/사용자ID 사용
  5. Card 안에 Card 중첩 (중첩 박스 금지)
  6. 백엔드 재실행하기 (nodemon이 자동 재시작)
  7. 사용자 메뉴를 React 하드코딩(.tsx)으로 만들기 (절대 금지!!!)
    • frontend/app/(main)/production/, frontend/app/(main)/warehouse/ 등에 page.tsx 파일을 만들어서 직접 UI를 코딩하는 것은 절대 금지
    • 사용자 메뉴는 반드시 screen_definitions + screen_layouts_v2 + menu_info DB 등록 방식으로 구현
    • 이미 /screen/[screenCode]/screens/[screenId] 렌더링 시스템이 존재함
    • 백엔드 API(controller/routes)와 프론트엔드 API 클라이언트(lib/api/)는 필요하면 코드로 작성 가능
    • 하지만 프론트엔드 화면 UI 자체는 DB의 V2 레이아웃 JSON으로만 구성