Communitygithub.com

pharder56k/quote-generator-skill

室内设计报价 Skill:飞书多维表/Excel → 专业 PDF 报价单。MIT。

quote-generator-skill란 무엇인가요?

이 스킬은 사용자가 입력한 프로젝트 데이터(飞书多维표 또는 Excel)를 전문적인 PDF 견적서로 변환합니다. 견적서는 표지, 총액 표, 세부 내역 페이지 등 여러 페이지로 구성되며, 스위스 디자인 스타일의 4가지 템플릿(Swiss IKB, B&W 등)을 지원합니다. Claude Code, Cursor, Codex 등 AI 어시스턴트가 飞书 CLI, Playwright, Node.js를 활용하여 데이터 읽기, 검증, 로고 처리, 세율 및 관리비 확인, 템플릿 선택, 자동 번역(지역명 → 영어), PDF 렌더링, 飞书 메시지/드라이브 전송까지의 전체 워크플로우를 자동화할 수 있습니다. MIT 라이선스로 제공됩니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add pharder56k/quote-generator-skill

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

전액 설계 견적 시스템

이 Skill은 작업량 데이터를 전문 PDF 견적서로 렌더링하며, 표지, 총액 표, 세부 내역 페이지 등 여러 페이지 출력을 지원합니다.

1. 이 Skill을 사용하는 경우

트리거 조건

다음 시나리오에서는 이 Skill을 사용해야 합니다:

  • 사용자가 /报价 또는 /quote를 입력하는 경우 — PDF 견적서 생성
  • 사용자가 멀티차트 또는 Excel의 견적 데이터를 PDF 견적서로 변환하려는 경우

다음 시나리오에서는 이 Skill을 사용하지 말아야 합니다:

  • 사용자가 멀티차트 데이터를 편집하는 중인 경우 (lark-base Skill 사용)
  • 사용자가 과거 견적을 조회만 하는 경우 (재생성 불필요)

사전 의존성

  • lark-base Skill — 飞书 멀티차트 데이터 읽기
  • lark-im Skill — PDF를 飞书 대화에 전송
  • lark-drive Skill — PDF를 飞书 문서에 업로드
  • xlsx Skill — Excel 파일 파싱 (사용자가 Excel 제공 시)
  • Node.js 런타임 + Playwright (프로젝트 디렉토리에 설치됨)

Step 0: 첫 사용 시 확인

사용자가 Skill을 처음 사용하거나 명령 실행 중 의존성 관련 오류가 발생하는 경우, Agent는 다음 확인 절차를 수행해야 합니다.

1. Node.js 환경 확인

node --version을 실행하고 버전이 >= 18인지 확인합니다. 실패하거나 버전이 낮은 경우:

  • 사용자에게 Node.js (>= 18) 설치를 안내합니다: https://nodejs.org
  • nvm을 사용한 버전 관리를 권장합니다

2. Playwright 브라우저 확인

프로젝트 디렉토리에서 npx playwright install chromium이 완료되었는지 확인합니다. render.js 실행 시 Executable doesn't exist 오류가 발생하는 경우:

  • 프로젝트 디렉토리에서: npx playwright install chromium 실행
  • 렌더링 재시도

3. lark-cli 확인

lark-cli --version을 실행합니다. 실패하는 경우 (command not found):

  • 사용자에게 lark-cli (飞书 명령줄 도구) 설치를 안내합니다
  • 설치 후: lark-cli auth login 실행

4. 飞书 로그인 상태 확인

lark-cli base +table-list --base-token LfjJbLrTHacijesHmIjcDtSpnJf를 실행하여 로그인 상태를 테스트합니다. 인증 오류가 반환되면:

  • 사용자에게 lark-cli auth login 실행을 안내합니다
  • 완료 후 재시도

5. 飞书 템플릿 제공

사용자는 프로젝트 템플릿을 자신의 飞书 공간에 복사해야 합니다:

Excel 데이터 소스 처리

사용자가 Excel 파일을 제공하는 경우, 직접 파싱하여 렌더링하지 않습니다. 안내 절차:

  1. 안내: 먼저 飞书 멀티차트로 가져오는 것을 권장합니다. 필드와 순서가 더 잘 정렬됩니다.
  2. 사용자가 Excel을 飞书로 가져오도록 안내:
    • 飞书 열기 → 새 멀티차트 생성 → 가져오기 → Excel 파일 선택
    • 또는 템플릿 멀티차트를 복사하고 Excel 데이터를 붙여넣기
  3. 사용자가 멀티차트 링크를 제공하면 /报价 절차 계속

