기계설비 ERP
기계설비 시공사의 현장 운영 전반(투입비·기성·계약·결재·장비·인사)을 하나의 웹 시스템으로 통합하고, 세금계산서·사업자등록증 등 증빙 서류를 AI OCR로 자동 파싱해 입력 업무를 자동화한 건설 ERP
- 기간
- 2026.03 ~ 2026.05
- 역할
- 팀 리더
- 구분
- 풀링포레스트
- 스택
- Next.js 16 (App Router), React 19, TypeScript, Prisma 6
프로젝트 배경
배경 & 목적
기계설비 시공 현장에서는 투입비 정산, 기성(기성고) 청구, 업체 계약, 내부 결재가 종이 서류와 엑셀로 흩어져 관리되고 있었다. 이 프로젝트는 현장(프로젝트) 단위로 비용·계약·기성·결재·장비·인력 데이터를 한 시스템에 모으고, 특히 세금계산서·거래명세서·통장사본 같은 증빙 문서를 업로드하면 AI가 자동으로 내용을 추출해 폼을 채워주는 것을 핵심 차별점으로 삼았다.
내 역할과 기여도
- ▶팀 구성: 5인 개발 (git 기여자 기준: KoDongHyun7724, 현승윤, DDu-lmg, ysk9926(본인), 이우진)
- ▶역할: 팀 리더
- ▶커밋 기여: 107건 / 전체 691건
- ▶주요 담당 (커밋 기준 확인):
- ▶
shared/document-parser통합 문서 파싱 모듈 설계·구현 (엔진 6종 + 파서 10종 + JSON Schema 10종) - ▶OpenAI/Gemini 기반 구조화 OCR 및 공급자 교체 가능 아키텍처
- ▶멀티 문서 PDF 2-Pass 분리·추출 파이프라인 (Pass 1 세그멘테이션 → Pass 2 병렬 추출)
- ▶수동 세그먼트 보정 UI(ManualSegmentModal), 재추출(re-extract) API
- ▶파일 스토리지 이중화 (dev: 로컬 / prod: Supabase Storage), Vercel 배포 이슈 해결
- ▶
핵심 구현
1. 문서 자동 파싱 시스템 (핵심 담당)
업로드 지점 10개 페이지에 <ParsedFileUpload> 공통 컴포넌트를 연동. 파일을 올리면 parseDocument(file, docType) 한 번의 호출로 확장자별 엔진 라우팅 → AI 구조화 추출 → 검증 → 폼 자동 채움까지 처리된다.
- ▶엔진 6종: 이미지/스캔PDF(OCR), 텍스트 PDF, XLSX, DOCX, HTML, HWP(어댑터 스텁 — 변환기 미연결)
- ▶파서 10종: 사업자등록증, 통장사본, 세금계산서, 계약서, 영수증, 신분증, 예산내역서, 기성내역서, 이력서, 거래내역서
- ▶이중 검증 구조: LLM json_schema strict 응답 → 타입 검증/포맷 정규화, 실패 시 정규식 fallback
- ▶적용 페이지: 업체계약 등록/결제/변경, 기성 신청, 비용 관리, 장비 수리이력, 협력사·거래처 등록, 회원가입, 투입비 등록
2. 멀티 문서 PDF 분리·추출 파이프라인 (핵심 담당)
세금계산서·거래명세서·간이전표 등 여러 서류가 한 PDF에 섞여 스캔되는 실무 상황을 처리하는 2-Pass 파이프라인.
- ▶Pass 1: Gemini로 페이지 썸네일+텍스트를 분석해 문서 경계(Segment) 분할 — 7종 문서 유형 분류, bbox·overlap·confidence 검증
- ▶Crop: 세그먼트를 이미지 또는 부분 PDF로 잘라냄 (bbox 클램핑, 페이지 렌더 캐시)
- ▶Pass 2: 세그먼트별 docType 전용 스키마로 병렬 추출 (동시성 5)
- ▶수동 보정: 저신뢰 세그먼트는 ManualSegmentModal(캐러셀+줌+DocGroup 편집)에서 사람이 경계를 확정 후 재추출
- ▶결과 활용: 헤더+라인아이템을 CandidateRow 트리로 집계해 투입비 입력 행으로 변환
3. 투입비·기성·계약 관리
- ▶투입비 등록 → 결재선(기본 결재선/현장별 결재선) 승인 → 현장별 집계·감사 이벤트 추적
- ▶기성 회차별 공종 라인(ProgressGongLine) 관리, 기성 청구 현황 대시보드
- ▶업체계약 등록·지급·변경이력·검토, 계약 서류 AI 자동 입력
4. 결재·대량이체
- ▶품의서(ResolutionDoc) 작성 → 결재선 승인 → 은행 대량이체 배치 생성 → 이체 파일 생성 → 완료 처리 흐름
- ▶회사 계좌(CompanyBankAccount) 관리
5. 현장(프로젝트) 통합 상세
- ▶현장별 13개 탭: 정보, 비용(차수별 리비전), 계약, 기성, 투입비, 장비, 체크리스트(공무/공사), 이력, 연락처, 협력사, 권한, 수익
- ▶공동도급(JV) 구성사 관리, 현장 좌표+기상청 API 연동 날씨 로그(크론 자동 기록)
6. 권한·조직·운영 기능
- ▶메뉴 단위 + 프로젝트 단위 이중 권한, 권한 템플릿 일괄 적용
- ▶회원가입 승인제(서류 8종 첨부), 조직(회사/지사/부서/직급) 관리
- ▶알림·멘션 시스템(폴링), 게시판, 일정(참석자·댓글·첨부), react-grid-layout 기반 사용자별 대시보드 위젯 배치
성과
- ▶담당 역할: 팀 리더
- ▶제품/서비스 관점에서 기능 우선순위와 개발 방향을 조율하며 구현을 진행했습니다.
- ▶포트폴리오 본문은 공개 가능한 수준의 프로젝트 개요와 역할 중심으로 자동 정리합니다.
트러블슈팅
[!important] 면접용 STAR 기법 — 코드/커밋/문서로 확인된 사례만 기재
사례 1: 13곳에 흩어진 파일 업로드를 통합 문서 파싱 모듈로 재설계
상황 (Situation) 프로젝트 내 파일 업로드 UI가 13곳에 흩어져 있었고, 그중 2곳만 각자 다른 방식의 AI 추출 로직을 갖고 있었다. 증빙 서류(세금계산서, 사업자등록증 등)의 수기 입력이 ERP 도입 효과를 깎아먹는 상태였다.
과제 (Task) OCR뿐 아니라 XLSX/DOCX/HTML 같은 구조화 파일까지 하나의 모듈로 통합하고, 모든 업로드 지점이 동일한 API로 파싱을 쓸 수 있게 만들어야 했다.
행동 (Action)
- ▶
file-router(확장자→엔진) → engine(원시 추출) → parser(도메인 정규화)3계층으로 분리 설계 — 엔진 교체가 파서에 영향을 주지 않는 구조 - ▶OpenAI Responses API의
json_schemastrict 모드로 문서 유형별 스키마 10종을 정의해 구조화 추출 - ▶LLM 응답 검증 + 정규식 fallback의 이중 경로로 안정성 확보
- ▶
<ParsedFileUpload>상태 머신 훅(idle→uploading→parsing→done/error)으로 10개 페이지 일괄 연동, 기존 개별 AI 로직 2곳 제거 - ▶3개 스프린트, 66커밋, 110개 테스트로 완료 (엔진/파서 단위 테스트 + 통합 테스트)
결과 (Result)
- ▶신규 서류 지원이 "파서 파일 1개 + 레지스트리 등록"으로 축소
- ▶계약·기성·투입비·회원가입 등 10개 화면에서 서류 업로드 시 폼 자동 채움 동작
- ▶OCR API 키는 DB에 AES-256-GCM 암호화 저장(OcrProviderConfig), 공급자·모델을 재배포 없이 교체 가능
사례 2: 여러 서류가 섞인 스캔 PDF의 2-Pass 분리·추출 파이프라인
상황 (Situation) 실무에서는 세금계산서·거래명세서·간이전표·통장사본이 한 번에 스캔된 수십 페이지 PDF가 올라온다. 단일 문서 전제의 파서로는 처리할 수 없었다.
과제 (Task) 문서 경계를 자동으로 찾아 유형별로 분리하고, 각 조각을 해당 유형의 스키마로 추출하되, AI가 확신하지 못하는 경계는 사람이 보정할 수 있어야 했다.
행동 (Action)
- ▶Pass 1: 페이지별 저해상도 썸네일+텍스트를 Gemini에 넘겨 세그먼트 분할 — strict JSON 스키마, bbox 클램핑, overlap/confidence 검증 로직 별도 구현
- ▶페이지 렌더러의 이터레이터 직렬화·렌더 캐시로 동시 호출 문제 해결
- ▶Pass 2: 세그먼트를 이미지/부분 PDF로 crop 후 문서 유형별 스키마로 동시성 5 병렬 추출
- ▶
needsManualReview세그먼트는 ManualSegmentModal(고해상도 캐러셀+줌, "페이지 상단 제목=새 문서" 경계 규칙, DocGroup 편집)로 수동 확정 →/api/parse/re-extract로 재추출 - ▶녹화된 Pass1/Pass2 응답 기반 통합 테스트 작성
결과 (Result)
- ▶혼합 스캔 PDF 한 번 업로드로 세그먼트별 헤더+라인아이템이 CandidateRow 트리로 집계되어 투입비 입력 행 자동 생성
- ▶단일 문서 파싱과 멀티 문서 파이프라인이
/api/parse한 진입점에서 자동 분기 (실패 시 기존 composite 경로 fallback)
사례 3: 환경별 스토리지 분기와 Vercel 배포 이슈 해결
상황 (Situation)
개발 단계에서는 public/uploads 로컬 저장을 썼지만, Vercel 서버리스 환경은 로컬 파일 시스템이 영구적이지 않아 운영 배포가 불가능했다.
행동 (Action)
- ▶
STORAGE_DRIVER환경변수로 로컬(dev) / Supabase Storage(prod) 분기 구현 - ▶Vercel 빌드 캐시로 Prisma Client가 갱신되지 않는 문제를
postinstall: prisma generate로 해결
결과 (Result)
- ▶동일 코드로 로컬 개발과 Vercel 운영 배포가 모두 동작, 체크리스트 마감·날씨 기록은 Vercel Cron으로 자동화