From bitda-plan-master
This skill registers BITDA ERP UI screens and components to Notion databases. Use this skill AFTER github-deployer when the deployed code has been reviewed and confirmed. Triggers on requests like "노션에 등록해줘", "Notion DB 업데이트해줘", "화면 DB에 올려줘", "컴포넌트 등록해줘". This skill requires the github-deployer to be completed first.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bitda-plan-master:notion-uploaderThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill handles the Notion registration phase for BITDA ERP UI:
This skill handles the Notion registration phase for BITDA ERP UI:
/notion-validator 스킬로 등록 데이터 품질 검증 (MANDATORY).claude/shared-references/notion-db-uploader.py for DB 행 등록 (화면/컴포넌트)notion-fetch, notion-search)와 속성 업데이트(notion-update-page update_properties)용| 작업 | 도구 | 이유 |
|---|---|---|
| 화면/컴포넌트 DB 행 등록 | python .claude/shared-references/notion-db-uploader.py | 빠르고 안정적, 토큰 0 |
| 마스터 코드 조회 | REST API lookup 명령 또는 MCP notion-search | 자동 해석 |
| 속성 업데이트 | MCP notion-update-page update_properties | 속성 전용 |
| 페이지 조회 | MCP notion-fetch, notion-search | 읽기 전용 |
| 테스트 데이터 삭제 | REST API archive 명령 | 빠른 정리 |
../../shared-references/convention-template.md: BITDA ERP screen code conventions (shared)../../shared-references/notion-db-uploader.py: REST API DB 행 등록 스크립트references/notion-db-config.md: Notion database IDs and schemasreferences/agent-integration-guide.md: Specialized agent usage for documentation quality기획문서 확인:
.claude/shared-references/notion-manifest.md에서 해당 기획문서의 Page ID 확인 (0 토큰)notion-fetch퍼블리싱 코드 분석:
테이블 API와 결합된 요소를 별도 등록하면 백엔드가 파편화된 문서를 참조하게 됨.
| 질문 | Yes → 분리 등록 | No → 병합 |
|---|---|---|
| 자체 CRUD 엔드포인트가 필요한가? | Sheet, Dialog | FilterBar, Toolbar |
| 독립적으로 데이터를 조회/저장하는가? | 별도 API 호출 위젯 | 테이블 쿼리 파라미터 변경 UI |
| 다른 화면에서도 동일 API로 재사용되는가? | 공통 모달 | 특정 테이블 전용 필터 |
| 유형 | 예시 | 병합 위치 |
|---|---|---|
| 필터바/검색바 | *FilterBar, *SearchBar | 부모 Table → 필터 파라미터 |
| 정렬/페이지네이션 | SortableHeader, *Pagination | 부모 Table → 정렬/페이징 |
| 테이블 툴바 | TableToolbar, BulkInputToolbar | 부모 Table → 대량 작업 |
| 인라인 액션 | 행 내 버튼, 토글 | 부모 Table → 행 액션 |
| 유형 | 예시 | 이유 |
|---|---|---|
| Sheet (생성/수정 폼) | UserSheet, OrderSheet | 독립적인 Create/Update API |
| Dialog (확인/삭제) | DeleteDialog, ConfirmDialog | 독립적인 Delete/Action API |
| 독립 모달 폼 | ImportExcelDialog | 독립적인 업로드 API |
BAD (파편화):
1. InventoryTable → 목록 조회 로직
2. InventoryFilterBar → 필터 로직 ← ❌ 별도 등록
3. InventoryPagination → 페이지네이션 ← ❌ 별도 등록
GOOD (병합):
1. InventoryTable → 목록 조회 + 필터 + 정렬 + 페이지네이션 통합
2. InventorySheet → CRUD 로직
배경: form-page.tsx, detail-page.tsx 등 route page가 화면 DB에 등록되었으나 대응하는 컴포넌트가 생성되지 않는 누락 사고가 발생함. 원인:
components/디렉토리에 Sheet 파일이 없는 자기완결형 route page를 에이전트가 컴포넌트로 인식하지 못함.
필수 검증: 화면 DB에 등록한 모든 route page에 대해 컴포넌트 1:1 매칭 확인.
| route 파일 패턴 | 화면유형 | 컴포넌트 매핑 방법 |
|---|---|---|
page.tsx | S (Screen) | components/*Table.tsx → 컴포넌트 등록 |
form-page.tsx 또는 form/page.tsx | F (Form) | 아래 판단 로직 적용 |
detail-page.tsx 또는 detail/page.tsx | F (Form) | 아래 판단 로직 적용 |
Form/Detail 컴포넌트 매핑 판단:
form-page.tsx 또는 form/page.tsx 발견
│
├─ components/ 에 *Sheet.tsx 존재?
│ ├─ YES → 해당 Sheet를 컴포넌트로 등록 (기존 패턴)
│ │ 예: SalesOrderSheet.tsx → form-page.tsx 화면에 연결
│ │
│ └─ NO → route page 자체를 컴포넌트로 등록 ⚠️
│ 명명: [Module]FormPage (예: MiscIncomingFormPage)
│ 비즈니스 로직: route 파일 내부 코드에서 추출
│
detail-page.tsx 또는 detail/page.tsx 발견
│
├─ components/ 에 *DetailSheet.tsx 존재?
│ ├─ YES → 해당 DetailSheet를 컴포넌트로 등록
│ │
│ └─ NO → route page 자체를 컴포넌트로 등록 ⚠️
│ 명명: [Module]DetailPage (예: MiscIncomingDetailPage)
최종 검증 (Phase 5 완료 직전):
모든 화면에 최소 1개 이상의 컴포넌트가 연결되어 있는가?
컴포넌트가 0개인 화면이 있으면 누락된 것이므로 추가 생성한 후 Phase 6으로 진행.
목적: 백엔드 개발자가 기획문서 없이 API를 개발할 수 있는 수준의 상세 명세
ENFORCEMENT: 데이터 필드 테이블의 "항목" 컬럼에는 반드시 한글 서술명만 사용. 변수명은 백엔드가 자체 정의하므로 FE 변수명을 기재하면 혼란만 초래함.
BAD - FE 변수명 사용:
| 항목 | 타입 | 필수 | 설명 |
|------|------|------|------|
| orderNumber | string | Y | 주문번호 |
| supplierId | string(UUID) | Y | 입고처 ID |
| totalAmount | number | Y | 합계 금액 |
| status | enum | Y | 진행상태 |
GOOD - 한글 서술명 사용:
| 항목 | 타입 | 필수 | 설명 |
|------|------|------|------|
| 발주번호 | string | Y | 자동 채번 (PO-yyyyMMdd-NNN) |
| 입고처 | string(UUID) | Y | 거래처 FK |
| 합계 금액 | number | Y | 품목별 금액 합산, 자동 계산 |
| 진행상태 | enum | Y | 작성중/발주완료/입고완료/취소 |
이 규칙은 필터 파라미터, 정렬 필드, 페이지네이션 파라미터에도 동일하게 적용됨.
BAD - 필터에 변수명:
| 파라미터 | 타입 | 설명 |
|---------|------|------|
| warehouseId | string[] | 창고 필터 |
| keyword | string | 검색어 |
GOOD - 필터에 한글명:
| 필터 항목 | 타입 | 설명 |
|----------|------|------|
| 창고 | string[] | 다중 선택 |
| 검색어 | string | 품목명/품목코드 부분 일치 |
## InventoryTable (재고 목록)
### 데이터 필드
| 항목 | 타입 | 필수 | 설명 |
|------|------|------|------|
| 품목 ID | string(UUID) | Y | 자동생성 |
| 품목명 | string | Y | 제품/원재료명 |
| 창고 | string | Y | 창고 FK |
| 현재고 | number | Y | 실시간 수량 |
| 단위 | string | Y | kg, L, EA 등 |
| 최종입고일 | datetime | N | 마지막 입고 일시 |
### 목록 조회
- GET /api/v1/inventory
#### 필터
| 필터 항목 | 타입 | 설명 |
|----------|------|------|
| 창고 | string[] | 다중 선택 |
| 품목 분류 | string | 분류 코드 |
| 검색어 | string | 품목명/품목코드 부분 일치 |
| 재고 상태 | enum | 전체/재고있음/재고없음 |
#### 정렬
| 정렬 기준 | 기본값 | 설명 |
|----------|--------|------|
| 최종입고일 | desc | 기본 정렬 |
| 품목명 | - | 가나다순 |
#### 페이지네이션
- 기본 20건, 최대 100건
- 응답에 전체 건수, 전체 페이지 수 포함
### 비즈니스 규칙
- 재고 0 이하: 빨간색 강조
- 권한: 전체 사용자 조회 가능
화면유형 코드 (DB ID: 2d3471f8-dcff-8051-ac76-000b25732bf2):
| 코드 | 원어 | 한글 |
|---|---|---|
| D | Dashboard | 대시보드 |
| S | Screen | 일반화면 |
| F | Form | 등록/수정 |
| P | Popup | 팝업/모달 |
| R | Report | 리포트 |
| M | Matrix | 매트릭스 |
마스터 기능코드 (DB ID: 2d3471f8-dcff-803d-8b2c-000b5b9855af):
CRITICAL: 중복 기능코드 선택 규칙
일부 기능코드(DCL, PMA 등)는 여러 모듈에 동일한 코드명으로 존재함.
notion-search로 기능코드를 검색하면 2건 이상 나올 수 있으므로, 반드시 모듈 코드(모듈 코드relation)를 확인하여 올바른 것을 선택해야 함.앱별 모듈 코드 매핑:
대상 앱 앱 폴더 모듈 코드 모듈 Page ID 주류 ERP apps/liquorTAX d71c7ac7-e101-49e9-aaad-a6ae2aea0b60세무서 연동 apps/tax-officeOFC 2e3471f8-dcff-8039-836f-fa67a897ae8d중복 기능코드 올바른 선택 테이블:
기능코드 주류앱(TAX) 사용 시 세무서앱(OFC) 사용 시 DCL 2d3471f8-dcff-8035-8fe4-c9b102554fd12e3471f8-dcff-80d2-9e5c-c51e3a37768bPMA 2d3471f8-dcff-80d2-8d8d-c1304047a73e2e3471f8-dcff-802f-8487-c69ee879f7a3검증 방법: 기능코드 페이지를
notion-fetch하여모듈 코드relation이 대상 앱의 모듈과 일치하는지 확인.
화면명에 화면코드를 절대 포함하지 않는다. 화면코드는 DB의
화면 코드 IDformula 속성에서 자동 생성되므로 화면명에 중복 기재하면 안 됨.
BAD - 화면코드 포함:
BITDA-CM-HAC-LOG-S001 검사일지 (목록)
BITDA-CM-HAC-LOG-F001 검사일지 등록/수정 (폼)
BITDA-BR-DOC-EVD-P001 증빙 미리보기 Dialog
GOOD - 한글 화면명만 사용:
검사일지 (목록)
검사일지 등록/수정 (폼)
증빙 미리보기 Dialog
네이밍 패턴:
| 화면유형 | 패턴 | 예시 |
|---|---|---|
| S (Screen) | [기능명] 또는 [기능명] (목록) | 증빙자료 관리, 검사품목 (목록) |
| F (Form) | [기능명] 등록/수정 Sheet 또는 [기능명] 등록/수정 (폼) | 보건증 등록/수정 Sheet |
| P (Popup) | [기능/동작명] Dialog | 삭제 확인 Dialog, 구매서 선택 Dialog |
| R (Report) | [리포트명] | 월간 보고서 |
| D (Dashboard) | [대시보드명] | 관리자 대시보드 |
CRITICAL:
source 링크필수 - 모든 화면에 GitHub source URL을 반드시 설정해야 함. 빈 값으로 등록하면 notion-validator에서 Critical 오류로 검출됨. 병렬 에이전트 작업 시 공유 지침에서 이 속성이 누락되면 전체 화면이 빈 URL로 등록되는 사고가 발생함.
source 링크 URL 구성 규칙:
| 화면유형 | URL 패턴 |
|---|---|
| S (Screen/PAGE) | [base]/[module]/page.tsx |
| F (Form) | [base]/[module]/form-page.tsx 또는 [base]/[module]/components/[Name]Sheet.tsx |
| P (Popup) | [base]/[module]/components/[Name]Dialog.tsx |
https://github.com/invigoworks/pre-publishing/blob/main/apps/[app]/src/[domain]/[feature]Glob으로 확인 권장)REST API로 등록 (권장):
# 단일 화면 등록
python .claude/shared-references/notion-db-uploader.py screen \
--title "검사일지 (목록)" \
--source "https://github.com/invigoworks/pre-publishing/blob/main/apps/liquor/src/haccp/inspection-log/page.tsx" \
--status "기획 완료" \
--screen-type "S" \
--feature-code "LOG" \
--plan-doc "기획문서-page-id"
# 일괄 등록 (JSON 파일)
python .claude/shared-references/notion-db-uploader.py batch --file /tmp/entries.json
JSON 일괄 등록 형식:
{
"screens": [
{
"title": "검사일지 (목록)",
"source": "https://github.com/invigoworks/pre-publishing/blob/main/...",
"status": "기획 완료",
"screen_type": "S",
"feature_code": "LOG",
"plan_doc": "기획문서-page-id"
}
],
"components": [
{
"title": "InspectionTable",
"logic": "## 목록 조회\n- GET /api/v1/inspections\n...",
"screen": "auto:0"
}
]
}
"screen": "auto:0"→ 같은 JSON의 screens[0] page_id를 자동 참조
MCP 대체 사용법 (REST API 실패 시 fallback):
notion-create-pages({
parent: { data_source_id: "2d3471f8-dcff-8067-b573-000b0e2b1d04" },
pages: [{
properties: {
"화면명": "[화면명]",
"source 링크": "https://github.com/.../[path]",
"상태": "기획 완료",
"화면유형 코드": "[\"[화면유형URL]\"]",
"기능코드": "[\"[기능코드URL]\"]",
"연관된 기획문서": "[\"[기획문서URL]\"]"
}
}]
})
등록 직후 확인: 모든 화면의
source 링크가 비어있지 않은지 검증. 1건이라도 빈 값이면 즉시 수정.
기획문서 DB의
퍼블리싱 결과 확인속성에 prepub URL을 반드시 설정해야 함. 이 속성이 화면 DB의미리보기 링크롤업으로 연결되므로, 빈 값이면 미리보기 링크도 빈 값이 됨.
Prepub URL 구성: https://prepub.invigoworks.co.kr/[route-path]
notion-update-page({
page_id: "[기획문서 Page ID]",
command: "update_properties",
properties: {
"퍼블리싱 결과 확인": "https://prepub.invigoworks.co.kr/[route-path]"
}
})
| 예시 | route-path | Prepub URL |
|---|---|---|
| 기초 자료 설정 | liquor-tax/basic-data | https://prepub.invigoworks.co.kr/liquor-tax/basic-data |
| 회사 관리 | admin/company | https://prepub.invigoworks.co.kr/admin/company |
Phase 2.5 완료 후 등록. FilterBar/Toolbar/Pagination은 부모 Table에 통합.
REST API로 등록 (권장):
# 단일 컴포넌트 등록
python .claude/shared-references/notion-db-uploader.py component \
--title "InspectionTable" \
--logic-file /tmp/inspection-table-logic.md \
--screen "화면-page-id"
# 비즈니스 로직을 인라인으로 전달
python .claude/shared-references/notion-db-uploader.py component \
--title "InspectionSheet" \
--logic "## 등록/수정\n- POST /api/v1/inspections\n..." \
--screen "화면-page-id"
비즈니스 로직이 긴 경우
--logic-file로 파일 경로 전달 권장 (2000자 자동 분할)
MCP 대체 사용법 (REST API 실패 시 fallback):
notion-create-pages({
parent: { data_source_id: "2d3471f8-dcff-8076-a4a3-000b502a3811" },
pages: [{
properties: {
"요소명(ID)": "[컴포넌트명]",
"비즈니스 로직": "[상세 비즈니스 로직]",
"화면 DB 연동": "[\"[화면URL]\"]"
}
}]
})
Phase 5 완료 후 반드시 /notion-validator 스킬 실행. 검수 결과에 따라:
| 결과 | 처리 |
|---|---|
| ✅ 통과 | 등록 완료 확정 |
| ⚠️ 경고 | 사용자에게 수정 권고 |
| ❌ 오류 | 즉시 수정 후 재검수 |
2d3471f8-dcff-8067-b573-000b0e2b1d04| 속성 | 타입 | 설명 |
|---|---|---|
| 화면명 | title | 화면 이름 |
| source 링크 | url | GitHub 소스 링크 |
| 기능코드 | relation | 마스터 기능코드 연결 |
| 화면유형 코드 | relation | 화면유형 코드 연결 |
| 연관된 기획문서 | relation | 기획문서 DB 연결 |
| 상태 | status | 시작 전/기획 중/개발 중/기획 완료/개발 완료 |
2d3471f8-dcff-8076-a4a3-000b502a3811| 속성 | 타입 | 설명 |
|---|---|---|
| 요소명(ID) | title | 컴포넌트 이름 |
| 비즈니스 로직 | text | 백엔드 API 개발용 상세 비즈니스 로직 |
| 화면 DB 연동 | relation | 화면 DB 연결 |
⚠️ REST API vs MCP ID 차이: MCP Data Source ID와 REST API Database ID가 다른 경우 있음.
notion-db-uploader.py에 올바른 REST API ID가 하드코딩되어 있으므로 스크립트 사용 시 별도 ID 지정 불필요.
| DB | MCP Data Source ID | REST API Database ID |
|---|---|---|
| 마스터 기능코드 | 2d3471f8-dcff-803d-8b2c-000b5b9855af | 2d3471f8-dcff-80cd-9de7-dac5de60856a |
| 화면유형 코드 | 2d3471f8-dcff-8051-ac76-000b25732bf2 | c7255e5a-4433-4977-95cb-18b1f8d31a39 |
| 기획문서 DB | 2df471f8-dcff-80b2-9a6d-f9972b15aa06 | 동일 (URL) |
Before:
After (MANDATORY):
source 링크가 비어있지 않은지 확인퍼블리싱 결과 확인이 비어있지 않은지 확인/notion-validator 검수 완료## Notion 등록 완료
### 화면 DB
| 화면명 | 화면코드 | 상태 | 연관된 기획문서 |
|--------|---------|------|----------------|
| [화면명] | BITDA-XX-XX-XX-S001 | 기획 완료 | [기획문서명] |
등록된 화면: [N]개
### 컴포넌트 & 로직 DB
| 요소명 | 연결 화면 | 비즈니스 로직 요약 |
|--------|----------|-------------------|
| [컴포넌트] | [화면명] | [CRUD 요약] |
등록된 컴포넌트: [N]개
### 확인 링크
- 화면 DB: https://www.notion.so/2d3471f8dcff802f945fc5add962fc6f
- 컴포넌트 DB: https://www.notion.so/2d3471f8dcff80d28041f0e98910c922
| 오류 | 해결 |
|---|---|
| Notion 연결 실패 | MCP 재연결 |
| 중복 등록 | 기존 항목 확인 |
| 코드 오류 | BITDA 컨벤션 재확인 |
| Relation 누락 | 마스터 DB에서 코드 검색 |
| 비즈니스 로직 부실 | Phase 3 가이드 재참조 |
npx claudepluginhub invigoworks/invigo-marketplace --plugin bitda-plan-masterProvides Notion API architecture patterns for headless CMS (blog), task tracker, knowledge base, form handler, and data pipeline. Includes TypeScript/JavaScript and Python code examples with schemas.
Interact with Notion workspaces via official API CLI: manage pages, databases, blocks, users, comments, and search. For AI agents or developers automating Notion tasks.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.