2. 작업 흐름

사용자 트리거 → 환경 확인 → 데이터 소스 확인 → 데이터 읽기 → 데이터 검증 → 로고 확인 → 세율 확인 → 템플릿 확인 → PDF 렌더링 → 飞书 전송

Step 1: 데이터 소스 확인

사용자는 다음 중 하나를 제공해야 합니다:

  1. 飞书 멀티차트 링크 — 예: https://xxx.feishu.cn/base/XXX
  2. Excel 파일 — 로컬 파일 경로 또는 대화를 통해 업로드

사용자가 제공하지 않은 경우, 데이터 소스를 선택하도록 요청합니다.

Step 2: 데이터 읽기

飞书 멀티차트 데이터 소스

  1. 사용자가 제공한 링크에서 base-token 추출 (URL에서 /base/ 다음 부분)
  2. 테이블 나열: lark-cli base +table-list --base-token <token>
  3. 프로젝트 정보와 견적 세부 내역 두 테이블의 table_id 찾기
  4. 프로젝트 정보 읽기: lark-cli base +record-list --base-token <token> --table-id <프로젝트정보_table_id> --format json
  5. 먼저 뷰 조회: lark-cli base +view-list --base-token <token> --table-id <견적세부내역_table_id> 기본 그리드 뷰 (예: "전체 프로젝트")의 view_id 가져오기
  6. 견적 세부 내역 읽기 (반드시 --view-id를 사용해야 함, 그렇지 않으면 반환 순서가 사용자가 飞书에서 드래그한 순서와 일치하지 않음): lark-cli base +record-list --base-token <token> --table-id <견적세부내역_table_id> --view-id <뷰ID> --format json --limit 200
  7. 프로젝트 정보에서 추출: 프로젝트 이름, 엔지니어링 번호, 작성 날짜, 작성자, 연락처 이메일, 회사 로고, 세율, 관리비
  8. 견적 세부 내역에서 추출: 영역, 엔지니어링 분류, 프로젝트 이름, 프로젝트 특성, 단위, 수량, 단가, 합계, 비고 (일련 번호는 읽지 않아도 됨, 렌더링 시 자동 생성)

Excel 데이터 소스

xlsx Skill을 사용하여 Excel을 파싱하고 동일한 구조의 데이터를 추출합니다. Excel에는 여러 시트가 있을 수 있으므로 견적 세부 내역이 포함된 시트를 찾아야 합니다 (일반적으로 "일련 번호", "엔지니어링 분류", "단가" 등 열 헤더가 있음).

Step 3: 데이터 검증

PDF를 렌더링하기 전에 Agent는 읽은 데이터를 검증해야 합니다. 건너뛰지 마세요.

검증 체크리스트 (항목별 실행):

3.1 프로젝트 정보 완전성

프로젝트 이름, 엔지니어링 번호, 작성 날짜 세 필드 확인:

  • 하나라도 비어 있음 → 사용자에게 정확히 어떤 필드가 누락되었는지 알리고, 飞书 멀티차트의 '프로젝트 정보' 테이블에서 보완하도록 요청
  • 모두 통과 → 계속

3.2 견적 세부 내역 항목 수

items 배열 확인:

  • 0이거나 존재하지 않음 → "견적 세부 내역에 데이터가 없습니다. 飞书 멀티차트의 '견적 세부 내역' 테이블에 항목을 추가한 후 다시 시도하세요."
  • 데이터 있음 → 계속

3.3 항목별 필드 확인

각 레코드에 대해 필수 필드를 확인하고 (엔지니어링 분류, 프로젝트 이름, 단위, 수량, 단가), 요약 보고:

데이터 검증 결과:
- 총 항목: 104
- 영역 누락: 3 (6, 9, 20번 항목)
- 엔지니어링 분류 누락: 2 (5, 18번 항목)
- 프로젝트 이름 누락: 0
- 단위 누락: 1 (12번 항목)
- 수량 누락: 0
- 단가 누락: 3 (5, 7, 22번 항목)
- 엔지니어링 분류가 표준 목록에 없음: 0

