skills/fs-merge/SKILL.md
Merge multi-year Korean financial statements, 재무제표, BS, PL, 제조원가명세서, from PDFs or spreadsheets into one comparison .xlsx. Use when the user provides two or more Korean FS files and asks to consolidate, compare, 합본, 합치기, combine year-over-year statements, or build a merged workbook.
npx skillsauth add sjunepark/custom-skills fs-mergeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
회계·세무 실무자가 제공한 N개의 연도별 재무제표 파일(PDF 또는 xlsx)을 받아, 모든 연도를 한 시트에 정렬해 비교 가능한 합본 xlsx를 만든다. 출력은 재무제표/손익계산서/제조원가명세서 3개 섹션이 단일 시트에 들어간 형식.
핵심 제약 두 가지:
| 형식 | 읽기 방법 |
|------|----------|
| .xlsx (정리된 FS) | 사용 가능한 스프레드시트 리더 또는 openpyxl read_only=True |
| .xlsx (DART 다운로드 raw) | 동일하되 시트가 여러 개일 수 있음 — 시트별로 점검 |
| .pdf (텍스트형 — 정상 추출) | pdftotext -layout, pypdf, 또는 사용 가능한 PDF 텍스트 추출기 |
| .pdf (텍스트형 — CID 추출 실패) | 이미지 변환 후 OCR/visual reading (아래 ⚠ 참조) |
| .pdf (스캔본) | scripts/pdf_to_images.py 로 페이지를 PNG로 렌더링 → 이미지를 직접 OCR/visual reading으로 읽기 |
PDF가 텍스트형인지 빠르게 판별:
pdftotext -f 1 -l 1 input.pdf - | head -20
세 가지 결과 분기:
pdftotext 그대로 사용pdf_to_images.py 경로Syntax Error: Missing language pack for 'Adobe-Korea1' mapping 또는 Unknown font tag 'CJK1' → CID 인코딩 문제 (다음 ⚠ 참조)세무사·회계법인이 발행한 한글 PDF는 종종 ToUnicode CMap이 누락된 CID 폰트(Adobe-Korea1)를 사용한다. 이 경우 pdftotext는 빈 출력 + 위 경고를 낸다. 처리 순서:
python -c "import pdfplumber; print(pdfplumber.open('x.pdf').pages[0].extract_text())" — 일부 케이스에서 동작python -c "import fitz; print(fitz.open('x.pdf').load_page(0).get_text())" — 추가 케이스 동작pdf_to_images.py 로 PNG 렌더링 → OCR/visual reading으로 읽기이 패턴에서는 숫자만 추출되고 한글 계정과목이 사라지는 partial 결과가 자주 나온다. 그런 결과는 신뢰하지 말고 이미지 경로로 재시도한다.
스캔본·이미지 변환 PDF에서 숫자를 읽을 때, 자릿수 변환 위험이 있는 셀은 명시적으로 OCR_의심 플래그에 기록한다.
scripts/build_workbook.py 는 Python 3 + openpyxl 이 필요하다.scripts/pdf_to_images.py 는 PDF 렌더링이 필요할 때 Python 3 + PyMuPDF (fitz) 를 사용한다.각 입력 파일이 어떤 기수(year)를 커버하는지 정리한다. 이때 결산기간(period span)도 같이 확인:
같은 연도가 여러 파일에 나오는 경우, 더 최근에 공시된 FS의 숫자를 채택한다 (재분류·수정 후 가장 최신 정보).
다음 형식으로 정리:
파일 | BS 일자 | PL 기간 | 비고
BSPL_2022.pdf | 2022-12-31 | 2022-01-01~12-31 | 12M
BSPL_2023.pdf | 2023-12-31 | 2023-01-01~12-31 | 12M (3기 비교)
| 2022-12-31 | 2022-01-01~12-31 |
BS_202506.pdf | 2025-06-30 | — | 6기 중간결산 BS
| 2024-12-31 | — | 5기 비교
PL_202506.pdf | — | 2025-01-01~06-30 | 6M 중간결산 PL
| — | 2024-01-01~12-31 | 12M 5기 비교
각 파일에서 PL · MS · BS 별로 (계정과목, 실계정 0/1, 값 배열) 을 뽑아낸다. 이 단계에서는 합치지 않는다 — 파일별로 raw 데이터만 확보.
스캔본/CID PDF는 이미지 변환 후 visual reading. 한 페이지씩 처리하면서 흐릿한 숫자에 플래그를 단다.
가장 최근 FS의 계정과목 순서·이름·실계정 구분(0/1)·소계 구조를 그대로 master로 채택. 출력 xlsx의 행 골격이 됨.
이 스킬의 핵심. 자세한 알고리즘은 references/matching_algorithm.md 참조.
요약:
재계산_차이 플래그 기록 후 진행매칭_의심 플래그 후 진행두 FS 파일 사이에 공통 연도가 없는 경우(예: 2023 FS 파일 + 2025-06 중간결산 파일, 그 사이 FY2024 standalone 파일 없음) 숫자 fingerprint 검증이 원천 불가능하다. 처리:
매칭_의심 플래그를 단다 (예: "2023 ↔ 2025/06 사이 FY2024 fingerprint 검증 불가 — 위치만 매칭")연도별 chart of accounts 변경(예: 매입채무 → 외상매입금, 현금및현금성자산 → 현금 + 보통예금 분리)은 자동 매칭하지 말 것. 결정 트리는 references/account_changes.md 참조.
checks 의 sum 형식)상품매출원가 = 기초재고 + 당기매입 - 기말재고Ⅲ.매출총이익 = Ⅰ.매출액 - Ⅱ.매출원가Ⅴ.영업이익 = Ⅲ.매출총이익 - Ⅳ.판매비와관리비Ⅷ.소득세차감전이익 = Ⅴ.영업이익 + Ⅵ.영업외수익 - Ⅶ.영업외비용Ⅹ.당기순이익 = Ⅷ.소득세차감전이익 - Ⅸ.소득세등자산총계 = 부채총계 + 자본총계 (구조상 자동으로 맞음)유동자산 = 당좌자산 + 재고자산, 비유동자산 = 투자+유형+무형+기타당기제품제조원가 (Ⅱ.매출원가 하위) = MS Ⅺ.당기제품제조원가 (Ref 섹션에서 차이 표시)비가산 검증식은 checks[].terms 필드로 부호 있는 선형 결합 표현 (references/output_layout.md 참조).
기말 이익잉여금 = 시초 + 당기순이익 ± 기타자본변동 검증은 자본 섹션이 다음 구조일 때만 수행:
개인사업자·소규모법인이 자본금 단일 행으로 처리하는 경우(자본+이익+인출금 lump-sum) 이 검증은 skip한다. 인출금 정보가 BS엔 없고 시산표에만 있어서 재구성 불가능.
검증 실패는 사용자에게 보고하되 출력은 일단 생성한다 (사용자가 결과를 보고 판단).
scripts/build_workbook.py 에 JSON 입력으로 데이터를 넘겨 xlsx를 생성한다.
python scripts/build_workbook.py /tmp/payload.json <output-dir>/FS_합본.xlsx
JSON schema는 빌드 스크립트 docstring 참조. 핵심 필드:
fiscal_year_ends: 결산기말일 ISO 문자열 배열 (오래된 것부터)period_notes (선택): fiscal_year_ends와 평행한 배열. 12개월이 아닌 기간엔 "6M interim" 등 짧은 라벨. 12M 정상이면 null. 헤더 아래 별도 행으로 표시됨.statements.PL / MS / BS: 행 객체 배열. 각 행은 account, is_leaf, values, flagsstatements.BS 의 행은 group 필드 추가 가능 (사용자 지시상 비워두는 게 default)is_section_header: true 가 있으면 실계정(C) 컬럼을 비워둠 (예: [자산]/[부채]/[자본] 시각적 구분 행)checks: 소계 검증. 두 가지 형식 지원:
child_indices: [a, b, c] — 모두 양수 합 (legacy)terms: [{idx, sign}, ...] — 부호 있는 선형 결합 (비가산 검증용)refs: 명세서 간 cross-reference 검증소계는 명시적으로 is_leaf: false 로 표시. is_leaf: true 인 행만 master/older 매칭의 포인터 진행 대상이다.
비제조업(MS 없음)의 경우 "MS": [] 로 빈 배열 전달 — build script가 섹션 자체를 스킵.
레이아웃 상세는 references/output_layout.md 참조.
xlsx 파일을 사용자가 지정했거나 현재 실행 환경에서 접근 가능한 출력 경로에 저장하고, 해당 환경의 파일 전달/첨부 방식으로 사용자에게 전달한다. 함께 다음을 요약 보고:
플래그가 많아도 그대로 보고. 사용자가 수기 검증할 거라고 명시적으로 말함.
DART URL을 받아도 직접 fetch 하지 않는다. 사용자에게 PDF/xlsx 다운로드 후 첨부해달라고 요청.
references/matching_algorithm.md)period_notes schema 추가references/account_changes.md 신규)checks[].terms 부호 있는 선형 결합 schema 추가is_section_header 행 옵션 추가 ([자산]/[부채]/[자본] 등)references/output_layout.md)development
Long-running systematic codebase review with a persistent ledger in reviews/. Use to plan review areas, continue the next review pass, check campaign status, triage findings with the user, or apply auto-tier fixes. Modes: plan, continue, status, triage, fix (default continue).
development
Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, empty states, UX review, visual hierarchy, information architecture, accessibility, performance, responsive behavior, theming, typography, spacing, layout, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, design systems, tokens, live browser iteration, and ambitious visual effects. Not for backend-only or non-UI tasks.
development
Manually integrate Git branch work without blind mechanical merges. Use when merging, transplanting, or refactoring branch work; resolving conflicts; preserving source-branch intent in a clean current-branch structure; or auditing that source additions, removals, tests, and docs landed intentionally.
testing
Prepare, audit, set up, and guide Release Please releases. Use when releasing, preparing or reviewing a release PR, adding Release Please, classifying SemVer impact or breaking changes, writing Release Please-compatible Conventional Commit guidance, or documenting release criteria. Release work requires existing Release Please config; setup requires an explicit setup request.