본문으로 건너뛰기

은행거래내역 CSV 파서

기반 ADR: 0003 Pack 1 채권 계산 §C4

개요

의뢰인이 가져온 은행 거래내역 CSV·PDF·엑셀 을 붙여넣으면 변제 내역을 자동 채움. 사무원 타이핑 시간 대폭 절감. AI 없이 결정론 파싱 (Phase 0) → AI 적요 분류 보조 (Phase 1).

왜 필요한가

  • 의뢰인이 가져오는 자료: 은행 거래내역 PDF/엑셀 + 카톡 스샷 + "2022년 봄쯤" 메모 (P2 사무장)
  • 한 칸씩 타이핑하게 두면 엑셀 대비 우위 없음 (P2)
  • 이게 없으면 사무장은 엑셀로 돌아감 (P10 회계 사무원)

Phase 별 범위

Phase 0 (결정론, AI 0)

  • 국민·카카오뱅크·토스뱅크 3개 은행 CSV 어댑터
  • 헤더 자동 감지 + 컬럼 매핑 미리보기
  • 적요 규칙 기반 80% 분류 (변제/이자/무관)
  • 수기 입력 병행

Phase 1 (AI 적요 분류 weight 1)

  • 추가 5개 은행: 신한·하나·우리·농협·IBK
  • 커스텀 컬럼 매핑 템플릿 저장 (로펌 법무팀 자체 양식)
  • AI 적요 분류 settlementParse (weight 1)
    • 폴백: 규칙 기반 80% + "미분류" 수동 배치
    • Gemini zero-shot structured output

Phase 2 (제외)

  • 적요 → 충당 금액 자동 분해: out-of-scope (AI 금지, P5·P10 합의)

사용자 플로우

기본 CSV 업로드

  1. 변제 섹션 하단 [📋 CSV 붙여넣기] 클릭
  2. 은행 드롭다운 선택 (Phase 0: 3개, Phase 1: 8개 + 커스텀)
  3. 엑셀·CSV 붙여넣기 or 파일 드래그
  4. 첫 5행 미리보기 + 컬럼 매핑 드롭다운
  5. 자동 분류 결과 확인 (예: "12건 중 10건 변제·2건 제외")
  6. 수동 보정 → [검토 완료] → 변제 테이블에 일괄 삽입

커스텀 템플릿 (Phase 1)

  • 은행 외 포맷 (법무팀 엑셀·구두 정리 자료)
  • 드롭다운 "기타 포맷 수기" 선택
  • 컬럼 매핑 수동 지정 (거래일·금액·적요)
  • [ 템플릿 저장 ] → 다음에 재사용

은행별 포맷

국민은행 (Phase 0)

컬럼의미
거래일시2026-03-15 14:32:11
적요박철수 2월이자
입금액500,000
출금액-
잔액3,200,000

카카오뱅크 (Phase 0)

컬럼의미
거래일시2026.03.15 14:32
거래구분입금 / 출금
거래금액500,000
잔액3,200,000
메모박철수 2월이자

토스뱅크 (Phase 0)

  • JSON 스타일 Excel
  • 헤더 감지 특수 처리

Phase 1 추가 5개 (신한·하나·우리·농협·IBK)

각 은행별 컬럼명·날짜 포맷·부호 (입금 + / 출금 -) 다름 → 어댑터 분기.

적요 해석 규칙 (Phase 0)

80% 커버 목표.

패턴 1 — 채무자 성명 매칭

  • 사건의 채무자 이름 "박철수" · 적요 "박철수" 포함 → 변제
  • 사건 의뢰인 이름과 다른 성명 포함 → 무관

패턴 2 — 변제 키워드

  • "이자", "원금", "변제", "반환", "차용금" 포함 → 변제
  • "이자" 단독 → appropriationOverride: "interest" 지정충당 추정

패턴 3 — 조합

  • 성명 + 월 단위 ("박철수 2월이자") → 변제 + 해당 월 추정

미분류 처리

  • 20% 미분류 → "미분류" 상태 + 사용자 수동 배치
  • 완전 자동화는 Phase 2 이후 검토

엣지 케이스

케이스처리
이체 취소 (음수 행)원행과 페어링 (거래일·금액·적요 매칭)
수수료 차감 (1,000,000 → 999,500)500원 수수료 보정 플래그
현금 입금 ("타행입금" vs "전자금융")증빙 강도 배지 분리
같은 날 같은 금액 여러 건 (정상 중복: 일급·용돈)경고 배지만, 완전 차단 ✗
중복 입력 (해시 충돌)(거래일 + 금액 + 적요) 해시 dedupe

어댑터 인터페이스

// apps/web/app/(workspace)/cases/[caseId]/_lib/bank-csv-parsers.ts
export interface BankAdapter {
readonly bankId: "kb" | "kakao" | "toss" | "shinhan" | "hana" | "woori" | "nh" | "ibk" | "custom";
readonly displayName: string;
readonly samplePreview: string; // 첫 5행 샘플 (UI 에서 표시)

parse(
content: string | ArrayBuffer,
options?: { columnMapping?: ColumnMapping }
): Promise<ParseResult>;
}

export interface ParseResult {
rows: TransactionRow[];
totalCount: number;
classifiedCount: { repayment: number; unrelated: number; unclassified: number };
warnings: Warning[];
}

export interface TransactionRow {
transactionDate: Timestamp;
amount: number; // 정수 원
direction: "in" | "out" | "cancel";
memo: string;
balance?: number;
classification: "repayment" | "unrelated" | "unclassified";
classificationReason: string; // 규칙 matched
feeAmount?: number;
duplicateWarning?: boolean;
sourceHash: string; // 중복 방지
}

AI 적요 분류 (Phase 1)

settlementParse feature, weight 1:

export async function classifyRepaymentsByAi(
caseId: string,
unclassifiedRows: TransactionRow[]
): Promise<ActionResult<TransactionRow[]>>;

프롬프트 구조:

  • 사건 정보 (채무자 이름·대여 건수·청구 금액)
  • 미분류 거래 20건 묶음
  • Gemini Flash structured JSON: { rows: [{ index, classification, reason }] }
  • Zod 검증 → 실패 시 classifyRefund 환불

폴백:

  • AI 실패 → "미분류" 상태 + 사용자 수동 배치 (기존 동작)
  • 품질 회귀 모니터링: P15 editRatio 증가 감지

기술 스택

  • CSV 파싱: papaparse (클라이언트)
  • XLSX 파싱: xlsx (Server Action 에서만, 클라 bundle 크기)
  • PDF 파싱: pdf-parse (OCR 필요 시 Document AI)
  • HWP 미지원 (은행 내역 HWP 사용 안 함)

테스트 (Phase 0)

  • 국민·카카오뱅크·토스뱅크 실제 CSV 샘플 각 20건 파싱 성공
  • 헤더 변형 (컬럼명 대소문자·공백) 자동 감지
  • 중복 해시 dedupe 검증
  • 취소 행 페어링 검증
  • 적요 규칙 분류 80%+ 커버 (50건 수동 라벨링 대비)

UI 참조

사건 상세 화면 설계서 §3 CSV 붙여넣기 모달

관련 기능

관련 ADR