3.4 누락된 필드 처리

  • 누락 항목 ≤ 총 항목의 20%: 사용자에게 구체적으로 어떤 항목에 문제가 있는지 알리고 "이 항목들을 건너뛰고 계속 생성하시겠습니까?" 질문
  • 누락 항목 > 20%: 사용자에게 데이터를 수정한 후 다시 시도하도록 요청, 렌더링 계속하지 않음
  • 사용자가 건너뛰기 확인 → 문제 항목 필터링, 유효한 데이터로 계속

3.7 영역 누락 확인 (영역별 분류 시에만)

사용자가 영역별 분류(Step 5.6에서 "영역별" 선택)를 선택한 경우, 각 레코드의 영역 필드를 추가로 확인:

영역 누락: X (X번 항목)
  • 누락 항목 ≤ 총 항목의 20%: 사용자에게 구체적으로 어떤 항목에 영역이 누락되었는지 알리고 "이 항목들을 '기타'로 분류하여 계속 생성하시겠습니까?" 질문
  • 누락 항목 > 20%: 사용자에게 영역을 보완한 후 다시 시도하도록 요청
  • 사용자 확인 → 영역이 누락된 항목은 "기타" 그룹으로 분류 (Step 3.4의 건너뛰기 논리와 상호 배타적, 사용자는 둘 중 하나 선택: 건너뛰기 또는 기타로 분류)

3.5 합계 자동 수정

각 레코드에 대해 합계가 수량 × 단가와 같은지 확인:

  • 차이 < 1원 → 처리하지 않음
  • 차이 ≥ 1원 또는 비어 있음 → 자동 계산 합계 = 수량 × 단가, 값을 렌더링 데이터에 기록
  • 수정 항목이 10% 초과 → 사용자에게 "X개 항목의 합계 데이터를 자동 수정했습니다" 알리고 멀티차트 수식 확인 권장

3.6 엔지니어링 분류 표준 목록

다음은 13가지 표준 분류입니다:

조치 공사, 철거 공사, 조적 공사, 콘크리트 및 철근 콘크리트 공사,
금속 구조 공사, 방수 공사, 단열 공사, 바닥 마감 공사,
벽/기둥면 마감 및 칸막이 공사, 천장 공사, 페인트/도장 공사,
기타 마감 공사, 설비 공사

목록에 없는 분류도 렌더링할 수 있지만, 사용자에게 "분류 'XXX'가 표준 목록에 없습니다."라고 알립니다.

Step 4: 로고 처리

반드시 실행해야 합니다. 건너뛸 수 없습니다. 데이터 소스가 멀티차트이든 Excel이든 관계없이 로고를 확인하고 처리해야 합니다.

  1. 멀티차트에서 읽기: 프로젝트 정보 테이블의 회사 로고 첨부 파일 필드 확인
    • 첨부 파일이 있는 경우 media API를 사용하여 다운로드 (drive +download는 멀티차트 첨부 파일을 지원하지 않음):
      lark-cli api GET /open-apis/drive/v1/medias/{file_token}/download --output ./logo.png
      
    • 이미지를 base64 data URI로 변환하여 렌더링 데이터의 logo_url 필드에 전달
  2. Excel에서 읽기: Excel에 로고 이미지가 있는지 확인 (일반적으로 시트에 포함되거나 첨부 파일로 제공됨)
    • 있는 경우 추출하여 data URI로 변환
  3. 로고가 없는 경우 (반드시 사용자에게 질문):
    • 데이터 소스에서 회사 로고 이미지를 찾을 수 없는 경우 반드시 사용자에게 질문:
      • "데이터 소스에서 회사 로고를 찾을 수 없습니다. 어떻게 처리하시겠습니까?"
      • 옵션 A: 로고 이미지 업로드
      • 옵션 B: 로고 이미지 URL 제공
      • 옵션 C: 로고 사용 안 함 (PDF에 기본 "R M" 텍스트 표시)
    • 이 단계를 기본적으로 건너뛰지 마십시오. 사용자가 "바로 생성"이라고 말하더라도 로고 처리 방식을 확인해야 합니다.

Step 5: 세율 및 관리비 확인

우선적으로 멀티차트 프로젝트 정보의 세율, 관리비 필드 값을 사용합니다. 멀티차트에 해당 필드가 없으면 사용자에게 질문합니다.

요율 규칙 (세율 및 관리비 공통):

  • 값 > 1 → 백분율 정수로 간주, 자동 ÷100 (예: 3 → 3%, 10 → 10%)
  • 값 ≤ 1 → 소수로 직접 사용 (예: 0.03 → 3%, 0.1 → 10%)
  • 빈 값: 세율 기본 3%, 관리비 기본 0 (부과 안 함)

계산 순서:

합계 = Σ 각 항목 합계
관리비 = 합계 × 관리비율
부가세 = (합계 + 관리비) × 세율
총액 = 합계 + 관리비 + 부가세

관리비 > 0인 경우 총액 표에 '관리비' 행 표시; 관리비 = 0인 경우 표시하지 않음 (이전 데이터와 호환).

Step 5.5: 템플릿 스타일 확인

반드시 질문해야 합니다. 건너뛸 수 없습니다. 이전에 특정 템플릿을 사용했더라도 매번 확인해야 합니다.

사용자에게 템플릿 선택 요청:

견적서 템플릿 스타일을 선택해 주세요:
1. Swiss IKB (기본) — 파란색 배경 전체 표지 + 이중 언어 분류 제목
2. Swiss IKB Zebra — 위와 동일 + 내용 세부 행 얼룩말 무늬 (흰색/연한 파란색 교대)
3. B&W — 흰색 배경 표지 + 연한 회색 강조, 흑백 인쇄에 적합
4. B&W Zebra — 위와 동일 + 내용 세부 행 얼룩말 무늬 (흰색/연한 회색 교대)

사용자 응답에 명확한 템플릿 이름 또는 번호가 포함된 경우 해당 템플릿을 직접 사용합니다:

  • swiss-ikb — Swiss IKB (기본)
  • swiss-ikb-zebra — Swiss IKB Zebra
  • bw — B&W 흑백 인쇄 버전
  • bw-zebra — B&W Zebra 흑백 인쇄 얼룩말 무늬 버전

개발 중 (현재 외부 제공 안 함): Editorial / Editorial B&W / Card / Card B&W 네 가지 템플릿 코드는 이미 존재하지만, 사용자가 향후 수정/완성할 때까지 활성화되지 않습니다. 사용자가 이러한 템플릿을 요청할 경우 node scripts/render.js --template editorial 등 명령을 실행할 수 있지만, 위의 4가지 활성화된 템플릿을 우선 권장합니다.

Step 5.6: 분류 방식 확인

반드시 질문해야 합니다. 건너뛸 수 없습니다. 렌더링할 때마다 확인해야 하며, 이전 옵션을 기본값으로 사용하지 마세요.

사용자에게 분류 방식 선택 요청:

견적서 분류 방식을 선택해 주세요:
1. 영역별 (현관, 거실, 주방…) — 총액 표를 영역별로 요약, 세부 표에 일련 번호 뒤에 엔지니어링 분류 열 추가
2. 엔지니어링 분류별 (조치 공사, 철거 공사…) — 전통적인 방식, 세부 표에 엔지니어링 분류 열 없음

사용자가 명확한 번호 또는 이름으로 응답하면 해당 모드를 사용합니다:

  • area — 영역별 분류, 렌더링 명령에 --group-by area 추가
  • category — 엔지니어링 분류별 (기본), 전달하지 않거나 --group-by category 추가

참고: "영역별"을 선택하는 경우 견적 세부 내역 테이블의 영역 필드가 채워져 있는지 확인해야 합니다 (Step 3.7에서 확인). 데이터에 영역이 아직 입력되지 않은 경우 "엔지니어링 분류별"을 우선 사용하는 것이 좋습니다.

Step 5.7: 영역명 영어 번역 (영역별 분류 시에만)

영역명은 프로젝트마다 다릅니다. 렌더링할 때마다 동적으로 번역해야 하며, 하드코딩된 매핑을 사용해서는 안 됩니다.

  1. 견적 세부 내역에서 이번에 나타난 모든 영역명 수집 (중복 제거)
  2. Agent가 영역명을 하나씩 영어로 번역 (디자인 업계 관용 번역 사용, 예: 玄关→Foyer, 客厅→Living Room, 阳光房→Sunroom)
  3. 번역 결과를 region_names 객체로 렌더링 데이터 JSON에 기록:
{
  "region_names": {
    "玄关": "Foyer",
    "阳光房": "Sunroom"
  }
}
  1. 렌더링 시 render.js는 region_names의 번역을 우선 사용 (제공되지 않은 영역명은 내장된 일반 영역 매핑으로 폴백, 그 후에도 없으면 AREA 표시)
  2. 렌더링 완료 후 보고서에 이번 영역 번역 대조표를 나열합니다. 사용자가 수정할 수 있으며, 다음 견적 시 다시 번역합니다.

Step 6: PDF 렌더링

프로젝트 디렉토리에서 실행:

node scripts/render.js --input <data.json> --template <템플릿명> --vat-rate <세율> --group-by <area|category> --output ./output/<프로젝트이름>_<엔지니어링번호>.pdf
  • --group-by area — 영역별 분류 (큰 분류=영역, 세부는 엔지니어링 분류 열 포함)
  • --group-by category 또는 전달 안 함 — 엔지니어링 분류별 (기존 동작)

렌더링 데이터 JSON 형식:

{
  "프로젝트 이름": "xxx",
  "엔지니어링 번호": "xxx",
  "작성 날짜": "xxx",
  "작성자": "xxx",
  "연락처 이메일": "xxx",
  "logo_url": "data:image/png;base64,...",
  "세율": 0.08,
  "관리비": 0.1,
  "items": [
    {
      "영역": "玄关",
      "엔지니어링 분류": "조치 공사",
      "프로젝트 이름": "비계",
      "프로젝트 특성": "실내 비계",
      "단위": "항",
      "수량": 1,
      "단가": 3200,
      "합계": 3200
    }
  ]
}

일련 번호 자동 생성 규칙: 일련 번호 필드는 데이터에 제공할 필요가 없습니다 (飞书 멀티차트에 해당 열을 만들지 않아도 됨). 렌더링 시 그룹 일련 번호.그룹 내 일련 번호 형식으로 자동 생성: 영역별 분류 시 01 영역 → 1.1, 1.2, … , 02 영역 → 2.1, 2.2, …; 엔지니어링 분류별 시 조치 공사 → 1.x, 철거 공사 → 2.x … 설비 공사 → 13.x. 그룹 내 순서 = 飞书 레코드 순서 (멀티차트에서 레코드를 드래그하여 정렬 가능).

세율 및 관리비 (Step 5 참조):

  • 세율 / 관리비 값 > 1은 백분율 정수로 간주 (3 → 3%), ≤ 1은 소수로 간주 (0.08 → 8%)
  • 관리비 = 합계 × 관리비율; 부가세 = (합계 + 관리비) × 세율; 총액 = 합계 + 관리비 + 부가세
  • 관리비가 제공되지 않거나 0인 경우 → 부과 안 함, 총액 표에 관리비 행 표시 안 함
  • --vat-rate 매개변수가 제공되지 않은 경우 render.js는 데이터의 세율 필드를 우선 읽음

Step 7: 저장 및 전송

PDF 렌더링 완료 후 반드시 사용자에게 저장 방식을 질문해야 합니다:

PDF 생성 완료: <프로젝트이름>_<엔지니어링번호>_<템플릿명>.pdf (XX개 항목, ¥XXX 세금 포함)

어떻게 저장하시겠습니까?
1. 현재 채팅창으로 전송
2. 飞书 클라우드 문서에 저장하고 문서 링크 푸시
3. 둘 다

사용자 선택에 따라 실행:

옵션 1 — 채팅창으로 전송

lark-cli im +messages-send --type media --file <PDF경로>

옵션 2 — 飞书 클라우드 문서에 저장

lark-cli drive +upload --file <PDF경로> --title "<프로젝트이름>_<엔지니어링번호>"

업로드 후 파일 링크를 가져와 사용자에게 응답:

飞书 클라우드 문서에 저장되었습니다: <프로젝트이름>_<엔지니어링번호>_<템플릿명>.pdf
문서 링크: https://xxx.feishu.cn/drive/xxx

옵션 3 — 둘 다

먼저 옵션 2 (업로드)를 실행한 후 옵션 1 (파일 + 링크 전송)을 실행합니다.

임시 파일 정리

전송/저장이 완료되면 렌더링 과정에서 생성된 임시 JSON 파일과 로고 다운로드 파일(있는 경우)을 삭제합니다.

3. 프로젝트 구조

quote-generator-skill/
├── package.json                # 프로젝트 설정
├── setup.sh                     # 원클릭 설치 스크립트
├── SKILL.md                     # Skill 정의
├── scripts/
│   ├── render.js               # HTML → PDF 렌더링 엔진
│   ├── demo.js                 # 즉시 사용 가능한 데모
│   └── generate-large-test.js  # 대용량 테스트 데이터 생성기
├── references/
│   ├── templates/
│   │   ├── content.html        # Handlebars PDF 템플릿 (내용 페이지)
│   │   ├── cover-screen.html   # Swiss IKB 표지 개별 템플릿
│   │   ├── cover-bw.html       # B&W 흑백 인쇄 표지 템플릿
│   │   ├── swiss-ikb.json      # Swiss IKB 설정
│   │   ├── swiss-ikb-zebra.json # Swiss IKB Zebra 설정
│   │   ├── bw.json             # B&W 흑백 인쇄 설정
│   │   └── bw-zebra.json       # B&W Zebra 설정
│   ├── helpers.js              # Handlebars 사용자 정의 helper
│   └── bitable-config.json     # 멀티차트 필드 설정
├── docs/plans/                 # 설계 문서
├── output/                     # 생성된 PDF 출력 디렉토리
└── README.md

4. 템플릿 설명

PDF 템플릿에는 세 가지 유형의 페이지가 포함됩니다:

  1. 표지 — 프로젝트 이름, 번호, 날짜, 작성자, 로고 (오른쪽 위)
  2. 총액 표 — 엔지니어링 분류별 금액 합계 + 합계/부가세/총액
  3. 세부 페이지 — 페이지당 약 8개 행 데이터, 분류 제목, 세부 행, 소계 행, 페이지 번호 포함

5. 참고 사항

  • 멀티차트의 합계는 수식 필드 (=수량×단가)이며, 읽을 때 이미 계산되어 있습니다.
  • 일련 번호는 飞书에서 유지 관리할 필요가 없습니다: 렌더링 시 자동 생성 (그룹 일련 번호.그룹 내 일련 번호, 그룹 내 레코드 순서). 세부 순서를 조정하려면 飞书 멀티차트에서 레코드를 드래그하여 정렬하면 됩니다.
  • 엔지니어링 분류는 단일 선택 필드이며, 13개 옵션이 13가지 엔지니어링 분류에 해당합니다.
  • 영역은 자유 텍스트 필드입니다 (飞书에서 단일 선택 필드로 변경 권장: 현관, 거실, 식당, 주방, 침실, 작은방, 욕실, 발코니, 서재, 드레스룸, 복도, 전집 등). 영역별 분류 시에만 사용되며 비워 둘 수 있습니다.
  • 영역 모드의 그룹 제목은 중영문 대조로 표시됩니다 (예: Living Room 거실). 영역명은 프로젝트마다 다르므로 Agent는 렌더링할 때마다 Step 5.7에 따라 동적으로 번역하여 region_names에 기록합니다. 내장된 일반 영역 매핑은 폴백으로만 사용되며, 일치하지 않으면 AREA가 표시됩니다.
  • 단위는 단일 선택 필드이며 사용자 정의 확장을 지원합니다.
  • 로고는 이미지 (권장)와 텍스트 두 가지 형식을 지원합니다.
  • 부가세율은 매번 사용자가 지정하며 고정되지 않습니다.
  • 출력 PDF는 A4 크기이며 인쇄에 적합합니다.

6. 일반적인 문제 처리

오류 현상원인Agent 처리 방식
command not found: lark-clilark-cli 미설치lark-cli 설치 안내, Step 0.3 참조
lark-cli 인증 오류 반환미로그인 또는 토큰 만료lark-cli auth login 실행 안내
Executable doesn't existPlaywright Chromium 미설치npx playwright install chromium 실행
렌더링된 PDF가 비어 있거나 형식이 잘못됨데이터 JSON 형식 오류프로젝트 이름, 엔지니어링 번호가 비어 있지 않은지, items가 1개 이상인지 확인
세부 일련 번호가 수동으로 입력한 것과 다름일련 번호가 자동 생성으로 변경됨정상 현상: 일련 번호가 그룹별로 자동 재편성됨 (예: 01 전집 → 1.1, 1.2…). 순서 조정은 飞书에서 레코드를 드래그
글꼴 크기/이상 현상극히 드물게 발생 (글꼴은 WOFF2로 내장되어 외부 CDN에 의존하지 않음)프로젝트 references/fonts/ 디렉토리의 글꼴 파일이 완전한지 확인
로고 다운로드 실패멀티차트 첨부 파일 API 권한 문제사용자 인증 확인 또는 "로고 사용 안 함" 선택
URL에서 base-token 추출 불가사용자가 멀티차트 링크를 제공하지 않음사용자에게 飞书 멀티차트 링크 제공 요청 (URL에 /base/ 포함되어야 함)

관련 스킬