Compare commits

253 Commits

Author SHA1 Message Date
김보곤
007e8a3ed3 docs: [quality] 실적신고 엑셀 Export 구현 가이드 추가
- dev/guides/performance-report-excel-export.md 신규 작성
- 품질관리 README 미구현 항목 → 구현 완료로 업데이트
- INDEX.md에 새 문서 등록
2026-03-17 16:55:19 +09:00
김보곤
ca1a5fdaba docs: [account] 계정과목 코드 변경 매핑 문서 작성
- 더존 3자리 163개 → KIS 5자리 458개 전면 교체 추적
- 이름 기준 매핑, 변경/누락 항목 표기
2026-03-17 16:34:40 +09:00
김보곤
b50e31a038 docs: [barobill] React 프론트엔드 개선 요청서 작성
- 신규 API 11개 엔드포인트 연결 가이드 (요청/응답 명세)
- 설정 페이지 개선: 연동 현황 대시보드, 계좌/카드 목록, 인증서/잔액
- 은행/카드 조회 화면: 동기화 버튼 추가 요청
- Server Action 6개 코드 예시 제공
- UI 와이어프레임 포함
2026-03-17 15:02:05 +09:00
김보곤
3588bb3dd7 docs: [barobill] API SOAP 구축 완료 반영 + 기술 참조 문서 신규
- README.md: 현재 상태 업데이트 (API SOAP 100% 구축 완료, 아키텍처 다이어그램)
- api-soap-reference.md: 신규 — 전체 메서드 49+7개, 동기화, 스케줄러, 테스트 환경 데이터
- tenant-onboarding.md: 구현 현황/테스트 시나리오 추가
- INDEX.md: 신규 문서 등록
2026-03-17 14:53:30 +09:00
김보곤
03a7a6c3ca docs: [plans] 절곡품 LOT 재고생산 React 구현 요청서 추가
- 프론트엔드 개발자 전달용 문서
- 화면 설계, 드롭다운 동작 흐름, API 엔드포인트, 작업 파일 목록
- 취소→등록 복원 기능, 담당자 기본값, 원자재 LOT 선택 모달 포함
2026-03-17 14:30:53 +09:00
김보곤
80406744bf docs: [api-specs] 문서 갱신 표기에서 v2 제거 2026-03-17 14:27:08 +09:00
김보곤
13f76a72d7 docs: [api-specs] 절곡품 LOT API v2 — 원자재 LOT 조회, 취소 복원, 담당자 기본값 2026-03-17 14:21:36 +09:00
김보곤
397ea25256 docs: [rules] 재공품(WIP) 생산 정책 PPTX 프레젠테이션 추가
- 8장 슬라이드: 표지, 재공품 정의, 미리 생산 효과 4가지
- 대상 품목 선정 기준, SAM 처리 방식, MTO/MTS/ATO 전략
- 과잉 생산 방지 주의사항, 핵심 요약
2026-03-17 13:47:15 +09:00
김보곤
e4fc92c012 docs: [barobill] 온보딩 실행 가이드 PPTX 추가
- 12슬라이드 구성 (표지/전체흐름/Step1~7/고객안내/트러블슈팅/API요약)
- 7단계 플로우 시각화, 역할 분담 (관리자/고객)
- 에러 코드 대응표, FAQ, 고객 준비물 안내
2026-03-17 13:46:11 +09:00
김보곤
4bc7f36b5e docs: [barobill] 온보딩 실행 가이드 작성
- 7단계 실행 절차 (사전준비→회원등록→인증서→계좌카드→검증→운영전환→자동동기화)
- 각 단계별 API 호출 예시 포함
- 에러 코드 대응표, 트러블슈팅 섹션
- 고객 안내 자료 템플릿, FAQ
- INDEX.md에 등록
2026-03-17 13:14:17 +09:00
김보곤
e619dd77f7 docs: [api-specs] 절곡품 LOT API 명세 추가 (프론트엔드 개발자용)
- 코드맵/품목매핑/LOT 채번 3개 엔드포인트 명세
- 캐스케이딩 드롭다운 구현 가이드 포함
- 저장 요청 options.bending_lot 구조 정의
2026-03-17 13:08:23 +09:00
김보곤
909d7481bd docs: [plans] 재고생산 기획 결정 사항 반영
- LOT 일련번호 suffix 전략 확정 (-001, -002)
- items 매핑: 매핑 테이블(bending_item_mappings) 확정
- 일반 재고생산 모드 분기 제거 (절곡품 전용)
2026-03-17 13:00:35 +09:00
김보곤
e92baec6e2 docs: [plans] 재고생산 절곡품 LOT 입력 개편 기획서 추가 2026-03-17 12:50:41 +09:00
강영보
4c7f4c1005 Merge branch 'main' of http://114.203.209.83:3000/SamProject/sam-docs 2026-03-17 11:34:05 +09:00
강영보
fbd0510cc1 docs: [bending] 절곡품 관리 개발 완료 상태 업데이트
- step1: 데이터 임포트 완료 (170+60건), artisan 커맨드 7개 실행 결과
- step2: API 12개 엔드포인트 완료, item_category 필수 필터 추가
- step3: MNG 샘플 완료 (4개 메뉴, 이미지 473건)
- step4: React 구현 가이드 전면 작성 (API 응답 구조, 컴포넌트 설계, 실무 노트)
- 코드 체계 변경 불가 사유, 265vs170 차이 설명, 운영 전 정리 항목 추가
2026-03-17 11:33:47 +09:00
김보곤
4bb22609cd docs: [changes] 재고생산 버그 수정 이력 추가 (2026-03-17)
- $isStock/$process 미정의 오류 수정
- 수량 정수 변환 (API + React)
2026-03-17 11:29:44 +09:00
김보곤
d9fb01c213 docs: [barobill] CEO 설명용 서비스 출시 계획 PPTX 추가
- 7장 슬라이드 (표지, 현황, 로드맵, 모드, 온보딩, 과금, Next Steps)
- 4단계 출시 로드맵 시각화
- 테스트/운영 모드 비교
- 과금 구조 및 수익 시뮬레이션
2026-03-17 09:10:02 +09:00
김보곤
9240034b97 docs: [barobill] 서비스 출시 단계별 준비 계획 문서 추가
- Phase 1~4 로드맵 (SOAP 이관→UI→베타→출시)
- 단계별 작업 목록 및 체크리스트
- 바로빌 파트너 정책 확인 필요 사항
- 리스크 및 대응 방안
2026-03-17 09:07:02 +09:00
김보곤
79ca132d1a docs: [barobill] 테넌트 온보딩 개념 정의 문서 추가
- 온보딩 vs 베타테스트 개념 구분
- 6단계 온보딩 프로세스 정의
- 테스트→운영 모드 전환 체크리스트
- 개발→베타→출시→온보딩 단계별 관계 정리
2026-03-17 09:00:00 +09:00
김보곤
469efce440 docs: [barobill] 바로빌 연동 시스템 문서 작성
- SOAP API 구조, 테스트/운영 모드 비교
- 과금 정책 및 멀티테넌트 처리
- 서비스 이관 계획 및 우선순위
- INDEX.md에 문서 등록
2026-03-17 08:54:02 +09:00
김보곤
7d280f3dd5 docs: [rules] 재공품(WIP) 생산 정책 문서 추가
- 재공품 개념 정의 (원자재 → 재공품 → 완성품)
- 재공품 미리 생산의 4가지 효과 (유휴시간 활용, 납기 단축, 생산 평준화, 긴급 대응)
- MTS/MTO/ATO 제조 전략 설명
- 제조업 공통 적용 사례 (가구, 자동차, 전자제품, 식품, 의류)
- 과잉 생산 방지 주의사항
- SAM 시스템 처리 방식 (내부 오더, 재고 생명주기)
2026-03-16 23:02:41 +09:00
김보곤
077a0a3331 docs: [sales] 재고생산관리 문서 보강
- 재공품(WIP) 개념 설명 추가
- Phase 1/2 구현 범위 정리
- 작업자 화면 절곡 탭 향후 과제 기록
- 전체 메뉴 영향범위 검토 결과 추가
2026-03-16 22:59:43 +09:00
김보곤
029d4b6f02 docs: [order] 재고생산관리 개발문서 + React 구현 요청서 추가
- dev/changes/20260316_stock_production_order.md: 변경이력
- plans/stock-production-react-request.md: 프론트 개발자 전달 문서
- INDEX.md 등록
2026-03-16 22:28:49 +09:00
김보곤
cd3ee4e817 docs: [order] 재고생산 API 스펙 업데이트
- 생산지시 자동 처리 항목 추가 (절곡 공정, project_name, scheduled_date)
- 프론트엔드 체크리스트 업데이트
2026-03-16 22:24:24 +09:00
김보곤
3529feeb70 docs: [sales] 재고생산관리 기능 설명 문서 추가
- features/sales/stock-production.md 신규 작성
- INDEX.md에 문서 등록
2026-03-16 21:41:42 +09:00
김보곤
6eb4f96eaa docs: CLAUDE.md 용어 정의 섹션 추가
- 서비스(API+React) / 백오피스(MNG) 명칭 정의
2026-03-16 21:27:21 +09:00
김보곤
054d5d23f7 docs: [order] 재고생산관리 API 명세 추가
- frontend/api-specs/stock-production-api.md 신규 작성
- INDEX.md에 재고생산관리 API 문서 등록
2026-03-16 21:27:17 +09:00
김보곤
2073af1d8e docs: [rd] 방화셔터 가이드레일 SVG/3D 렌더링 기술문서 추가
- 철재스라트 15세그먼트 절곡 프로파일 상세
- 스크린형 4부재 구성 및 치수 라벨 체계
- 2D SVG 좌표계 및 3D Three.js 변환 매핑
- INDEX.md, README.md 등록
2026-03-16 21:08:48 +09:00
김보곤
253b9defd5 fix: [sales] 단체 가입 합계 33% → 30% 수정 2026-03-16 20:35:20 +09:00
김보곤
380bed83ed chore: [sales] customer-pricing PPTX 재생성 (이카운트 제거 반영)
- HTML→PPTX 변환 스크립트 추가
- 이카운트 연동 행 제거된 슬라이드 반영
2026-03-16 20:33:07 +09:00
김보곤
775cfb4262 docs: [sales] 단체 가입 유치 파트너 3% 영업파트너 문서에서 제거
- 단체 가입은 '단체 수당 30%'만 표시 (유치 파트너 3%는 내부 정산용)
- 수당 계산 예시 테이블 단체 컬럼 수정
- PPTX 슬라이드 반영
2026-03-16 20:14:17 +09:00
김보곤
21e7559c91 docs: [sales] 이카운트 연동 모듈 제거 — 바로빌은 기본 포함
- 개별 모듈 가격표에서 '이카운트 연동' 행 제거 (별도 상품 아님)
- 영업 전략 '이카운트 연동 추천' → '바로빌 부가 서비스 안내'로 변경
- 데모 테넌트 정책 '바로빌/이카운트' → '바로빌 등 외부 연동'으로 통일
- 브로셔/슬라이드 HTML 반영
- PPTX 재생성
2026-03-16 18:07:36 +09:00
김보곤
3ffb612917 chore: [sales] 가격정책 PPTX 무료체험 제거 반영 재생성 2026-03-16 17:52:39 +09:00
김보곤
8f54b43de9 docs: [sales] 무료 체험 관련 내용 전면 제거
- 가격정책 파트너 가이드: 4.3 무료 체험 섹션 삭제, FAQ Q6 삭제
- PPT 생성 스크립트: 무료 체험 카드/Q&A/전략/키포인트 제거
- 할인 종류 4가지 → 3가지로 변경
- 1년차 비용 계산에서 무료 체험 반영 제거
2026-03-16 17:52:39 +09:00
김보곤
828b452186 feat: [bending] 절곡품 관리 기능 개발 계획서 추가
- README.md: 전체 개요, 메뉴 구조, 작업 순서
- step1-데이터분석.md: 레거시 매핑 + options 확장 스키마
- step2-API.md: 엔드포인트 설계 (docs 규칙 준수)
- step3-MNG화면.md: Blade+HTMX 화면 구성 (3타입별 폼)
- step4-React연동.md: 견적 이미지 + 운영 화면 계획
2026-03-16 17:41:13 +09:00
김보곤
02073d4640 docs: [sales] 영업파트너 수당 체계 PPTX 재생성
- 수당 구조 개편 반영 (유치 파트너 5%/3%, 매니저 첫달 구독료)
- 무료 체험 관련 내용 전체 제거
- 개발비-구독료 반비례 연동 공식 반영
2026-03-16 17:19:47 +09:00
김보곤
5fae156bde docs: [sales] 영업 정책 변경 — 수당 구조 개편 및 무료 체험 폐지
- partner-commission.md: 무료 체험 참조 제거, 프로모션 3종으로 변경
- customer-pricing.md: 무료 체험 섹션 삭제, 연동 공식 반비례로 변경
- sam-pricing-simple-guide.md: 무료 체험 관련 전체 삭제, FAQ 정리
- changes/20260316_sales_policy_changes.md: 변경 이력 기록
- INDEX.md: 변경 이력 등록
2026-03-16 17:19:47 +09:00
김보곤
b7a5204c22 fix: [sales] 단체 가입 수당 33% 원복 (30% + 유치 파트너 3%)
- 단체 가입: 단체 30% + 유치 파트너 3% = 33% 구조 복원
- 개인 가입: 파트너 20% + 유치 파트너 5% = 25% 유지
- 전체 문서 및 PPTX에 단체 유치 파트너 3% 반영
2026-03-16 17:19:47 +09:00
김보곤
aa5255788d fix: [sales] PPTX 수당 체계 변경 반영 재생성
- 매니저 수당 → 유치 파트너 수당 5% (개인)
- 매니저 수당: 첫달 구독료 별도 지급
- 협업지원금 3% 제거
- 합계: 개인 25%, 단체 30%
2026-03-16 17:19:47 +09:00
김보곤
aef403123e docs: [pricing] 수당 체계 변경
- 개인 가입: 파트너 20% + 유치 파트너 5% = 합계 25%
- 단체 가입: 단체 30% (유치 파트너 없음)
- 매니저 수당: 개발비 요율 → 첫달 구독료 별도 지급
- 협업지원금(유치자) 3% 완전 제거
- PPTX 생성 스크립트 슬라이드 5, 6 동일 반영
2026-03-16 17:19:47 +09:00
김보곤
3c9a8ac9a6 docs: [수당] 수당 체계 개편 - 유치 파트너/매니저 수당 변경, 협업지원금 제거
- 매니저 수당 5% → 유치 파트너 수당 5% (개인 가입)
- 매니저 수당: 개발비 요율 → 첫달 구독료 별도 지급으로 변경
- 협업지원금(유치자) 3% 완전 제거
- 합계: 개인 28%→25%, 단체 33%→30%
- 3개 문서 동시 반영 (partner-commission, billing-policy, price-simulator-partner-guide)
2026-03-16 17:19:47 +09:00
김보곤
943892e004 docs: [guides] API 요청 생명주기 학습 가이드 추가
- Client API(거래처)를 예제로 8단계 전체 흐름 해설
- 미들웨어→라우트→FormRequest→Controller→Service→Model→Response
- 코드 기반 상세 해설 + CRUD 전체 비교표
2026-03-16 17:19:47 +09:00
김보곤
ccab9003e9 fix: [sales] PPTX 슬라이드 6 레이아웃 오버플로우 수정
- 비교표 행 간격 0.38→0.32, 카드 높이 1.6→1.35로 압축
- 팁 박스 위치/높이 조정 (3.4→2.9, 0.5→0.38)
- 조견표 시작점 상향 (4.05→3.4)
- 최하단 행 y=4.76 (푸터 5.25 이전 확보)
- 레이아웃 계산 상수를 S6 객체로 구조화
2026-03-16 17:19:47 +09:00
김보곤
4adfcccbd8 docs: [sales] 가격정책 PPTX 재생성 (무료 체험 1주일 반영) 2026-03-16 17:19:47 +09:00
김보곤
b815f84b03 docs: [pricing] 무료 체험 기간을 1주일(7일)로 변경
- 기존 1/2/3/6개월 선택지 → 없음/1주일(7일) 단일 옵션으로 축소
- 1년차 총 비용 예시를 무료 체험 1주일 기준으로 재계산
- 4개 문서 동시 수정: customer-pricing, sam-pricing-simple-guide, price-simulator-partner-guide, partner-commission
2026-03-16 17:19:47 +09:00
김보곤
b29d78aeca fix: [pricing] 무료 체험 기간을 1주일(7일)로 통일
- 슬라이드 8: 무료 체험 설명 1/2/3/6개월 → 1주일(7일)
- 슬라이드 9: 1년차 비용 계산 예시 반영 (무료 3개월 → 1주일)
- 슬라이드 12: 영업 팁, 고객 FAQ 무료 체험 기간 수정
2026-03-16 17:19:47 +09:00
91e248eeab docs: [plans] 절곡품 관리 현황 분석 문서 추가
- 경동기업(5130) vs SAM 시스템 절곡품 관리 비교
- BD-XX-XXX 코드 체계, 갭 분석, 데이터 흐름 정리
2026-03-16 10:20:07 +09:00
4693acfd01 docs: [plans] QA 점검 이슈 수정 계획 문서 추가
- 경동dev 모듈별 기능/UI 점검 37건 이슈 분석
- Phase 0~4 단계별 수정 계획 수립
- 코드 레벨 심층 분석 (파일경로, 라인번호, 근본원인)
- 컨펌 6건 결정 반영 (5건 확정, 1건 보류)
2026-03-16 10:20:07 +09:00
ac7fc2946b docs: [MES] 데이터 정합성 보고서 v2 → v2.1 업데이트
- 이슈 #2 품질검사: 출하 연동 불필요 (품질검사는 출하 후 시공 완료 후)
- 이슈 #3 can_ship:  해결 완료
- 이슈 #4 재고차감:  비활성화 완료
- 이슈 #6 ShipmentItem FK:  해결 완료
- P0/P1/P2 로드맵 상태 전체 갱신
2026-03-16 10:20:07 +09:00
987030f24c docs: [ops] 서버 계정 관리 문서 업데이트
- 09-security: 서버 계정 관리 섹션 신규 추가 (Linux/MySQL 계정 현황, 생성 절차, 잠금/해제)
- 09-security: SSH 인증 정책 정리 (패스워드 허용, root 외부 접근 차단)
- 01-server-overview: 3개 서버 사용자 정보 업데이트 (hskwon/pro/kkk)
- 01-server-overview: 운영 DB 사용자 테이블에 pro, kkk 추가
2026-03-16 10:20:07 +09:00
김보곤
2ccbe0b5f1 docs: [sales] 영업파트너용 SAM 가격정책 쉬운 안내서 추가
- 가격정책 쉬운 안내서 (sam-pricing-simple-guide.md) 신규
- 시뮬레이터 상세 가이드 (price-simulator-partner-guide.md) 추가
- INDEX.md에 guides/ 섹션 등록
2026-03-15 10:41:40 +09:00
김보곤
907b566749 docs: [system] API 코드 품질 감사 보고서 추가
- 정석 패턴 6가지 (R1~R6) 정리
- 안티패턴 3가지 식별
- 보안 감사 결과 (해결 1건 + 미해결 7건)
- 신규 API 개발 체크리스트
2026-03-15 10:36:05 +09:00
김보곤
a02239b60d docs: [changes] API eval() 제거 변경이력 추가 2026-03-15 10:31:32 +09:00
김보곤
009efce594 docs: [sales] 매니저 수당 산정 방식을 개발비 비율 기반으로 수정
- partner-commission: 매니저 수당 "구독료 1개월분" → "개발비 × 5%" 수정
- partner-commission: 매니저 지급 시점 "첫 구독료 입금" → "파트너와 동일 분할" 수정
- partner-commission: 프로모션 예시 매니저 수당 50만→100만원 수정
- billing-policy: 마진 예시 매니저 수당 50만→100만원, 본사 순수익 재계산
2026-03-14 18:21:35 +09:00
김보곤
9139c81776 docs: [sales] 가격 시뮬레이터 내용을 가격정책 문서에 반영
- customer-pricing: 프로모션/할인 정책 섹션 추가 (개발비 할인, 구독료 할인, 무료 체험, 1년차 총 비용 공식)
- partner-commission: 분할 지급 구조, 수당 지급 시점, 매니저 수당 산정, 프로모션 할인과 수당 관계 추가
- billing-policy: 마진 구조 상세화, 프로모션 마진 영향 분석, 시뮬레이터/정산 코드 참조 추가
2026-03-14 17:49:17 +09:00
김보곤
f452ec94db docs: [changes] 운영 코드 안전성 검토 결과 추가
- 수정 2개 파일의 동작 동등성 검증 (수정 전 = 수정 후)
- 엣지 케이스 5건 검증 (null, 빈 배열, 없는 ID 등)
- 전체 256개 테스트 결과, 수정으로 인한 실패 0건 확인
- 기존 문제 발견: process_items tenant_id 필터 누락
2026-03-14 16:39:57 +09:00
김보곤
b6edc6db27 docs: [영업] 최저가 정책 및 개발비-구독료 연동 문서 반영
- customer-pricing.md: 최저가 정책, 개발비-구독료 연동 비율 섹션 추가
- partner-commission.md: 최저가와 수당 관계, 시뮬레이터 안내 섹션 추가
- products.md: min_development_fee/min_subscription_fee 필드, 시뮬레이터 연동 섹션 추가
2026-03-14 15:25:51 +09:00
김보곤
01fed097e4 docs: [changes] API 품질 개선 서버 변경이력 작성
- D1(테스트 56개) + D2(N+1 최적화 3건) 전체 근거 문서
- 왜 수정했는가, 무엇을 수정했는가, 성능 개선 효과 포함
- 수정 전/후 코드 비교, 쿼리 절감률, 회귀 테스트 결과
2026-03-14 14:49:16 +09:00
김보곤
f11d363380 docs: [changes] API 테스트 인프라 정비 및 수주 테스트 결과 기록
- TestCase 공통화, Factory 3개, Order 테스트 12개 결과
- 발견된 문제 (빈 데이터 수주 생성, 기존 테스트 실패) 기록
- 다음 단계 로드맵 (Stock, Approval, WorkOrder)
2026-03-14 09:50:46 +09:00
김보곤
58c3d8812f docs: [demo] 데모 체험 프로그램 매뉴얼 PPTX 업데이트
- 10페이지 구성: 표지, 3-Tier 설명, 생성/프리셋/관리/전환/모니터링/시나리오/스케줄/Q&A
- MNG 기반 워크플로우 반영
2026-03-14 08:39:40 +09:00
김보곤
87b1ed08d7 docs: [system] API 구조 분석 및 개선 로드맵 문서 추가
- 프로젝트 규모 정량 분석 (1,400 EP, 261 모델, 202 서비스)
- 아키텍처 3대 원칙, 요청 처리 흐름, 표준 테이블 구조
- 기술 부채 8건 식별 (D1~D8)
- P1~P3 우선순위별 개선 로드맵 수립
- INDEX.md에 문서 등록
2026-03-14 08:37:03 +09:00
김보곤
553e1e387a docs: [claude-code] /btw 사이드 질문 기능 가이드 추가
- v2.1.72에서 도입된 /btw 기능 상세 설명
- 사용법, 특징, 서브에이전트 비교, 베스트 프랙티스
- INDEX.md에 문서 등록
2026-03-14 08:13:12 +09:00
김보곤
9d03f13071 docs: [demo] 데모 테넌트 사용 가이드 문서 및 PPTX 매뉴얼 추가
- demo-tenant-usage-guide.md: 영업파트너/관리자용 사용 가이드 (API, 커맨드, 시나리오)
- demo-tenant-manual.pptx: 초보자용 10슬라이드 시각 매뉴얼
- INDEX.md에 새 문서 등록
2026-03-13 23:01:09 +09:00
김보곤
4c50ba488c docs: [sales] 영업파트너 데모 테넌트 정책 기획서 추가
- 3-Tier 전략: 쇼케이스(공용), 파트너데모, 고객체험
- 기술 구현 방안 및 단계별 로드맵 (Phase 1~4)
- INDEX.md에 문서 등록
2026-03-13 21:52:15 +09:00
김보곤
5738f7442c docs: [sales] '가입비' 용어를 '개발비'로 전면 변경
- 가입비 → 개발비로 용어 통일
- 원가/적용가 구분 명확화 (development_fee=원가, registration_fee=적용가)
- 상품관리정보, 수당지급, 영업파트너가이드북 등 10개 문서 수정
2026-03-13 21:25:43 +09:00
김보곤
9447e60896 docs: [system] 프로젝트 규모 현황 문서 추가
- 순수 개발자 코드 113만행, 5,114파일 규모 조사
- MNG/API/React/Docs 프로젝트별 레이어 상세 분석
- 조사 이력 테이블로 변화 추적 가능
2026-03-13 21:15:27 +09:00
김보곤
dda539f7f5 docs: [api] API 라우트 구조 개선 계획 문서 추가
- 1,099개 라우트 전수 분석 결과
- 7개 개선 포인트 식별 (stats 난립, 중복 리소스, 분개 반복 등)
- 실행 우선순위 및 예상 효과 포함
2026-03-13 20:37:40 +09:00
김보곤
c822a2317d docs: [bim-viewer] Phase 3 SAM Show Effects 20종 문서 추가
- Show Effects 아키텍처 (클로저 기반 update 패턴)
- 헬퍼 메서드 (_mkItem, _mkFlash, _setOp, mkMix)
- 20종 효과 목록 및 설명
- UI 구성 (드롭다운 + 재생 버튼)
- 메모리 관리 (_cleanupShow)
- 향후 계획 Phase 번호 업데이트
2026-03-13 20:37:40 +09:00
4e8e6b8423 docs: [plan] 사용자-사원 삭제 동기화 계획 문서 추가
- Phase 1~4 영향도 분석 및 실행 순서 포함
- 전체 Phase 완료 상태
2026-03-13 00:30:36 +09:00
bac20a093e docs: [QMS] 문서 양식 연동 상세 계획 수립
- 수주서/출고증/납품확인서 Mock→실데이터 전환 계획
- Phase 1-2 (실 데이터 매핑) 상세화, Phase 3-4 보류
- 검증 분석 반영 (필드명 수정, 구조 보강, 래퍼 컴포넌트 경유)
2026-03-12 23:54:07 +09:00
김보곤
6e61d7654b docs: [system] MNG→API+React 이관 현황 및 로드맵 문서 추가
- 이관 완료 24개 도메인 현황 정리
- 미이관 15개 기능 멀티테넌시 적합도 분석
- Phase 1~4 실전 서비스 개발 로드맵 수립
- MNG 유지 11개 기능 사유 정리
- React UI 보강 대상 8개 기능 식별
2026-03-12 23:22:38 +09:00
김보곤
93ddc74352 docs: [vehicle] 차량관리 React 구현 요청서 작성
- 프론트엔드 개발자용 구현 가이드 (3개 메뉴)
- 파일 구조, 타입 정의, API 호출 예시 포함
- 컴포넌트 활용 가이드, 배지 색상, 체크리스트
- vehicle-api.md 엔드포인트 수 17→20 업데이트
2026-03-12 22:38:13 +09:00
김보곤
0e6d4e6adf docs: [vehicle] 차량 사진 API 문서 추가
- vehicle-api.md에 사진 API 3개 엔드포인트 추가 (섹션 7)
- corporate-vehicles.md에 사진 이관 현황 및 엔드포인트 추가
2026-03-12 22:26:40 +09:00
김보곤
efbd74788a docs: [vehicle] 차량관리 프론트엔드 API 명세 추가
- 17개 엔드포인트 (차량목록 6 + 차량일지 6 + 정비이력 5)
- 데이터 모델, Enum 값, 유효성 검증 규칙
- UI 구현 가이드 (화면 레이아웃, 요약 카드 계산식, 특수 기능)
- INDEX.md에 문서 등록
2026-03-12 22:04:11 +09:00
김보곤
74facf050a docs: [card-vehicle] 차량관리 3개 메뉴 이관 문서 최신화
- README.md: 기술 스택 버전 수정 (Laravel 12, PHP 8.4), 이관 현황 테이블 추가
- corporate-vehicles.md: 이관 현황 + API 이관 스펙 (엔드포인트, 필터, 고려사항)
- vehicle-logs.md: 이관 현황 + API 이관 스펙 (summary 응답 구조 포함)
- vehicle-maintenance.md: 이관 현황 + API 이관 스펙 (주행거리 갱신 로직 포함)
2026-03-12 21:56:36 +09:00
김보곤
af20f974f7 docs: [equipment] 설비 등록 시 사진 업로드 기능 문서 반영
- README.md: 등록 시 사진 대기열+자동업로드 설명 추가
- equipment-frontend-request.md: 등록/수정 화면 사진 관리 가이드 업데이트
- equipment-service-build-plan.md: EquipmentForm 컴포넌트 설명 보강
2026-03-12 17:46:22 +09:00
김보곤
64f1262d51 docs: [standards] Blade + React(JSX) 혼용 정책 문서 추가
- 이중 중괄호 충돌 방지 규칙, 허용/금지 패턴, 체크리스트 포함
- INDEX.md에 등록
2026-03-12 17:08:15 +09:00
김보곤
ad0fed9d55 docs: DB 아키텍처 문서 현행화 - MNG 자체 마이그레이션 관리 반영
- codebridge 서버 분리 이후 MNG 자체 DB 관리 구조 반영
- 이전 규칙(모든 마이그레이션 API에서만) → 현행(각 프로젝트 자체 관리)
- CLAUDE.md, mng-structure, overview, database/README, PROJECT_DEVELOPMENT_POLICY 수정
2026-03-12 14:56:38 +09:00
73a8f525ea docs: [QMS] 점검표 템플릿 계획 문서 추가 2026-03-12 13:58:21 +09:00
김보곤
9c17850782 docs: [equipment] 사진 API 스펙 업데이트 (GCS→R2)
- 프론트엔드 요청 문서: 사진 업로드 API 상세 스펙 추가
- multipart/form-data files[] 배열 형식 명시
- 검증 규칙, Request/Response 예시 추가
- GCS 언급을 Cloudflare R2로 수정
- features/equipment README 동일 수정
2026-03-12 13:47:48 +09:00
김보곤
fa85bd388a docs: [bim] BIM 뷰어 문서 Phase 2 반영
- Phase 1 전용 → Phase 2 완료 상태로 업데이트
- IFC 업로드/다운로드, web-ifc, 듀얼 모드 설명 추가
- IFC→Three.js 변환 파이프라인, IFC Export 구조 문서화
- BimScene 클래스 메서드 목록 최신화
2026-03-12 13:35:14 +09:00
김보곤
efd0427cd6 docs: [equipment] React 프론트엔드 구현 요청 문서 작성
- 26개 API 엔드포인트 상세 스펙 (파라미터, 응답 구조)
- 8개 화면 구현 가이드 (레이아웃, 컬럼, 드롭다운 옵션)
- 점검 그리드 동작 규칙 (셀 토글, 비근무일, 자동 판정)
- 비즈니스 규칙 정리 (권한, 사진 제한 등)
2026-03-12 13:31:34 +09:00
김보곤
1330ebac01 docs: [construction-pmis] BIM 뷰어 기술 문서 추가
- Three.js 기반 웹 3D 건물 모델 뷰어 기술 원리 문서화
- 렌더링 파이프라인, 건물 모델 생성, React-Three.js 연동 패턴
- INDEX.md에 문서 등록
2026-03-12 12:50:06 +09:00
김보곤
5d2933c176 docs: [equipment] API Phase 1 구현 현황 문서 업데이트
- 상태 변경: API+React 미구현 → API Phase 1 완료
- API 구현 현황 섹션 추가 (모델, 서비스, 컨트롤러, 라우트 26개)
- MNG→API 변환 규칙, DB 연결 분리 설명 추가
- Phase 로드맵 (Phase 1 완료, Phase 2-3 미착수)
2026-03-12 12:19:28 +09:00
김보곤
6b4eae5252 docs: [equipment] 설비관리 화면 설계 스토리보드 PPTX 생성
- 9개 화면 14슬라이드 기획서
- 대시보드, 대장CRUD, 점검그리드, 수리이력, Import
2026-03-12 12:19:28 +09:00
김보곤
366d51fcd1 docs: [equipment] API+React 서비스 구축 계획 수립 2026-03-12 12:19:28 +09:00
김보곤
9643994e2c docs: [equipment] 설비관리 R&D 현황 문서 업데이트
- MNG 완료된 전체 구현 현황 상세 문서화
- DB 테이블 6개, ERD, 주요 컬럼 명세
- 모델/서비스/컨트롤러/뷰/라우트 구조
- InspectionCycle 6주기, 비즈니스 규칙
- API+React 서비스 구축을 위한 참조 문서
2026-03-12 12:19:28 +09:00
김보곤
f6374867ac docs: [system] Untitled UI 도입 검토 문서 추가
- Figma/React UI Kit 가격 및 제품 비교
- SAM 현재 디자인 시스템(shadcn/ui)과 호환성 분석
- 도입 방안 3가지 및 시기별 권장안
2026-03-12 12:19:28 +09:00
김보곤
dc2806b698 docs: [system] React 컴포넌트 아키텍처 현황 문서 추가
- Atomic Design 적용 현황 분석 (이상 vs 현실)
- Import 비율: ui/ 직접 83.7%, 계층 경유 16.2%
- 핵심 컴포넌트 사용 빈도 TOP 10
- 테마 시스템 (light/dark/senior)
- 신규 화면 개발 가이드
2026-03-12 12:19:28 +09:00
김보곤
e7bc9232fa docs: [email] features/email 기능 문서 추가
- features/email/README.md 신규 생성 (기능 개요, 아키텍처, 테이블, 서비스, 라우트)
- INDEX.md features 섹션에 이메일 시스템 항목 추가
2026-03-12 12:19:28 +09:00
김보곤
73d64d4b03 docs: [email] 테넌트 이메일 연동 가이드 추가
- 테넌트 메일 연동 기술문서 신규 작성 (SMTP 프리셋, MNG 관리 화면, 연결 테스트)
- 기존 email-policy.md에 연동 가이드 참조 추가
- INDEX.md에 이메일 연동 문서 등록
2026-03-12 12:19:28 +09:00
유병철
65b6a27479 docs: [frontend] 동적 멀티테넌트 페이지 시스템 JSONB 저장 방식 확정
- JSONB vs JSON 비교 및 채택 근거 추가
- DB 테이블 구조 제안 (page_configs)
- JSONB가 config 설계에 미치는 영향 정리
- 백엔드 협의 필요 사항 업데이트
- 문서 버전 1.1 → 1.2
2026-03-11 22:33:38 +09:00
김보곤
f4620889da fix: [pricing] 파일 저장 공간 추가요금 10만원→5만원 변경
- customer-pricing.md
- 서비스 이용계약서 (01-service-agreement.md)
- CHANGELOG.md
- 요금 슬라이드 (slide-05.html)
2026-03-11 21:55:19 +09:00
김보곤
5c7685f6aa docs: [email] 멀티테넌시 이메일 정책 문서 및 발표자료 추가
- 이메일 발송 정책 기술문서 (dev/standards/email-policy.md)
- 개발팀 설명용 PPTX 12슬라이드 (presentations/sam-email-policy.pptx)
- INDEX.md에 이메일 정책 문서 등록
2026-03-11 21:47:36 +09:00
김보곤
26bd2e024a docs: [approval] MNG↔API 비교 분석 및 React 구현 가이드 추가
- MNG 결재관리 개발 히스토리 (7단계, ~90커밋)
- MNG vs API 기능 비교 매트릭스
- API 반영 현황 및 미반영 항목 정리
- React 구현 시 참조 파일 가이드
- 구현 우선순위 Phase A~D 제안
2026-03-11 21:12:26 +09:00
김보곤
1eaf6564e5 docs: [barobill] 바로빌 회계 데이터 REST API 명세 추가
- 카드 거래/은행 거래/홈택스 세금계산서 42개 엔드포인트 명세
- 아키텍처, 데이터 패턴, 분개 시스템, 구현 파일 목록 포함
- INDEX.md에 문서 등록
2026-03-11 19:53:11 +09:00
김보곤
dbc34e826d docs: [payroll] 프론트엔드 개발 가이드 추가
- 급여관리 화면 구성 와이어프레임 (목록, 등록/수정 폼, 명세서)
- 계산 미리보기, 법정공제 수동입력 등 구현 유의사항
- 상태별 UI 제어, 에러 처리 가이드
- 월간 워크플로우 안내
2026-03-11 19:47:34 +09:00
김보곤
764ef9f82a docs: [approval] 결재관리 통합 계획서 현행화
- P1~P4 완료 상태 반영 (설계 중 → P1~P4 완료)
- 현재 구현 현황 (45 라우트, 48 서비스 메서드) 추가
- API/MNG 기능 비교표를 실제 코드 기준으로 갱신
- 남은 작업: P5(Leave 연동), P6(테스트), 병렬결재/위임 inbox 검증
2026-03-11 19:40:29 +09:00
김보곤
e83954eddd docs: [payroll] 급여관리 API 프론트엔드 연동 명세서 추가
- 18개 엔드포인트 전체 명세 (CRUD, 상태변경, 일괄생성, 미리보기 등)
- 4대보험/근로소득세 계산 엔진 설명
- 상태 흐름도 (draft → confirmed → paid)
- 프론트엔드 구현 가이드 및 UI 와이어프레임
- INDEX.md에 문서 등록
2026-03-11 19:30:00 +09:00
김보곤
593bef9e5d docs: [payroll] 급여관리 API 구현 기획서 작성
- MNG 급여관리 시스템 → API 이식 3단계 계획 수립
- Phase 1: 핵심 계산 엔진 (소득세, 4대보험, 공제 오버라이드)
- Phase 2: 상태 관리 + 일괄 처리 (unconfirm, unpay, bulkGenerate)
- Phase 3: 문서 생성 (PDF 명세서, 전표 변환, 엑셀 내보내기)
- INDEX.md에 문서 등록
2026-03-11 18:04:10 +09:00
김보곤
5493788800 docs: [approval] 결재관리 API 프론트엔드 연동 명세서 추가
- 28개 엔드포인트 전체 명세 (요청/응답 포맷 포함)
- 상태 흐름도, 탭 구성, 버튼 조건 등 UI 가이드
- INDEX.md에 frontend/api-specs/ 섹션 등록
2026-03-11 17:40:53 +09:00
김보곤
5517b7f04d docs: [esign] 근로계약서 최신 연봉정보 반영 문서화
- features/esign/README.md: 근로계약서 사원 연동 섹션 추가
- projects/e-sign/changelog.md: v1.1.1 변경 이력 추가
- rules/employee-api.md: 전자계약 연동 참조 추가
- dev/changes/20260311: esign 연봉정보 개선 내용 추가
2026-03-11 17:04:27 +09:00
유병철
5cd97962b4 docs: [frontend] v2 동적 멀티테넌트 페이지 시스템 설계 초안 추가
- v2/01-dynamic-multi-tenant-page-system.md 신규 작성
- _index.md에 v2 섹션 및 문서 목록 추가
- 빠른 참조 가이드에 v1/ 경로 접두사 반영

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:56:34 +09:00
김보곤
6959fd8fcf docs: [hr] 연봉이력 삭제 기능 문서화
- rules/employee-api.md: 연봉 API 엔드포인트 및 데이터 구조 추가
- system/database/hr.md: salary_info JSON 구조 추가
- dev/changes/20260311_salary_history_delete.md: 변경 이력 생성
- INDEX.md: 변경 이력 등록
2026-03-11 16:49:22 +09:00
김보곤
ab0178517e docs: [approval] 결재관리 시스템 통합 계획서 작성
- MNG→API 결재 기능 이식 6단계 계획
- 모델/서비스/엔드포인트/위임/Leave연동 범위 정리
- INDEX.md에 결재관리 필수 문서 등록
2026-03-11 16:46:54 +09:00
김보곤
8ba4a60aa2 docs: [changes] 전자서명 체크박스, 전표 적요 동기화, 거래처 드롭다운, 바로빌 중복 키 수정 이력 추가 2026-03-11 15:51:54 +09:00
cb77190cd6 docs: [standards] DomPDF 사용 가이드 전면 재작성
- 인스턴스 규칙, setOptions 금지, chroot/symlink 주의사항 추가
- font-weight 800 금지, 서브셋팅 경량화 섹션 병합
- 배포 환경(릴리스/shared) 대응 가이드 포함
2026-03-11 14:00:27 +09:00
d727673e54 docs: 서버 접근 권한 문서 업데이트 (v1.3)
- OS 그룹 현황 섹션 추가 (webservice/develop 그룹 역할, 서버별 구성)
- Jenkins 롤백 기능 문서화 (파라미터, 동작 방식, 릴리스 보관)
- sam-cicd pro 계정 현황 추가
- OS 잠금 시 DB 접근 차단 참고사항 추가
- "외부 인원" → "서브 관리자" 문구 수정
- 변경 이력: develop 그룹 삭제(prod/cicd), pro 계정 잠금(prod/cicd)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:58:36 +09:00
김보곤
e03541b678 docs: [pdf] 폰트 정책 NanumGothic → Pretendard 전환 반영 2026-03-11 11:50:37 +09:00
김보곤
909eb58307 docs: CLAUDE.md PDF 폰트 정책 필수 규칙 추가 2026-03-11 11:05:53 +09:00
김보곤
df19310c2e docs: [standards] PDF 폰트 정책 — 프로젝트 번들링 방식으로 전환
- 시스템 폰트(fonts-nanum) 의존 → resources/fonts/ 번들링으로 변경
- ensureKoreanFont() 코드 예시 resource_path() 방식으로 갱신
- 체크리스트, 관련 문서 경로 업데이트
2026-03-11 11:03:19 +09:00
김보곤
95bf896536 docs: [standards] PDF 경량화 설정 및 font-weight 주의사항 추가
- 폰트 서브셋팅(enable_font_subsetting) 필수 설정 추가
- font-weight 800 이상 사용 금지 규칙 추가
- 섹션 번호 정리 (5.경량화, 6.수정가이드, 7.긴급복구, 8.체크리스트)
2026-03-11 10:50:06 +09:00
김보곤
f0d7a29be9 docs: [db] codebridge DB 분리 문서에 크로스 DB FK 제거 내용 추가
- 깨진 FK 제약조건 52개 제거 (users, tenants 등 참조) 문서화
- 운영 서버 적용 절차 5단계 → 6단계로 개정 (API 마이그레이션 단계 추가)
2026-03-11 10:32:50 +09:00
김보곤
06ce65576c docs: [changes] 자금일보 동기화 및 계정과목 정리 변경이력 추가
- 20260311 변경이력 문서 추가
- INDEX.md에 dev/changes/ 섹션 추가
2026-03-11 10:32:42 +09:00
김보곤
d1d6a56702 docs: [standards] PDF 폰트 정책 업데이트
- NanumGothic 표준 폰트 + ensureKoreanFont 자동 등록 패턴 반영
- DomPDF 미등록 폰트(Malgun Gothic 등) 단독 사용 금지 추가
- storage/fonts/ 캐시 구조 및 서버 환경 체크리스트 추가
2026-03-11 09:56:13 +09:00
김보곤
909d3e11b8 docs: [standards] PDF 생성 시 폰트 정책 추가
- 구글 폰트 외부 로드 금지, isRemoteEnabled 금지
- 운영서버 권한 오류 사례 및 긴급 복구 절차
- 시스템 기본 폰트 사용 가이드, 로컬 폰트 설치 방법
2026-03-11 09:39:41 +09:00
김보곤
1407893c26 docs: [guides] Claude Code → 슬랙 붙여넣기 가이드 추가
- 터미널 줄바꿈 혼재, Markdown vs mrkdwn 차이, 슬랙 공백 처리 원인 분석
- 클코 to 슬랙 변환기 사용법 안내
- 리치 텍스트 복사 작동 원리 설명
2026-03-11 09:35:39 +09:00
김보곤
0cd445b546 docs: [payroll] 급여관리 문서 전면 개정
- 상태 워크플로우, 슈퍼관리자 권한 추가
- 일반전표 변환 분개 구조 상세 기술
- 기타공제 수기 입력 주의사항 명시
- 멀티테넌트 확장 계획 추가
- MNG API 엔드포인트 전체 목록
2026-03-11 07:06:03 +09:00
84fae0041a docs: [QMS] API 연동 계획 상태 업데이트 (Phase 1~3 구현 완료)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:53:23 +09:00
47cef8be96 docs: [QMS] API 연동 계획 문서 보강 — 아키텍처 결정 사항 및 실제 코드 기반 상세화
- IQC 추적 경로: StockLot 직접 → WorkOrderMaterialInput 경유로 수정 (생산입고 vs 투입 관계)
- actions.ts: executeServerAction + buildApiUrl + ActionResult<T> 프로젝트 표준 적용
- snake→camelCase 변환 레이어 및 API 원본 타입 추가
- 필드명 수정: order_code→order_no, order_date→received_at, orderNodes()→nodes()
- 상태 관리 커스텀 훅 설계 (useDay1Audit, useDay2LotAudit) 및 로딩 세분화
- confirm 토글 원자성 보강, null 방어, FormRequest 추가
- Phase 3 일정 재산정 (2.5일→4.5일, 총 9일→11.5일)

- 아키텍처 결정 사항 7건 추가 (2단계 로딩, FG 제품명, 채번 형식, StockLot 기반 IQC, 비관적 업데이트, subType, PR 없는 문서 처리)
- 프론트엔드 상세 구조 추가 (types.ts 전체, page.tsx 상태/핸들러, mockData 계층, 컴포넌트 목록)
- 백엔드 기존 코드 참조 추가 (모델/서비스/컨트롤러 경로, DB 스키마 4개 테이블, 모델 관계 맵)
- 구현 패턴 가이드 추가 (Controller/Service/FormRequest/Model/API 응답/라우트 코드 예시)
- 8종 서류 조합 의사 코드 및 API 응답 매핑 코드 추가
- Phase별 체크리스트 보강

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:53:23 +09:00
유병철
b1f276aa9d Merge branch 'main' of http://114.203.209.83:3000/SamProject/sam-docs 2026-03-10 17:34:10 +09:00
유병철
7701677418 chore: .gitignore 변경 되돌리기
- 잘못 포함된 frontend 폴더 추적 허용 제거
2026-03-10 17:33:39 +09:00
유병철
e34796a53f docs: [frontend] 브라우저 네비게이션 규칙 문서 추가
- AI/E2E 자동화 시 URL 추측 금지, 메뉴 클릭 필수 규칙
- .gitignore에 frontend 폴더 추적 허용
- _index.md에 11번 문서 항목 추가
2026-03-10 17:32:05 +09:00
cf0c128764 chore: .gitignore 화이트리스트→블랙리스트 방식으로 변경
- 기존: 모든 파일 무시(*) + 폴더별 허용(!path) → 새 파일 추가 시 git add -f 필요
- 변경: 쓰레기 파일만 제외 (.DS_Store, *.log, *.tmp 등)
2026-03-10 09:51:32 +09:00
김보곤
13a5a56146 docs: 개발서버 sam-docs 폴더에서 누락 문서 5건 복구
- guides/project-launch-roadmap.md
- plans/SAM_ERP_Storyboard_D1.4.md
- plans/SAM_ERP_회계관리_Storyboard_D1.6.md
- plans/integrated-master-plan.md
- plans/production-deployment-plan.md
2026-03-10 09:28:07 +09:00
김보곤
ee1aaf183d chore: .claude 폴더를 git 추적에서 제외 (로컬 전용) 2026-03-09 23:06:34 +09:00
김보곤
c143c7e9f8 chore: CLAUDE.md를 git 추적에서 제외 (로컬 전용) 2026-03-09 23:02:30 +09:00
7a969b9d57 refactor: [structure] sam/ 하위 문서를 docs 루트로 재배치
- .gitignore를 sam/ 기반에서 루트 기반으로 변경
- sam/docs/ 하위 문서를 루트로 이동 (contracts, features, guides, plans 등)
- sam/ 폴더 삭제 (docker, coocon 포함)
2026-03-09 22:53:07 +09:00
cc38b00c11 refactor: [structure] sam/ 하위 문서를 docs 루트로 재배치
- sam/docs/ 하위 62개 신규 파일을 루트로 이동 (contracts, features, guides, plans 등)
- sam/docs/ 하위 52개 변경 파일을 루트에 덮어쓰기 (brochure, rules 등)
- sam/ 폴더 전체 삭제 (docker, coocon 포함)
2026-03-09 22:36:16 +09:00
bfcd6178ea docs: [quality] 품질관리 시스템 기능 문서 작성
- README.md: 전체 개요, 역할별 프로세스 플로우, 메뉴 구조, 데이터 구조, API, 스토리보드 참조
- inspection-management.md: 제품검사 관리 (15개 검사항목, 상태판정, 캘린더뷰, 요청서/성적서 양식)
- performance-reports.md: 생산실적신고 (자동생성, 확정, 누락체크, 건기원 프로세스)
- quality-certification-audit.md: 품질인정심사 (기준/매뉴얼 심사 + 로트 추적 심사)
- INDEX.md에 품질관리 문서 등록
2026-03-09 22:36:15 +09:00
04e877dea3 docs: [ops-manual] sam-dev 서버 유지보수 정책 문서화
- 01-server-overview: sam-dev 서비스 현황 갱신 (Swap, PHP 5.6/Apache 비활성화, cron 정리)
- 02-daily-operations: sam-dev 리소스 관리 섹션 추가 (Swap, Gitea 캐시, 비활성 서비스)
- 06-database: sam-dev binlog 7일 보관 정책 추가
2026-03-09 22:36:15 +09:00
85dc30bfcd docs: [infra] 서버 정보 오류 수정 (ops-manual 기준 정렬)
- server-access-management.md: sam-cicd IP 정정 (114.203.209.83 → 110.10.147.46), sam-dev 추가, DB 계정/백업 경로 갱신, 리플리케이션 섹션 제거
- CLAUDE.md: dev 서버에서 Jenkins 제거 (Jenkins는 cicd 서버), MySQL 8.0 → 8.4, Next.js 포트 수정
2026-03-09 22:36:15 +09:00
김보곤
e94123ad49 docs: [rd, approvals] 누락 문서 2건 복원
- features/rd/sound-logo-studio.md (사운드 로고 스튜디오)
- dev/changes/20260306_purchase_request_payment_method.md (품의서 지급방법)
2026-03-09 22:29:07 +09:00
김보곤
1f7bd13816 docs: [database] codebridge 분리 문서 최종 상태 업데이트
- 운영서버 revert 사유 및 교훈 기록
- 로컬 samdb 58개 삭제, 로컬/개발 265개 동기화 반영
- DevTools 테이블 실제 이름(admin_ prefix) 수정
- 운영서버 적용 절차 5단계로 개정 (DB 선행 필수)
2026-03-09 21:32:47 +09:00
김보곤
03ccd7ba93 docs: [database] codebridge 분리 문서 최종 업데이트
- Equipment 하위 4개 테이블 추가 (55→59개)
- 개발 서버 samdb에서 59개 테이블 삭제 완료 반영
- 테이블명 불일치 수정 (api_bookmarks→admin_api_bookmarks 등)
- 운영 서버 적용 절차 4단계로 구체화
2026-03-09 21:02:50 +09:00
김보곤
ec3abc1a85 docs: [approvals] 결재관리 DB 변경사항 및 API 모델 동기화 현황 문서 작성
- 2026-02-27 ~ 03-05 마이그레이션 15개 변경 타임라인 정리
- API/MNG 모델 $fillable/$casts 동기화 비교표 작성
- API 모델 미반영으로 인한 잠재적 오류 영향 분석
2026-03-09 20:34:11 +09:00
김보곤
5000c67ec1 docs: [database] codebridge 분리 대상에서 API 사용 테이블 22개 제외
- Barobill 12개: API 모델/서비스/컨트롤러에서 직접 사용
- ESign 4개: API 전자계약 기능 (EsignService, EsignContractController)
- Audit 2개: API 전사 감사 시스템 (AuditLogService, TriggerAuditLogController)
- DevTools 1개: api_request_logs (SystemStatService)
- System 2개: ai_pricing_configs, ai_token_usages (API 모델)
- HR 1개: income_tax_brackets (API Seeder)
- codebridge 이동 대상 100개 → 55개로 축소
2026-03-09 19:58:07 +09:00
925ed82ae1 docs: 신규 개발자 로컬 환경 셋팅 가이드 추가
- Docker 기반 로컬 개발 환경 전체 셋팅 절차
- api, mng, react, docs, hotfix 5개 저장소 설명
- SSL 인증서, hosts, 환경변수, 트러블슈팅 포함

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:21:39 +09:00
유병철
8f939d3609 docs: [frontend] 프론트엔드 아키텍처/가이드 문서 v1 작성
- _index.md: 문서 목록 및 버전 관리
- 01~09: 아키텍처, API패턴, 컴포넌트, 폼, 스타일, 인증, 대시보드, 컨벤션
- 10: 문서 API 연동 스펙 (api-specs에서 이관)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:24:25 +09:00
김보곤
2efe56df70 docs: [plans] 방화셔터 도면생성 기능 기획서 작성
- 가이드레일 단면도 + 셔터박스 단면도 + 3D 렌더링 4탭 구성
- 파라미터 기반 SVG 실시간 렌더링 + Three.js 3D 조립체
- 기존 자동도면 생성 아키텍처 확장 (순수 클라이언트 측)
- 4단계 개발 계획: 가이드레일 → 셔터박스 → 3D → 출력/프리셋
2026-03-08 19:20:23 +09:00
김보곤
129332d4b1 Merge remote-tracking branch 'origin/main' 2026-03-08 15:11:09 +09:00
김보곤
4d13301ce0 docs: [plans] 사운드 로고 생성기 기획서 고도화
- 모드 C를 Lyria RealTime(WebSocket, 브라우저 직접) + Lyria 2(REST, 폴백) 듀얼 구조로 개편
- 별도 API 키 발급 불필요 확인 (기존 Gemini API 키 + Vertex AI 서비스 계정 재활용)
- API 인증 현황, Lyria RealTime/Lyria 2 사양, 공식 문서 참조 추가
2026-03-08 12:09:51 +09:00
김보곤
7c9f7afb52 docs: [plans] 사운드 로고 생성기 기획서 작성
- 3가지 모드 설계: 수동(Web Audio), AI 어시스트(Gemini), AI 자동(Lyria)
- 기존 BgmService/CmSongController 인프라 재활용 계획
- 4 Phase 개발 로드맵, UI 레이아웃, API 설계 포함
2026-03-08 12:05:03 +09:00
김보곤
8e700fcd64 docs: [rd] 디자인 인사이트 기능 문서 추가
- features/rd/design-insight.md 신규 작성 (아키텍처, 카드/카테고리 체계, CSS 와이어프레임, AI 프롬프트 복사)
- features/rd/README.md에 디자인 인사이트 메뉴·컨트롤러·관련 문서 등록
- INDEX.md에 디자인 인사이트 문서 등록
2026-03-08 11:22:09 +09:00
김보곤
ba68e138e6 docs: [plans] UI/UX 디자인 인사이트 연구 메뉴 기획서 작성
- 기획디자인 모티브의 UI/UX 연구 도구 기획
- 4종 인사이트 카드 (레퍼런스/분석/패턴/Before-After)
- CRAP 디자인 원칙 체크리스트
- 4 Phase 개발 로드맵
2026-03-08 09:43:17 +09:00
김보곤
95b9efbcc5 docs: [planning-design] v1.2 작업 영역 극대화 기능 문서 업데이트
- 사이드바/Description 패널 접기/펼치기 기능 추가
- 캔버스 폭 자동 확장 (1100→1400px) 반영
- 이미지 블록 더블클릭 업로드 변경 반영
- 파일 줄 수 4,300→4,430줄 갱신
- 버전 v1.1 → v1.2 갱신
2026-03-08 09:30:14 +09:00
김보곤
2dc20952b2 docs: [projects] 기획디자인 스토리보드 에디터 프로젝트 문서 추가
- projects/planning-design/README.md: 프로젝트 개요, 구현 이력(v1.0~v1.1), 로드맵
- index_projects.md에 planning-design 프로젝트 등록
2026-03-08 08:46:37 +09:00
김보곤
428e77aa9b docs: [rd] R&D 기획디자인 스토리보드 에디터 기술문서 추가
- features/rd/README.md: R&D 메뉴 전체 개요 (라우트, 컨트롤러, 기능현황)
- features/rd/planning-design.md: 기획디자인 에디터 상세 기술문서
  - 블록 유형 15종, 데이터 구조, 서식 시스템
  - 올가미 다중 선택, Undo/Redo, 키보드 단축키
  - 플로팅 서식 툴바, 우클릭 컨텍스트 메뉴
  - HTML 내보내기, 좌표 기반 인쇄
- INDEX.md에 R&D 문서 등록
2026-03-08 01:35:33 +09:00
03850fefdd docs: 서버 접근 권한 관리 문서 업데이트
- 운영 관리자 정보 추가 (hskwon/권혁성, pro/김보곤)
- 서버 시간대 설정 정리 (OS, PHP CLI/FPM, Laravel)
- develop 그룹 + setgid 공동 관리 구조 추가
- DB 리플리케이션 현황 (sam, sam_stat, codebridge)
- DB 백업 설정 (/data/ 경로, codebridge 포함)
- sam-dev 서버 정보 추가
- INDEX.md에 서버 접근/백업 문서 등록

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:28:08 +09:00
cf189fd453 docs: FQC 문서 시스템 계획 Phase 3 완료 (100%)
- Phase 3 통합 테스트 전체 통과
- 검증 결과 및 테스트 시나리오 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 22:02:51 +09:00
b1472f3c35 docs: FQC 문서 시스템 계획 Phase 2 완료 (67%)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:43:07 +09:00
5bfc89afa7 docs: [제품검사] FQC 문서 시스템 계획 + 스냅샷 Lazy Snapshot 반영
- fqc-document-system-plan.md: FormRequest 상태 수정, Phase 2.4 Lazy Snapshot 확정, 참고 파일 추가
- document-snapshot-architecture-plan.md: Lazy Snapshot 캡처 원칙 추가
- server-access-management.md 신규
- README.md 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:09:57 +09:00
f1683f753e docs: [문서스냅샷] 계획 문서 보정 - API 수정, 오프스크린 렌더링, 변경이력 반영
- Phase 2 보정 내용 변경이력 3건 추가
- 참고 파일에 UpsertRequest.php, capture-rendered-html.tsx 추가
- 자기완결성 점검 작업 수 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:35:39 +09:00
김보곤
5798058125 docs: [projects] 조직도 관리 시스템 기술문서 추가
- projects/org-chart/README.md: 아키텍처, API, DB, 프론트엔드 상세
- index_projects.md: 조직도 프로젝트 등록
- INDEX.md: 조직도 문서 링크 추가
2026-03-06 20:34:06 +09:00
614e90066f docs: [제품검사] FQC 문서 시스템 구축 계획 작성 + 방법론 수정 6건
- 제품검사 성적서(template 65 보완) + 요청서(신규) 개발 계획
- 방안 C 확정(template items 완전 이관), 시더 방식, 자동 생성 확정
- 방법론 수정: 컬럼 아키텍처(template 2개+시각 8컬럼), rowSpan 복합키,
  프론트 타입 갭, measurement_type=none, Template ID 안정성, 시더 위치 명확화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:10:50 +09:00
8efe0ac477 docs: [문서스냅샷] Phase 3.3 완료 - 코드 작업 100% 완료
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:54:07 +09:00
303de36e1c docs: [문서스냅샷] Phase 2 완료 - 진행률 90% 업데이트
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:47:13 +09:00
334c8f3918 docs: 문서 스냅샷 아키텍처 계획 + 절곡 문서 매칭 계획
- document-snapshot-architecture-plan.md: B안(HTML 스냅샷) + 구조화 데이터 병행 계획
- mng-bending-document-matching-plan.md: 절곡 중간검사/작업일지 MNG 매칭 계획

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:52:27 +09:00
김보곤
6d042f5bfd docs: [approvals] 품의서 5종 상세 스펙 및 2단계 양식 선택 UI 문서화
- 품의서 5종 공통 Alpine.js 컴포넌트 구조 문서화 (섹션 9)
- 지출/계약체결/구매/출장/비용정산 품의서 Content JSON 스펙 (섹션 10~14)
- 2단계 양식 선택 UI 구조 문서화 (분류→양식 드롭다운)
- 14종 양식 설명 카드 기능 문서화
- 파일 구조에 _purchase-request-form/show 추가
- ApprovalForm 카테고리 DB/UI 분류 구분 설명
- 조회 흐름에 pr_ prefix 분기 로직 추가
2026-03-06 13:33:10 +09:00
김보곤
51446080db docs: [plans] 양식 디자이너 고도화 계획 수립 (6 Phase)
- Phase 2: 블록 런타임 렌더러 + EAV 데이터 바인딩
- Phase 3: 결재선 블록 + 워크플로우 연동
- Phase 4: 동적 테이블 + 변수/매크로 시스템
- Phase 5: 수식 엔진 + 조건부 표시 + 이미지 블록
- Phase 6: 인쇄/PDF + Legacy Builder 대체
- INDEX.md에 계획 문서 등록
2026-03-06 09:29:06 +09:00
김보곤
37bbab7cd4 docs: [documents] 문서양식관리 UI 명칭 반영 (블록 빌더 → 양식 디자이너) 2026-03-06 08:56:52 +09:00
김보곤
29117d65d4 docs: [documents] MNG 문서양식관리 기술문서 추가
- Legacy Builder / Block Builder 비교 및 상세 동작
- saveRelations ID 보존 upsert 메커니즘
- 프리셋 시스템, 연결품목 중복 검증
- 화면 구성 (목록, 편집, 블록 에디터, 미리보기)
- README에 관련 문서 링크 추가
2026-03-06 08:43:14 +09:00
김보곤
78cfc292a9 docs: [documents] MNG 문서관리 시스템 상세 기술문서 추가
- 탭별 기능 (문서목록, 서식관리, FQC현황)
- EAV 데이터 저장 패턴 상세 설명
- 서식 빌더 (Legacy/Block) 아키텍처
- 결재 워크플로우 및 자재 LOT 추적
- README에 관련 문서 링크 추가
2026-03-06 08:36:46 +09:00
김보곤
4f90c0e869 docs: [planning] 주일기업 기획 메뉴 기술문서 추가
- README.md: 전체 개요, 5개 하위 메뉴 구조, 아키텍처
- construction-photos.md: 공사현장 사진대지 (GCS, 행 구조, 음성입력)
- meeting-minutes.md: 회의록 (STT 화자분리, Gemini AI 요약, 오디오 녹음)
- planning-views.md: 견적/프로젝트/워크플로우 화면 명세
- INDEX.md: 문서 인덱스에 planning 등록
2026-03-06 08:25:20 +09:00
김보곤
09793e629b docs: [approvals] 결재 양식 기술 명세 문서 추가
- form-types.md: 6개 양식(휴가/지출결의/재직증명/경력증명/위촉증명/사직서) 필드 구조, JSON Content, UI 인터랙션 명세
- README.md: 문서 구조에 form-types.md 링크 추가
2026-03-06 08:09:56 +09:00
0223c33fd9 docs: [품질관리] 개발 계획 Phase 4 프론트엔드 API 연동 완료 업데이트
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:45:27 +09:00
db63fcff85 refactor: [docs] 팀별 폴더 구조 재편 (공유/개발/프론트/기획)
- 개발팀 전용 폴더 dev/ 생성 (standards, guides, quickstart, changes, deploys, data, history, dev_plans 이동)
- 프론트엔드 전용 폴더 frontend/ 생성 (api/ → frontend/api-specs/)
- 기획팀 폴더 requests/ 생성
- plans/ → dev/dev_plans/ 이름 변경
- README.md 신규 (사람용 안내), INDEX.md 재작성 (Claude Code용)
- resources.md 신규 (노션 링크용, assets/brochure 이관 예정)
- CURRENT_WORKS.md 삭제, TODO.md → dev/ 이동
- 전체 참조 경로 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:46:03 +09:00
7e1daca81b docs: [생산지시] 개발 계획 진행 상태 업데이트 (Phase 1~3 완료)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:42:08 +09:00
a320c85e94 docs: [quality] 품질관리 스토리보드 D1.9 분석 문서 작성
- 17장 슬라이드 기반 개발 참조용 MD 문서
- 화면별 상세 명세 (제품검사, 실적신고, 품질인정심사)
- 데이터 모델, 비즈니스 규칙, API 엔드포인트 설계 포함

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:37:31 +09:00
김보곤
ee42b12c2b docs: [changes] 계좌 입출금내역 무한루프 버그 분석 문서 추가
- 근본 원인: splitDateRangeMonthly() cursor 이동 버그
- 재현 조건, 검증 결과, 교훈/방지 규칙 포함
- 코드베이스 전체 유사 패턴 점검 결과 포함
2026-03-04 13:32:06 +09:00
김보곤
4c581ad7f5 docs: [ai] Gemini 2.5-flash 마이그레이션 문서 추가
- AI 관리 종합 가이드 신규 (ai-management.md)
- 모델 업데이트 워크플로우 신규 (ai-model-update-workflow.md)
- 변경 이력 기록 (20260303_gemini_model_upgrade.md)
- AI 설정 기술문서 모델명 업데이트
- INDEX.md에 AI 문서 3건 등록
2026-03-03 08:09:12 +09:00
김보곤
52417acad6 docs: [credit] 신용평가 시스템 내부 문서 추가
- 쿠콘 API 연동, 국세청 API, DB 구조, 과금 정책 등 정리
2026-03-02 18:40:30 +09:00
김보곤
8cb15cf3c4 docs: [guides] 테이블 설계 가이드 비전문가용 문서 추가
- options JSON 컬럼 패턴을 엑셀 비유로 쉽게 설명
- 멀티테넌시(tenant_id) 개념 해설
- 실제 SAM 테이블 예시 (주문, 입고, 공정)
- FAQ 5개, 판단 흐름도, 한 장 요약 포함
- INDEX.md에 문서 등록
2026-03-02 17:15:25 +09:00
김보곤
a3c910d91b docs: [CLAUDE.md] options JSON 컬럼 정책 필수 참조 규칙 추가
- 테이블 생성/수정 시 options-column-policy.md 참조 의무화
- 전용 컬럼 vs options JSON 분류 기준 요약 포함
- 필수 준수 사항 및 작업 전 체크리스트 추가
2026-03-02 17:06:50 +09:00
김보곤
f8c4536331 docs: [ai-quotation] STT/음성 녹음 현황 반영 — 미구현→구현완료 업데이트
- 음성 녹음 섹션: 기초만→구축 완료로 변경 (GoogleCloudService, AiVoiceRecordingService 등)
- Phase 2: 기존 STT 인프라 재사용 반영, 기간 2주→1주 단축
- 참조 구현 파일 목록 추가
2026-03-02 15:27:41 +09:00
김보곤
23570d3ee9 docs: [vision] SAM AI 자동화 비전 문서 및 PPTX 슬라이드 추가
- docs/system/ai-automation-vision.md 장기 비전 기술문서 생성
- docs/rules/slides/usage-plan/ 7장 HTML 슬라이드 + PPTX 변환
- INDEX.md에 ai-automation-vision.md 등록
2026-03-02 13:25:26 +09:00
김보곤
b8fa244271 docs: [brochure] v7 1page 개선 - 히어로 SVG, Before/After, 기술태그 추가
- 히어로 섹션에 대시보드 모니터 SVG 아이콘 추가
- Before/After 인포그래픽 추가
- 6대 핵심기능 2열 그리드 + SVG 아이콘
- 기술 태그 5개 (실시간, PC+모바일, 역할별 권한, 데이터 암호화, 클라우드)
- PPTX 재생성
2026-03-01 19:37:52 +09:00
김보곤
4c9fd233cc docs: [brochure] v6~v9 CEO Dashboard 브로셔 4종 추가
- v6: Corporate Blue & White (대기업/공공기관 스타일)
- v7: Warm Gray + Teal (IT/SaaS 스타일)
- v8: Two-Tone Navy/White Split (금융/컨설팅 스타일)
- v9: Minimal White + Indigo (Apple/디자인 에이전시 스타일)
- README.md에 v6~v9 디자인 컨셉 문서화
2026-03-01 19:35:32 +09:00
김보곤
8769b68ef0 docs: [brochure] v1~v5 버전별 디자인 컨셉 README 문서화
- 버전별 컬러 팔레트, 디자인 컨셉, 콘텐츠 구성 정리
- 폴더 구조 및 PPTX 변환 주의사항 포함
2026-03-01 19:22:02 +09:00
김보곤
132c573ab9 fix: [brochure] v5 PPTX 빈 파일 수정 - body 그래디언트 → 단색 변경
- html2pptx가 CSS gradient 검출 시 슬라이드 생성 전에 throw하여 빈 PPTX 생성됨
- body background를 단색(#1A1640)으로 변경, 그래디언트는 convert 스크립트에서 PNG로 덮어쓰기
- 구분선 gradient도 solid rgba로 교체
2026-03-01 19:06:55 +09:00
김보곤
415c55b7c0 docs: [brochure] v5 Premium Executive Gradient 브로셔 생성
- 네이비→인디고 그래디언트 배경 + 골드 액센트 디자인
- 글래스모피즘 카드, SVG 아이콘 적용
- Sharp로 그래디언트 배경 PNG 사전 렌더링 (PPTX 호환)
- 앞면/뒷면/1페이지 통합본 + PPTX 변환 스크립트
2026-03-01 18:28:21 +09:00
김보곤
66db1832da refactor: [brochure] docs/brochure-vN → docs/brochure/vN 구조로 통합
- docs/brochure/ → docs/brochure/v1/
- docs/brochure-v2/ → docs/brochure/v2/
- docs/brochure-v3/ → docs/brochure/v3/
- docs/brochure-v4/ → docs/brochure/v4/
- docs 하위 폴더를 큰 단위로 유지
2026-03-01 18:12:38 +09:00
김보곤
d5e6172c22 fix: [brochure] v3/v4 Before/After 텍스트 줄바꿈 방지
- <br> 멀티라인 <p>를 개별 <p> + white-space: nowrap으로 분리
- PPTX 렌더링 시 <span> 텍스트가 다음 행으로 넘어가는 문제 해결
- html2pptx 엔진이 nowrap 감지 → wrap: false 적용
2026-03-01 17:48:41 +09:00
김보곤
08577b5af9 fix: [brochure] v3/v4 Before/After 카드 하단 패딩 12pt로 확대
- PPTX 렌더링 시 AFTER 카드 마지막 줄 잘림 현상 수정
- Before/After 카드 하단 padding: 5pt → 12pt
2026-03-01 17:45:32 +09:00
김보곤
7b45b4c635 fix: [brochure] v4 1page Before/After 카드 하단 텍스트 넘침 수정
- Before/After 카드 padding 5pt → 5pt 6pt 8pt 6pt로 하단 여백 확대
- PPTX 폰트 렌더링 차이로 마지막 줄이 카드 경계를 벗어나는 문제 해결
2026-03-01 17:43:09 +09:00
김보곤
1f06c1a607 docs: [brochure] v4 밝은 배경 CEO Dashboard 브로셔 생성
- v3 다크 테마(#0B1929) → v4 라이트 테마(#F8FAFC)로 변환
- 텍스트 색상: 흰색 → 슬레이트 계열(#0F172A, #475569, #94A3B8)
- 카드 배경: 반투명 다크 → 화이트 + 그림자/테두리
- BI 로고: sam_bi_white → sam_bi_black
- 앞면/뒷면/1page 통합본 HTML + PPTX 변환 스크립트 포함
2026-03-01 16:44:43 +09:00
김보곤
00d7a583cb docs: [guides] HTML → PPTX 변환 도구 사용법 가이드 추가
- 슬라이드 작성법, 변환 스크립트 구조, 실행 방법 포함
- 기존 사용 사례, 문제 해결, 빠른 시작 가이드 포함
2026-03-01 13:02:43 +09:00
김보곤
8be729c698 docs: [brochure] SAM 전체 프로젝트 범용 영업 브로셔 생성
- 1장/2장 브로셔 HTML 슬라이드 및 PPTX 생성
- usecase 방화셔터 브로셔 패턴 활용, 범용 제조업 타깃으로 변환
- 핵심 모듈 8종, 가격 체계, 도입 프로세스, 기대 효과 포함
2026-03-01 12:52:45 +09:00
김보곤
9c5443aec1 docs: [interview] 마스터 질문 SQL에 parent_id 계층 구조 반영
- 대분류 '제조업-방화셔터' INSERT 추가
- 8개 도메인 카테고리에 parent_id=@root_manufacturing 설정
2026-02-28 21:23:36 +09:00
김보곤
5d76705f4f fix: [interview] SQL 파일 한글 인코딩 깨짐 수정
- SET NAMES utf8mb4 추가하여 double-encoding 방지
2026-02-28 21:02:22 +09:00
김보곤
b52c31a700 docs: [interview] 인터뷰 마스터 질문 SQL 파일 추가
- 8개 도메인 × 16개 템플릿 × 80개 질문
- 시더 대신 직접 SQL INSERT 방식
2026-02-28 20:24:54 +09:00
김보곤
490477421d docs: [approvals] 결재관리 시스템 문서 4종 작성
- README.md: 시스템 개요, 아키텍처, DB 스키마, 상태 관리, 권한 매트릭스
- workflows.md: 워크플로우 상세 (승인/반려/회수/보류/전결/복사재기안)
- api-reference.md: API 엔드포인트 20개 명세
- ui-screens.md: UI 화면 구성 및 인터랙션
- INDEX.md에 결재관리 문서 등록
2026-02-28 00:09:08 +09:00
김보곤
359dc5d029 docs: CLAUDE.md MNG 커밋 즉시 자동 푸시 정책 추가
- MNG: 커밋 후 develop push + main cherry-pick 자동 실행
- API/React: 기존 트리거 워드 방식 유지
2026-02-27 12:59:47 +09:00
김보곤
0123c3d780 docs: CLAUDE.md 운영서버 푸시 대상에 API 추가 2026-02-27 09:34:20 +09:00
김보곤
fc97dfe454 revert: CLAUDE.md DB 마이그레이션 정책 원래대로 복원 2026-02-27 09:30:10 +09:00
김보곤
0ae6eec973 docs: CLAUDE.md DB 마이그레이션 정책 변경 (MNG 허용) 2026-02-27 09:24:17 +09:00
김보곤
d24a19a3f1 docs: [esign] 전자계약 알림톡/SMS 환경별 설정 가이드 작성
- esign-notification-guide.md 신규 작성 (환경별 설정, 역할 기반 알림, 템플릿 분기)
- README.md 현황 업데이트 (완료 템플릿, OTP SMS, 환경별 분기 반영)
- INDEX.md에 새 문서 등록
2026-02-27 08:26:14 +09:00
김보곤
ac35c5c0f9 docs: [attendance] MNG 근태현황 개발 계획서 작성
- Phase 1: 버그 수정, 엑셀 다운로드, 일괄 삭제, 통계 기간 선택
- Phase 2: 개인별 상세, 출퇴근 설정, 월간/주간 요약, 일괄 등록
2026-02-26 20:32:43 +09:00
김보곤
fd60e51ac9 docs: CLAUDE.md 운영서버 SSH 접근 불가 정책 추가 2026-02-25 17:10:18 +09:00
김보곤
dd3b045c46 docs: CLAUDE.md 운영서버 푸시를 cherry-pick 방식으로 변경 2026-02-25 17:01:36 +09:00
김보곤
62fdc6869b docs: CLAUDE.md MNG 운영 브랜치 master→main 통일 2026-02-25 15:46:03 +09:00
김보곤
d44b99d5e4 docs: CLAUDE.md 푸시 정책 트리거 워드 기반으로 개편
- "개발서버 푸시" / "운영서버 푸시" 트리거 워드 추가
- 운영서버 푸시 시 main 최신화 → merge → push → develop 동기화 절차 명시
- 브랜치 동기화 규칙 추가 (충돌 방지)
- 푸시 대상 자동 판별 규칙 추가
2026-02-25 15:36:58 +09:00
김보곤
007277d401 fix: [docs] MNG 개발서버 도메인 수정
- mng.dev.codebridge-x.com → admin.codebridge-x.com
- 도메인 스왑(48ef98e) 반영
2026-02-25 09:27:03 +09:00
김보곤
9c00447e18 docs: docs/CLAUDE.md 인프라 변경 동기화
- ~/CLAUDE.md와 동일한 인프라 정보 반영
- 기술 스택: Laravel 12 + PHP 8.4 + MySQL 8.0
- 서버 접속 정보: 개발/운영 2서버, Jenkins CI/CD
- React 빌드: Jenkins 자동화 + fallback 정책
- DB 환경 분리: samdb/sam_prod/sam_stat
- 실행 환경: 3-Tier 비교, 서버 구조도, 도메인 매핑
- 공동 개발: 브랜치 전략, 비상 수동 배포 절차
2026-02-25 06:20:58 +09:00
김보곤
bbe410150d docs: CLAUDE.md 인프라 변경 반영
- 기술 스택: Laravel 12 + PHP 8.4 + MySQL 8.0 업데이트
- 서버 접속 정보: 개발/운영 2서버 분리, Jenkins CI/CD 반영
- 배포 흐름: Jenkins 자동화 파이프라인 다이어그램 추가
- React 빌드: Jenkins 빌드 + fallback 정책으로 변경
- DB 아키텍처: 환경별 분리(samdb/sam_prod/sam_stat), --force 플래그
- 실행 환경: 3-Tier 환경 비교, 서버 구조도, 도메인 매핑 추가
- 공동 개발: 브랜치 전략(develop→개발, main→운영), 비상 수동 배포 절차
2026-02-25 06:16:21 +09:00
김보곤
b8a8ca5442 merge: origin/main sam-docs 저장소 통합
- Gitea sam-docs 원격 저장소 연결
- ops-manual, deploys, 운영 매뉴얼 문서 반영
- admin/mng 도메인 스왑 문서 포함
2026-02-25 05:56:58 +09:00
김보곤
8d6fd5aee6 docs: [business-card] 명함신청 기능 문서 추가
- features/business-card-request.md 생성 (테이블, 워크플로우, 화면 구성, API)
- INDEX.md에 문서 등록
2026-02-25 05:49:33 +09:00
김보곤
41b1e01ce4 refactor: [contracts] 영업파트너 위촉계약서(단체용)에서 관리자(3%) 역할 제거
- 용어 정의에서 관리자 항목 삭제
- 3.2 관리자의 역할 섹션 삭제, 3.3→3.2 번호 조정
- 수수료 비율 테이블에서 관리자 행 삭제
- 수수료 산정 예시 테이블에서 관리자 칼럼 삭제
- docx, md 동시 반영
2026-02-24 17:04:38 +09:00
김보곤
b8e249c6b3 fix: [contracts] 8.4 할인 계약 해지 조건 간소화
- 구독료 관련 조항 제거, 개발비 정산 조건만 유지
2026-02-24 16:56:18 +09:00
김보곤
5acac8f558 refactor: [contracts] 개발사 보호 특약을 제8조 8.4항으로 통합
- 별도 특약 6개 조항 → 제8조 내 4개 항목으로 간소화
- 중복 내용 제거, 핵심 조건만 유지
- docx, md 파일 동시 반영
2026-02-24 16:46:28 +09:00
김보곤
f98d287958 feat: [contracts] 서비스이용계약서 마크다운에 개발사 보호 특약 추가
- docx와 동일한 특약 6개 조항 md 파일에 반영
- 버전 v4.1 → v4.2 업데이트
2026-02-24 16:39:10 +09:00
김보곤
e9c7cd21cc feat: [contracts] 전자계약서에 개발사 보호 특약 추가
- 제1조 특별 할인 및 가격 구조
- 제2조 할인 환수 (1년/2년/3년 감면)
- 제3조 중도 해지 시 정산
- 제4조 서비스 게시 후 해지
- 제5조 손해배상의 예정 (30% 조항)
- 제6조 특약의 효력
2026-02-24 16:37:22 +09:00
김보곤
0c923401bf refactor: [docker] tenant 저장소를 shared-storage에서 mng/storage/app/tenants로 변경
- docker-compose: shared-storage 볼륨 마운트 제거
- entrypoint: storage/app/tenants 디렉토리 생성으로 변경
- nginx: tenant-storage alias 경로 변경
2026-02-23 21:32:51 +09:00
김보곤
73d25b99ec docs: [CLAUDE.md] 로컬(Docker) vs 서버(네이티브) 환경 구분 명확화
- Docker 환경 섹션을 실행 환경 섹션으로 변경
- 서버는 Docker 없이 네이티브로 운영됨을 명시
- 로컬/서버 명령어 비교표 추가
- 서버 접근 정책에서 docker ps/logs 제거 (서버에 Docker 없음)
- 마이그레이션 실행, 공동 개발 워크플로우 등 관련 섹션 일괄 수정
2026-02-23 14:04:15 +09:00
김보곤
b7d1fb97b4 chore: [docker] MNG 컨테이너에 Pretendard 폰트 설치 추가
- LibreOffice Word→PDF 변환 시 Pretendard 폰트 인식을 위해 설치
- wget으로 GitHub 릴리즈에서 OTF 폰트 9개 weight 다운로드
- fc-cache 갱신으로 시스템 폰트로 등록
2026-02-23 13:34:06 +09:00
김보곤
5957261ffa chore: [claude] svg-precision 스킬 CLAUDE.md에 등록 2026-02-23 13:31:13 +09:00
김보곤
9660c58bf4 fix: [contracts] 홈택스 조회 서비스 금액 30,000원으로 수정
- docx 계약서 변경사항 반영 (33,000원 → 30,000원)
2026-02-23 10:43:16 +09:00
김보곤
8601d1738e chore: [docker] MNG 컨테이너에 sales 폴더 read-only 마운트 추가 2026-02-23 08:08:42 +09:00
김보곤
f0f4a8627d docs: [plans] General Rule 스토리보드 D1.0 마크다운 변환
- SAM_General_Rule_Storyboard_D1.0_260116.pdf (43p) → 마크다운 변환
- UIUX 공통 규칙: 인터랙션, 반응형 브레이크포인트, 화면 템플릿, 메시지, GNB/LNB/푸터
- 목록/상세 화면 4단계 반응형 (PC/태블릿/모바일) 정의
- 셀렉트박스, 나의메뉴, 검색필터정렬, 페이지/섹션 설정, 태스크 알림 아이콘
- INDEX.md에 새 문서 등록
- .gitignore에 sam/docs/plans/*.md 허용 추가
2026-02-23 00:55:26 +09:00
김보곤
a0de29d5ec docs: [guides] 서버 동작 원리 초보자 가이드 추가
- 웹 요청 흐름 (브라우저→Nginx→PHP-FPM→Laravel→MySQL)
- 각 구성 요소 역할 및 Supervisor 프로세스 구성
- 로컬 Docker vs 서버 Bare-metal 환경 비교
- git push 후 PHP/React 배포 절차 설명
- 도메인별 서비스 매핑 및 요청 경로
- INDEX.md에 새 문서 등록
2026-02-22 20:50:40 +09:00
김보곤
27e17bad48 docs: [academy] 방화셔터 백과사전 이미지 생성 프롬프트 문서 추가
- Gemini용 이미지 생성 프롬프트 12종 기술문서 저장
- docs/INDEX.md에 문서 등록
- .gitignore에 features/academy 경로 허용
2026-02-22 20:18:54 +09:00
김보곤
98b01bf633 fix: [과금정책] 홈택스 매입/매출 조회 단일 서비스 33,000원으로 수정
- 홈택스 매입/매출은 하나의 서비스 (월 33,000원 × 2 → 월 33,000원)
- billing-policy.md: 매입/매출 2행 → 1행 통합
- customer-pricing.md: × 2 제거
- 서비스이용계약서 DOCX/Markdown: × 2 제거
- 슬라이드 HTML 2종: × 2 제거, 2행 → 1행 통합
2026-02-22 18:55:58 +09:00
김보곤
cd3b155cdc fix: [contracts] 4.5/4.6 테이블 헤더 음영 적용
- 기존 테이블과 동일한 D9D9D9 회색 음영을 헤더 행에 적용
2026-02-22 18:27:56 +09:00
김보곤
e4b875a69f fix: [contracts] 4.5/4.6 테이블 테두리 스타일 적용
- 새로 추가된 사용량 기반 과금 및 바로빌 테이블에 기존 테이블과 동일한 테두리 적용
- tblStyle, tblBorders, tblLayout, tblW 속성 추가
2026-02-22 18:24:58 +09:00
김보곤
92c5b3575d feat: [contracts] 서비스이용계약서 v4.1 사용량 기반 추가 과금 조항 추가
- 제4조 4.5 사용량 기반 추가 과금 조항 추가 (저장 공간, AI 토큰)
- 제4조 4.6 바로빌 부가 서비스 요금 조항 추가
- Markdown 미러 재추출 및 동기화 100% 달성
- revisions.json, CHANGELOG.md 업데이트
2026-02-22 18:05:20 +09:00
김보곤
52e3f8e375 fix: [contracts] Markdown ↔ DOCX 동기화 100% 달성
- 분할 문단 원복 (비밀유지서약서, 영업파트너 위촉계약서 2종)
- 제목 꺾쇠(< >) 복원 (영업파트너 위촉계약서 2종)
- 회사 이메일 누락 복원 (영업파트너 위촉계약서 2종)
- sync_check 정규화 개선 (Bold 마커, 리스트 접두사, 빈 테이블 행)
2026-02-22 17:52:57 +09:00
김보곤
3013406100 fix: [contracts] DOCX 원본 복원 및 개정이력 삽입 스크립트 제거
- DOCX 파일에서 개정이력 테이블 제거 (원본 복원)
- insert_revision_table.py 삭제 (버전 관리는 Markdown에서만)
- docx/ 폴더는 바로 사용 가능한 배포본 유지
2026-02-22 17:46:21 +09:00
김보곤
96f25fc0eb feat: [contracts] 계약서 버전 관리 시스템 구축
- DOCX 4종 → Markdown 미러링 체계 구축 (Git diff 추적)
- DOCX에 개정이력 테이블 삽입 (Pretendard 9pt, 파란 헤더)
- 자동화 스크립트 3종 (추출/삽입/동기화 검증)
- revisions.json, CHANGELOG.md, INDEX.md 업데이트
- .gitignore에 contracts 경로 allowlist 추가
2026-02-22 17:42:31 +09:00
김보곤
d57b84c8f2 docs: [과금정책] 3분할 문서 + 프레젠테이션 PPTX 3종 + 브랜딩 통합
- billing-policy.md → customer-pricing / partner-commission / billing-policy 3분할
- HTML 슬라이드 20장 디자인 (div+flexbox, html2pptx 호환)
- PPTX 3종 생성: customer-pricing(7장), partner-commission(6장), billing-policy(7장)
- 회사명 통일: 주일/경동 → (주)코드브릿지엑스 (전체 문서 + PPTX)
- SAM BI 로고 이미지 7종 추가 (docs/assets/bi/)
- CLAUDE.md PPT 제작 전역 규칙 추가
- e-sign PPTX 내부 회사명 교체
2026-02-21 21:09:56 +09:00
김보곤
01eee88e40 docs: [과금정책] 단체가입 수수료율 추가 및 부가세 별도 명시
- 개인가입(20%/5%/3%) vs 단체가입(30%/0%/3%) 수당 체계 추가
- 유치자 협업지원금(3%) 정책 추가
- 모든 개발비/구독료에 VAT 별도 명시
2026-02-21 19:24:19 +09:00
김보곤
bf6bbf92f7 docs: [과금정책] 가입비 → 개발비 명칭 변경 2026-02-21 19:07:08 +09:00
김보곤
24a542cb95 docs: [과금정책] 과금정책 통합 문서 작성
- 본사 지출 과금정책 (바로빌, AI/클라우드)
- 고객 안내용 과금정책 (가입비, 구독료, 추가 옵션)
- 내부 정산 정책 (영업 수당, 마진 구조)
- INDEX.md에 과금정책 문서 등록
2026-02-21 19:03:12 +09:00
김보곤
6fb6e4fdbe docs: [서버정책] 서버 직접 접근 금지 규칙 추가
- SSH 접속, 파일 수정, 명령 실행 전면 금지
- Claude는 코드 작성/커밋까지만, 배포는 사용자/팀장 역할
- 2026-02-21 502 사고 재발 방지
2026-02-21 16:52:13 +09:00
김보곤
833a957d9e docs: [react] React 빌드/배포 정책 추가
- 서버 빌드 금지, 로컬 빌드 후 배포 정책 명시
- 프로젝트 경로에 react 추가
2026-02-21 15:50:02 +09:00
김보곤
1a1ef04798 docs: [claude] Git 커밋 규칙을 sam/docs 협약 기준으로 통일
- 커밋 형식: type:메시지 → type: [scope] 작업내용
- Co-Authored-By 서명 제외 정책 반영
- style, test 타입 추가
- 푸시 정책 (자동 푸시 금지) 추가
- 커밋 전 체크리스트 보강
2026-02-20 21:34:01 +09:00
김보곤
ccb93e3aca docs:CLAUDE.md에 sam/docs 문서 작성 규칙 협약 추가
- 개발팀 협약으로 sam/docs 문서 작성 기법 준용 기록
- 폴더 선택 기준, 파일명 규칙, 문서 구조 템플릿 정리
- 작성 스타일 규칙 (한글 기본, 섹션 번호, 코드 블록 등)
- plans/ 워크플로우 및 문서 작성 체크리스트 포함

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:26:02 +09:00
김보곤
06e8d5f328 chore:API Docker 환경 설정 (Queue Worker, Scheduler, OPcache 추가)
- supervisord.conf에 queue-worker 1개 + scheduler 추가
- opcache.ini 생성 (MNG 설정과 동일, 256MB)
- docker-compose.yml에 opcache.ini 볼륨 마운트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 17:56:08 +09:00
김보곤
71654f5f63 fix:supervisord.conf 경로 수정 (/var/www/sales → /var/www/mng)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:09:31 +09:00
김보곤
03e12d8fe2 chore:Supervisor에 Queue Worker 2개 자동 실행 추가
- numprocs=2 (영상 2개 동시 생성 가능)
- timeout=1800, max-jobs=10, max-time=3600
- 자동 재시작 (autorestart=true)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:11:58 +09:00
김보곤
56fdf76f49 chore:Docker MNG에 FFmpeg 설치 추가 (영상 합성용)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:47:09 +09:00
김보곤
8278284e97 feat:Claude Code 스킬/에이전트 파일 Git 추적 추가
- .gitignore에 .claude/skills/, .claude/agents/ 허용 규칙 추가
- pptx-skill SKILL.md에 Direct PptxGenJS 방식 추가 (권장 방법)
- 전체 12개 에이전트, 40+ 스킬 파일 초기 커밋

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:54:21 +09:00
김보곤
665e6b52a4 chore:Docker MNG에 나눔 한글 폰트 추가 (DOCX→PDF 한글 깨짐 해결)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:56:58 +09:00
김보곤
61f226be7f chore:Docker MNG에 LibreOffice 설치 추가 (DOCX→PDF 변환용)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:13:10 +09:00
김보곤
b1b6a83aef chore:Docker MNG에 GD 확장 추가 (PDF 서명 합성용)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:42:17 +09:00
김보곤
768ab68f13 docs:CLAUDE.md 메뉴 관리 규칙 추가 (시더 실행 금지)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 15:22:39 +09:00
김보곤
017f492d70 docs:CLAUDE.md 에이전트 목록 업데이트 (12개 전체 반영)
- 신규 에이전트 9개 추가 (code-reviewer, debugger, test-runner, security-auditor, performance-optimizer, refactoring-agent, laravel-expert, git-manager, doc-writer)
- 카테고리별 분류 (코드품질/개발, 워크플로우/문서)
- 모델 및 출처 정보 표기

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 08:02:45 +09:00
김보곤
24271cfef3 docs:CLAUDE.md 스킬 목록 업데이트 (44개 전체 반영)
- 카테고리별 분류 (문서, 코드품질, 테스트, 보안, 디버깅, 프론트엔드, 유틸리티)
- 신규 설치 스킬 21개 추가 (levnikolaevich, Trail of Bits, anthropics 공식)
- 각 스킬별 출처 표기

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 07:41:34 +09:00
pro
6ba8738b71 docs:공동 개발 워크플로우 가이드 추가
- 로컬(Docker) 환경 업데이트 절차
- 서버 환경 업데이트 절차
- 환경별 명령어 요약 표
- pull 후 체크리스트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:11:12 +09:00
pro
a8e5e2fba0 docs:데이터베이스 아키텍처 규칙 추가
- 모든 마이그레이션은 API 프로젝트에서만 관리
- MNG database/migrations 폴더에 파일 생성 금지
- 마이그레이션 실행은 sam-api-1 컨테이너에서만

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 12:53:55 +09:00
pro
9a2948da6c docs:쿠콘 나이스평가정보 API 문서 마크다운 변환
- PDF 문서(477KB)를 마크다운(29KB)으로 변환
- 용량 약 94% 절감

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:56:37 +09:00
pro
89226629eb docs: Docker 환경 필수 인지 규칙 추가
- 로컬 개발 환경이 Docker 기반임을 명시
- Docker 컨테이너 구조 설명
- php artisan, composer 등 명령어는 docker exec로 실행
- 체크리스트 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 08:18:13 +09:00
pro
a28a4ef2f2 fix:.gitignore .claude 폴더 제외 (민감정보 보호) 2026-01-21 19:49:40 +09:00
pro
57b9a189a4 chore:전역 CLAUDE.md 및 .gitignore 초기 설정 2026-01-21 19:49:21 +09:00
680 changed files with 66420 additions and 759 deletions

18
.gitignore vendored
View File

@@ -1 +1,19 @@
# OS/에디터 생성 파일
.DS_Store
Thumbs.db
*.swp
*.swo
*~
# 로그/임시 파일
*.log
*.tmp
*.temp
*.bak
*.cache
# 노션 내보내기 임시
_to_notion/
# 백업 파일
contracts/docx/backup/

1085
CLAUDE.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +0,0 @@
# SAM Docs 작업 현황
> 모든 문서 정리 및 E2E 테스트 버그 수정 완료. 현재 활발한 작업 없음.
## 최근 커밋 이력 (참고용)
| 날짜 | 내용 |
|------|------|
| 2026-01-15 | E2E 테스트 버그 수정 완료 (Phase 1-3) |
| 2025-12-26 | 문서 업데이트 및 정리 (Phase 1-4.5) |
| 2025-12-22 | MNG 견적수식 관리 개발 계획 문서 작성 |

524
INDEX.md
View File

@@ -1,391 +1,317 @@
# SAM 프로젝트 문서 인덱스
# SAM 문서 인덱스 (Claude Code용)
> **Claude Code 작업 전 필수 확인** — 작업 유형에 맞는 문서를 먼저 읽고 시작하세요.
> **최종 갱신**: 2026-02-27
> 작업 유형에 맞는 문서를 먼저 읽고 시작하세요.
> 최종 갱신: 2026-03-13 (프로젝트 규모 현황 추가)
---
## 🎯 작업별 필수 문서
## 작업별 필수 문서
| 작업 유형 | 필수 문서 | 용도 |
|----------|----------|------|
| **API 개발** | `standards/api-rules.md` | Service-First, FormRequest, i18n 규칙 |
| **DB 변경** | `system/database/README.md` | 테이블 구조, 관계, 컬럼 규칙 |
| **새 기능 구현** | `system/overview.md` | 전체 아키텍처 이해 |
| **보안 관련** | `system/security-policy.md` | 인증/인가, 보안 규칙 |
| **Git 커밋** | `standards/git-conventions.md` | 커밋 메시지, 브랜치 전략 |
| **품질 검증** | `standards/quality-checklist.md` | 코드 품질 체크리스트 |
| **Swagger 작성** | `guides/swagger-guide.md` | API 문서 작성법 |
| **품목관리** | `rules/item-policy.md` | 품목 정책 (유형, 예약어, API 규칙) |
| **단가관리** | `rules/pricing-policy.md` | 원가/판매가 계산, 리비전 관리 |
| **견적관리** | `features/quotes/README.md` | 견적 시스템, BOM 계산, 10단계 로직 |
| **운영 배포** | `plans/production-deployment-plan.md` | 운영 환경 배포 계획 |
| **서버 운영** | `deploys/ops-manual/README.md` | 서버 운영 매뉴얼 |
| **MES 개발** | `projects/mes/README.md` | MES 프로젝트 개요 |
| API 개발 | `dev/standards/api-rules.md` | Service-First, FormRequest, i18n |
| DB 변경 | `system/database/README.md` | 테이블 구조, 관계, 컬럼 규칙 |
| 새 기능 | `system/overview.md` | 전체 아키텍처 |
| 보안 | `system/security-policy.md` | 인증/인가, 보안 규칙 |
| Git 커밋 | `dev/standards/git-conventions.md` | 커밋 메시지, 브랜치 전략 |
| 품질 검증 | `dev/standards/quality-checklist.md` | 코드 품질 체크리스트 |
| Swagger | `dev/guides/swagger-guide.md` | API 문서 작성법 |
| 이메일 정책 | `dev/standards/email-policy.md` | 멀티테넌시 이메일 발송 아키텍처 |
| Blade+React | `dev/standards/blade-react-policy.md` | Blade JSX 이중 중괄호 충돌 방지 |
| 이메일 연동 | `dev/guides/tenant-email-integration-guide.md` | 테넌트 메일 연동, SMTP 프리셋, MNG 관리 |
| 품목관리 | `rules/item-policy.md` | 품목 정책 |
| 단가관리 | `rules/pricing-policy.md` | 원가/판매가, 리비전 |
| 견적관리 | `features/quotes/README.md` | 견적 시스템, BOM 계산 |
| 급여관리 API | `frontend/api-specs/payroll-api.md` | 급여관리 API 전체 명세 (18개 엔드포인트) |
| 바로빌 회계 API | `frontend/api-specs/barobill-api.md` | 카드/은행/홈택스 REST API (42개 엔드포인트) |
| 바로빌 시스템 | `features/barobill/README.md` | SOAP 연동, 테스트/운영 모드, 과금, 멀티테넌트 (API 구축 완료) |
| 바로빌 API SOAP | `features/barobill/api-soap-reference.md` | API SOAP 49+7 메서드, 동기화 서비스, 스케줄러, MNG 대응표 |
| 바로빌 출시 계획 | `dev/dev_plans/barobill-service-launch-plan.md` | 4단계 출시 로드맵 (SOAP 이관→UI→베타→출시) |
| 바로빌 온보딩 가이드 | `guides/barobill-onboarding-guide.md` | 신규 고객 바로빌 연동 실행 절차 (7단계, API 예시, 트러블슈팅) |
| 재공품 생산 정책 | `rules/wip-production-policy.md` | 재공품(WIP) 개념, 제조업 공통 패턴, SAM 처리 방식 |
| 재고생산관리 API | `frontend/api-specs/stock-production-api.md` | 재고생산 API 명세 (기존 수주 API + STOCK 타입) |
| 절곡품 LOT API | `frontend/api-specs/bending-lot-api.md` | 절곡품 코드맵/품목매핑/LOT 채번 API (프론트엔드 구현 가이드 포함) |
| 결재관리 | `dev/dev_plans/approval-system-unification-plan.md` | MNG→API 결재 통합 계획 |
| API 품질 | `system/api-code-quality-audit.md` | 정석 패턴 R1~R6, 안티패턴, 보안, 체크리스트 |
| API 학습 | `dev/guides/api-request-lifecycle.md` | Client API로 배우는 요청 생명주기 8단계 |
| API 개선 | `dev/dev_plans/api-route-improvement-plan.md` | API 라우트 구조 개선 계획 (1,099개 분석) |
| 재고생산 개편 | `dev/dev_plans/stock-production-lot-form-plan.md` | 절곡품 LOT 방식 도입 (캐스케이딩 드롭다운, LOT 자동 생성) |
| 운영 배포 | `dev/dev_plans/production-deployment-plan.md` | 배포 계획 |
| 서버 운영 | `dev/deploys/ops-manual/README.md` | 서버 운영 매뉴얼 |
| 서버 접근/백업 | `system/server-access-management.md` | 계정, 권한, 백업, 리플리케이션 |
| 이관 작업 | `system/migration-status.md` | MNG→API+React 이관 현황, 우선순위, 로드맵 |
| API 개선 로드맵 | `system/api-analysis-report.md` | API 구조 분석, 기술 부채 8건, P1~P3 개선 계획 |
| MES | `projects/mes/README.md` | MES 프로젝트 |
---
## 📁 폴더 구조
## 폴더 구조
```
docs/
├── system/ # 시스템 현황 — 아키텍처, DB 스키마, 인프라 (architecture/ + specs/ 통합)
├── standards/ # 개발 표준 — "어떻게 코드를 작성할 것인가"
├── rules/ # 비즈니스 규칙 — "무엇이 유효한 데이터인가"
├── features/ # 기능별 상세 — 도메인별 기능 문서
├── guides/ # 구현 가이드 — "어떻게 구현할 것인가"
├── quickstart/ # 빠른 시작 — 핵심 요약, 명령어
├── plans/ # 작업 추적 — 예정 → 진행 → 완료 → archive/
├── projects/ # 프로젝트 자료 — 프로젝트성 분석, 설계, 참고
├── deploys/ # 운영 매뉴얼 — 서버 운영, 배포
├── changes/ # 변경 이력
├── data/ # 데이터 분석
├── history/ # 히스토리 기록
├── api/ # API 통합 문서
├── requests/ # 요청/기획 문서
└── assets/ # BI 등 정적 자산
├── [공유]
│ ├── features/ # 기능별 상세 명세
├── rules/ # 비즈니스 규칙·정책
│ ├── projects/ # 프로젝트별 자료
│ ├── system/ # 시스템 현황 (아키텍처, DB, 인프라)
├── [개발팀]
│ ├── dev/standards/ # 개발 표준
├── dev/guides/ # 구현 가이드
│ ├── dev/quickstart/ # 빠른 시작
├── dev/changes/ # 변경 이력
│ ├── dev/deploys/ # 배포/운영
│ ├── dev/data/ # 데이터 분석
│ ├── dev/history/ # 과거 이력
│ ├── dev/dev_plans/ # 개발 계획 (임시)
├── [프론트엔드]
│ ├── frontend/api-specs/ # API 연동 명세
│ ├── frontend/integration/ # 연동 가이드
├── [기획팀]
│ ├── requests/ # 기획 요청
├── [영업/파트너]
│ ├── guides/ # 영업파트너 가이드
├── resources.md # 외부 자료 링크 (노션)
├── README.md # 사람용 안내
└── INDEX.md # 이 파일 (Claude Code용)
```
---
## 📚 폴더별 문서 목록
## 폴더별 문서 목록
### system/ — 시스템 현황
> 아키텍처, DB 스키마, 기술 스펙, 인프라 (기존 architecture/ + specs/ 통합)
| 문서 | 설명 |
|------|------|
| [overview.md](system/overview.md) | 전체 시스템 아키텍처 (api/react/mng 구조, 기술 스택) |
| [api-structure.md](system/api-structure.md) | API 서버 구조 (~1,027 엔드포인트, 18 도메인) |
| [react-structure.md](system/react-structure.md) | React 프론트엔드 구조 (249 페이지, 612 컴포넌트) |
| [mng-structure.md](system/mng-structure.md) | MNG 관리자 패널 구조 (171 컨트롤러, 436 뷰) |
| [docker-setup.md](system/docker-setup.md) | Docker 환경 + CI/CD (7 서비스, Jenkins) |
| [database/README.md](system/database/README.md) | DB 스키마 인덱스 (220 모델, 32 도메인, 459 마이그레이션) |
**DB 도메인별 스키마:**
| 문서 | 포함 도메인 |
|------|-----------|
| [database/tenants.md](system/database/tenants.md) | 테넌트, 사용자, 권한 (63 모델) |
| [database/products.md](system/database/products.md) | 제품, 품목, 설계 (21 모델) |
| [database/sales.md](system/database/sales.md) | 영업, 수주, 견적 (18 모델) |
| [database/production.md](system/database/production.md) | 생산, 시공, 자재, 품질 (20 모델) |
| [database/finance.md](system/database/finance.md) | 재무, 회계 |
| [database/hr.md](system/database/hr.md) | 인사, 면접 |
| [database/documents.md](system/database/documents.md) | 문서, 전자서명 (19 모델) |
| [database/commons.md](system/database/commons.md) | 공통, 게시판, 감사 (17 모델) |
| [database/stats.md](system/database/stats.md) | 통계 (21 모델, sam_stat DB) |
**이관 완료 (architecture/ + specs/ → system/):**
| 문서 | 설명 |
|------|------|
| [security-policy.md](system/security-policy.md) | 보안 정책 (다층 방어, Sanctum, RBAC) |
| [scaling-roadmap.md](system/scaling-roadmap.md) | 10K 테넌트 스케일링 로드맵 |
| [board-system-spec.md](system/board-system-spec.md) | 게시판 시스템 설계 스펙 |
| [overview.md](system/overview.md) | 전체 시스템 아키텍처 |
| [api-structure.md](system/api-structure.md) | API 서버 구조 (~1,027 엔드포인트) |
| [react-structure.md](system/react-structure.md) | React 프론트엔드 구조 |
| [react-component-architecture.md](system/react-component-architecture.md) | React 컴포넌트 아키텍처 (Atomic Design 적용 현황, UI 스택, 테마) |
| [mng-structure.md](system/mng-structure.md) | MNG 관리자 패널 구조 |
| [docker-setup.md](system/docker-setup.md) | Docker 환경 + CI/CD |
| [database/README.md](system/database/README.md) | DB 스키마 인덱스 |
| [security-policy.md](system/security-policy.md) | 보안 정책 |
| [server-access-management.md](system/server-access-management.md) | 서버 접근 권한, 백업, 리플리케이션 |
| [scaling-roadmap.md](system/scaling-roadmap.md) | 스케일링 로드맵 |
| [untitled-ui-evaluation.md](system/untitled-ui-evaluation.md) | Untitled UI 도입 검토 (Figma/React UI Kit 평가) |
| [board-system-spec.md](system/board-system-spec.md) | 게시판 시스템 설계 |
| [migration-status.md](system/migration-status.md) | MNG→API+React 이관 현황 및 로드맵 (Phase 1~4) |
| [project-scale.md](system/project-scale.md) | 프로젝트 규모 현황 (코드 행 수, 파일 수) |
| [item-master-integration.md](system/item-master-integration.md) | 품목 마스터 통합 설계 |
| [remote-work-setup.md](system/remote-work-setup.md) | 원격 개발 설정 (DEPRECATED) |
| [erp-analysis/](system/erp-analysis/) | ERP 스토리보드 분석 (9개 파일) |
| [erp-analysis/](system/erp-analysis/) | ERP 스토리보드 분석 |
| [api-analysis-report.md](system/api-analysis-report.md) | API 구조 분석 및 개선 로드맵 (기술 부채 8건, P1~P3) |
| [api-code-quality-audit.md](system/api-code-quality-audit.md) | API 코드 품질 감사 — 정석 패턴 6가지 + 보안 감사 + 개발 체크리스트 |
DB 도메인별:
| 문서 | 도메인 |
|------|--------|
| [database/tenants.md](system/database/tenants.md) | 테넌트, 사용자, 권한 |
| [database/products.md](system/database/products.md) | 제품, 품목, 설계 |
| [database/sales.md](system/database/sales.md) | 영업, 수주, 견적 |
| [database/production.md](system/database/production.md) | 생산, 시공, 자재, 품질 |
| [database/finance.md](system/database/finance.md) | 재무, 회계 |
| [database/hr.md](system/database/hr.md) | 인사 |
| [database/documents.md](system/database/documents.md) | 문서, 전자서명 |
| [database/commons.md](system/database/commons.md) | 공통, 게시판, 감사 |
| [database/stats.md](system/database/stats.md) | 통계 |
---
### standards/ — 개발 표준
> 코딩 컨벤션, 스타일 가이드, 품질 기준
### dev/standards/ — 개발 표준
| 문서 | 설명 | 필수 확인 시점 |
|------|------|--------------|
| [api-rules.md](standards/api-rules.md) | API 개발 규칙 (Service-First, FormRequest, i18n) | API 개발 전 |
| [git-conventions.md](standards/git-conventions.md) | Git 커밋 메시지, 브랜치 전략 | 커밋 전 |
| [quality-checklist.md](standards/quality-checklist.md) | 코드 품질 체크리스트 | PR 전 |
| [pagination-policy.md](standards/pagination-policy.md) | 페이지네이션 표준 | 목록 API 구현 시 |
| [options-column-policy.md](standards/options-column-policy.md) | JSON options 컬럼 표준 정책 (마이그레이션, 모델, 쿼리) | 테이블 생성/확장 시 |
| 문서 | 설명 |
|------|------|
| [api-rules.md](dev/standards/api-rules.md) | API 개발 규칙 |
| [git-conventions.md](dev/standards/git-conventions.md) | Git 컨벤션 |
| [quality-checklist.md](dev/standards/quality-checklist.md) | 품질 체크리스트 |
| [pagination-policy.md](dev/standards/pagination-policy.md) | 페이지네이션 표준 |
| [options-column-policy.md](dev/standards/options-column-policy.md) | JSON options 컬럼 정책 |
| [pdf-font-policy.md](dev/standards/pdf-font-policy.md) | PDF 생성 시 폰트 정책 (DomPDF) |
| [email-policy.md](dev/standards/email-policy.md) | 멀티테넌시 이메일 발송 정책 |
| [blade-react-policy.md](dev/standards/blade-react-policy.md) | Blade + React(JSX) 혼용 시 이중 중괄호 충돌 방지 정책 |
---
### rules/ — 비즈니스 규칙
> 도메인 로직, 검증 규칙, 정책
| 문서 | 설명 | 필수 확인 시점 |
|------|------|--------------|
| [README.md](rules/README.md) | 비즈니스 규칙 개요 | 도메인 로직 구현 전 |
| [item-policy.md](rules/item-policy.md) | 품목 정책 (유형, 예약어, API 규칙) | 품목 관련 작업 전 |
| [pricing-policy.md](rules/pricing-policy.md) | 단가 정책 (원가/판매가, 리비전) | 단가 관련 작업 전 |
| [customer-pricing.md](rules/customer-pricing.md) | 고객 안내용 서비스 요금표 | 고객 요금 안내 시 |
| [partner-commission.md](rules/partner-commission.md) | 영업파트너 수당 체계 및 정산 | 수당/정산 관련 작업 전 |
| [billing-policy.md](rules/billing-policy.md) | 내부용 원가/마진/코드참조 (CONFIDENTIAL) | 과금 코드 개발 전 |
| [client-policy.md](rules/client-policy.md) | 고객사 관리 정책 | 고객 관련 작업 전 |
| [attendance-api.md](rules/attendance-api.md) | 근태 API 규칙 | 근태 관련 작업 전 |
| [department-tree-api.md](rules/department-tree-api.md) | 부서 트리 API 규칙 | 부서 관련 작업 전 |
| [employee-api.md](rules/employee-api.md) | 직원 API 규칙 | 직원 관련 작업 전 |
| [numbering-rules.md](rules/numbering-rules.md) | 채번규칙 (패턴 기반 자동 번호 생성) | 채번 로직 수정 전 |
| 문서 | 설명 |
|------|------|
| [item-policy.md](rules/item-policy.md) | 품목 정책 |
| [pricing-policy.md](rules/pricing-policy.md) | 단가 정책 |
| [numbering-rules.md](rules/numbering-rules.md) | 채번 규칙 |
| [client-policy.md](rules/client-policy.md) | 고객사 관리 정책 |
| [wip-production-policy.md](rules/wip-production-policy.md) | 재공품(WIP) 생산 정책 (개념, MTS/MTO/ATO, 제조업 공통 패턴) |
| [billing-policy.md](rules/billing-policy.md) | 과금 정책 (CONFIDENTIAL) |
| [customer-pricing.md](rules/customer-pricing.md) | 고객 요금표 |
| [partner-commission.md](rules/partner-commission.md) | 영업파트너 수당 체계 |
| [attendance-api.md](rules/attendance-api.md) | 근태 API 규칙 |
| [department-tree-api.md](rules/department-tree-api.md) | 부서 트리 API |
| [employee-api.md](rules/employee-api.md) | 직원 API |
---
### features/ — 기능별 문서
> 도메인별 기능 상세 (기능 설명 + 엔드포인트 경로 + Swagger 참조)
| 문서 | 설명 |
|------|------|
| [quotes/README.md](features/quotes/README.md) | 견적 시스템 (BOM 계산, 10단계 로직) |
| [boards/README.md](features/boards/README.md) | 게시판 시스템 구현 |
| [boards/mng-implementation.md](features/boards/mng-implementation.md) | MNG 게시판 구현 상세 |
| [hr/attendance-management-spec.md](features/hr/attendance-management-spec.md) | 근태관리 기획서 |
| [hr/hr-api-analysis.md](features/hr/hr-api-analysis.md) | HR API 분석 (근태/직원/부서) |
| [barobill-kakaotalk/README.md](features/barobill-kakaotalk/README.md) | 바로빌 카카오톡 + 세금계산서 연동 |
| ~~business-card-request.md~~ | 명함신청 관리 (DB 마이그레이션만 존재, 문서 미작성) |
| [sales/README.md](features/sales/README.md) | 영업 관리 (면접 시나리오 포함) |
| [crm/README.md](features/crm/README.md) | CRM (거래처, 미수금, 미지급금) |
| [finance/README.md](features/finance/README.md) | 재무 관리 (14개 하위 문서) |
| [card-vehicle/README.md](features/card-vehicle/README.md) | 법인카드·차량 관리 |
| [settlement/README.md](features/settlement/README.md) | 정산 관리 |
| [esign/README.md](features/esign/README.md) | 전자서명 (계약·OTP·PDF 합성) |
| [documents/README.md](features/documents/README.md) | 문서관리 (EAV 기반 서식·결재) |
| [ai/README.md](features/ai/README.md) | AI 분석 리포트 (Gemini 연동) |
| [equipment/README.md](features/equipment/README.md) | 설비관리 (MNG 전용) |
| [quotes/README.md](features/quotes/README.md) | 견적 시스템 |
| [sales/README.md](features/sales/README.md) | 영업 관리 |
| [documents/README.md](features/documents/README.md) | 문서관리 |
| [finance/README.md](features/finance/README.md) | 재무 관리 |
| [finance/payroll.md](features/finance/payroll.md) | 급여관리 (전표 변환, 권한, 멀티테넌트) |
| [hr/](features/hr/) | 인사관리 |
| [crm/README.md](features/crm/README.md) | CRM |
| [esign/README.md](features/esign/README.md) | 전자서명 |
| [equipment/README.md](features/equipment/README.md) | 설비관리 (API Phase 1 완료 + DB 스키마) |
| [boards/README.md](features/boards/README.md) | 게시판 |
| [ai/README.md](features/ai/README.md) | AI 분석 |
| [card-vehicle/README.md](features/card-vehicle/README.md) | 법인카드·차량 |
| [settlement/README.md](features/settlement/README.md) | 정산 |
| [sales/stock-production.md](features/sales/stock-production.md) | 재고생산관리 (내부 오더 방식, 수주 테이블 공유) |
| [sales/demo-tenant-policy.md](features/sales/demo-tenant-policy.md) | 영업파트너 데모 테넌트 정책 (3-Tier 전략) |
| [sales/demo-tenant-usage-guide.md](features/sales/demo-tenant-usage-guide.md) | 데모 테넌트 사용 가이드 (영업파트너/관리자용) |
| [barobill/README.md](features/barobill/README.md) | 바로빌 연동 시스템 (SOAP API, 테스트/운영 모드, 과금, 이관 계획) |
| [barobill/tenant-onboarding.md](features/barobill/tenant-onboarding.md) | 바로빌 테넌트 온보딩 (개념 정의, 6단계 프로세스, 베타테스트와의 차이) |
| [barobill/api-soap-reference.md](features/barobill/api-soap-reference.md) | API SOAP 서비스 기술 참조 (49+7 메서드, 동기화, 스케줄러, MNG 대응표) |
| [barobill-kakaotalk/README.md](features/barobill-kakaotalk/README.md) | 바로빌 카카오톡 |
| [quality-management/README.md](features/quality-management/README.md) | 품질관리 (제품검사, 실적신고) |
| [approvals/README.md](features/approvals/README.md) | 결재관리 시스템 |
| [approvals/mng-api-comparison.md](features/approvals/mng-api-comparison.md) | 결재관리 MNG↔API 비교 분석 및 React 구현 가이드 |
| [email/README.md](features/email/README.md) | 이메일 시스템 (테넌트별 SMTP 설정, 프리셋, 연결 테스트) |
| [construction-pmis/bim-viewer.md](features/construction-pmis/bim-viewer.md) | BIM 뷰어 (Three.js 기반 웹 3D 건물 모델 뷰어) |
| [rd/README.md](features/rd/README.md) | R&D 메뉴 전체 개요 |
| [rd/fire-shutter-drawing-guide-rail.md](features/rd/fire-shutter-drawing-guide-rail.md) | 방화셔터 가이드레일 SVG/3D 렌더링 기술 명세 |
---
### guides/ — 구현 가이드
> 특정 기능 구현을 위한 단계별 매뉴얼
| 문서 | 설명 | 필수 확인 시점 |
|------|------|--------------|
| [swagger-guide.md](guides/swagger-guide.md) | Swagger API 문서 작성법 | API 문서 작성 전 |
| [file-storage-guide.md](guides/file-storage-guide.md) | 파일 업로드/다운로드 구현 | 파일 기능 구현 전 |
| [item-management-migration.md](guides/item-management-migration.md) | Item 시스템 전환 가이드 | 마이그레이션 작업 전 |
| [project-launch-roadmap.md](guides/project-launch-roadmap.md) | 런칭 준비 현황 | 런칭 관련 작업 시 |
| [production-env-sync.md](guides/production-env-sync.md) | 운영 전환 시 .env 동기화 | 테스트→운영 전환 시 |
| [server-how-it-works.md](guides/server-how-it-works.md) | 서버 동작 원리 | 신규 합류 시 |
| [nginx-fastcgi-guide.md](guides/nginx-fastcgi-guide.md) | Nginx & FastCGI 가이드 | 서버 이해 시 |
| [php-fpm-guide.md](guides/php-fpm-guide.md) | PHP-FPM 가이드 | 서버 이해 시 |
| [jenkins-setup-guide.md](guides/jenkins-setup-guide.md) | Jenkins CI/CD 셋업 | Jenkins 설치/설정 시 |
| [auto-login-guide.md](guides/auto-login-guide.md) | MNG→DEV 자동 로그인 | 자동 로그인 구현 시 |
| [erp-api-list.md](guides/erp-api-list.md) | ERP API 목록 (List vs Detail 구분) | 프론트 API 연동 시 |
| [erp-api-detail.md](guides/erp-api-detail.md) | ERP API 상세 스펙 | 프론트 API 연동 시 |
| [item-master-guide.md](guides/item-master-guide.md) | 품목기준관리 페이지-섹션-필드 구조 | 품목 UI 구현 시 |
| [item-master-items-api.md](guides/item-master-items-api.md) | ItemMaster & Items API 문서 | 품목 API 연동 시 |
---
### quickstart/ — 빠른 시작
> 핵심 규칙 요약, 자주 쓰는 명령어
### guides/ — 영업파트너 가이드
| 문서 | 설명 |
|------|------|
| [quick-start.md](quickstart/quick-start.md) | 프로젝트 핵심 규칙 요약 |
| [dev-commands.md](quickstart/dev-commands.md) | 일상 개발 명령어 모음 |
| [sam-pricing-simple-guide.md](guides/sam-pricing-simple-guide.md) | SAM 가격정책 쉬운 안내서 (영업파트너용) |
| [price-simulator-partner-guide.md](guides/price-simulator-partner-guide.md) | 가격 시뮬레이터 상세 가이드 (영업파트너용) |
| [ai-management.md](guides/ai-management.md) | AI 관리 가이드 |
| [pptx-generation-guide.md](guides/pptx-generation-guide.md) | PPTX 생성 가이드 |
| [project-launch-roadmap.md](guides/project-launch-roadmap.md) | 프로젝트 런칭 로드맵 |
| [table-design-guide.md](guides/table-design-guide.md) | 테이블 설계 가이드 |
| [barobill-onboarding-guide.md](guides/barobill-onboarding-guide.md) | 바로빌 온보딩 실행 가이드 (7단계 절차, API 예시, 트러블슈팅, 고객 안내 자료) |
---
### plans/ — 작업 추적
> 예정 → 진행 → 완료 → archive/ (이미 정리 완료, 현행 유지)
### dev/guides/ — 구현 가이드
| 문서 | 설명 |
|------|------|
| [index_plans.md](plans/index_plans.md) | 계획 인덱스 (ACTIVE + PLANNED) |
| [GUIDE.md](plans/GUIDE.md) | 계획 문서 작성 가이드 |
| [api-request-lifecycle.md](dev/guides/api-request-lifecycle.md) | API 요청 생명주기 — Client API로 배우는 8단계 전체 흐름 |
| [swagger-guide.md](dev/guides/swagger-guide.md) | Swagger 작성법 |
| [file-storage-guide.md](dev/guides/file-storage-guide.md) | 파일 업로드/다운로드 |
| [item-management-migration.md](dev/guides/item-management-migration.md) | Item 전환 가이드 |
| [server-how-it-works.md](dev/guides/server-how-it-works.md) | 서버 동작 원리 |
| [jenkins-setup-guide.md](dev/guides/jenkins-setup-guide.md) | Jenkins CI/CD |
| [erp-api-list.md](dev/guides/erp-api-list.md) | ERP API 목록 |
| [erp-api-detail.md](dev/guides/erp-api-detail.md) | ERP API 상세 |
| [item-master-guide.md](dev/guides/item-master-guide.md) | 품목기준관리 구조 |
| [claude-code-to-slack.md](dev/guides/claude-code-to-slack.md) | Claude Code → 슬랙 붙여넣기 가이드 |
| [claude-code-btw-guide.md](dev/guides/claude-code-btw-guide.md) | Claude Code /btw 사이드 질문 기능 가이드 |
| [tenant-email-integration-guide.md](dev/guides/tenant-email-integration-guide.md) | 테넌트 이메일 연동 (SMTP 프리셋, MNG 관리 화면, 연결 테스트) |
| [performance-report-excel-export.md](dev/guides/performance-report-excel-export.md) | 실적신고 확정건 엑셀 Export (건기원 양식, PhpSpreadsheet, 셀 병합) |
---
### projects/ — 프로젝트 자료
> 프로젝트성 분석, 설계, 참고 자료 (지속 보관)
| 프로젝트 | 문서 | 설명 |
|---------|------|------|
| [index_projects.md](projects/index_projects.md) | 프로젝트 인덱스 | |
| **MES** | [README.md](projects/mes/README.md) | MES 프로젝트 개요 |
| **MES** | [MES_PROJECT_ROADMAP.md](projects/mes/MES_PROJECT_ROADMAP.md) | 개발 로드맵 |
| **5130 이관** | [MASTER_PLAN.md](projects/5130-migration/MASTER_PLAN.md) | 레거시 이관 마스터 플랜 |
| **API 연동** | [MASTER_PLAN.md](projects/api-integration/MASTER_PLAN.md) | React↔API 연동 |
| **Legacy** | [draw-module.md](projects/legacy-5130/draw-module.md) | 레거시 드로우 모듈 |
| **견적** | [quotation/](projects/quotation/) | 견적 프로젝트 자료 |
| **전자서명** | [e-sign/](projects/e-sign/) | 전자서명 프로젝트 자료 |
| MES | [projects/mes/README.md](projects/mes/README.md) | MES 개요 |
| 5130 이관 | [projects/5130-migration/](projects/5130-migration/) | 레거시 이관 |
| API 연동 | [projects/api-integration/](projects/api-integration/) | React↔API |
| 견적 | [projects/quotation/](projects/quotation/) | 견적 프로젝트 |
| 전자서명 | [projects/e-sign/](projects/e-sign/) | 전자서명 |
---
### deploys/ — 운영 매뉴얼
> 서버 운영, 배포 (현행 유지)
### dev/changes/ — 변경 이력
| 문서 | 설명 |
|------|------|
| [ops-manual/README.md](deploys/ops-manual/README.md) | 서버 운영 매뉴얼 (11부 구성) |
| [20260311_daily_fund_sync_and_account_codes_fix.md](dev/changes/20260311_daily_fund_sync_and_account_codes_fix.md) | 자금일보 바로빌 자동동기화 + 계정과목 데이터 정리 |
| [20260311_esign_journal_barobill_fixes.md](dev/changes/20260311_esign_journal_barobill_fixes.md) | 전자서명 체크박스, 전표 적요 동기화, 거래처 드롭다운, 바로빌 중복 키 수정 |
| [20260311_salary_history_delete.md](dev/changes/20260311_salary_history_delete.md) | 연봉이력 삭제 기능 추가 (사원관리 연봉정보) |
| [20260314_api_test_infrastructure_and_order_tests.md](dev/changes/20260314_api_test_infrastructure_and_order_tests.md) | API 테스트 인프라 정비 + 수주 테스트 12개 추가 |
| [20260314_api_quality_improvement_deploy.md](dev/changes/20260314_api_quality_improvement_deploy.md) | API 품질 개선 배포 — 테스트 56개 + N+1 최적화 3건 (근거 문서 포함) |
| [20260315_eval_removal_safe_math_evaluator.md](dev/changes/20260315_eval_removal_safe_math_evaluator.md) | API 보안 개선 — eval() 3건 제거, SafeMathEvaluator 도입 |
| [20260316_sales_policy_changes.md](changes/20260316_sales_policy_changes.md) | 영업 정책 변경 — 수당 구조 개편 및 무료 체험 폐지 |
| [20260316_stock_production_order.md](dev/changes/20260316_stock_production_order.md) | 재고생산관리 기능 추가 (STOCK 타입, 절곡 공정 자동, 생산지시 연동) |
| [20260317_account_code_migration_mapping.md](changes/20260317_account_code_migration_mapping.md) | 계정과목 코드 변경 매핑 (더존 3자리 → KIS 5자리) |
---
### changes/ — 변경 이력
> 파일명 형식: `YYYYMMDD_description.md`
### dev/deploys/ — 배포/운영
| 문서 | 설명 |
|------|------|
| [ops-manual/README.md](dev/deploys/ops-manual/README.md) | 서버 운영 매뉴얼 |
---
### data/ — 데이터 분석
### dev/quickstart/ — 빠른 시작
| 문서 | 설명 |
|------|------|
| [analysis/item-db-analysis.md](data/analysis/item-db-analysis.md) | Item DB/API 분석 최종본 |
| [analysis/bom-item-mapping-analysis.md](data/analysis/bom-item-mapping-analysis.md) | BOM-품목 매핑 분석 |
| [quick-start.md](dev/quickstart/quick-start.md) | 핵심 규칙 요약 |
| [dev-commands.md](dev/quickstart/dev-commands.md) | 개발 명령어 모음 |
### contracts/ - 전자계약서 버전 관리
> DOCX 배포본 + Markdown 추적본 + 자동화 스크립트
---
### frontend/api-specs/ — 프론트엔드 API 연동 명세
| 문서 | 설명 |
|------|------|
| [CHANGELOG.md](contracts/CHANGELOG.md) | 전체 개정이력 |
| [revisions.json](contracts/revisions.json) | 개정 데이터 |
| [docx/](contracts/docx/) | DOCX 배포본 (전자서명용 4종, 바로 사용 가능) |
| [markdown/](contracts/markdown/) | Markdown 추적본 (Git diff용 4종) |
| [scripts/extract_to_markdown.py](contracts/scripts/extract_to_markdown.py) | DOCX → Markdown 추출 |
| [scripts/sync_check.py](contracts/scripts/sync_check.py) | DOCX ↔ Markdown 동기화 검증 |
| [approval-api.md](frontend/api-specs/approval-api.md) | 결재관리 API 전체 명세 (28개 엔드포인트) |
| [document-api-integration.md](frontend/api-specs/document-api-integration.md) | 문서 API 연동 명세 |
| [payroll-api.md](frontend/api-specs/payroll-api.md) | 급여관리 API 전체 명세 (18개 엔드포인트) |
| [barobill-api.md](frontend/api-specs/barobill-api.md) | 바로빌 회계 데이터 API 명세 (42개 엔드포인트) |
| [equipment-api.md](requests/equipment-frontend-request.md) | 설비관리 React 프론트엔드 구현 요청 (26개 엔드포인트 + 화면 가이드) |
| [vehicle-api.md](frontend/api-specs/vehicle-api.md) | 차량관리 API 명세 (20개 엔드포인트: 차량목록, 차량일지, 정비이력, 사진) |
| [stock-production-api.md](frontend/api-specs/stock-production-api.md) | 재고생산관리 API 명세 (기존 수주 API + STOCK 타입) |
| [vehicle-react-implementation.md](plans/vehicle-react-implementation.md) | 차량관리 React 구현 요청서 (3개 메뉴, 컴포넌트 구조, 타입 정의) |
| [stock-production-react-request.md](plans/stock-production-react-request.md) | 재고생산관리 React 구현 요청서 (수주 화면 단순화, API 스펙 포함) |
| [bending-lot-react-request.md](plans/bending-lot-react-request.md) | 절곡품 LOT 재고생산 React 구현 요청서 (캐스케이딩 드롭다운, LOT 자동생성, 취소 복원) |
| [barobill-react-improvement-request.md](plans/barobill-react-improvement-request.md) | 바로빌 React 개선 요청서 (동기화 버튼, 인증서/잔액 표시, 계좌/카드 목록, Server Action 6개) |
### plans/ - 개발 계획
> 임시 개발 계획 문서 (작업 완료 후 정리 → 삭제)
### frontend/integration/ — 프론트엔드 개발 가이드
| 문서 | 설명 |
|------|------|
| [SAM_ERP_Storyboard_D1.4_260116.md](plans/SAM_ERP_Storyboard_D1.4_260116.md) | ERP 전체 스토리보드 D1.4 (167p PDF → 마크다운 변환, 14개 섹션 146개 화면) |
| [SAM_ERP_Storyboard_D1.4.md](plans/SAM_ERP_Storyboard_D1.4.md) | ERP 스토리보드 D1.4 AI 최적화 버전 (구조화된 한글 마크다운, 15개 섹션) |
| [SAM_ERP_회계관리_Storyboard_D1.6.md](plans/SAM_ERP_회계관리_Storyboard_D1.6.md) | ERP 회계관리 스토리보드 D1.6 (65p PDF → 마크다운 변환) |
| [SAM_General_Rule_Storyboard_D1.0.md](plans/SAM_General_Rule_Storyboard_D1.0.md) | General Rule 스토리보드 D1.0 (43p PDF → 마크다운 변환, UIUX 공통 규칙) |
| [production-deployment-plan.md](plans/production-deployment-plan.md) | 운영 환경 배포 계획 (CI/CD, 서버 아키텍처) |
| [attendance-management-plan.md](plans/attendance-management-plan.md) | 근태현황 개발 계획 (Phase 1~2, HTMX 기반) |
| [leave-management-plan.md](plans/leave-management-plan.md) | 휴가관리 모듈 개발 계획 (연차 발생/신청/승인/정책) |
### features/ - 기능별 문서
| 문서 | 설명 |
|------|------|
| [barobill-kakaotalk/README.md](features/barobill-kakaotalk/README.md) | 바로빌 카카오톡 (알림톡/친구톡) 연동 |
| [boards/README.md](features/boards/README.md) | 게시판 시스템 구현 |
| [boards/mng-implementation.md](features/boards/mng-implementation.md) | MNG 게시판 구현 상세 |
| [hr/attendance-management-spec.md](features/hr/attendance-management-spec.md) | 근태관리 기획서 (화면/데이터/비즈니스규칙/API) |
| [hr/hr-api-analysis.md](features/hr/hr-api-analysis.md) | HR API 분석 (근태/직원/부서) |
| [quotes/README.md](features/quotes/README.md) | 견적 시스템 분석 (BOM 계산, 10단계 로직) |
| [business-card-request.md](features/business-card-request.md) | 명함신청 관리 (3단계 워크플로우: 요청→제작의뢰→처리완료) |
| [academy/fire-shutter-image-prompts.md](features/academy/fire-shutter-image-prompts.md) | 방화셔터 백과사전 이미지 생성 프롬프트 (Gemini용) |
### projects/ - 프로젝트별 문서
| 프로젝트 | 문서 | 설명 |
|---------|------|------|
| **MES** | [README.md](projects/mes/README.md) | MES 프로젝트 개요 |
| **MES** | [MES_PROJECT_ROADMAP.md](projects/mes/MES_PROJECT_ROADMAP.md) | 개발 로드맵 |
| **Legacy** | [draw-module.md](projects/legacy-5130/draw-module.md) | 레거시 드로우 모듈 |
### history/ - 히스토리
| 기간 | 문서 |
|------|------|
| **2025-11** | [item-master-gap-analysis.md](history/2025-11/item-master-gap-analysis.md), [item-master-spec.md](history/2025-11/item-master-spec.md), [front-requests/](history/2025-11/front-requests/), [item-master-archived/](history/2025-11/item-master-archived/) |
| **2025-09** | [checkpoint.md](history/2025-09/checkpoint.md), [database-schema.md](history/2025-09/database-schema.md) |
| **Roadmaps** | [december-2025.md](history/roadmaps/december-2025.md) |
| [payroll-guide.md](frontend/integration/payroll-guide.md) | 급여관리 프론트엔드 개발 가이드 (화면 구성, 구현 유의사항) |
---
### 서브프로젝트 문서
각 서브프로젝트는 독립적인 `docs/` 디렉토리를 가집니다.
| 프로젝트 | 문서 경로 | 설명 |
|---------|----------|------|
| **API** | [api/docs/](../api/docs/) | REST API 프로젝트 |
| **MNG** | [mng/docs/](../mng/docs/) | Plain Laravel 관리자 |
| **React** | [react/docs/](../react/docs/) | Next.js 프론트엔드 |
| 프로젝트 | 경로 |
|---------|------|
| API | [api/docs/](../api/docs/) |
| MNG | [mng/docs/](../mng/docs/) |
| React | [react/docs/](../react/docs/) |
---
## 📝 문서 작성 규칙
### 폴더 선택 기준
## 폴더 선택 기준
| 질문 | 폴더 |
|------|------|
| "시스템 현재 어떤 상태인가?" | `system/` |
| "어떻게 코드 작성할 것인가?" | `standards/` |
| "무엇이 유효한 데이터인가?" | `rules/` |
| "이 기능은 어떻게 동작하는가?" | `features/` |
| "어떻게 구현할 것인가?" | `guides/` |
| "무슨 작업을 할 것인가?" | `plans/` |
| "프로젝트 자료를 보관하고 싶다" | `projects/` |
| "무엇이 변경되었는가?" | `changes/` |
### 파일명 규칙
| 유형 | 규칙 | 예시 |
|------|------|------|
| 기술 문서 (코드 참조) | 영문 kebab-case | `api-rules.md`, `database-schema.md` |
| 업무/비즈니스 문서 | 한글 허용 | `영업파트너가이드북.md`, `수당지급.md` |
| 변경 이력 | `YYYYMMDD_description.md` | `20260205_sus_inspection_template.md` |
| 폴더 인덱스 | `README.md` (대문자) | `features/finance/README.md` |
| **혼용 금지** | 한글+영문 섞지 않음 | ❌ `영업partner가이드.md` |
### 크기 제한
- **목표**: 10KB 이하
- 초과 시 도메인별로 분할
### 문서 구조 템플릿
#### 정책/규칙 문서 (`rules/`, `standards/`)
```markdown
# 제목
> **작성일**: YYYY-MM-DD
> **상태**: 설계 확정
---
## 1. 개요
## 2. 핵심 원칙
## 3. 상세 규칙
## 4. API 엔드포인트 (해당 시)
## 관련 문서
---
**최종 업데이트**: YYYY-MM-DD
```
#### 변경 이력 문서 (`changes/`)
```markdown
# 변경 내용 요약
**날짜:** YYYY-MM-DD
## 변경 개요
## 수정된 파일
## 상세 변경 사항
## 테스트 체크리스트
```
### 작성 스타일
| 항목 | 규칙 |
|------|------|
| **언어** | 한글 기본, 코드/경로/기술 식별자만 영어 |
| **어조** | 서술형 ("X 한다") |
| **경고** | `> **경고: ...**` 블록인용 |
| **금지/필수** | `❌` 금지, `✅` 필수 |
| **우선순위** | `🔴 필수`, `🟡 중요`, `🟢 권장` |
| **코드 블록** | 반드시 언어 지정 (```php, ```bash 등) |
| **인라인 코드** | 파일 경로, 메서드명, 변수명에 백틱 |
| **구분선** | `---` 주요 섹션 사이 |
### 새 문서 작성 시 체크리스트
- [ ] 적절한 폴더에 배치
- [ ] 파일명 규칙 준수
- [ ] 문서 구조 템플릿 준수
- [ ] 이 INDEX.md에 등록
---
## 🔄 문서 정비 진행 현황
> 참조: [docs-comprehensive-update-plan.md](plans/docs-comprehensive-update-plan.md)
| Phase | 작업 | 상태 |
|-------|------|------|
| **Phase 0** | 문서 정책 재정립 | ✅ 완료 |
| **Phase 1** | 시스템 현황 문서화 (DB, API, React, MNG, Docker) | ✅ 완료 (14개 문서) |
| **Phase 2** | 기존 문서 정비 (architecture/+specs/ → system/ 이관) | ⏳ 대기 |
| **Phase 3** | 신규 도메인 기능 문서 작성 | ⏳ 대기 |
| **Phase 4** | 최종 검증 및 INDEX 갱신 | ⏳ 대기 |
| 시스템 현재 상태? | `system/` |
| 코드 작성 규칙? | `dev/standards/` |
| 비즈니스 규칙? | `rules/` |
| 기능 동작 방식? | `features/` |
| 구현 방법? | `dev/guides/` |
| 개발 계획? | `dev/dev_plans/` |
| 프로젝트 자료? | `projects/` |
| 변경 이력? | `dev/changes/` |

128
README.md Normal file
View File

@@ -0,0 +1,128 @@
# SAM 프로젝트 문서
SAM ERP 시스템의 기술 문서, 비즈니스 규칙, 기능 명세를 관리하는 저장소입니다.
---
## 대상별 안내
### 전 팀 공유
누구나 참고할 수 있는 공통 문서입니다.
| 폴더 | 설명 | 예시 |
|------|------|------|
| **features/** | 기능별 상세 명세 | 견적, CRM, 문서관리, 인사, 재무 등 |
| **rules/** | 비즈니스 규칙·정책 | 품목 정책, 단가 정책, 채번 규칙, 청구 정책 |
| **projects/** | 프로젝트별 자료 | MES, 5130 마이그레이션, 전자서명 등 |
| **system/** | 시스템 현황 | 아키텍처, DB 스키마, Docker, 인프라 |
| **resources.md** | 외부 자료 링크 | BI, 제품 소개서 등 대용량 자료 (노션 링크) |
### 개발팀 전용 (`dev/`)
개발 표준, 가이드, 변경 이력 등 개발자 대상 문서입니다.
| 폴더 | 설명 | 예시 |
|------|------|------|
| **dev/standards/** | 개발 표준 | API 규칙, Git 컨벤션, 품질 체크리스트 |
| **dev/guides/** | 구현 가이드 | Swagger 작성법, 파일 저장, Jenkins 설정 |
| **dev/quickstart/** | 빠른 시작 | 개발 명령어, 퀵스타트 가이드 |
| **dev/changes/** | 변경 이력 | 날짜별 변경 내용 기록 |
| **dev/deploys/** | 배포·운영 | 운영 매뉴얼, 배포 SQL |
| **dev/data/** | 데이터 분석 | BOM 매핑 분석, 견적 데이터 |
| **dev/history/** | 과거 이력 | 월별 히스토리, 로드맵 |
| **dev/dev_plans/** | 개발 계획 | 작업별 계획 문서 (개인 작업용, 정리 후 폐기 가능) |
### 프론트엔드 전용 (`frontend/`)
프론트엔드 개발자 대상 문서입니다.
| 폴더 | 설명 | 예시 |
|------|------|------|
| **frontend/api-specs/** | API 연동 명세 | 문서 API 연동 가이드 |
| **frontend/integration/** | 프론트-백엔드 연동 | 연동 패턴, 주의사항 |
### 기획팀 (`requests/`)
기획 요청 및 확인 문서입니다.
| 폴더 | 설명 | 예시 |
|------|------|------|
| **requests/** | 기획 확인 요청 | 기획서 검토 요청, 워크플로우 공유 |
---
## 폴더 구조
```
docs/
├── features/ # [공유] 기능별 상세 명세
│ ├── quotes/ # 견적 시스템
│ ├── sales/ # 영업/수주
│ ├── documents/ # 문서관리
│ ├── finance/ # 재무/회계
│ ├── hr/ # 인사관리
│ ├── crm/ # 고객관리
│ ├── esign/ # 전자서명
│ ├── equipment/ # 설비관리
│ ├── boards/ # 게시판
│ ├── ai/ # AI 기능
│ └── ...
├── rules/ # [공유] 비즈니스 규칙
│ ├── item-policy.md
│ ├── pricing-policy.md
│ ├── numbering-rules.md
│ └── ...
├── projects/ # [공유] 프로젝트별 자료
│ ├── mes/
│ ├── 5130-migration/
│ ├── e-sign/
│ └── ...
├── system/ # [공유] 시스템 현황
│ ├── overview.md
│ ├── database/
│ ├── docker-setup.md
│ └── ...
├── resources.md # [공유] 외부 자료 링크 (노션)
├── dev/ # [개발팀] 개발 전용
│ ├── standards/ # 개발 표준
│ ├── guides/ # 구현 가이드
│ ├── quickstart/ # 빠른 시작
│ ├── changes/ # 변경 이력
│ ├── deploys/ # 배포/운영
│ ├── data/ # 데이터 분석
│ ├── history/ # 과거 이력
│ └── dev_plans/ # 개발 계획 (개인 작업용)
├── frontend/ # [프론트엔드] 프론트 전용
│ ├── api-specs/ # API 연동 명세
│ └── integration/ # 연동 가이드
├── requests/ # [기획팀] 기획 요청
├── README.md # 이 문서 (사람용 안내)
├── INDEX.md # Claude Code용 문서 인덱스
└── TODO.md
```
---
## 문서 작성 규칙
### 파일 이름
- 영문 소문자, 하이픈(`-`) 구분: `item-policy.md`
- 변경 이력: `YYYYMMDD_설명.md` (예: `20260305_login_fix.md`)
- 한글 파일명 허용 (가이드 등 내부 문서)
### 문서 구조
- 모든 MD 파일은 `# 제목`으로 시작
- 폴더에 파일이 3개 이상이면 `README.md`로 목차 제공
- 이미지/대용량 파일은 노션에 업로드하고 `resources.md`에 링크 추가
### 폴더 관리
- **공유 폴더**: 전 팀이 수정 가능, 변경 시 관련 팀에 공유
- **dev/**: 개발팀만 수정
- **frontend/**: 프론트엔드 팀만 수정 (API 명세는 개발팀이 제공)
- **requests/**: 기획팀이 작성, 개발팀이 확인
- **dev/dev_plans/**: 개인 작업용, 완료 후 archive/ 이동 또는 삭제

Binary file not shown.

Binary file not shown.

View File

@@ -197,10 +197,12 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.08); padding-top: 10pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.7);">SAM</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.7);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3);">무료 데모 및 상담</p>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 600; color: #10B981;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -200,8 +200,8 @@
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">점검/납기 알림</p>
</div>
<div style="flex: 1; background: rgba(255,255,255,0.04); border-radius: 5pt; padding: 5pt 8pt; text-align: center;">
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 600; color: rgba(255,255,255,0.6);">이카운트 연동</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">기존 ERP 동기화</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 600; color: rgba(255,255,255,0.6);">바로빌 회계</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3);">세금계산서·카드</p>
</div>
</div>
@@ -209,17 +209,19 @@
<div style="margin-top: auto; background: rgba(16,185,129,0.08); border: 1pt solid rgba(16,185,129,0.2); border-radius: 8pt; padding: 12pt 14pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="white-space: nowrap; font-size: 10pt; font-weight: 800; color: #ffffff;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 7.5pt; color: rgba(255,255,255,0.45); margin-top: 3pt;">귀사에 최적화된 맞춤 데모를 제공합니다</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.4); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #10B981;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.4); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 6pt; text-align: center;">
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2);">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2);">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -110,8 +110,8 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.08); padding-top: 12pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.7);">SAM</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.7);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.35);">뒷면에서 상세 기능과 가격을 확인하세요</p>

View File

@@ -248,10 +248,12 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.06); padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.65);">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.25); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.65);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.25); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.3);">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 600; color: #0EA5E9;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -224,17 +224,19 @@
<div style="margin-top: auto; background: rgba(14,165,233,0.08); border: 1.5pt solid rgba(14,165,233,0.2); border-radius: 8pt; padding: 10pt 14pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="white-space: nowrap; font-size: 10pt; font-weight: 800; color: #ffffff;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.4); margin-top: 2pt;">대표님 전용 대시보드를 직접 체험해 보세요</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.35); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #0EA5E9;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.35); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 5pt; text-align: center;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.18);">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.18);">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -160,8 +160,8 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.06); padding-top: 10pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.65);">SAM</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.25); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 700; color: rgba(255,255,255,0.65);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.25); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 7pt; color: rgba(255,255,255,0.3);">뒷면에서 상세 기능을 확인하세요</p>

View File

@@ -392,10 +392,12 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.06); padding-top: 7pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: rgba(255,255,255,0.6);">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: rgba(255,255,255,0.6);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.25);">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #0EA5E9;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -354,18 +354,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#0EA5E9" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #ffffff;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.35); margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #0EA5E9;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.15);">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.15);">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -250,8 +250,8 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(255,255,255,0.06); padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.6);">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.6);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.25);">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -392,10 +392,12 @@
<div style="margin-top: auto; border-top: 1pt solid #E2E8F0; padding-top: 7pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #475569;">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: #CBD5E1; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #475569;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: #CBD5E1; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8;">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #0EA5E9;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -354,18 +354,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#0EA5E9" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #0F172A;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8; margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8; margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #0EA5E9;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8; margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: #CBD5E1;">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #CBD5E1;">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -248,8 +248,8 @@
<div style="margin-top: auto; border-top: 1pt solid #E2E8F0; padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #475569;">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #CBD5E1; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #475569;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #CBD5E1; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8;">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -306,10 +306,12 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(251,191,36,0.1); padding-top: 7pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: rgba(255,255,255,0.6);">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: rgba(255,255,255,0.6);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.25);">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #FBBF24;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -292,18 +292,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#FBBF24" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #ffffff;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.25); margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #FBBF24;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.25); margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.15);">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.15);">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -204,8 +204,8 @@
<div style="margin-top: auto; border-top: 1pt solid rgba(251,191,36,0.1); padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.6);">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: rgba(255,255,255,0.6);">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.2); margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.25);">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -359,10 +359,12 @@
<div style="margin-top: auto; background: #EFF6FF; border-radius: 5pt; padding: 7pt 10pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #1E293B;">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #1E293B;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: #94A3B8;">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #2563EB;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -316,18 +316,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#FFFFFF" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #FFFFFF;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.6); margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.5); margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #FFFFFF;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.5); margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: #94A3B8;">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #94A3B8;">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</div>

View File

@@ -217,8 +217,8 @@
<div style="margin-top: auto; background: #EFF6FF; border-radius: 5pt; padding: 8pt 12pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #1E293B;">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #1E293B;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8;">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -363,10 +363,12 @@
<div style="margin-top: auto; border-top: 1pt solid #D6D3D1; padding-top: 7pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #57534E;">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: #A8A29E; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 700; color: #57534E;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: #A8A29E; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: #A8A29E;">무료 데모 신청</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #0D9488;">contact@codebridge-x.com</p>
</div>
</div>
</div>

View File

@@ -354,18 +354,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#0D9488" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #292524;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #A8A29E; margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: #A8A29E; margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #0D9488;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: #A8A29E; margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: #A8A29E;">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #A8A29E;">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -266,8 +266,8 @@
<div style="margin-top: auto; border-top: 1pt solid #D6D3D1; padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #57534E;">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #A8A29E; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #57534E;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #A8A29E; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: #A8A29E;">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -218,18 +218,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#F97316" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 800; color: #FFFFFF;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.5); margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6pt; font-weight: 700; color: #F97316;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="margin-top: 5pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5pt; color: #94A3B8;">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5pt; color: #94A3B8;">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</div>
</body>

View File

@@ -301,18 +301,20 @@
<path d="M11 6 L11 11 L15 13" fill="none" stroke="#F97316" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<div>
<p style="white-space: nowrap; font-size: 9pt; font-weight: 800; color: #FFFFFF;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: rgba(255,255,255,0.5); margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #F97316;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 6pt; color: rgba(255,255,255,0.3); margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- 회사명 -->
<div style="padding: 5pt 0; text-align: center;">
<p style="white-space: nowrap; font-size: 5.5pt; color: #94A3B8;">SAM Smart Automation Management</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #94A3B8;">(주)코드브릿지엑스 | SAM - Smart Automation Management</p>
</div>
</body>
</html>

View File

@@ -268,8 +268,8 @@
<div style="margin-top: auto; border-top: 1pt solid #E2E8F0; padding-top: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #475569;">SAM</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7.5pt; font-weight: 700; color: #475569;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<div style="text-align: right;">
<p style="white-space: nowrap; font-size: 6.5pt; color: #94A3B8;">뒷면에서 상세 기능을 확인하세요 &#9654;</p>

View File

@@ -250,15 +250,17 @@
<div style="margin-top: auto; background: #F8FAFC; border: 1pt solid #F1F5F9; border-radius: 5pt; padding: 8pt 10pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="white-space: nowrap; font-size: 8pt; font-weight: 800; color: #0F172A;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #64748B; margin-top: 1pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
<div style="text-align: right; border-left: 2pt solid #6366F1; padding-left: 8pt;">
<p style="white-space: nowrap; font-size: 5pt; color: #CBD5E1; margin-top: 1pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6pt; font-weight: 700; color: #6366F1;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 5pt; color: #CBD5E1; margin-top: 1pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<div style="margin-top: 4pt; text-align: center;">
<p style="white-space: nowrap; font-size: 4.5pt; color: #CBD5E1;">SAM</p>
<p style="white-space: nowrap; font-size: 4.5pt; color: #CBD5E1;">(주)코드브릿지엑스</p>
</div>
</body>
</html>

View File

@@ -211,17 +211,19 @@
<div style="margin-top: auto; background: #F8FAFC; border: 1pt solid #F1F5F9; border-radius: 6pt; padding: 12pt 14pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="white-space: nowrap; font-size: 10pt; font-weight: 800; color: #0F172A;">무료 데모를 신청하세요</p>
<p style="white-space: nowrap; font-size: 6pt; color: #64748B; margin-top: 2pt;">대표님 전용 대시보드를 직접 체험</p>
</div>
<div style="text-align: right; border-left: 2pt solid #6366F1; padding-left: 10pt;">
<p style="white-space: nowrap; font-size: 5.5pt; color: #CBD5E1; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 6.5pt; font-weight: 700; color: #6366F1;">contact@codebridge-x.com</p>
<p style="white-space: nowrap; font-size: 5.5pt; color: #CBD5E1; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
</div>
</div>
<!-- Footer -->
<div style="margin-top: 6pt; text-align: center;">
<p style="white-space: nowrap; font-size: 5pt; color: #CBD5E1;">SAM</p>
<p style="white-space: nowrap; font-size: 5pt; color: #CBD5E1;">(주)코드브릿지엑스</p>
</div>
</body>
</html>

View File

@@ -172,8 +172,8 @@
<!-- Footer -->
<div style="margin-top: auto; display: flex; justify-content: space-between; align-items: flex-end;">
<div>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #0F172A;">SAM</p>
<p style="white-space: nowrap; font-size: 6pt; color: #CBD5E1; margin-top: 2pt;">www.sam.it.kr</p>
<p style="white-space: nowrap; font-size: 7pt; font-weight: 600; color: #0F172A;">(주)코드브릿지엑스</p>
<p style="white-space: nowrap; font-size: 6pt; color: #CBD5E1; margin-top: 2pt;">www.codebridge-x.com</p>
</div>
<p style="white-space: nowrap; font-size: 5.5pt; color: #CBD5E1;">뒷면에서 상세 기능을 확인하세요</p>
</div>

View File

@@ -0,0 +1,119 @@
# Gemini 모델 업그레이드: 2.0-flash → 2.5-flash
**날짜:** 2026-03-03
**작업자:** Claude Code
---
## 변경 개요
Google이 2026년 6월 1일부로 Gemini 2.0 Flash 모델 서비스를 종료한다는 통보를 받아, SAM 시스템 전체의 Gemini 모델을 `gemini-2.0-flash``gemini-2.5-flash`로 마이그레이션했다.
---
## 변경 사유
- Google의 공식 메일 통보: Gemini 2.0 Flash / 2.0 Flash-Lite → 2026-06-01 강제 종료
- 마이그레이션 경로: `gemini-2.0-flash``gemini-2.5-flash`
- API 키, Base URL 변경 없음 (모델명만 변경)
---
## 수정된 파일
### API 프로젝트 (`/home/aweso/sam/api`)
| 파일 | 변경 내용 |
|------|----------|
| `.env` | `GEMINI_MODEL=gemini-2.0-flash``gemini-2.5-flash` |
| `config/services.php` | fallback 기본값 `gemini-2.0-flash``gemini-2.5-flash` |
| `app/Services/AiReportService.php` | fallback 기본값 변경 |
### MNG 프로젝트 (`/home/aweso/sam/mng`)
| 파일 | 변경 내용 |
|------|----------|
| `.env` | `GEMINI_MODEL=gemini-2.0-flash``gemini-2.5-flash` |
| `config/services.php` | fallback 기본값 변경 |
| `app/Models/System/AiConfig.php` | `DEFAULT_MODELS['gemini']` 상수 + `getActiveGemini()` fallback 변경 |
| `app/Services/NotionService.php` | fallback 기본값 변경 |
| `resources/views/system/ai-config/index.blade.php` | UI placeholder, 기본값, JS defaultModels 변경 |
| `resources/views/google-cloud/ai-guide/index.blade.php` | 서비스 현황 테이블 모델명 7곳 변경 |
| `resources/views/academy/env-management.blade.php` | 환경변수 예시 테이블 변경 |
### 문서 (`/home/aweso/sam/docs`)
| 파일 | 변경 내용 |
|------|----------|
| `guides/ai-config-settings.md` | 기본 모델명 업데이트, 최종 업데이트 날짜 변경 |
| `guides/ai-management.md` | **신규** — AI 관리 종합 가이드 (아키텍처, 버전 이력, 온보딩) |
| `guides/ai-model-update-workflow.md` | **신규** — 모델 업데이트 표준 절차 (7단계 워크플로우) |
| `changes/20260303_gemini_model_upgrade.md` | **신규** — 이 변경 이력 문서 |
### 수정하지 않은 파일 (의도적)
| 파일 | 이유 |
|------|------|
| `api/database/migrations/2026_01_27_*.php` | 이미 실행된 마이그레이션 — 변경 시 DB 무결성 문제 |
| `api/database/migrations/2026_02_07_*.php` | 동일 |
| `api/database/migrations/2026_02_09_*.php` | 동일 |
| `mng/views/google-cloud/cloud-api-pricing/index.blade.php` | `2.0 → 2.5` 마이그레이션 안내 UI — 이전 모델명이 의도적 잔존 |
---
## 서버 .env 수정 필요 (배포 후)
| 환경 | 파일 | 변수 | 담당 |
|------|------|------|------|
| 개발서버 | `/home/webservice/api/.env` | `GEMINI_MODEL=gemini-2.5-flash` | SSH 접속 수정 |
| 개발서버 | `/home/webservice/mng/.env` | `GEMINI_MODEL=gemini-2.5-flash` | SSH 접속 수정 |
| 운영서버 | `/home/webservice/api/.env` | `GEMINI_MODEL=gemini-2.5-flash` | 개발팀장 직접 |
| 운영서버 | `/home/webservice/mng/.env` | `GEMINI_MODEL=gemini-2.5-flash` | 개발팀장 직접 |
수정 후 반드시 실행:
```bash
php artisan config:clear
```
---
## DB 단가 설정 필요
MNG `/system/ai-token-usage` → 단가 설정에서:
- 기존 `gemini-2.0-flash` 단가 → 비활성화
- 신규 `gemini-2.5-flash` 단가 추가:
- `input_price_per_million`: 0.15
- `output_price_per_million`: 0.60
- `exchange_rate`: 현재 환율
---
## 테스트 체크리스트
- [x] 로컬 .env 수정 완료
- [x] 코드 fallback 전체 변경 완료
- [ ] 로컬 연결 테스트 (MNG `/system/ai-config`)
- [ ] 개발서버 .env 수정 + config:clear
- [ ] 개발서버 연결 테스트
- [ ] 운영서버 .env 수정 + config:clear
- [ ] DB 단가 설정 (gemini-2.5-flash)
- [ ] 토큰 사용량 로그 확인 (새 모델명)
---
## 롤백 절차
문제 발생 시 `.env`만 되돌리면 즉시 복구:
```bash
# 모든 환경의 .env에서
GEMINI_MODEL=gemini-2.0-flash
php artisan config:clear
```
---
## 관련 문서
- [AI 관리 종합 가이드](../guides/ai-management.md)
- [모델 업데이트 워크플로우](../guides/ai-model-update-workflow.md)
- [AI 설정 기술문서](../guides/ai-config-settings.md)

View File

@@ -0,0 +1,165 @@
# 계좌 입출금내역 부분 월 조회 시 무한루프 크래시 수정
**날짜:** 2026-03-04
**작업자:** Claude Code
---
## 변경 개요
계좌 입출금내역 페이지에서 **날짜를 수동 입력**하여 조회 시 500 에러가 발생하는 문제를 수정했다.
편의 버튼(이번달, 지난달 등)은 항상 전체 월(1일~말일)을 사용하여 문제가 없었으나,
수동으로 날짜를 입력하면 **부분 월**(예: 12/01~12/18)이 되어 무한루프가 발생했다.
---
## 근본 원인
### `splitDateRangeMonthly()` 함수의 cursor 이동 버그
긴 기간 조회 시 바로빌 SOAP API의 한계로 인해 기간을 **월별 청크**로 분할하는 함수에서,
endDate가 **월 중간**일 때 cursor가 **같은 달 1일로 되돌아가** 무한루프가 발생했다.
```php
// ❌ 버그 코드 — endDate가 월 중간이면 무한루프
$cursor = $chunkEnd->copy()->addDay()->startOfMonth();
// 예시: endDate = 20251218
// chunkEnd = 20251218
// → addDay() = 20251219
// → startOfMonth() = 20251201 ← 같은 달 1일로 되돌아감!
// → while($cursor <= $end) 조건 여전히 true → 무한 반복
```
```php
// ✅ 수정 코드 — chunkStart 기준으로 다음 월로 이동
$cursor = $chunkStart->copy()->addMonth()->startOfMonth();
// 예시: startDate = 20251201
// chunkStart = 20251201
// → addMonth() = 20260101
// → startOfMonth() = 20260101 ← 다음 달로 정상 이동
// → while($cursor <= $end) 조건 false → 루프 종료
```
### 재현 조건
| 조건 | 결과 |
|------|------|
| 전체 월 (12/01~12/31) | 정상 — `addDay()` = 01/01 → `startOfMonth()` = 01/01 |
| 부분 월 (12/01~12/18) | **무한루프**`addDay()` = 12/19 → `startOfMonth()` = 12/01 |
| 다중 월 (12/01~02/18) | **무한루프** — 마지막 월이 부분 월이면 동일 증상 |
### 증상
- PHP 프로세스가 메모리 한도(256M/512M)에 도달하여 **Fatal Error로 크래시**
- Laravel 로그에 에러 기록 없음 (try-catch 밖에서 프로세스가 종료)
- 프론트엔드에 `서버 응답 오류 (500):` (빈 응답 본문)
---
## 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `app/Http/Controllers/Barobill/EaccountController.php` | `splitDateRangeMonthly()` cursor 이동 로직 수정 |
---
## 검증 결과
tinker에서 수정 전후 비교 테스트:
```
=== 수정 전 (버그): 20251201~20251218 ===
→ 같은 청크 무한 반복 (10회 제한으로 강제 중단)
=== 수정 후: 20251201~20251218 ===
→ [{start: 20251201, end: 20251218}] ← 1개 청크, 정상
=== 수정 후: 20251201~20260218 (다중 월) ===
→ [{20251201~20251231}, {20260101~20260131}, {20260201~20260218}] ← 3개 청크, 정상
=== 수정 후: 20251215~20251231 ===
→ [{start: 20251215, end: 20251231}] ← 1개 청크, 정상
```
---
## 동일 패턴 코드베이스 점검 결과
`sam/mng` 전체를 검색하여 유사 패턴을 점검했다:
| 파일 | 함수 | 패턴 | 위험도 |
|------|------|------|--------|
| `EaccountController.php` | `splitDateRangeMonthly()` | 월별 청크 분할 | ✅ 수정 완료 |
| `DashboardStatService.php` | `generateDateRange()` | `addDay()` 단순 증가 | 안전 |
| `InspectionCycle.php` | `getHolidayDates()` | `addDay()` 단순 증가 | 안전 |
| `CorporateCardController.php` | `getNextBusinessDay()` | `addDay()` 단순 증가 | 안전 |
| `PartitionManagementService.php` | `addPartitions()` | `for` 루프 (고정 횟수) | 안전 |
> **결론**: `EaccountController` 외에 동일 버그 패턴 없음.
> 다른 코드들은 모두 `addDay()` 단순 증가 패턴을 사용하여 무한루프 위험 없음.
---
## 교훈 및 방지 규칙
### R1. 날짜 cursor 이동 시 `chunkEnd` 기반 이동 금지
```php
// ❌ 위험: chunkEnd가 월 중간이면 startOfMonth()가 같은 달로 되돌림
$cursor = $chunkEnd->copy()->addDay()->startOfMonth();
// ✅ 안전: chunkStart 기준으로 항상 다음 월로 이동
$cursor = $chunkStart->copy()->addMonth()->startOfMonth();
```
### R2. 날짜 루프에 안전장치(max iterations) 추가 권장
```php
$maxIterations = 120; // 10년 = 120개월
$iterations = 0;
while ($cursor->lte($end) && $iterations < $maxIterations) {
// ... 청크 처리 ...
$iterations++;
}
if ($iterations >= $maxIterations) {
Log::error('날짜 분할 루프 안전장치 작동', compact('startDate', 'endDate'));
}
```
### R3. 부분 월 테스트 필수
날짜 범위를 분할하는 코드 작성/수정 시 반드시 다음 케이스를 테스트:
- [ ] 전체 월 (01일~말일)
- [ ] 부분 월 — 시작 (01일~중간)
- [ ] 부분 월 — 끝 (중간~말일)
- [ ] 다중 월 (마지막 월이 부분 월)
- [ ] 같은 날 (시작일 = 종료일)
---
## 부수 개선 사항
이 문제 조사 과정에서 추가로 발견/수정된 항목:
| 항목 | 내용 |
|------|------|
| WSDL 캐싱 | `WSDL_CACHE_NONE``WSDL_CACHE_BOTH` (4개 바로빌 컨트롤러 전체) |
| 소켓 타임아웃 | `default_socket_timeout` 60→120초 연장 |
| Shutdown handler | PHP Fatal Error 감지 시 Laravel 로그에 기록 |
| SOAP 호출 로깅 | 호출 시작/완료 시간 + 소요시간(ms) 기록 |
---
## 관련 문서
- `app/Http/Controllers/Barobill/EaccountController.php` — 바로빌 계좌 입출금내역
---
**최종 업데이트**: 2026-03-04

View File

@@ -0,0 +1,69 @@
# 품의서 지급방법 UI 개선
**날짜:** 2026-03-06
**작업자:** Claude Code
## 변경 개요
품의서 2종(구매품의서, 비용정산품의서)에 지급방법 선택 기능을 추가/개선하였다.
## 변경 내용
### 1. 구매품의서 (pr_purchase) - 지급방법 추가
- 납품 정보(납품업체/납품예정일/납품장소) 아래에 **지급방법 radio** 추가
- 옵션: `법인카드` / `계좌이체`
- **일괄 선택** 방식 (전체 구매건에 하나의 지급방법)
### 2. 비용정산품의서 (pr_settlement) - 지급방법 행별 변경
- 기존: 테이블 아래에 일괄 radio (법인카드/개인선지출)
- 변경: 각 내역행에 **지급방법 select** 컬럼 추가
- 테이블 하단에 **지급방법별 합계표** 추가 (법인카드 합계 / 개인선지출 합계)
- 이유: 하나의 정산서에 법인카드/개인선지출 내역이 혼재할 수 있음
### 3. 지출품의서 (pr_expense) - 라벨 변경
- `사용일자` -> `지출일자` 라벨 변경 (폼 + 조회 화면)
## 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `mng/resources/views/approvals/partials/_purchase-request-form.blade.php` | 구매품의서 지급방법 radio 추가, 비용정산품의서 행별 select + 합계표, 지출일자 라벨 변경 |
| `mng/resources/views/approvals/partials/_purchase-request-show.blade.php` | 구매품의서/비용정산품의서 조회 화면 동기화 |
## Alpine.js 데이터 변경
### 구매품의서
```javascript
// formData에 추가
payment_method: initialData?.payment_method || '',
// getFormData()에 포함
{ ...base, ..., payment_method: this.formData.payment_method }
```
### 비용정산품의서
```javascript
// makeItem()에 추가
payment_method: data?.payment_method || '',
// computed 속성 추가
get corporateCardTotal() { /* corporate_card 행만 합산 */ },
get personalAdvanceTotal() { /* personal_advance 행만 합산 */ },
// getFormData() 변경
// 기존: payment_method: this.formData.payment_method (일괄)
// 변경: 각 item.payment_method (행별) + corporate_card_total, personal_advance_total
```
## 관련 문서
- [결재 양식 기술 명세](../features/approvals/form-types.md) - 섹션 12, 14 업데이트
---
**최종 업데이트**: 2026-03-06

View File

@@ -0,0 +1,76 @@
# 영업 정책 변경 — 수당 구조 개편 및 무료 체험 폐지
**날짜:** 2026-03-16
**작업자:** Claude Code
**승인:** 경영진 결정
## 변경 개요
경영진 판단에 따라 영업 수당 구조를 전면 개편하고, 무료 체험 제도를 폐지합니다.
## 주요 변경사항
### 1. 수당 구조 개편
| 항목 | 변경 전 | 변경 후 |
|------|--------|--------|
| **개인 가입** | 파트너 20% + 매니저 5% | 파트너 20% + 유치 파트너 5% |
| **단체 가입** | 단체 30% + 매니저 0% | 단체 30% + 유치 파트너 3% |
| **매니저 수당** | 개발비의 5% (요율) | 첫 달 구독료 (고정액) |
| **협업지원금 3%** | 유치 파트너 있음 체크박스 (선택) | 폐지 (비공식 지원이므로 공식 문서에서 제거) |
### 2. 무료 체험 폐지
| 항목 | 변경 전 | 변경 후 |
|------|--------|--------|
| **무료 체험** | 1주일(7일) 구독료 면제 | **전면 폐지** |
| **사유** | — | 신규 개발 컨셉에 무료 체험이 존재할 수 없는 구조 |
### 3. 용어 통일
| 변경 전 | 변경 후 | 비고 |
|--------|--------|------|
| 매니저 수당 (상품 수당) | 유치 파트너 수당 | 상품관리, 수당 시뮬레이션 |
| 유치자 | 유치 파트너 | 공식 용어로 통일 |
| 추천인(유치자) | 추천인(유치 파트너) | 파트너 관리 화면 |
### 4. 개발비-구독료 연동 공식 변경
| 항목 | 변경 전 | 변경 후 |
|------|--------|--------|
| **연동 방식** | 정비례 (개발비 UP → 구독료 UP) | 반비례 (개발비 UP → 구독료 DOWN) |
| **공식** | 구독료 = 조정개발비 × (기준구독료/기준개발비) | 구독료 = (기준개발비 × 기준구독료) ÷ 조정개발비 |
### 5. 가격 시뮬레이터 기능 개선
- 개발비 직접 입력 기능 추가 (콤마 포맷, 슬라이더와 동기화)
- 본사 순수익/마진율 표시 제거
## 수정된 파일
### MNG (코드)
| 파일 | 변경 내용 |
|------|----------|
| `resources/views/sales/price-simulator/index.blade.php` | 수당 구조 개편, 무료 체험 삭제, 반비례 연동, 직접 입력 |
| `resources/views/sales/products/index.blade.php` | 매니저→유치 파트너 |
| `resources/views/sales/products/partials/product-list.blade.php` | 매니저→유치 파트너 |
| `resources/views/sales/admin-prospects/partials/show-modal.blade.php` | 매니저→유치 파트너 |
| `resources/views/sales/managers/*.blade.php` | 유치자→유치 파트너 (6개 파일) |
### Docs (문서)
| 파일 | 변경 내용 |
|------|----------|
| `rules/partner-commission.md` | 수당 구조 전면 개편 |
| `rules/customer-pricing.md` | 무료 체험 삭제 |
| `guides/sam-pricing-simple-guide.md` | 무료 체험 삭제, 수당 구조 반영 |
| `guides/price-simulator-partner-guide.md` | 시뮬레이터 변경사항 반영 |
## 관련 문서
- `rules/partner-commission.md` — 수당 체계 정책
- `rules/customer-pricing.md` — 고객 요금 정책
- `guides/sam-pricing-simple-guide.md` — 영업파트너 가격 안내
- `guides/price-simulator-partner-guide.md` — 가격 시뮬레이터 가이드
---
**최종 업데이트**: 2026-03-16

View File

@@ -0,0 +1,328 @@
# 계정과목 코드 변경 매핑 (더존 3자리 → KIS 5자리)
**날짜:** 2026-03-17
**작업자:** Claude Code
## 변경 개요
기존 더존 표준 3자리 계정과목 163개를 KIS 5자리 표준 458개 체계로 전면 교체.
이름이 동일하거나 유사한 항목을 기준으로 매핑한 결과이며, 매핑 불가 항목은 별도 표기.
---
## 1. 자산 (Assets)
### 1.1 유동자산 — 당좌자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 101 | 현금 | 10100 | 현금 | |
| 102 | 당좌예금 | 10200 | 당좌예금 | |
| 103 | 보통예금 | 10300 | 보통예금 | |
| 104 | 정기예금 | 10400 | 기타제예금 | 이름 변경 |
| 105 | 정기적금 | 10500 | 정기적금 | |
| 106 | 외화예금 | — | — | ❌ KIS 해당 없음 |
| 107 | 별단예금 | — | — | ❌ KIS 해당 없음 |
| 108 | 외상매출금 | 10800 | 외상매출금 | |
| 109 | 대손충당금 | 10900 | 대손충당금(외상매출금) | 이름 변경 |
| 110 | 받을어음 | 11000 | 받을어음 | |
| 111 | 단기대여금 | 11400 | 단기대여금 | |
| 112 | 미수금 | 12000 | 미수금 | |
| 113 | 미수수익 | 11600 | 미수수익 | |
| 114 | 선급금 | 13100 | 선급금 | |
| 115 | 선급비용 | 13300 | 선급비용 | |
| 116 | 가지급금 | 13400 | 가지급금 | |
| 117 | 부가세대급금 | 13500 | 부가세대급금 | |
| 118 | 선납세금 | 13600 | 선납세금 | |
| 119 | 유가증권 | 12300 | 매도가능증권 | ⚠️ 이름 변경, 확인 필요 |
| 120 | 단기금융상품 | 10600 | 기타단기금융상품예금 | ⚠️ 이름 변경, 확인 필요 |
### 1.2 유동자산 — 재고자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 141 | 상품 | 14600 | 상품 | |
| 142 | 제품 | 15000 | 제품 | |
| 143 | 반제품 | — | — | ❌ KIS 해당 없음 |
| 144 | 재공품 | 16900 | 재공품 | |
| 145 | 원재료 | 15300 | 원재료 | |
| 146 | 부재료 | 16200 | 부재료 | |
| 147 | 저장품 | 16700 | 저장품 | |
| 148 | 미착품 | 16800 | 미착품 | |
### 1.3 비유동자산 — 투자자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 151 | 장기금융상품 | 17600 | 장기성예금 | 이름 변경 |
| 152 | 장기대여금 | 17900 | 장기대여금 | |
| 153 | 투자유가증권 | 17800 | 장기투자증권 | 이름 변경 |
| 154 | 출자금 | 19100 | 출자금 | |
| 155 | 장기성매출채권 | 96500 | 장기외상매출금 | 이름 변경 |
| 156 | 보증금 | 96400 | 기타보증금 | 이름 변경 |
| 157 | 임차보증금 | 96200 | 임차보증금 | |
### 1.4 비유동자산 — 유형자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 161 | 토지 | 20100 | 토지 | |
| 162 | 건물 | 20200 | 건물 | |
| 163 | 건물감가상각누계액 | 20300 | 감가상각누계액(건물) | 이름 변경 |
| 164 | 구축물 | 20400 | 구축물 | |
| 165 | 구축물감가상각누계액 | 20500 | 감가상각누계액(구축물) | 이름 변경 |
| 166 | 기계장치 | 20600 | 기계장치 | |
| 167 | 기계장치감가상각누계액 | 20700 | 감가상각누계액(기계장치) | 이름 변경 |
| 168 | 차량운반구 | 20800 | 차량운반구 | |
| 169 | 차량운반구감가상각누계액 | 20900 | 감가상각누계액(차량운반구) | 이름 변경 |
| 170 | 공구와기구 | 21000 | 공구와기구 | |
| 171 | 공구와기구감가상각누계액 | 21100 | 감가상각누계액(공구와기구) | 이름 변경 |
| 172 | 비품 | 21200 | 비품 | |
| 173 | 비품감가상각누계액 | 21600 | 감가상각누계액(비품) | 이름 변경 |
| 174 | 건설중인자산 | 21300 | 건설중인자산 | |
### 1.5 비유동자산 — 무형자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 181 | 영업권 | 23100 | 영업권 | |
| 182 | 산업재산권 | 23200 | 특허권 | ⚠️ 이름 변경, 확인 필요 |
| 183 | 개발비 | 23900 | 개발비 | |
| 184 | 소프트웨어 | 24000 | 소프트웨어 | |
| 185 | 창업비 | 23800 | 창업비 | |
### 1.6 기타 비유동자산
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 191 | 이연법인세자산 | 96100 | 이연법인세자산 | |
---
## 2. 부채 (Liabilities)
### 2.1 유동부채
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 201 | 외상매입금 | 25100 | 외상매입금 | |
| 202 | 지급어음 | 25200 | 지급어음 | |
| 203 | 단기차입금 | 26000 | 단기차입금 | |
| 204 | 미지급금 | 25300 | 미지급금 | |
| 205 | 미지급비용 | 26200 | 미지급비용 | |
| 206 | 선수금 | 25900 | 선수금 | |
| 207 | 예수금 | 25400 | 예수금 | |
| 208 | 부가세예수금 | 25500 | 부가세예수금 | |
| 209 | 미지급세금 | 26100 | 미지급세금 | |
| 210 | 미지급법인세 | — | — | ❌ KIS 해당 없음 |
| 211 | 미지급배당금 | 26500 | 미지급배당금 | |
| 212 | 가수금 | 25700 | 가수금 | |
| 213 | 선수수익 | — | — | ❌ KIS 해당 없음 |
| 214 | 유동성장기부채 | 26400 | 유동성장기차입금 | 이름 변경 |
| 215 | 당기법인세부채 | — | — | ❌ KIS 해당 없음 |
### 2.2 비유동부채
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 251 | 장기차입금 | 29300 | 장기차입금 | |
| 252 | 사채 | 29100 | 사채 | |
| 253 | 장기성매입채무 | 30800 | 장기성지급어음 | ⚠️ 이름 변경, 확인 필요 |
| 254 | 퇴직급여충당부채 | 29500 | 퇴직급여충당부채 | |
| 255 | 장기미지급금 | — | — | ❌ KIS 해당 없음 |
| 256 | 임대보증금 | 29400 | 임대보증금 | |
| 257 | 이연법인세부채 | 27300 | 이연법인세부채 | |
---
## 3. 자본 (Capital)
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 301 | 자본금 | 33100 | 자본금 | |
| 311 | 주식발행초과금 | 34100 | 주식발행초과금 | |
| 312 | 감자차익 | 34200 | 감자차익 | |
| 313 | 자기주식처분이익 | 34300 | 자기주식처분이익 | |
| 321 | 이익준비금 | 35100 | 이익준비금 | |
| 322 | 기업합리화적립금 | 35200 | 기업합리화적립금 | |
| 323 | 재무구조개선적립금 | 35400 | 재무구조개선적립금 | |
| 324 | 임의적립금 | 35500 | 임의적립금 | |
| 331 | 이월이익잉여금 | 37500 | 이월이익잉여금 | |
| 332 | 당기순이익 | 37900 | 당기순이익 | |
| 333 | 전기이월이익잉여금 | — | — | ❌ KIS 해당 없음 |
---
## 4. 수익 (Revenue)
### 4.1 매출
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 401 | 상품매출 | 40100 | 상품매출 | |
| 402 | 제품매출 | 40400 | 제품매출 | |
| 403 | 공사수입 | 40700 | 공사수입금 | 이름 변경 |
| 404 | 용역수입 | — | — | ❌ KIS 해당 없음 |
| 405 | 임대수입 | 41000 | 임대료수입 | 이름 변경 |
| 406 | 수출매출 | — | — | ❌ KIS 해당 없음 |
| 407 | 기타매출 | — | — | ❌ KIS 해당 없음 |
| 408 | 매출에누리 | 40200 | 매출환입및에누리(상품) | ⚠️ 이름 변경, 확인 필요 |
| 409 | 매출환입 | — | — | ❌ 40200에 통합 |
| 410 | 매출할인 | 40300 | 매출할인(상품) | 이름 변경 |
### 4.2 영업외수익
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 901 | 이자수익 | 90100 | 이자수익 | |
| 902 | 배당금수익 | 90300 | 배당금수익 | |
| 903 | 임대료수익 | 90400 | 수입임대료 | 이름 변경 |
| 904 | 유가증권처분이익 | 90600 | 단기투자자산처분이익 | ⚠️ 이름 변경, 확인 필요 |
| 905 | 유형자산처분이익 | 91400 | 유형자산처분이익 | |
| 906 | 외환차익 | 90700 | 외환차익 | |
| 907 | 외화환산이익 | 91000 | 외화환산이익 | |
| 908 | 대손충당금환입 | 90800 | 대손충당금환입 | |
| 909 | 잡이익 | 93000 | 잡이익 | |
---
## 5. 비용 (Expenses)
### 5.1 매출원가
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 501 | 상품매출원가 | 45100 | 상품매출원가 | |
| 502 | 기초상품재고액 | — | — | ❌ KIS 해당 없음 |
| 503 | 당기상품매입액 | — | — | ❌ KIS 해당 없음 |
| 504 | 기말상품재고액 | — | — | ❌ KIS 해당 없음 |
| 505 | 제품매출원가 | 45500 | 제품매출원가 | |
| 506 | 기초제품재고액 | — | — | ❌ KIS 해당 없음 |
| 507 | 당기제품제조원가 | — | — | ❌ KIS 해당 없음 |
| 508 | 기말제품재고액 | — | — | ❌ KIS 해당 없음 |
| 509 | 타계정대체 | — | — | ❌ KIS 해당 없음 |
### 5.2 판매비와관리비
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 801 | 급여 | 80100 | 임원급여 | ⚠️ KIS에서 임원/직원 분리 (80200 직원급여) |
| 802 | 상여금 | 80300 | 상여금 | |
| 803 | 잡급 | 80500 | 잡급 | |
| 804 | 퇴직급여 | 80600 | 퇴직급여 | |
| 805 | 복리후생비 | 81100 | 복리후생비 | |
| 806 | 여비교통비 | 81200 | 여비교통비 | |
| 807 | 접대비 | 81300 | 접대비 | |
| 808 | 통신비 | 81400 | 통신비 | |
| 809 | 수도광열비 | 81500 | 수도광열비 | |
| 810 | 전력비 | 81600 | 전력비 | |
| 811 | 세금과공과 | 81700 | 세금과공과금 | 이름 변경 |
| 812 | 임차료 | 81900 | 지급임차료 | 이름 변경 |
| 813 | 감가상각비 | 81800 | 감가상각비 | |
| 814 | 무형자산상각비 | 84000 | 무형고정자산상각 | 이름 변경 |
| 815 | 수선비 | 82000 | 수선비 | |
| 816 | 보험료 | 82100 | 보험료 | |
| 817 | 차량유지비 | 82200 | 차량유지비 | |
| 818 | 운반비 | 82400 | 운반비 | |
| 819 | 교육훈련비 | 82500 | 교육훈련비 | |
| 820 | 도서인쇄비 | 82600 | 도서인쇄비 | |
| 821 | 사무용품비 | 82900 | 사무용품비 | |
| 822 | 소모품비 | 83000 | 소모품비 | |
| 823 | 지급수수료 | 83100 | 지급수수료 | |
| 824 | 광고선전비 | 83300 | 광고선전비 | |
| 825 | 대손상각비 | 83500 | 대손상각비 | |
| 826 | 건물관리비 | 83700 | 건물관리비 | |
| 827 | 경상연구개발비 | 82300 | 경상연구개발비 | |
| 828 | 판매수수료 | 83900 | 판매수수료 | |
| 829 | 판매촉진비 | 83400 | 판매촉진비 | |
| 830 | 포장비 | 82800 | 포장비 | |
| 831 | 하역비 | — | — | ❌ KIS 해당 없음 |
| 832 | 보관료 | 83200 | 보관료 | |
| 833 | 견본비 | 84200 | 견본비 | |
| 834 | 회의비 | 82700 | 회의비 | |
| 835 | 잡비 | 84800 | 잡비 | |
| 836 | 외주가공비 | 50200 | 외주가공비 | ⚠️ 제조원가로 분류 변경 |
| 837 | 리스료 | — | — | ❌ KIS 해당 없음 |
| 838 | 용역비 | — | — | ❌ KIS 해당 없음 |
### 5.3 영업외비용
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 951 | 이자비용 | 93100 | 이자비용 | |
| 952 | 기부금 | 93300 | 기부금 | |
| 953 | 유가증권처분손실 | 93800 | 단기투자자산처분손실 | ⚠️ 이름 변경, 확인 필요 |
| 954 | 유형자산처분손실 | 95000 | 투자자산처분손실 | ⚠️ 이름 변경, 확인 필요 |
| 955 | 재고자산감모손실 | 93900 | 재고자산감모손실 | |
| 956 | 외환차손 | 93200 | 외환차손 | |
| 957 | 외화환산손실 | 93500 | 외화환산손실 | |
| 958 | 잡손실 | 96000 | 잡손실 | |
### 5.4 법인세비용
| 이전 코드 | 이전 명칭 | 신규 코드 | 신규 명칭 | 비고 |
|:---------:|----------|:---------:|----------|------|
| 991 | 법인세비용 | 99800 | 법인세 | 이름 변경 |
---
## 6. 코드에서 하드코딩 수정 완료된 항목
이번 작업에서 MNG 소스코드에 하드코딩된 계정코드를 수정한 항목:
| 이전 | 신규 | 용도 | 수정 파일 |
|:----:|:----:|------|----------|
| 108 | 10800 | 외상매출금 (미수금 조회) | ReceivableController, hometax/index |
| 204 | 20400 | 미지급금 (미지급금 조회) | PayableController, payables.blade |
| 205 | 20500 | 미지급비용 (미지급금 조회/전표 생성) | PayableController, EcardController, PayrollController, payables.blade, ecard/index |
| 207 | 20700 | 예수금 (급여 전표) | PayrollController |
| 801 | 80100 | 급여 (급여 전표) | PayrollController |
| 103 | 10300 | 보통예금 (은행거래 분개) | journal-entries.blade |
| 135 | 13500 | 부가세대급금 (카드/매입 분개) | EcardController, ecard/index, journal-entries.blade |
| 253 | 25300 | 미지급금 (매입 분개) | journal-entries.blade |
| 826 | 82600 | 잡비 (카드 분개 기본값) | EcardController, ecard/index |
| 401 | 40100 | 상품매출 (홈택스 매출 분개) | hometax/index |
| 208 | 20800 | 부가세예수금 (홈택스 매출 분개) | hometax/index |
| 501 | 50100 | 상품매출원가 (홈택스 매입 분개) | hometax/index |
| 117 | 11700 | 부가세대급금 (홈택스 매입 분개) | hometax/index |
| 201 | 20100 | 외상매입금 (홈택스 매입 분개) | hometax/index |
---
## 7. 통계 요약
| 구분 | 개수 |
|------|:----:|
| 이전 계정과목 (더존 3자리) | 163개 |
| 신규 계정과목 (KIS 5자리) | 458개 |
| 정상 매핑 (이름 동일) | 104개 |
| 이름 변경 매핑 | 30개 |
| 확인 필요 (⚠️) | 11개 |
| KIS 해당 없음 (❌) | 18개 |
---
## 관련 파일
| 파일 | 설명 |
|------|------|
| `mng/database/seeders/AccountCodeSeeder.php` | 이전 3자리 계정과목 163개 원본 |
| `api/database/migrations/2026_03_06_220000_seed_default_account_codes_for_all_tenants.php` | KIS 5자리 기본 128건 |
| `api/database/migrations/2026_03_09_000000_seed_additional_account_codes_for_all_tenants.php` | KIS 5자리 추가 330건 |
| `api/database/migrations/2026_03_17_111249_replace_tenant1_account_codes_with_kis_standard.php` | tenant_id=1 전면 교체 |
| `mng/database/migrations/2026_03_17_112601_replace_codebridge_account_codes_with_kis_standard.php` | codebridge DB 교체 |
---
## 관련 커밋
| 저장소 | 커밋 | 내용 |
|--------|------|------|
| API | `ead546e` | feat: [account] tenant_id=1 계정과목을 KIS 5자리 표준으로 완전 교체 |
| MNG | `c9f35811` | feat: [account] codebridge DB 계정과목을 KIS 5자리 표준으로 교체 |
| MNG | `5de768b7` | fix: [finance] 미수금/미지급금 계정코드 5자리로 수정 |
| MNG | `0cc0ddf4` | fix: [finance] 전체 하드코딩 계정코드 3자리→5자리 수정 |
---
**최종 업데이트**: 2026-03-17

42
contracts/CHANGELOG.md Normal file
View File

@@ -0,0 +1,42 @@
# 계약서 개정이력
> **작성일**: 2026-02-22
> **관리 대상**: 전자계약 DOCX 4종
---
## v4.1 (2026-02-22)
**작성자**: 개발팀
**대상**: 고객사 서비스 이용계약서
- 제4조에 사용량 기반 추가 과금 조항(4.5) 추가
- 파일 저장 공간: 기본 100GB 초과 시 100GB당 50,000원/월
- AI 토큰: 월 100만 토큰 기본, 초과 시 1,000토큰 단위 실비 과금
- 제4조에 바로빌 부가 서비스 요금 조항(4.6) 추가
- 계좌조회, 카드내역, 세금계산서 발행 요금 명시
- 홈택스 매입/매출 조회는 회사 부담 명시
---
## v4.0 (2026-02-22)
**작성자**: 개발팀
- 계약서 버전 관리 시스템 도입
- DOCX → Markdown 미러링 체계 구축
- 4개 전자계약 문서에 개정이력 테이블 삽입
- 동기화 검증 스크립트 구축
### 대상 문서
| 파일 | 문서명 |
|------|--------|
| `01_고객_서비스이용계약서_v4_0_전자서명용.docx` | 고객사 서비스 이용계약서 |
| `비밀유지서약서.docx` | 비밀유지서약서 (NDA) |
| `영업파트너 위촉계약서.docx` | 영업파트너 위촉계약서 |
| `영업파트너 위촉계약서(단체용).docx` | 영업파트너 위촉계약서 (단체용) |
---
**최종 업데이트**: 2026-02-22 (v4.1)

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,458 @@
---
title: "고객사 서비스 이용계약서"
version: "v4.2"
date: "2026-02-24"
docx_file: "01_고객_서비스이용계약서_v4_0_전자서명용.docx"
---
# 고객사 서비스 이용계약서
Customer Service Agreement
계약번호:
계약일:
본 계약은 주식회사 코드브릿지엑스(이하 “회사”)와 간에 SAM 서비스 제공과 관련하여 다음과 같이 계약을 체결합니다.
## 제1조 (계약의 목적)
본 계약은 회사가 고객에게 SAM(Smart MES/ERP Solution) 서비스를 제공함에 있어 필요한 사항을 규정하고, 양측의 권리와 의무를 명확히 함을 목적으로 합니다.
## 제2조 (용어의 정의)
- **서비스**: 회사가 제공하는 SAM 클라우드 기반 MES/ERP 솔루션
- **SaaS**: Software as a Service (서비스형 소프트웨어)
- **서비스 게시**: 개발 완료 후 고객이 서비스에 접근 가능하도록 제공하는 것
- **액세스 제공**: 고객에게 서비스 사용 권한을 부여하는 것
- **검수 기간**: 서비스 게시 전 고객이 완성도를 확인하는 기간 (최대 1개월)
- **하자**: 계약서에 명시된 기능의 오류, 미구현, 성능 미달 등
- **하자담보 책임**: 서비스 게시 후 1년간 하자를 무상으로 수정하는 의무
## 제3조 (서비스 내용)
### 3.1 서비스 범위
회사는 다음의 서비스를 제공합니다:
- **맞춤형 개발**:
- 고객 요구사항에 맞춘 SAM 시스템 개발
- 개발 범위: [별첨 기획서 참조]
- 개발 기간: 계약일로부터 [ 3 ]개월
- **클라우드 제공** (SaaS):
- 연중무휴 24시간 접근 가능
- 자동 백업 및 보안
- **기술 지원**:
- 고객센터 운영 (평일 09:00~18:00)
- 이메일 지원 (24시간)
- 긴급 장애 대응
- **하자담보 책임** (1년):
- 서비스 게시일로부터 1년간 무상 수정
- 버그, 미구현 기능, 성능 개선 등
### 3.2 제공 방식
- 회사는 서비스를 **SaaS 방식**으로 제공합니다.
- 고객은 서비스에 대한 **사용 권한**만을 부여받으며, 소유권은 회사에 귀속됩니다.
- 소스코드는 제공되지 않습니다.
## 제4조 (비용 및 납부)
### 4.1 개발비
| 구분 | 금액 (부가세 별도) | 지급 시기 | 비고 |
| --- | --- | --- | --- |
| 1차 개발비 | 총 개발비의 50% | 계약 체결 시 | 착수금 |
| 2차 개발비 | 총 개발비의 50% | 서비스 게시일로부터 3일 이내 | 잔금 |
| 총 개발비 | [ ]원 | | |
### 4.2 월 구독료
| 구분 | 금액 (부가세 별도) | 지급 시기 | 비고 |
| --- | --- | --- | --- |
| 월 구독료 | 원 ~ | 매월 말일 | 후불제, 사용량 기준 청구 |
> ⚠️ 중요: - 월 구독료는 원이며, 영업 협상 및 개발 범위에 따라 증액될 수 있습니다.
- 계약 시 확정된 구독료: [ ]원/월
### 4.3 납부 방법
- **개발비**:
- 계좌이체 (세금계산서 발행)
- 입금 계좌: 기업은행 170-175519-04-011  (주)코드브릿지엑스
- **구독료**:
- CMS 자동이체 (권장)
- 또는 세금계산서 발행 후 계좌이체
### 4.4 잔금 지급 기한 [법률 검토 반영]
- **지급 기한**: 서비스 게시일로부터 **3일 이내**
- **사전 준비**: 회사는 영업 단계부터 납품 일정을 공유하여 고객이 미리 준비할 수 있도록 합니다.
- **미납 시 조치**: 제13조 참조
### 4.5 사용량 기반 추가 과금
기본 제공 한도 초과 시 다음과 같이 실비 과금됩니다.
| 항목 | 기본 제공 | 추가 과금 기준 |
| --- | --- | --- |
| 파일 저장 공간 | 100GB | 100GB당 50,000원/월 (부가세 별도) |
| AI 토큰 | 월 100만 토큰 | 1,000토큰 단위 실비 과금 |
- **파일 저장 공간: **기본 100GB를 초과하는 경우 100GB 단위로 월 50,000원(부가세 별도)이 추가 과금됩니다.
- **AI 토큰: **월 100만 토큰 기본 제공되며, 초과 사용 시 1,000토큰 단위로 실비 과금됩니다.
- 미사용 잔여 토큰은 이월되지 않습니다. (매월 1일 갱신)
- 기본 제공량 80%, 100% 소진 시 자동 알림이 발송됩니다.
### 4.6 바로빌 부가 서비스 요금
고객이 선택적으로 이용하는 바로빌 연동 서비스의 요금은 다음과 같습니다.
| 서비스 | 과금 방식 | 기본 제공 | 추가 과금 |
| --- | --- | --- | --- |
| 계좌조회 | 월정액 10,000원 | 1계좌 | 추가 1계좌당 10,000원 |
| 카드내역 | 월정액 10,000원 | 5장 | 추가 1장당 5,000원 |
| 세금계산서 발행 | 건별 | 100건 | 추가 50건당 5,000원 |
- **바로빌 서비스 요금은 고객이 부담하며, 월 구독료와 별도로 청구됩니다.**
- 홈택스 매입/매출 조회 서비스(월 30,000원)는 회사가 부담합니다.
- 상기 금액은 부가세 별도입니다.
## 제5조 (마일스톤 및 진행 일정)
### 5.1 개발 단계 (5단계 통일)
| 단계 | 주요 활동 | 진행률 | 기간 | 납부 |
| --- | --- | --- | --- | --- |
| M1 | 요구사항 분석 및 기획 | 20% | [ 2 ]주 | 1차 개발비 (착수금 50%) |
| M2 | 설계 및 개발 착수 | 50% | [ 2 ]주 | - |
| M3 | 개발 진행 (50% 완료) | 60% | [ 2 ]주 | - |
| M4 | 개발 완료 및 테스트 | 80% | [ 2 ]주 | - |
| M5 | 검수 및 서비스 게시 | 100% | 최대 2주 | 2차 개발비 (잔금 50%) |
> ⚠️ 중요: - 5단계 마일스톤으로 통일 관리 - M5 검수 완료 후 서비스 게시 - 서비스 게시일로부터 3일 이내 잔금 납부
### 5.2 일정 조정
- 개발 일정은 고객의 협조에 따라 변동될 수 있습니다.
- 고객 귀책 사유로 인한 지연은 회사의 책임이 아닙니다.
- 불가항력으로 인한 지연 시 양측 협의하여 일정을 조정합니다.
## 제6조 (서비스 게시 및 검수)
### 6.1 서비스 게시
- 회사는 개발 완료 후 고객에게 **서비스 게시**를 통지합니다.
- **서비스 게시일**은 고객이 서비스에 접근 가능한 날짜를 의미합니다.
- 서비스 게시일부터 구독료가 발생합니다.
### 6.2 검수 기간
- 고객은 개발 완료 후 **최대 2주간 검수 기간**을 가집니다.
- 검수 기간은 서비스 게시 **전**에 이루어집니다.
- 검수 기간 중 발견된 하자는 회사가 무상으로 수정합니다.
### 6.3 검수 완료
- 고객이 서면으로 검수 완료를 통지하거나,
- 검수 기간 2주 종료 시점에 특별한 이의가 없으면 자동 승인으로 간주합니다.
- 검수 완료 후 서비스 게시일이 확정되고, 하자담보 책임 정책이 적용됩니다.
## 제7조 (하자담보 책임)
### 7.1 책임 기간
서비스 게시일로부터 1년 (소프트웨어산업진흥법 제16조, 민법 제667조)
### 7.2 하자담보 범위 (무상 처리)
| 항목 | 내용 | 예시 |
| --- | --- | --- |
| 버그 수정 | 소프트웨어 오류 | 계산 오류, 기능 미작동 |
| 미구현 기능 | 계약서에 명시된 기능 누락 | 약속된 기능 미구현 |
| 성능 개선 | 명시된 성능 기준 미달 | 속도 저하, 응답 지연 |
| UI/UX 수정 | 사용성 문제 | 버튼 미작동, 화면 깨짐 |
| 데이터 오류 | 데이터 손실 또는 오류 | 데이터 삭제, 중복 생성 |
| 보안 패치 | 보안 취약점 수정 | 해킹 방지, 암호화 |
### 7.3 제외 사항 (별도 비용)
| 항목 | 내용 | 예시 |
| --- | --- | --- |
| 신규 기능 개발 | 계약서에 없던 새 기능 | 새로운 모듈, 기능 확장 |
| 구조 변경 | 시스템 아키텍처 변경 | DB 구조, 프레임워크 교체 |
| 추가 모듈 | 새로운 모듈 개발 | 회계 모듈, 재고 모듈 |
| 기획 변경 | 초기 기획과 다른 요구사항 | 화면 구성, 프로세스 변경 |
| 교육/컨설팅 | 사용자 교육, 업무 컨설팅 | 직원 교육, 프로세스 개선 |
### 7.4 하자 처리 절차
| 단계 | 내용 | 기간 |
| --- | --- | --- |
| 1. 하자 신고 | 고객이 이메일로 하자 신고 | - |
| 2. 하자 확인 | 회사가 하자 여부 판정 | 3영업일 |
| 3. 수정 작업 | 하자 인정 시 무상 수정 | 7영업일 |
| 4. 검수 완료 | 고객이 수정 사항 확인 | - |
> ⚠️ 긴급 하자 (서비스 중단)는 24시간 이내 조치합니다.
### 7.5 책임 면제 사유
다음의 경우 하자담보 책임이 면제됩니다:
- **고객 귀책 사유**:
- 고객의 임의 수정 또는 변경
- 승인되지 않은 제3자 개입
- 사용 환경 미준수
- **불가항력**:
- 천재지변 (지진, 태풍 등)
- 전쟁, 테러, 전염병
- 정부 규제 또는 법령 변경
- **기간 만료**:
- 서비스 게시일로부터 1년 경과
## 제8조 (계약 해제 및 환불)
### 8.1 환불 정책 개요
고객의 임의 해제 권리와 회사의 투입 비용 보전의 균형을 고려하여 수립되었습니다.
### 8.2 단계별 환불
### Phase 1: 상담(인터뷰) 시작 전
- **환불율**: 100% (전액 환불)
- **조건**: 계약 후 상담(인터뷰) 배정 전
- **위약금**: 없음
- **임의 해제 가능**
### Phase 2: 상담(인터뷰) 시작 후, 개발 착수 전
| 진행 상황 | 환불율 | 공제 내역 |
| --- | --- | --- |
| M1: 기획안 작성 중 (50% 미만) | 80% | 상담매니저 및 기획/개발자 투입 비용 20% 공제 |
| M2: 기획안 완료 (50% 이상) | 50% | 상담매니저 및 기획/개발자 투입 비용 50% 공제 |
### Phase 3: 개발 진행 중 (5단계 마일스톤 기준)
| 마일스톤 | 진행률 | 청구 금액(개발비 대비) | 비고 |
| --- | --- | --- | --- |
| M3: 개발 진행 중 (50%) | 70% | 70% | 30% 환불 |
| M4: 개발 완료 및 테스트 | 90% | 90% | 10% 환불 |
| M5: 서비스 개시 완료 | 100% | 100% | 환불 불가 |
> ⚠️ 중요: 5단계 마일스톤으로 통일 관리
### Phase 4: 서비스 게시 후
- **환불율**: 0% (환불 불가)
- **개발비**: 전액 확정, 환불 불가
- **구독료**: 매월 말일 후불제이므로 사용한 만큼만 청구 (환불 개념 없음)
- **대신 제공**: 하자담보 책임 (1년) + 유지보수 (구독 기간 전체)
### 8.3 환불 불가 사유
- **고객 귀책 사유**:
- 협조 지연으로 인한 개발 지연
- 요구사항 변경으로 인한 추가 개발
- 승인 거부 또는 회피
- **약관 위반**:
- 허위 정보 제공
- 부정 사용 또는 재판매
- 회사 명예 훼손
### 8.4 할인 계약 해지 시 추가 조건
본 계약이 정상가 대비 할인 조건으로 체결된 경우, 다음 조건이 추가 적용된다.
- 발주자 귀책 해지 시 정상가(할인 전 금액) 기준으로 정산한다.
## 제9조 (구독 및 해지)
### 9.1 구독 시작
- **시작일**: 서비스 게시일 (검수 완료 후)
- **결제일**: 매월 말일
- **청구 방식**: 후불제 (해당 월 사용량 기준)
- **일할 계산**: (사용 일수 / 해당 월 일수) × 구독료
> ⚠️ 중요: - 계약 시 확정된 구독료 금액은 [ ]원/월입니다.
- 매월 말일에 해당 월 사용일수만큼만 후불 청구됩니다.
### 9.2 구독 해지
- 고객은 언제든지 구독을 해지할 수 있습니다. (위약금 없음)
- 해지 신청 후 30일간 데이터 백업 기간 제공
- 해지일로부터 30일 후 모든 데이터 완전 삭제
## 제10조 (유지보수 정책)
### 10.1 유지보수 개요
- **적용 대상**: 구독료를 정상 납부하는 고객
- **적용 기간**: 구독 기간 전체 (하자담보 책임 1년 이후에도 구독 중이면 계속 제공)
- **비용**: 월 구독료(500,000원)에 포함
### 10.2 하자담보 책임과의 차이
| 구분 | 하자담보 책임 (제7조) | 유지보수 (제9조의2) |
| --- | --- | --- |
| 기간 | 서비스 게시일로부터 1년 | 구독 기간 전체 |
| 근거 | 법적 의무 (소프트웨어산업진흥법) | 계약 조건 |
| 비용 | 무상 | 구독료에 포함 |
| 범위 | 하자(버그, 미구현 등) | 하자 + 일반 유지보수 |
### 10.3 유지보수 범위 (구독료에 포함)
> ✅ 무상 제공: - 모든 버그 수정 및 오류 처리 - 보안 패치 및 업데이트 - 성능 최적화 - 긴급 장애 대응 (24시간 이내) - 데이터 백업 및 복구 - 기술 지원 (고객센터, 이메일) - 플랫폼 업데이트 (프레임워크, 브라우저 호환성)
> ❌ 별도 비용: - 신규 기능 개발 - 커스터마이징 및 추가 개발 - 기획 변경 (화면 구성, 프로세스 변경) - 외부 시스템 연동 - 추가 교육 및 컨설팅
### 10.4 서비스 레벨 (SLA)
| 심각도 | 상황 | 응답 시간 | 해결 목표 |
| --- | --- | --- | --- |
| 긴급 (P0) | 서비스 완전 중단 | 1시간 | 24시간 |
| 높음 (P1) | 주요 기능 장애 | 4시간 | 3영업일 |
| 보통 (P2) | 일반 버그 | 1영업일 | 7영업일 |
| 낮음 (P3) | 문의/안내 | 1영업일 | 3영업일 |
### 10.5 정기 유지보수
- **월간**: 보안 패치, 백업 점검 (매월 첫째 주 일요일 새벽)
- **분기**: 성능 최적화 (분기 말 일요일 새벽)
- **반기**: 시스템 점검 (6월/12월 일요일 새벽)
> ⚠️ 모든 정기 점검은 최소 7일 전 사전 공지됩니다.
### 10.6 유지보수 신청
- **고객센터**: 02-6347-0005 (평일 09:00~18:00 )
- **이메일**: support@codebridge-x.com (24시간)
- **시스템 내**: SAM 시스템 내 고객지원 메뉴
### 10.7 유지보수 종료
다음의 경우 유지보수 서비스가 종료됩니다: 1. 구독 해지 시 2. 구독료 3개월 연속 미납 시 3. 중대한 약관 위반 시
## 제11조 (고객의 의무)
고객은 다음 사항을 준수해야 합니다:
- **정확한 정보 제공**: 허위 정보 제공 금지
- **협조 의무**: 개발에 필요한 자료 및 정보 제공
- **부정 사용 금지**: 서비스의 재판매, 재배포 금지
- **지적재산권 존중**: 무단 복제, 역설계 금지
## 제12조 (회사의 의무)
회사는 다음 사항을 준수합니다:
- **서비스 제공**: 계약서에 명시된 서비스 제공
- **하자담보 책임**: 1년간 하자 무상 수정
- **개인정보 보호**: 개인정보보호법 준수
- **기술 지원**: 고객센터 운영 및 기술 지원
## 제13조 (미입금 시 법적 조치)
### 13.1 개발비 미입금 절차
| 단계 | 시점 | 조치 내용 |
| --- | --- | --- |
| 1차 독촉 | 기한 경과 후 3일 | 이메일 및 SMS 발송 |
| 내용증명 | 기한 경과 후 7일 | 우편 발송, 7일 내 입금 요청 |
| 추심등 | 기한 경과 후 14일 | 신용정보사 연체 등록, 법률대리인 위임 |
| 법적 조치 | 기한 경과 후 30일 | 지급명령 신청 또는 소송 제기 |
### 13.2 구독료 미입금 절차
| 단계 | 시점 | 조치 내용 |
| --- | --- | --- |
| 1차 실패 | 익일 | 재출금 |
| 2차 실패 | 기한 경과 후 3일 | 재출금 |
| 3차 실패 | 미수금 처리 | 서비스 접근 제한, 1차 독촉 |
| 내용증명 | 기한 경과 후 7일 | 우편 발송, 7일 내 입금 요청 |
| 서비스 중단 | 기한 경과 후 14일 | 로그인 불가, 데이터 격리 |
| 강제 해지 | 기한 경과 후 30일 | 계약 해지, 법적 조치 검토 |
## 제14조 (개인정보 보호)
- 회사는 「개인정보 보호법」을 준수합니다.
- 고객의 개인정보는 서비스 제공 목적으로만 사용됩니다.
- 제3자에게 제공하지 않습니다. (법령 제외)
- 계약 종료 시 개인정보는 즉시 삭제됩니다. (법정 보관 의무 제외)
## 제15조 (지적재산권)
- **소유권**: 서비스에 대한 모든 지적재산권은 회사에 귀속됩니다.
- **사용 권한**: 고객은 서비스 사용 권한만을 부여받습니다.
- **금지 사항**: 복제, 배포, 역설계, 재판매 금지
## 제16조 (손해배상)
- 회사 또는 고객이 본 계약을 위반하여 상대방에게 손해를 입힌 경우 배상 책임이 있습니다.
- 다만, 불가항력으로 인한 손해는 배상 책임에서 제외됩니다.
## 제17조 (불가항력)
다음의 사유로 서비스 제공이 불가능한 경우 회사는 책임을 지지 않습니다:
- 천재지변 (지진, 태풍, 홍수 등)
- 전쟁, 테러, 전염병
- 정부 규제 또는 법령 변경
- 제3자의 불법 행위 (해킹 등)
## 제18조 (분쟁 해결)
- 본 계약과 관련한 분쟁은 상호 협의하여 해결합니다.
- 협의가 이루어지지 않을 경우, **서울중앙지방법원**을 관할 법원으로 합니다.
## 제19조 (계약의 효력)
- 본 계약은 계약일로부터 효력이 발생합니다.
- 본 계약은 구독 해지 시까지 유효합니다.
## 제20조 (기타)
- 본 계약서는 2부 작성하여 회사와 고객이 각 1부씩 보관합니다.
- 본 계약의 해석 및 적용은 대한민국 법률을 준거법으로 합니다.
## 계약 당사자
### [회사]
상호: 주식회사 코드브릿지엑스
대표자: 이의찬
사업자등록번호: 664-86-03713
주소: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호
이메일: contact@codebridge-x.com
전화: 02-6347-0005
서명:
날짜:
### [고객]
상호:
대표자:
사업자등록번호:
주소:
이메일:
전화:
서명:
날짜:
## 별첨
### 별첨 1: 기획서
[별도 첨부]
### 별첨 2: 개발 일정표
[별도 첨부]
### 별첨 3: 기능 명세서
[별도 첨부]
주식회사 코드브릿지엑스
이메일: contact@codebridge-x.com
전화: 02-6347-0005
주소: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호

View File

@@ -0,0 +1,199 @@
---
title: "비밀유지서약서 (NDA)"
version: "v4.0"
date: "2026-02-22"
docx_file: "비밀유지서약서.docx"
---
# 비밀유지서약서 (NDA)
- **작성일**:
- **서약인 정보**
- **구분**:
- **인적 사항:**
상호(성명): _______________
대표자(본인): _______________
사업자등록번호(주민등록번호): ____________________
주소: ______________________________________________________________________
연락처: _______________
이메일: _______________
## 제1조 (목적)
- 본 서약서는 주식회사 코드브릿지(이하 “회사”)와의 업무 관계에서 알게 된 기밀 정보를
- 보호하기 위해 작성되었습니다.
## 제2조 (기밀 정보의 정의)
- 다음 각 호의 정보는 회사의 기밀 정보로 간주됩니다:
### 2.1 고객 정보
- 고객사 명단 (법인명, 대표자명, 연락처)
- 고객사 담당자 정보 (성명, 부서, 연락처, 이메일)
- 계약 내역 (개발비, 할인율, 구독료, 특약 사항)
- 고객사의 사업 정보 (매출, 직원 수, 거래처 등)
- 고객사가 회사에 요구한 개발 내역 및 기획 문서
### 2.2 영업 정보
- 가격 정책 (정가, 할인 정책, 최소 개발비)
- 수수료 정책 (비율, 지급 기준, 상계 방식)
- 영업 전략 및 마케팅 계획
- 잠재 고객 리스트
- 계약 체결 노하우 및 제안서 템플릿
### 2.3 기술 정보
- SAM 시스템의 소스코드
- 데이터베이스 구조 및 설계 문서
- 개발 프로세스 및 방법론
- 서버 인프라 구성 및 보안 정책
- API 키, 접속 정보, 관리자 권한
### 2.4 경영 정보
- 회사의 재무 정보 (매출, 이익, 원가)
- 조직도 및 인사 정보
- 사업 계획 및 전략
- 투자 유치 및 M&A 관련 정보
### 2.5 기타
- 회사가 **“기밀(Confidential)”** 또는 **“대외비”**로 표시한 모든 문서 및 정보
## 제3조 (기밀 유지 의무)
### 3.1 기본 의무
- 본인은 업무 수행 중 알게 된 모든 기밀 정보를:
- **외부에 누설하지 않습니다**
- **업무 목적 외에 사용하지 않습니다**
- **무단으로 복사, 복제, 전송하지 않습니다**
- **제3자에게 제공하거나 공개하지 않습니다**
### 3.2 정보 관리
- 기밀 문서는 안전한 장소에 보관
- 이메일, 메신저 등 전송 시 암호화
- 업무 종료 시 모든 기밀 자료 반환 또는 파기
- 개인 디바이스에 기밀 정보 저장 금지
### 3.3 제3자 접근 차단
- 가족, 친구 등 타인이 기밀 정보에 접근하지 못하도록 조치
- 공공장소(카페, 도서관 등)에서 기밀 정보 취급 금지
- 비밀번호 및 접속 정보 타인 공유 금지
## 제4조 (예외 사항)
- 다음의 정보는 기밀 정보에서 제외됩니다:
- 본인이 알기 전에 이미 공개된 정보
- 본인의 귀책사유 없이 공개된 정보
- 제3자로부터 적법하게 취득한 정보
- 본인이 독자적으로 개발한 정보
- 법원, 정부기관의 법적 요구에 따라 공개해야 하는 정보 (단, 회사에 사전 통지 필수)
## 제5조 (의무 기간)
### 5.1 기간
- 본 서약서의 기밀 유지 의무는:
- **계약 체결일로부터 효력 발생**
- **계약 종료 후 2년간 유지**
### 5.2 영구 보호
- 단, 다음 정보는 **영구적으로** 보호됩니다:
- 고객사 개인정보
- 회사의 영업 비밀 (부정경쟁방지법상 영업 비밀)
- 기술 정보 (특허, 저작권 대상)
## 제6조 (위반 시 책임)
### 6.1 민사 책임
- 본인이 본 서약을 위반하여 회사 또는 고객에게 손해를 입힌 경우:
- **실손해**** 배상**: 실제 발생한 손해 전액
- **징벌적 손해배상**: 실손해의 최대 3배 (악의적 유출 시)
- **법률 비용**: 소송 비용, 변호사 비용 등
### 6.2 형사 책임
- 다음의 경우 형사 고발 대상이 됩니다:
- **부정경쟁방지법** 위반 (영업 비밀 침해)
- **개인정보보호법** 위반 (고객 정보 유출)
- **정보통신망법** 위반 (기술 정보 침해)
- **형법** 위반 (업무상 배임)
- **※ 형사 처벌: 5년 이하 징역 또는 5천만원 이하 벌금**
### 6.3 계약 해지
- 회사는 본 서약 위반 시 즉시 계약을 해지할 수 있으며, 이미 지급한 수수료 또는
- 대금을 환수할 수 있습니다.
## 제7조 (자료 반환)
### 7.1 반환 대상
- 계약 종료 또는 요청 시 다음을 즉시 반환해야 합니다:
- 회사로부터 제공받은 모든 문서 (종이, 파일)
- 고객사 계약서 및 개인정보
- 가격표, 제안서, 템플릿 등 영업 자료
- USB, 하드디스크 등 저장 매체
### 7.2 파기 확인
- 반환 불가능한 파일(이메일, 클라우드 등)은 즉시 삭제하고, **삭제 확인서**를 회사에
- 제출해야 합니다.
## 제8조 (경업 금지)
### 8.1 경업 금지 기간
- 계약 종료 후 **6개월간** 다음 행위를 금지합니다:
- 회사의 고객에게 경쟁 제품 판매
- 회사의 기밀 정보를 이용한 유사 사업
- 회사 직원 또는 영업파트너를 스카우트
### 8.2 예외
- 단순히 경쟁사 제품을 판매하는 것은 허용되나, 회사의 기밀 정보를 활용해서는
- 안 됩니다.
## 제9조 (분쟁 해결)
### 9.1 관할 법원
- 본 서약과 관련된 분쟁은 회사 본사 소재지 관할 법원으로 합니다.
### 9.2 준거법
- 본 서약은 대한민국 법률에 따라 해석됩니다.
- **서약 확인**
- 본인은 위 내용을 충분히 이해하였으며, 이를 성실히 준수할 것을 서약합니다.
- **서약일**: ___________________
- **서약인**
상호(성명): _______________
대표자(본인): _______________
주민등록번호(또는 사업자등록번호): _______________
- **서명 또는 인**: _______________
- **수령인 (주식회사 ****코드브릿지엑스****)**
- 대표이사: 이의찬
- **확인****일**: ___________________
- **서명 또는 인**: _______________
- **참고: 관련 법률**
- **부정경쟁방지법 제2조 (영업비밀)**
- “영업비밀”이란 공공연히 알려져 있지 아니하고 독립된 경제적 가치를 가지는 것으로서,
- 비밀로 관리된 생산방법, 판매방법, 그 밖에 영업활동에 유용한 기술상 또는 경영상의
- 정보를 말한다.
- **부정경쟁방지법 제18조 (벌칙)**
- 영업비밀을 외국에서 사용하거나 외국에서 사용되게 할 목적으로 취득·사용 또는 제3자에게 누설한 자는 **15년 이하의 징역** 또는 **15억원 이하의 벌금**에 처한다.
- **※ 본 서약서는 2부를 작성하여 회사와 서약인이 각 1부씩 보관합니다.**
- **※ 서약 위반 시 민·형사상 책임을 질 수 있습니다.**

View File

@@ -0,0 +1,276 @@
---
title: "영업파트너 위촉계약서"
version: "v4.0"
date: "2026-02-22"
docx_file: "영업파트너 위촉계약서.docx"
---
# < 영업파트너 위촉계약서 >
# Sales Partner Engagement Agreement
- 본 계약은 주식회사 코드브릿지엑스(이하 “회사”)와 (이하 “파트너)간에 SAM 서비스 영업 활동과 관련하여 다음과 같이 위촉계약을 체결합니다.
## 제1조 (계약의 목적)
- 본 계약은 회사와 파트너 간의 영업파트너 위촉 관계를 규정하고, 상호 권리와 의무를
- 명확히 함을 목적으로 합니다.
## 제2조 (용어의 정의)
- **판매자**: 고객을 발굴하고 계약 체결을 주도하는 영업파트너
- **관리자**: 판매자를 관리하고 지원하는 상급 영업파트너
- **개발비**: 고객이 SAM 서비스 개발을 위해 지급하는 비용
- **수수료**: 파트너가 영업 활동의 대가로 받는 보상
- **서비스 게시**: 개발 완료 후 고객이 서비스에 접근 가능하도록 제공하는 것
## 제3조 (파트너의 역할 및 업무)
### 3.1 판매자의 역할
- 잠재 고객 발굴 및 초기 접촉
- SAM 서비스 소개 및 제안
- 고객과의 계약 체결 지원
- 계약 후 고객 관리 및 사후 지원
### 3.2 관리자의 역할
- 판매자 모집 및 관리
- 판매자 교육 및 지원
- 영업 전략 수립 및 실행
- 회사와 판매자 간 소통 중재
### 3.3 공통 의무
- 회사의 브랜드 이미지 유지
- 정확한 정보 제공
- 윤리적 영업 활동 준수
- 비밀 유지 의무
## 제4조 (수수료 정책)
### 4.1 수수료 비율
| 역할 | 수수료 비율 | 산정 기준 |
| --- | --- | --- |
| 판매자 | 개발비의 20% | 1차,2차 입금액 기준 |
| 관리자 | 개발비의 5% | 1차,2차 입금액 기준 |
### 4.2 수수료 산정 예시
- **총 개발비 80,000,000원 계약 시**
| 단계 | 고객 입금 | 판매자 수수료 (20%) | 관리자 수수료 (5%) |
| --- | --- | --- | --- |
| 1차 착수금 (50%) | 40,000,000원 | 8,000,000원 | 2,000,000원 |
| 2차 잔금 (50%) | 40,000,000원 | 8,000,000원 | 2,000,000원 |
| 총계 | 80,000,000원 | 16,000,000원 | 4,000,000원 |
- **⚠️ 중요**: 개발비만 수수료 산정 대상이며, 구독료는 수수료 대상이 아닙니다.
### 4.3 지급 시기
- **지급일**: 고객 입금일 **익월 10일**
- **지급 방식**: 계좌 이체
- **세금**: 3.3% 원천징수 (사업소득)
### 4.4 수수료 지급 조건
- 고객이 개발비를 실제로 입금한 경우에만 지급
- 계약 해지 또는 환불 시 수수료 미지급 또는 환수
- 파트너가 계약 위반 시 수수료 지급 보류
## 제5조 (수수료 정책 변경)
### 5.1 사전 고지 의무
- 회사는 수수료 정책을 변경할 경우 **최소 1개월 전** 서면 또는 이메일로 파트너에게 고지합니다.
- 수수료 정책을 완전히 폐지하는 경우에도 동일하게 1개월 전 고지합니다.
- 고지 기간 중 체결된 계약은 기존 수수료 정책을 적용합니다.
### 5.2 변경 효력
- 변경된 수수료 정책은 고지일로부터 **1개월 후** 새로 체결되는 계약부터 적용됩니다.
- 고지 기간 만료 전에 체결된 계약은 기존 정책을 따릅니다.
- 진행 중인 계약은 최초 약정 조건을 유지합니다.
### 5.3 변경 예시
#### 예시 1: 수수료율 변경
- 고지일: 2026년 2월 1일
- 변경 내용: 판매자 수수료 20% → 18%
- 적용일: 2026년 3월 1일 이후 체결 계약부터
#### 예시 2: 수수료 정책 폐지
- 고지일: 2026년 2월 1일
- 변경 내용: 수수료 정책 완전 폐지
- 적용일: 2026년 3월 1일 이후 체결 계약부터
## 제6조 (계약 기간)
- 본 계약은 계약일로부터 **1년간** 유효합니다.
- 양측이 계약 만료 **30일 전**까지 서면으로 해지 의사를 통지하지 않으면 자동으로 **1년 연장**됩니다.
- 자동 연장은 동일한 조건으로 반복됩니다.
## 제7조 (계약 해지)
### 7.1 일반 해지 (양방향)
- **통지 기간**: 양측은 **30일 전** 서면 통지로 계약을 해지할 수 있습니다.
- **통지 방법**: 이메일 또는 등기우편
- **효력 발생**: 통지일로부터 30일 후
- **미지급 수수료**: 해지일 이전에 발생한 수수료는 정산하여 지급
- **예시**:
- 통지일: 2026년 2월 1일
- 해지일: 2026년 3월 1일
- 2월 중 발생한 수수료는 3월 10일 정상 지급
### 7.2 즉시 해지 사유
- 회사는 다음의 경우 **즉시 계약을 해지**할 수 있습니다:
- **(1) 품위 유지 결격사유 발생 [신설]**
- 음주운전으로 적발된 경우
- 형사 범죄로 기소 또는 구속된 경우
- 사회적 물의를 일으킨 경우
- 기타 파트너로서의 품위를 훼손한 경우
- **(2) 계약 위반**
- 허위 정보 제공 또는 사기 행위
- 회사 명예 훼손 또는 영업 방해
- 비밀 유지 의무 위반
- 중대한 업무 태만
- **(3) 부정 행위**
- 고객으로부터 금품 수수
- 계약서 위조 또는 변조
- 회사 자산 횡령 또는 유용
### 7.3 즉시 해지 시 조치
- 미지급 수수료는 지급하지 않습니다.
- 이미 지급한 수수료는 환수하지 않습니다. (단, 사기 행위는 예외)
- 진행 중인 계약은 회사가 직접 관리합니다.
## 제8조 (비밀 유지)
### 8.1 비밀 정보
- 다음 정보는 비밀로 유지되어야 합니다:
- 회사의 영업 전략 및 계획
- 고객 정보 (회사명, 담당자, 연락처 등)
- 수수료 정책 및 계약 조건
- 기술 정보 및 노하우
- 회사 내부 자료
### 8.2 비밀 유지 의무
- 파트너는 업무 중 알게 된 비밀 정보를 외부에 누설하지 않습니다.
- 비밀 유지 의무는 계약 종료 후에도 **3년간** 유효합니다.
- 위반 시 손해배상 책임이 있습니다.
## 제9조 (지적재산권)
- SAM 서비스에 대한 모든 지적재산권은 회사에 귀속됩니다.
- 파트너는 회사의 사전 서면 동의 없이 회사의 상표, 로고, 브랜드를 무단으로 사용할 수 없습니다.
- 영업 활동에 필요한 자료는 회사가 제공합니다.
## 제10조 (세금 및 원천징수)
### 10.1 사업소득
- 파트너 수수료는 **사업소득**으로 간주됩니다.
### 10.2 원천징수
| 항목 | 비율 | 비고 |
| --- | --- | --- |
| 소득세 | 3.0% | |
| 지방소득세 | 0.3% | 소득세의 10% |
| 합계 | 3.3% | |
### 10.3 지급명세서
- 회사는 매월 수수료를 지급한 후에 파트너에게 **지급명세서**를 발급합니다.
## 제11조 (손해배상)
### 11.1 파트너의 귀책 사유
- 파트너가 다음의 행위로 회사에 손해를 입힌 경우 배상 책임이 있습니다:
- 허위 정보 제공으로 계약 취소
- 고객과의 분쟁으로 회사 명예 훼손
- 비밀 유지 의무 위반
- 부정 행위
### 11.2 회사의 귀책 사유
- 회사가 정당한 사유 없이 수수료를 지급하지 않을 경우, 연체 이자를 더하여 지급합니다.
## 제12조 (분쟁 해결)
- 본 계약과 관련한 분쟁은 상호 협의하여 해결합니다.
- 협의가 이루어지지 않을 경우, **서울중앙지방법원**을 관할 법원으로 합니다.
## 제13조 (기타 사항)
### 13.1 계약서 교부
- 본 계약서는 2부 작성하여 회사와 파트너가 각 1부씩 보관합니다.
### 13.2 통지
- 모든 통지는 다음의 연락처로 발송됩니다:
- **회사**:
- 이메일: admin@codebridge-x.com
- 전화: 02-6347-0005
- **파트너**:
- 이메일:
- 전화:
### 13.3 준거법
- 본 계약은 대한민국 법률에 따라 해석되고 적용됩니다.
- **계약 당사자**
- **[회사]**
- **상호**: 주식회사 코드브릿지엑스
- **대표자**: 이의찬 (인)
- **사업자등록번호**: 664-86-03713
- **주소**: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호
- **이메일**: admin@codebridge-x.com
- **전화**: 02-6347-0005
- **날짜**:
- **[파트너]**
- **상호/성명**:
- **대표자/본인**: (서명)
- **사업자등록번호**:
- **주소**:
- **이메일**:
- **전화**:
- **날짜**:
- **별첨**
#### 별첨 1: 수수료 정산표
| 계약번호 | 고객사 | 입금일 | 입금액 | 수수료율 | 수수료 | 지급일 |
| --- | --- | --- | --- | --- | --- | --- |
| | | | | | | |
#### 별첨 2: 영업 활동 보고서
| 날짜 | 활동내용 | 고객사 | 진행 상황 |
| --- | --- | --- | --- |
| | | | |
- 첨부 서류
- 사업자등록증 사본 (사업자인 경우)
- 주민등록등본 사본 (개인인 경우)
- 통장 사본 (수수료 입금용)
- 비밀유지서약서
- **주식회사 코드브릿지엑스**
- 이메일: admin@codebridge-x.com
- 전화: 02-6347-0005
- 주소: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호

View File

@@ -0,0 +1,267 @@
---
title: "영업파트너 위촉계약서 (단체용)"
version: "v4.0"
date: "2026-02-22"
docx_file: "영업파트너 위촉계약서(단체용).docx"
---
# < 영업파트너 위촉계약서 >
# Sales Partner Engagement Agreement
- 본 계약은 주식회사 코드브릿지엑스(이하 “회사”)와 (이하 “파트너)간에 SAM 서비스 영업 활동과 관련하여 다음과 같이 위촉계약을 체결합니다.
## 제1조 (계약의 목적)
- 본 계약은 회사와 파트너 간의 영업파트너 위촉 관계를 규정하고, 상호 권리와 의무를
- 명확히 함을 목적으로 합니다.
## 제2조 (용어의 정의)
- **판매자**: 고객을 발굴하고 계약 체결을 주도하는 영업파트너
- **개발비**: 고객이 SAM 서비스 개발을 위해 지급하는 비용
- **수수료**: 파트너가 영업 활동의 대가로 받는 보상
- **서비스 게시**: 개발 완료 후 고객이 서비스에 접근 가능하도록 제공하는 것
## 제3조 (파트너의 역할 및 업무)
### 3.1 판매자의 역할
- 잠재 고객 발굴 및 초기 접촉
- SAM 서비스 소개 및 제안
- 고객과의 계약 체결 지원
- 계약 후 고객 관리 및 사후 지원
### 3.2 공통 의무
- 회사의 브랜드 이미지 유지
- 정확한 정보 제공
- 윤리적 영업 활동 준수
- 비밀 유지 의무
## 제4조 (수수료 정책)
### 4.1 수수료 비율
| 역할 | 수수료 비율 | 산정 기준 |
| --- | --- | --- |
| 판매자 | 개발비의 30% | 1차,2차 입금액 기준 |
### 4.2 수수료 산정 예시
- **총 개발비 80,000,000원 계약 시**
| 단계 | 고객 입금 | 판매자 수수료 (30%) |
| --- | --- | --- |
| 1차 착수금 (50%) | 40,000,000원 | 12,000,000원 |
| 2차 잔금 (50%) | 40,000,000원 | 12,000,000원 |
| 총계 | 80,000,000원 | 24,000,000원 |
- **⚠️ 중요**: 개발비만 수수료 산정 대상이며, 구독료는 수수료 대상이 아닙니다.
### 4.3 지급 시기
- **지급일**: 고객 입금일 **익월 10일**
- **지급 방식**: 계좌 이체
- **세금**: 사업소득일 경우 3.3% 원천징수
### 4.4 수수료 지급 조건
- 고객이 개발비를 실제로 입금한 경우에만 지급
- 계약 해지 또는 환불 시 수수료 미지급 또는 환수
- 파트너가 계약 위반 시 수수료 지급 보류
## 제5조 (수수료 정책 변경)
### 5.1 사전 고지 의무
- 회사는 수수료 정책을 변경할 경우 **최소 1개월 전** 서면 또는 이메일로 파트너에게 고지합니다.
- 수수료 정책을 완전히 폐지하는 경우에도 동일하게 1개월 전 고지합니다.
- 고지 기간 중 체결된 계약은 기존 수수료 정책을 적용합니다.
### 5.2 변경 효력
- 변경된 수수료 정책은 고지일로부터 **1개월 후** 새로 체결되는 계약부터 적용됩니다.
- 고지 기간 만료 전에 체결된 계약은 기존 정책을 따릅니다.
- 진행 중인 계약은 최초 약정 조건을 유지합니다.
### 5.3 변경 예시
#### 예시 1: 수수료율 변경
- 고지일: 2026년 2월 1일
- 변경 내용: 판매자 수수료 20% → 18%
- 적용일: 2026년 3월 1일 이후 체결 계약부터
#### 예시 2: 수수료 정책 폐지
- 고지일: 2026년 2월 1일
- 변경 내용: 수수료 정책 완전 폐지
- 적용일: 2026년 3월 1일 이후 체결 계약부터
## 제6조 (계약 기간)
- 본 계약은 계약일로부터 **1년간** 유효합니다.
- 양측이 계약 만료 **30일 전**까지 서면으로 해지 의사를 통지하지 않으면 자동으로 **1년 연장**됩니다.
- 자동 연장은 동일한 조건으로 반복됩니다.
## 제7조 (계약 해지)
### 7.1 일반 해지 (양방향)
- **통지 기간**: 양측은 **30일 전** 서면 통지로 계약을 해지할 수 있습니다.
- **통지 방법**: 이메일 또는 등기우편
- **효력 발생**: 통지일로부터 30일 후
- **미지급 수수료**: 해지일 이전에 발생한 수수료는 정산하여 지급
- **예시**:
- 통지일: 2026년 2월 1일
- 해지일: 2026년 3월 1일
- 2월 중 발생한 수수료는 3월 10일 정상 지급
### 7.2 즉시 해지 사유
- 회사는 다음의 경우 **즉시 계약을 해지**할 수 있습니다:
- **(1) 품위 유지 결격사유 발생 [신설]**
- 음주운전으로 적발된 경우
- 형사 범죄로 기소 또는 구속된 경우
- 사회적 물의를 일으킨 경우
- 기타 파트너로서의 품위를 훼손한 경우
- **(2) 계약 위반**
- 허위 정보 제공 또는 사기 행위
- 회사 명예 훼손 또는 영업 방해
- 비밀 유지 의무 위반
- 중대한 업무 태만
- **(3) 부정 행위**
- 고객으로부터 금품 수수
- 계약서 위조 또는 변조
- 회사 자산 횡령 또는 유용
### 7.3 즉시 해지 시 조치
- 미지급 수수료는 지급하지 않습니다.
- 이미 지급한 수수료는 환수하지 않습니다. (단, 사기 행위는 예외)
- 진행 중인 계약은 회사가 직접 관리합니다.
## 제8조 (비밀 유지)
### 8.1 비밀 정보
- 다음 정보는 비밀로 유지되어야 합니다:
- 회사의 영업 전략 및 계획
- 고객 정보 (회사명, 담당자, 연락처 등)
- 수수료 정책 및 계약 조건
- 기술 정보 및 노하우
- 회사 내부 자료
### 8.2 비밀 유지 의무
- 파트너는 업무 중 알게 된 비밀 정보를 외부에 누설하지 않습니다.
- 비밀 유지 의무는 계약 종료 후에도 **3년간** 유효합니다.
- 위반 시 손해배상 책임이 있습니다.
## 제9조 (지적재산권)
- SAM 서비스에 대한 모든 지적재산권은 회사에 귀속됩니다.
- 파트너는 회사의 사전 서면 동의 없이 회사의 상표, 로고, 브랜드를 무단으로 사용할 수 없습니다.
- 영업 활동에 필요한 자료는 회사가 제공합니다.
## 제10조 (세금 및 원천징수)
### 10.1 사업소득
- 파트너 수수료는 **사업소득**으로 간주됩니다.
### 10.2 원천징수
| 항목 | 비율 | 비고 |
| --- | --- | --- |
| 소득세 | 3.0% | |
| 지방소득세 | 0.3% | 소득세의 10% |
| 합계 | 3.3% | |
### 10.3 지급명세서
- 회사는 매월 수수료를 지급한 후에 파트너에게 **지급명세서**를 발급합니다.
## 제11조 (손해배상)
### 11.1 파트너의 귀책 사유
- 파트너가 다음의 행위로 회사에 손해를 입힌 경우 배상 책임이 있습니다:
- 허위 정보 제공으로 계약 취소
- 고객과의 분쟁으로 회사 명예 훼손
- 비밀 유지 의무 위반
- 부정 행위
### 11.2 회사의 귀책 사유
- 회사가 정당한 사유 없이 수수료를 지급하지 않을 경우, 연체 이자를 더하여 지급합니다.
## 제12조 (분쟁 해결)
- 본 계약과 관련한 분쟁은 상호 협의하여 해결합니다.
- 협의가 이루어지지 않을 경우, **서울중앙지방법원**을 관할 법원으로 합니다.
## 제13조 (기타 사항)
### 13.1 계약서 교부
- 본 계약서는 2부 작성하여 회사와 파트너가 각 1부씩 보관합니다.
### 13.2 통지
- 모든 통지는 다음의 연락처로 발송됩니다:
- **회사**:
- 이메일: admin@codebridge-x.com
- 전화: 02-6347-0005
- **파트너**:
- 이메일:
- 전화:
### 13.3 준거법
- 본 계약은 대한민국 법률에 따라 해석되고 적용됩니다.
- **계약 당사자**
- **[회사]**
- **상호**: 주식회사 코드브릿지엑스
- **대표자**: 이의찬 (인)
- **사업자등록번호**: 664-86-03713
- **주소**: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호
- **이메일**: admin@codebridge-x.com
- **전화**: 02-6347-0005
- **날짜**:
- **[파트너]**
- **상호/성명**:
- **대표자/본인**: (서명)
- **사업자등록번호**:
- **주소**:
- **이메일**:
- **전화**:
- **날짜**:
- **별첨**
#### 별첨 1: 수수료 정산표
| 계약번호 | 고객사 | 입금일 | 입금액 | 수수료율 | 수수료 | 지급일 |
| --- | --- | --- | --- | --- | --- | --- |
| | | | | | | |
#### 별첨 2: 영업 활동 보고서
| 날짜 | 활동내용 | 고객사 | 진행 상황 |
| --- | --- | --- | --- |
| | | | |
- 첨부 서류
- 사업자등록증 사본 (사업자인 경우)
- 주민등록등본 사본 (개인인 경우)
- 통장 사본 (수수료 입금용)
- 비밀유지서약서
- **주식회사 코드브릿지엑스**
- 이메일: admin@codebridge-x.com
- 전화: 02-6347-0005
- 주소: 서울특별시 강서구 양천로 583, 우림블루나인 B동 1602호

58
contracts/revisions.json Normal file
View File

@@ -0,0 +1,58 @@
{
"documents": {
"01-service-agreement": {
"title": "고객사 서비스 이용계약서",
"docx_file": "01_고객_서비스이용계약서_v4_0_전자서명용.docx",
"revisions": [
{
"version": "v4.0",
"date": "2026-02-22",
"author": "개발팀",
"description": "버전 관리 시스템 도입, 개정이력 추적 시작"
},
{
"version": "v4.1",
"date": "2026-02-22",
"author": "개발팀",
"description": "제4조에 사용량 기반 추가 과금(4.5) 및 바로빌 부가 서비스 요금(4.6) 조항 추가"
}
]
},
"02-nda": {
"title": "비밀유지서약서 (NDA)",
"docx_file": "비밀유지서약서.docx",
"revisions": [
{
"version": "v4.0",
"date": "2026-02-22",
"author": "개발팀",
"description": "버전 관리 시스템 도입, 개정이력 추적 시작"
}
]
},
"03-partner-agreement": {
"title": "영업파트너 위촉계약서",
"docx_file": "영업파트너 위촉계약서.docx",
"revisions": [
{
"version": "v4.0",
"date": "2026-02-22",
"author": "개발팀",
"description": "버전 관리 시스템 도입, 개정이력 추적 시작"
}
]
},
"04-partner-agreement-group": {
"title": "영업파트너 위촉계약서 (단체용)",
"docx_file": "영업파트너 위촉계약서(단체용).docx",
"revisions": [
{
"version": "v4.0",
"date": "2026-02-22",
"author": "개발팀",
"description": "버전 관리 시스템 도입, 개정이력 추적 시작"
}
]
}
}
}

View File

@@ -0,0 +1,334 @@
#!/usr/bin/env python3
"""
DOCX → Markdown 추출 스크립트
4개 전자계약 DOCX 파일을 Markdown으로 변환한다.
- 서비스이용계약서: Heading 스타일 기반 매핑
- 나머지 3개: Bold 런 + 패턴 매칭으로 구조 유추
"""
import re
import sys
from datetime import date
from pathlib import Path
from docx import Document
# 경로 설정
BASE_DIR = Path(__file__).resolve().parent.parent
DOCX_DIR = BASE_DIR / "docx"
MD_DIR = BASE_DIR / "markdown"
# DOCX → Markdown 매핑
FILE_MAP = {
"01_고객_서비스이용계약서_v4_0_전자서명용.docx": {
"output": "01-service-agreement.md",
"title": "고객사 서비스 이용계약서",
"type": "styled",
},
"비밀유지서약서.docx": {
"output": "02-nda.md",
"title": "비밀유지서약서 (NDA)",
"type": "pattern",
},
"영업파트너 위촉계약서.docx": {
"output": "03-partner-agreement.md",
"title": "영업파트너 위촉계약서",
"type": "pattern",
},
"영업파트너 위촉계약서(단체용).docx": {
"output": "04-partner-agreement-group.md",
"title": "영업파트너 위촉계약서 (단체용)",
"type": "pattern",
},
}
def table_to_markdown(table):
"""DOCX 테이블을 Markdown 테이블로 변환"""
rows = []
for row in table.rows:
cells = [cell.text.strip().replace("\n", " ") for cell in row.cells]
rows.append(cells)
if not rows:
return ""
lines = []
# 헤더
lines.append("| " + " | ".join(rows[0]) + " |")
lines.append("| " + " | ".join(["---"] * len(rows[0])) + " |")
# 본문
for row in rows[1:]:
# 셀 개수 맞추기
while len(row) < len(rows[0]):
row.append("")
lines.append("| " + " | ".join(row[: len(rows[0])]) + " |")
return "\n".join(lines)
def get_paragraph_heading_level_styled(para):
"""스타일 기반 문서의 헤딩 레벨 판별 (서비스이용계약서)"""
style = para.style.name if para.style else ""
if style == "Heading 1":
return 1
elif style == "Heading 2":
return 2
elif style == "Heading 3":
return 3
return 0
def get_paragraph_heading_level_pattern(para):
"""패턴 매칭 기반 문서의 헤딩 레벨 판별 (비밀유지서약서, 영업파트너 위촉계약서)"""
text = para.text.strip()
has_bold = any(r.bold for r in para.runs if r.bold)
if not text or not has_bold:
return 0
# "제X조" 패턴 → ## (h2)
if re.match(r"^<?[ ]*제\d+조", text):
return 2
# "X.X " 패턴 (소제목) → ### (h3)
if re.match(r"^\d+\.\d+\s", text):
return 3
# 문서 제목 (첫 번째 bold 텍스트)
if re.match(r"^<?\s*(영업파트너|비밀유지서약서|Sales Partner)", text):
return 1
return 0
def is_list_item(para, doc_type):
"""리스트 아이템인지 판별"""
text = para.text.strip()
if not text:
return False
if doc_type == "styled":
style = para.style.name if para.style else ""
return style == "Compact"
# pattern 기반: bold가 아닌 일반 텍스트이면서 제X조나 X.X 패턴이 아닌 것
has_bold = any(r.bold for r in para.runs if r.bold)
if not has_bold and not re.match(r"^(제\d+조|<?|계약 당사자|\[)", text):
return True
return False
def extract_styled_doc(doc, file_info):
"""스타일 기반 문서 추출 (서비스이용계약서)"""
lines = []
table_positions = {}
# 테이블 위치 매핑: 문단 인덱스 기준으로 테이블이 어디에 삽입되는지 추적
body = doc.element.body
table_idx = 0
para_idx = 0
for child in body:
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if tag == "p":
para_idx += 1
elif tag == "tbl":
table_positions[para_idx] = table_idx
table_idx += 1
para_idx = 0
for child in body:
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if tag == "p":
para = doc.paragraphs[para_idx]
para_idx += 1
text = para.text.strip()
if not text:
lines.append("")
continue
style = para.style.name if para.style else ""
level = get_paragraph_heading_level_styled(para)
if level > 0:
lines.append("")
lines.append(f"{'#' * level} {text}")
lines.append("")
elif style == "Compact":
# Bold 런이 있으면 강조 리스트
has_bold = any(r.bold for r in para.runs if r.bold)
if has_bold:
# Bold 부분과 일반 부분 분리
parts = []
for run in para.runs:
if run.bold:
parts.append(f"**{run.text}**")
else:
parts.append(run.text)
combined = "".join(parts)
lines.append(f"- {combined}")
else:
# 들여쓰기된 하위 항목
lines.append(f" - {text}")
elif style in ("Body Text", "First Paragraph"):
# 본문 텍스트
if text.startswith("⚠️") or text.startswith("") or text.startswith(""):
lines.append("")
lines.append(f"> {text}")
lines.append("")
else:
lines.append(text)
else:
lines.append(text)
elif tag == "tbl":
if table_idx <= len(doc.tables):
current_table_idx = sum(
1
for c in list(body)[: list(body).index(child)]
if (c.tag.split("}")[-1] if "}" in c.tag else c.tag) == "tbl"
)
if current_table_idx < len(doc.tables):
lines.append("")
lines.append(table_to_markdown(doc.tables[current_table_idx]))
lines.append("")
return "\n".join(lines)
def extract_pattern_doc(doc, file_info):
"""패턴 매칭 기반 문서 추출 (비밀유지서약서, 영업파트너 위촉계약서)"""
lines = []
body = doc.element.body
para_idx = 0
for child in body:
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if tag == "p":
para = doc.paragraphs[para_idx]
para_idx += 1
text = para.text.strip()
if not text:
lines.append("")
continue
level = get_paragraph_heading_level_pattern(para)
has_bold = any(r.bold for r in para.runs if r.bold)
if level > 0:
lines.append("")
# 제목에서 < > 제거
clean_text = re.sub(r"^<\s*|\s*>$", "", text).strip()
lines.append(f"{'#' * level} {clean_text}")
lines.append("")
elif has_bold:
# Bold 텍스트는 강조 처리
parts = []
for run in para.runs:
if run.bold:
parts.append(f"**{run.text}**")
else:
parts.append(run.text)
combined = "".join(parts)
# (1), (2) 같은 번호 패턴
if re.match(r"^\*\*\(\d+\)", combined):
lines.append(f"- {combined}")
# "예시 N:", "Phase N:" 같은 패턴
elif re.match(r"^\*\*(예시|Phase|별첨)\s", combined):
lines.append("")
lines.append(f"#### {text}")
lines.append("")
else:
lines.append(f"- {combined}")
else:
# 일반 텍스트
# 빈칸 양식 (___) 유지
if "___" in text:
lines.append(text)
elif re.match(r"^(이메일|전화|주소|상호|대표|사업자|주민|연락처|날짜):", text):
lines.append(f"- {text}")
else:
lines.append(f" - {text}")
elif tag == "tbl":
current_table_idx = sum(
1
for c in list(body)[: list(body).index(child)]
if (c.tag.split("}")[-1] if "}" in c.tag else c.tag) == "tbl"
)
if current_table_idx < len(doc.tables):
lines.append("")
lines.append(table_to_markdown(doc.tables[current_table_idx]))
lines.append("")
return "\n".join(lines)
def add_frontmatter(content, file_info, docx_name):
"""YAML 프론트매터 추가"""
frontmatter = f"""---
title: "{file_info['title']}"
version: "v4.0"
date: "{date.today().isoformat()}"
docx_file: "{docx_name}"
---
"""
return frontmatter + "\n" + content
def extract_file(docx_name, file_info):
"""단일 DOCX 파일 추출"""
docx_path = DOCX_DIR / docx_name
if not docx_path.exists():
print(f" [SKIP] {docx_name} - 파일 없음")
return False
doc = Document(str(docx_path))
if file_info["type"] == "styled":
content = extract_styled_doc(doc, file_info)
else:
content = extract_pattern_doc(doc, file_info)
# 프론트매터 추가
content = add_frontmatter(content, file_info, docx_name)
# 연속 빈 줄 정리 (3줄 이상 → 2줄로)
content = re.sub(r"\n{3,}", "\n\n", content)
# 파일 저장
output_path = MD_DIR / file_info["output"]
output_path.write_text(content, encoding="utf-8")
print(f" [OK] {docx_name}{file_info['output']}")
return True
def main():
print("DOCX → Markdown 추출 시작")
print(f" DOCX 디렉토리: {DOCX_DIR}")
print(f" 출력 디렉토리: {MD_DIR}")
print()
MD_DIR.mkdir(parents=True, exist_ok=True)
success = 0
for docx_name, file_info in FILE_MAP.items():
if extract_file(docx_name, file_info):
success += 1
print(f"\n완료: {success}/{len(FILE_MAP)} 파일 변환됨")
return 0 if success == len(FILE_MAP) else 1
if __name__ == "__main__":
sys.exit(main())

View File

@@ -0,0 +1,263 @@
#!/usr/bin/env python3
"""
DOCX ↔ Markdown 동기화 검증 스크립트
DOCX에서 텍스트를 추출하고 Markdown 파일의 텍스트와 비교하여
불일치 항목을 리포트한다.
"""
import difflib
import re
import sys
from pathlib import Path
from docx import Document
BASE_DIR = Path(__file__).resolve().parent.parent
DOCX_DIR = BASE_DIR / "docx"
MD_DIR = BASE_DIR / "markdown"
# DOCX → Markdown 파일 매핑
FILE_MAP = {
"01_고객_서비스이용계약서_v4_0_전자서명용.docx": "01-service-agreement.md",
"비밀유지서약서.docx": "02-nda.md",
"영업파트너 위촉계약서.docx": "03-partner-agreement.md",
"영업파트너 위촉계약서(단체용).docx": "04-partner-agreement-group.md",
}
def extract_text_from_docx(docx_path):
"""DOCX에서 순수 텍스트만 추출 (개정이력 테이블 제외, 인터리빙 방식)"""
doc = Document(str(docx_path))
lines = []
from docx.oxml.ns import qn as _qn
body = doc.element.body
para_idx = 0
table_idx = 0
skip_revision = False
for child in body:
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if tag == "p":
if para_idx < len(doc.paragraphs):
text = doc.paragraphs[para_idx].text.strip()
para_idx += 1
if "개정이력" in text:
skip_revision = True
continue
if text:
skip_revision = False
lines.append(text)
elif tag == "tbl":
if table_idx < len(doc.tables):
table = doc.tables[table_idx]
table_idx += 1
# 개정이력 테이블 건너뛰기
if len(table.rows) > 0:
first_row_text = [cell.text.strip() for cell in table.rows[0].cells]
if "버전" in first_row_text and "날짜" in first_row_text:
skip_revision = False
continue
if skip_revision:
skip_revision = False
continue
for row in table.rows:
cells = [cell.text.strip() for cell in row.cells]
# 빈 셀만 있는 행 건너뛰기
if not any(cells):
continue
row_text = " | ".join(cells)
if row_text.strip():
lines.append(row_text)
return lines
def extract_text_from_markdown(md_path):
"""Markdown에서 순수 텍스트만 추출 (프론트매터, 마크업 제거)"""
content = md_path.read_text(encoding="utf-8")
lines = []
in_frontmatter = False
in_table = False
for line in content.split("\n"):
stripped = line.strip()
# YAML 프론트매터 건너뛰기
if stripped == "---":
in_frontmatter = not in_frontmatter
continue
if in_frontmatter:
continue
# 빈 줄 건너뛰기
if not stripped:
in_table = False
continue
# Markdown 마크업 제거
text = stripped
# 헤딩 마크업 제거
text = re.sub(r"^#{1,6}\s+", "", text)
# 리스트 마크업 제거
text = re.sub(r"^\s*[-*+]\s+", "", text)
# Bold/Italic 마크업 제거
text = re.sub(r"\*\*(.+?)\*\*", r"\1", text)
text = re.sub(r"\*(.+?)\*", r"\1", text)
# 블록인용 제거
text = re.sub(r"^>\s*", "", text)
# 테이블 구분선 건너뛰기
if re.match(r"^\|[\s\-|]+\|$", text):
continue
# 테이블 행
if text.startswith("|") and text.endswith("|"):
# 파이프 제거하고 셀 텍스트 추출
cells = [c.strip() for c in text.strip("|").split("|")]
text = " | ".join(cells)
text = text.strip()
if text:
lines.append(text)
return lines
def normalize_text(text):
"""비교를 위한 텍스트 정규화"""
# 공백 정규화
text = re.sub(r"\s+", " ", text).strip()
# 특수문자 정규화
text = text.replace("\u00a0", " ") # non-breaking space
text = text.replace("\u3000", " ") # ideographic space
# 언더스코어 빈칸 정규화
text = re.sub(r"_{3,}", "___", text)
# Bold 마크업(**) 제거 (DOCX 텍스트에 리터럴 ** 포함되는 경우)
text = re.sub(r"\*\*(.+?)\*\*", r"\1", text)
# 선행 리스트 마커 제거 (DOCX 텍스트가 "- "로 시작하는 경우)
text = re.sub(r"^-\s+", "", text)
return text
def compare_documents(docx_name, md_name):
"""두 문서의 텍스트를 비교"""
docx_path = DOCX_DIR / docx_name
md_path = MD_DIR / md_name
if not docx_path.exists():
return {"status": "error", "message": f"DOCX 파일 없음: {docx_name}"}
if not md_path.exists():
return {"status": "error", "message": f"Markdown 파일 없음: {md_name}"}
docx_lines = [normalize_text(l) for l in extract_text_from_docx(docx_path) if l.strip()]
md_lines = [normalize_text(l) for l in extract_text_from_markdown(md_path) if l.strip()]
# difflib로 비교
matcher = difflib.SequenceMatcher(None, docx_lines, md_lines)
ratio = matcher.ratio()
# 차이점 추출
diffs = []
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == "equal":
continue
elif tag == "replace":
for idx in range(max(i2 - i1, j2 - j1)):
docx_text = docx_lines[i1 + idx] if i1 + idx < i2 else "(없음)"
md_text = md_lines[j1 + idx] if j1 + idx < j2 else "(없음)"
diffs.append({
"type": "변경",
"docx": docx_text[:80],
"markdown": md_text[:80],
})
elif tag == "delete":
for idx in range(i1, i2):
diffs.append({
"type": "DOCX에만 존재",
"docx": docx_lines[idx][:80],
"markdown": "-",
})
elif tag == "insert":
for idx in range(j1, j2):
diffs.append({
"type": "Markdown에만 존재",
"docx": "-",
"markdown": md_lines[idx][:80],
})
return {
"status": "ok",
"similarity": round(ratio * 100, 1),
"docx_lines": len(docx_lines),
"md_lines": len(md_lines),
"diff_count": len(diffs),
"diffs": diffs[:20], # 상위 20개만
}
def main():
print("=" * 70)
print("DOCX ↔ Markdown 동기화 검증")
print("=" * 70)
all_ok = True
for docx_name, md_name in FILE_MAP.items():
print(f"\n{'' * 50}")
print(f"문서: {docx_name}")
print(f"{md_name}")
print(f"{'' * 50}")
result = compare_documents(docx_name, md_name)
if result["status"] == "error":
print(f" [ERROR] {result['message']}")
all_ok = False
continue
similarity = result["similarity"]
status_icon = "OK" if similarity >= 80 else "WARN" if similarity >= 60 else "FAIL"
print(f" 유사도: {similarity}% [{status_icon}]")
print(f" DOCX 라인: {result['docx_lines']}")
print(f" Markdown 라인: {result['md_lines']}")
print(f" 차이점: {result['diff_count']}")
if result["diffs"]:
print(f"\n 주요 차이점 (상위 {min(len(result['diffs']), 10)}개):")
for i, diff in enumerate(result["diffs"][:10]):
print(f" [{diff['type']}]")
if diff["docx"] != "-":
print(f" DOCX: {diff['docx']}")
if diff["markdown"] != "-":
print(f" MD: {diff['markdown']}")
if similarity < 80:
all_ok = False
print(f"\n{'=' * 70}")
if all_ok:
print("결과: 모든 문서 동기화 상태 양호")
else:
print("결과: 일부 문서에서 불일치 발견 - 확인 필요")
print(f"{'=' * 70}")
return 0 if all_ok else 1
if __name__ == "__main__":
sys.exit(main())

View File

@@ -0,0 +1,279 @@
-- ============================================================
-- 인터뷰 질문 마스터 데이터 SQL
-- 8개 도메인 × 16개 템플릿 × 80개 질문
--
-- 실행 방법:
-- 로컬: docker exec -i sam-mysql-1 mysql -u root -p samdb < docs/data/interview-master-questions.sql
-- 개발서버: mysql -u <user> -p samdb < interview-master-questions.sql
-- phpMyAdmin: SQL 탭에서 전체 복사 후 실행
--
-- 주의: 한 번만 실행할 것. 중복 실행 시 데이터가 중복됨.
-- ============================================================
SET NAMES utf8mb4;
SET @tenant_id = 1;
SET @user_id = 1;
SET @now = NOW();
-- ============================================================
-- 대분류: 제조업-방화셔터 (parent_id=null, 루트 카테고리)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, NULL, '제조업-방화셔터', '방화셔터 제조업 인터뷰', NULL, 1, 1, @user_id, @user_id, @now, @now);
SET @root_manufacturing = LAST_INSERT_ID();
-- ============================================================
-- Domain 1: 제품 분류 체계 (product_classification)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '제품 분류 체계', '제품 카테고리, 모델 코드, 분류 기준 파악', 'product_classification', 3, 1, @user_id, @user_id, @now, @now);
SET @cat_1 = LAST_INSERT_ID();
-- 템플릿 1.1: 제품 카테고리 구조
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_1, '제품 카테고리 구조', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_1_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_1_1, '귀사의 주요 제품군을 모두 나열해주세요', 'text', NULL, '쉼표 구분으로 제품군 나열', NULL, NULL, 'product_classification', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '각 제품군의 하위 모델명과 코드 체계를 알려주세요', 'table_input', '{"columns":["모델코드","모델명","비고"]}', '코드-이름 매핑 테이블', NULL, NULL, 'product_classification', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '제품을 분류하는 기준은 무엇인가요? (소재, 용도, 크기 등)', 'multi_select', '{"choices":["소재별","용도별","크기별","설치방식별","인증여부별"]}', NULL, NULL, NULL, 'product_classification', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '인증(인정) 제품과 비인증 제품의 구분이 있나요?', 'select', '{"choices":["있음","없음"]}', NULL, NULL, NULL, 'product_classification', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '인증 제품의 경우 구성이 고정되나요?', 'checkbox', NULL, NULL, NULL, '{"question_index":3,"value":"있음"}', 'product_classification', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '카테고리별 제품 수는 대략 몇 개인가요?', 'number', NULL, NULL, '', NULL, 'product_classification', 0, 6, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '제품 코드 명명 규칙을 설명해주세요 (예: KSS01의 의미)', 'text', NULL, '코드 체계의 각 자릿수 의미', NULL, NULL, 'product_classification', 0, 7, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_1, '기존 시스템(ERP/엑셀)에서 사용하는 제품 분류 방식을 캡처하여 업로드해주세요', 'file_upload', NULL, NULL, NULL, NULL, 'product_classification', 0, 8, 1, @user_id, @user_id, @now, @now);
-- 템플릿 1.2: 설치 유형별 분류
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_1, '설치 유형별 분류', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_1_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_1_2, '설치 유형(벽면형, 측면형, 혼합형 등)에 따라 견적이 달라지나요?', 'select', '{"choices":["예, 크게 달라짐","약간 달라짐","달라지지 않음"]}', NULL, NULL, NULL, 'product_classification', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_2, '각 설치 유형별로 어떤 부품이 달라지나요?', 'table_input', '{"columns":["설치유형","추가부품","제외부품","비고"]}', NULL, NULL, NULL, 'product_classification', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_1_2, '설치 유형에 따른 추가 비용 항목이 있나요?', 'text', NULL, NULL, NULL, NULL, 'product_classification', 0, 3, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 2: BOM 구조 (bom_structure)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, 'BOM 구조', '완제품-부품 관계, 부품 카테고리, BOM 레벨', 'bom_structure', 4, 1, @user_id, @user_id, @now, @now);
SET @cat_2 = LAST_INSERT_ID();
-- 템플릿 2.1: 완제품-부품 관계
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_2, '완제품-부품 관계', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_2_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_2_1, '대표 제품 1개의 완제품→부품 구성을 트리로 그려주세요', 'bom_tree', NULL, '최상위 제품부터 하위 부품까지 트리 구조', NULL, NULL, 'bom_structure', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_1, '모든 제품에 공통으로 들어가는 부품은 무엇인가요?', 'multi_select', '{"choices":["가이드레일","케이스","모터","제어기","브라켓","볼트/너트"]}', '직접 입력 가능', NULL, NULL, 'bom_structure', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_1, '제품별로 선택적(옵션)인 부품은 무엇인가요?', 'table_input', '{"columns":["제품명","옵션부품","적용조건"]}', NULL, NULL, NULL, 'bom_structure', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_1, 'BOM이 현재 엑셀로 관리되고 있나요? 파일을 업로드해주세요', 'file_upload', NULL, NULL, NULL, NULL, 'bom_structure', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_1, '하위 부품의 단계(레벨)는 최대 몇 단계인가요?', 'number', NULL, NULL, '단계', NULL, 'bom_structure', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_1, '부품 수량이 고정인 것과 계산이 필요한 것을 구분해주세요', 'table_input', '{"columns":["부품명","고정/계산","고정수량 또는 계산식"]}', NULL, NULL, NULL, 'bom_structure', 0, 6, 1, @user_id, @user_id, @now, @now);
-- 템플릿 2.2: 부품 카테고리
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_2, '부품 카테고리', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_2_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_2_2, '부품을 카테고리로 분류하면 어떻게 나눠지나요? (본체, 절곡품, 전동부, 부자재 등)', 'text', NULL, '부품 분류 체계', NULL, NULL, 'bom_structure', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_2, '각 카테고리에 속하는 부품 목록을 정리해주세요', 'table_input', '{"columns":["카테고리","부품명","규격"]}', NULL, NULL, NULL, 'bom_structure', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_2, '외주 구매 부품과 자체 제작 부품의 구분이 있나요?', 'select', '{"choices":["있음","없음"]}', NULL, NULL, NULL, 'bom_structure', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_2_2, '부자재(볼트, 너트, 패킹 등)는 별도 관리하나요?', 'checkbox', NULL, NULL, NULL, NULL, 'bom_structure', 0, 4, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 3: 치수/변수 계산 (dimension_formula)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '치수/변수 계산', '오픈 사이즈→제작 사이즈 변환, 파생 변수 계산', 'dimension_formula', 5, 1, @user_id, @user_id, @now, @now);
SET @cat_3 = LAST_INSERT_ID();
-- 템플릿 3.1: 오픈 사이즈 → 제작 사이즈
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_3, '오픈 사이즈 → 제작 사이즈', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_3_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_3_1, '고객이 입력하는 기본 치수 항목은 무엇인가요? (폭, 높이, 깊이 등)', 'multi_select', '{"choices":["폭(W)","높이(H)","깊이(D)","두께(T)","지름(Ø)"]}', NULL, NULL, NULL, 'dimension_formula', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '오픈 사이즈에서 제작 사이즈로 변환할 때 더하는 마진값은?', 'formula_input', NULL, '예: W1 = W0 + 120, H1 = H0 + 50', 'mm', NULL, 'dimension_formula', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '제품 카테고리별로 마진값이 다른가요?', 'table_input', '{"columns":["제품카테고리","W 마진(mm)","H 마진(mm)","비고"]}', NULL, NULL, NULL, 'dimension_formula', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '면적(㎡) 계산 공식을 알려주세요', 'formula_input', NULL, '예: area = W1 * H1 / 1000000', '', NULL, 'dimension_formula', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '중량(kg) 계산 공식을 알려주세요', 'formula_input', NULL, '예: weight = area * 단위중량(kg/㎡)', 'kg', NULL, 'dimension_formula', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '기타 파생 변수가 있나요? (예: 분할 개수, 절곡 길이 등)', 'table_input', '{"columns":["변수명","계산식","단위","비고"]}', NULL, NULL, NULL, 'dimension_formula', 0, 6, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_1, '치수 계산에 사용하는 엑셀 수식을 캡처해주세요', 'file_upload', NULL, NULL, NULL, NULL, 'dimension_formula', 0, 7, 1, @user_id, @user_id, @now, @now);
-- 템플릿 3.2: 변수 의존 관계
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_3, '변수 의존 관계', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_3_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_3_2, '변수 간 의존 관계를 설명해주세요 (A는 B와 C로 계산)', 'text', NULL, '계산 순서와 변수 의존성', NULL, NULL, 'dimension_formula', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_2, '계산 순서가 중요한 변수가 있나요?', 'text', NULL, NULL, NULL, NULL, 'dimension_formula', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_3_2, '단위는 mm, m, kg 중 어떤 것을 기본으로 사용하나요?', 'select', '{"choices":["mm","m","cm","혼용"]}', NULL, NULL, NULL, 'dimension_formula', 0, 3, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 4: 부품 구성 상세 (component_config)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '부품 구성 상세', '주요 부품별 규격, 선택 기준, 특수 구성', 'component_config', 6, 1, @user_id, @user_id, @now, @now);
SET @cat_4 = LAST_INSERT_ID();
-- 템플릿 4.1: 주요 부품별 상세
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_4, '주요 부품별 상세', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_4_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_4_1, '가이드레일의 표준 길이 규격은? (예: 1219, 2438, 3305mm)', 'table_input', '{"columns":["규격코드","길이(mm)","비고"]}', NULL, NULL, NULL, 'component_config', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '가이드레일 길이 조합 규칙은? (어떤 길이를 몇 개 사용?)', 'text', NULL, '높이에 따른 가이드레일 조합 로직', NULL, NULL, 'component_config', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '케이스(하우징) 크기별 규격과 부속품 차이를 설명해주세요', 'table_input', '{"columns":["케이스규격","적용조건","부속품"]}', NULL, NULL, NULL, 'component_config', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '모터 용량 종류와 선택 기준은? (무게별? 면적별?)', 'table_input', '{"columns":["모터용량","적용범위(최소)","적용범위(최대)","단위"]}', '무게/면적 범위별 모터 매핑', NULL, NULL, 'component_config', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '모터 전압 옵션은? (380V, 220V 등)', 'multi_select', '{"choices":["380V","220V","110V","DC 24V"]}', NULL, NULL, NULL, 'component_config', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '제어기 종류와 선택 기준은? (노출형/매립형 등)', 'table_input', '{"columns":["제어기유형","적용조건","비고"]}', NULL, NULL, NULL, 'component_config', 0, 6, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '절곡품(판재 가공) 목록과 각각의 치수 결정 방식은?', 'table_input', '{"columns":["절곡품명","치수결정방식","재질","두께(mm)"]}', NULL, NULL, NULL, 'component_config', 0, 7, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_1, '부자재(볼트, 너트, 패킹 등) 목록과 수량 결정 방식은?', 'table_input', '{"columns":["부자재명","규격","수량결정방식","기본수량"]}', NULL, NULL, NULL, 'component_config', 0, 8, 1, @user_id, @user_id, @now, @now);
-- 템플릿 4.2: 특수 구성
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_4, '특수 구성', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_4_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_4_2, '연기차단재 등 특수 부품이 있나요? 적용 조건은?', 'text', NULL, NULL, NULL, NULL, 'component_config', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_2, '보강재(샤프트, 파이프, 앵글 등) 사용 조건은?', 'table_input', '{"columns":["보강재명","규격","적용조건","수량"]}', NULL, NULL, NULL, 'component_config', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_4_2, '고객 요청에 따라 추가/제외되는 옵션 부품은?', 'table_input', '{"columns":["옵션부품","추가/제외","추가비용","비고"]}', NULL, NULL, NULL, 'component_config', 0, 3, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 5: 단가 체계 (pricing_structure)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '단가 체계', '단가 관리 방식, 계산 방식, 마진/LOSS율', 'pricing_structure', 7, 1, @user_id, @user_id, @now, @now);
SET @cat_5 = LAST_INSERT_ID();
-- 템플릿 5.1: 단가 관리 방식
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_5, '단가 관리 방식', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_5_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_5_1, '부품별 단가를 어디서 관리하나요? (엑셀, ERP, 구두 등)', 'select', '{"choices":["엑셀","ERP 시스템","구두/경험","기타"]}', NULL, NULL, NULL, 'pricing_structure', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, '단가표 파일을 업로드해주세요', 'file_upload', NULL, NULL, NULL, NULL, 'pricing_structure', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, '단가 변경 주기는? (월/분기/연 등)', 'select', '{"choices":["수시","월 단위","분기 단위","반기 단위","연 단위"]}', NULL, NULL, NULL, 'pricing_structure', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, '단가에 포함되는 항목은? (재료비만? 가공비 포함?)', 'multi_select', '{"choices":["재료비","가공비","운송비","설치비","마진"]}', NULL, NULL, NULL, 'pricing_structure', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, '고객별/거래처별 차등 단가가 있나요?', 'select', '{"choices":["있음 (등급별)","있음 (거래처별)","없음 (일괄 동일)"]}', NULL, NULL, NULL, 'pricing_structure', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, 'LOSS율(손실률)을 적용하나요? 적용 방식은?', 'formula_input', NULL, '예: 실제수량 = 계산수량 × (1 + LOSS율)', '%', NULL, 'pricing_structure', 0, 6, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_1, '마진율 설정 방식은? (일괄? 품목별?)', 'select', '{"choices":["일괄 마진율","품목별 마진율","카테고리별 마진율","고객별 마진율"]}', NULL, NULL, NULL, 'pricing_structure', 0, 7, 1, @user_id, @user_id, @now, @now);
-- 템플릿 5.2: 단가 계산 방식
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_5, '단가 계산 방식', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_5_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_5_2, '면적 기반 단가 품목은? (원/㎡)', 'table_input', '{"columns":["품목명","단가(원/㎡)","비고"]}', NULL, '원/㎡', NULL, 'pricing_structure', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_2, '중량 기반 단가 품목은? (원/kg)', 'table_input', '{"columns":["품목명","단가(원/kg)","비고"]}', NULL, '원/kg', NULL, 'pricing_structure', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_2, '수량 기반 단가 품목은? (원/EA)', 'table_input', '{"columns":["품목명","단가(원/EA)","비고"]}', NULL, '원/EA', NULL, 'pricing_structure', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_2, '길이 기반 단가 품목은? (원/m)', 'table_input', '{"columns":["품목명","단가(원/m)","비고"]}', NULL, '원/m', NULL, 'pricing_structure', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_5_2, '기타 특수 단가 계산 방식이 있나요?', 'text', NULL, NULL, NULL, NULL, 'pricing_structure', 0, 5, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 6: 수량 수식 (quantity_formula)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '수량 수식', '부품별 수량 결정 규칙, 계산식, 검증', 'quantity_formula', 8, 1, @user_id, @user_id, @now, @now);
SET @cat_6 = LAST_INSERT_ID();
-- 템플릿 6.1: 수량 결정 규칙
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_6, '수량 결정 규칙', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_6_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_6_1, '고정 수량 부품 목록 (항상 1개, 2개 등)', 'table_input', '{"columns":["부품명","고정수량","비고"]}', NULL, NULL, NULL, 'quantity_formula', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_1, '치수 기반 수량 계산 부품과 수식', 'formula_input', NULL, '예: 슬랫수량 = CEIL(H1 / 슬랫피치)', NULL, NULL, 'quantity_formula', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_1, '면적 기반 수량 계산 부품과 수식', 'formula_input', NULL, '예: 스크린수량 = area / 기준면적', NULL, NULL, 'quantity_formula', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_1, '중량 기반 수량 계산 부품과 수식', 'formula_input', NULL, NULL, NULL, NULL, 'quantity_formula', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_1, '올림/내림/반올림 규칙이 있는 계산은?', 'table_input', '{"columns":["계산항목","올림/내림/반올림","소수점자릿수"]}', NULL, NULL, NULL, 'quantity_formula', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_1, '여유 수량(LOSS) 적용 품목과 비율은?', 'table_input', '{"columns":["품목명","LOSS율(%)","비고"]}', NULL, NULL, NULL, 'quantity_formula', 0, 6, 1, @user_id, @user_id, @now, @now);
-- 템플릿 6.2: 수식 검증
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_6, '수식 검증', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_6_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_6_2, '실제 견적서에서 수량 계산 예시를 보여주세요 (W=3000, H=2500일 때)', 'table_input', '{"columns":["부품명","수식","계산결과","단위"]}', NULL, NULL, NULL, 'quantity_formula', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_2, '수식에 사용하는 함수가 있나요? (SUM, CEIL, ROUND 등)', 'multi_select', '{"choices":["CEIL (올림)","FLOOR (내림)","ROUND (반올림)","MAX","MIN","IF 조건문","SUM"]}', NULL, NULL, NULL, 'quantity_formula', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_6_2, '조건에 따라 수식이 달라지는 경우가 있나요?', 'text', NULL, '예: 폭이 3000 초과이면 분할 계산', NULL, NULL, 'quantity_formula', 0, 3, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 7: 조건부 로직 (conditional_logic)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '조건부 로직', '범위/매핑 기반 부품 자동 선택 규칙', 'conditional_logic', 9, 1, @user_id, @user_id, @now, @now);
SET @cat_7 = LAST_INSERT_ID();
-- 템플릿 7.1: 범위 기반 선택
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_7, '범위 기반 선택', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_7_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_7_1, '무게 범위별 모터 용량 선택표를 작성해주세요', 'price_table', '{"columns":["범위 시작(kg)","범위 끝(kg)","모터용량","비고"]}', NULL, NULL, NULL, 'conditional_logic', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_7_1, '크기 범위별 부품 자동 선택 규칙이 있나요?', 'table_input', '{"columns":["조건(변수)","범위","선택부품","비고"]}', NULL, NULL, NULL, 'conditional_logic', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_7_1, '브라켓 크기 결정 기준은?', 'table_input', '{"columns":["조건","범위","브라켓 규격"]}', NULL, NULL, NULL, 'conditional_logic', 0, 3, 1, @user_id, @user_id, @now, @now);
-- 템플릿 7.2: 매핑 기반 선택
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_7, '매핑 기반 선택', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_7_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_7_2, '제품 모델 → 기본 부품 세트 매핑표', 'table_input', '{"columns":["제품모델","기본부품1","기본부품2","기본부품3"]}', NULL, NULL, NULL, 'conditional_logic', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_7_2, '설치 유형 → 추가 부품 매핑표', 'table_input', '{"columns":["설치유형","추가부품","수량","비고"]}', NULL, NULL, NULL, 'conditional_logic', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_7_2, '제어기 유형 → 부속품 매핑표', 'table_input', '{"columns":["제어기유형","부속품1","부속품2","부속품3"]}', NULL, NULL, NULL, 'conditional_logic', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_7_2, '기타 조건부 자동 선택 규칙', 'text', NULL, '위 항목에 해당하지 않는 조건-결과 매핑', NULL, NULL, 'conditional_logic', 0, 4, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- Domain 8: 견적서 양식 (quote_format)
-- ============================================================
INSERT INTO interview_categories (tenant_id, interview_project_id, parent_id, name, description, domain, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, NULL, @root_manufacturing, '견적서 양식', '출력 양식, 항목 그룹, 소계/합계 구조', 'quote_format', 10, 1, @user_id, @user_id, @now, @now);
SET @cat_8 = LAST_INSERT_ID();
-- 템플릿 8.1: 출력 양식
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_8, '출력 양식', 1, 1, @user_id, @user_id, @now, @now);
SET @tpl_8_1 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_8_1, '현재 사용 중인 견적서 양식을 업로드해주세요', 'file_upload', NULL, NULL, NULL, NULL, 'quote_format', 1, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '견적서에 표시되는 항목 그룹은? (재료비, 노무비, 설치비 등)', 'multi_select', '{"choices":["재료비","노무비","경비","설치비","운반비","이윤","부가세"]}', NULL, NULL, NULL, 'quote_format', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '소계/합계 계산 구조를 설명해주세요', 'text', NULL, '항목 그룹별 소계와 최종 합계의 관계', NULL, NULL, 'quote_format', 0, 3, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '할인 적용 방식은? (일괄? 항목별?)', 'select', '{"choices":["일괄 할인","항목별 할인","할인 없음","협의 할인"]}', NULL, NULL, NULL, 'quote_format', 0, 4, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '부가세 표시 방식은? (별도? 포함?)', 'select', '{"choices":["별도 표시","포함 표시","선택 가능"]}', NULL, NULL, NULL, 'quote_format', 0, 5, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '견적서에 표시하지 않는 내부 관리 항목은?', 'text', NULL, NULL, NULL, NULL, 'quote_format', 0, 6, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_1, '견적 번호 체계를 알려주세요', 'text', NULL, '예: Q-2026-001 형식', NULL, NULL, 'quote_format', 0, 7, 1, @user_id, @user_id, @now, @now);
-- 템플릿 8.2: 특수 요구사항
INSERT INTO interview_templates (tenant_id, interview_category_id, name, sort_order, is_active, created_by, updated_by, created_at, updated_at)
VALUES (@tenant_id, @cat_8, '특수 요구사항', 2, 1, @user_id, @user_id, @now, @now);
SET @tpl_8_2 = LAST_INSERT_ID();
INSERT INTO interview_questions (tenant_id, interview_template_id, question_text, question_type, options, ai_hint, expected_format, depends_on, domain, is_required, sort_order, is_active, created_by, updated_by, created_at, updated_at) VALUES
(@tenant_id, @tpl_8_2, '산출내역서(세부 내역)를 별도로 제공하나요?', 'checkbox', NULL, NULL, NULL, NULL, 'quote_format', 0, 1, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_2, '위치별(층/부호) 개별 산출이 필요한가요?', 'checkbox', NULL, NULL, NULL, NULL, 'quote_format', 0, 2, 1, @user_id, @user_id, @now, @now),
(@tenant_id, @tpl_8_2, '일괄 산출(여러 위치 합산)을 사용하나요?', 'checkbox', NULL, NULL, NULL, NULL, 'quote_format', 0, 3, 1, @user_id, @user_id, @now, @now);
-- ============================================================
-- 완료 확인
-- ============================================================
SELECT
(SELECT COUNT(*) FROM interview_categories WHERE interview_project_id IS NULL AND domain IS NOT NULL) AS master_categories,
(SELECT COUNT(*) FROM interview_templates t JOIN interview_categories c ON t.interview_category_id = c.id WHERE c.interview_project_id IS NULL AND c.domain IS NOT NULL) AS master_templates,
(SELECT COUNT(*) FROM interview_questions q JOIN interview_templates t ON q.interview_template_id = t.id JOIN interview_categories c ON t.interview_category_id = c.id WHERE c.interview_project_id IS NULL AND c.domain IS NOT NULL) AS master_questions;

View File

@@ -90,5 +90,5 @@ CANCELLED → DRAFT (복구 가능)
- Swagger UI에서 API 테스트 가능: http://api.sam.kr/api-docs/index.html
## 🔗 관련 문서
- 계획 문서: `docs/plans/order-management-plan.md`
- 계획 문서: `docs/dev_plans/order-management-plan.md`
- 참고 패턴: `app/Services/WorkOrderService.php`, `app/Http/Controllers/Api/V1/WorkOrderController.php`

View File

@@ -75,4 +75,4 @@ public function revokeAccount(int $id): TenantUserProfile
- 기존 사원 데이터에 영향 없음
## 🔗 관련 문서
- docs/plans/employee-user-linkage-plan.md
- docs/dev_plans/employee-user-linkage-plan.md

View File

@@ -2,7 +2,7 @@
**날짜:** 2025-12-30 14:30
**작업자:** Claude Code
**관련 문서:** docs/plans/react-fcm-push-notification-plan.md
**관련 문서:** docs/dev_plans/react-fcm-push-notification-plan.md
## 📋 변경 개요

View File

@@ -94,7 +94,7 @@ Route::post('/calculate/bom', [QuoteController::class, 'calculateBom'])->name('v
- 기존 API에 영향 없음 (신규 엔드포인트 추가)
## 🔗 관련 문서
- 계획 문서: `docs/plans/quote-calculation-api-plan.md`
- 계획 문서: `docs/dev_plans/quote-calculation-api-plan.md`
- FormulaEvaluatorService: `api/app/Services/Quote/FormulaEvaluatorService.php`
## 📊 API 사용 예시

View File

@@ -13,7 +13,7 @@
| 파일 | 변경 내용 |
|------|----------|
| `react/src/components/business/construction/handover-report/actions.ts` | Mock → API 완전 변환 |
| `docs/plans/sub/handover-report-plan.md` | 진행 상태 업데이트 |
| `docs/dev_plans/sub/handover-report-plan.md` | 진행 상태 업데이트 |
## 🔧 상세 변경 사항

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-22
**작업자:** Claude Code
**계획 문서:** docs/plans/card-management-section-plan.md
**계획 문서:** docs/dev_plans/card-management-section-plan.md
**Phase:** 1.1 카드 거래 대시보드 API 개발
## 📋 변경 개요
@@ -71,5 +71,5 @@ Route::get('/dashboard', [CardTransactionController::class, 'dashboard'])
특이사항 없음 (DB 스키마 변경 없음)
## 🔗 관련 문서
- 계획 문서: `docs/plans/card-management-section-plan.md`
- 계획 문서: `docs/dev_plans/card-management-section-plan.md`
- 기존 API 문서: `api/app/Swagger/v1/CardTransactionApi.php`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-22
**작업자:** Claude Code
**계획 문서:** docs/plans/card-management-section-plan.md
**계획 문서:** docs/dev_plans/card-management-section-plan.md
**Phase:** 1.2 가지급금 대시보드 API 개발
## 📋 변경 개요
@@ -78,6 +78,6 @@ Route::get('/dashboard', [LoanController::class, 'dashboard'])
특이사항 없음 (DB 스키마 변경 없음)
## 🔗 관련 문서
- 계획 문서: `docs/plans/card-management-section-plan.md`
- 계획 문서: `docs/dev_plans/card-management-section-plan.md`
- Phase 1.1 변경: `docs/changes/20260122_card_transaction_dashboard_api.md`
- 기존 API 문서: `api/app/Swagger/v1/LoanApi.php`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-22
**작업자:** Claude Code
**계획 문서:** docs/plans/card-management-section-plan.md
**계획 문서:** docs/dev_plans/card-management-section-plan.md
**Phase:** 1.3 세금 시뮬레이션 API 개발
## 📋 변경 개요
@@ -98,7 +98,7 @@ Route::get('/tax-simulation', [LoanController::class, 'taxSimulation'])
특이사항 없음 (DB 스키마 변경 없음)
## 🔗 관련 문서
- 계획 문서: `docs/plans/card-management-section-plan.md`
- 계획 문서: `docs/dev_plans/card-management-section-plan.md`
- Phase 1.1 변경: `docs/changes/20260122_card_transaction_dashboard_api.md`
- Phase 1.2 변경: `docs/changes/20260122_loan_dashboard_api.md`
- 기존 API 문서: `api/app/Swagger/v1/LoanApi.php`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-26
**작업자:** Claude Code
**관련 계획:** docs/plans/quote-management-url-migration-plan.md (Step 1.3, 1.4)
**관련 계획:** docs/dev_plans/quote-management-url-migration-plan.md (Step 1.3, 1.4)
## 📋 변경 개요
V2 견적 상세/수정 테스트 페이지(test/[id])에서 Mock 데이터를 실제 API 연동으로 변경
@@ -135,7 +135,7 @@ const handleSave = useCallback(async (data: QuoteFormDataV2, saveType: "temporar
- [ ] Step 2.3: 기존 V1 페이지 처리 결정
## 🔗 관련 문서
- 계획 문서: `docs/plans/quote-management-url-migration-plan.md`
- 계획 문서: `docs/dev_plans/quote-management-url-migration-plan.md`
- Step 1.1 변경 내역: `docs/changes/20260126_quote_v2_transform_functions.md`
- Step 1.2 변경 내역: `docs/changes/20260126_quote_v2_test_new_api.md`
- V2 컴포넌트: `react/src/components/quotes/QuoteRegistrationV2.tsx`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-26
**작업자:** Claude Code
**관련 계획:** docs/plans/quote-management-url-migration-plan.md (Step 1.2)
**관련 계획:** docs/dev_plans/quote-management-url-migration-plan.md (Step 1.2)
## 📋 변경 개요
V2 견적 등록 테스트 페이지(test-new)에서 Mock 저장을 실제 API 연동으로 변경
@@ -76,6 +76,6 @@ const handleSave = useCallback(async (data: QuoteFormDataV2, saveType: 'temporar
- [ ] test/[id] 수정 API 연동 (updateQuote)
## 🔗 관련 문서
- 계획 문서: `docs/plans/quote-management-url-migration-plan.md`
- 계획 문서: `docs/dev_plans/quote-management-url-migration-plan.md`
- Step 1.1 변경 내역: `docs/changes/20260126_quote_v2_transform_functions.md`
- V2 컴포넌트: `react/src/components/quotes/QuoteRegistrationV2.tsx`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-26
**작업자:** Claude Code
**관련 계획:** docs/plans/quote-management-url-migration-plan.md (Step 1.1)
**관련 계획:** docs/dev_plans/quote-management-url-migration-plan.md (Step 1.1)
## 📋 변경 개요
V2 견적 컴포넌트(QuoteRegistrationV2)에서 사용할 데이터 변환 함수 구현
@@ -82,5 +82,5 @@ API 응답을 V2 폼 데이터로 변환
- [ ] test/[id] 수정 API 연동 (updateQuote)
## 🔗 관련 문서
- 계획 문서: `docs/plans/quote-management-url-migration-plan.md`
- 계획 문서: `docs/dev_plans/quote-management-url-migration-plan.md`
- V2 컴포넌트: `react/src/components/quotes/QuoteRegistrationV2.tsx`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-26
**작업자:** Claude Code
**관련 계획:** docs/plans/quote-management-url-migration-plan.md (Phase 1 버그 수정)
**관련 계획:** docs/dev_plans/quote-management-url-migration-plan.md (Phase 1 버그 수정)
## 📋 변경 개요
V2 견적 등록 컴포넌트에서 작성자 필드가 "드미트리"로 하드코딩된 버그 수정
@@ -72,5 +72,5 @@ useEffect(() => {
3. **edit/view 모드**: initialData의 writer 값 유지 (덮어쓰지 않음)
## 🔗 관련 문서
- 계획 문서: `docs/plans/quote-management-url-migration-plan.md`
- 계획 문서: `docs/dev_plans/quote-management-url-migration-plan.md`
- AuthContext: `react/src/contexts/AuthContext.tsx`

View File

@@ -98,7 +98,7 @@
## 🔗 관련 문서
- 계획 문서: `docs/plans/document-management-system-plan.md`
- 계획 문서: `docs/dev_plans/document-management-system-plan.md`
- 다음 작업: Phase 1.2 - 모델 생성 (Document, DocumentApproval, DocumentData, DocumentAttachment)
## ⚠️ 배포 시 주의사항

View File

@@ -56,4 +56,4 @@
## 🔗 관련 문서
- Phase 1.1: 마이그레이션 (`20260128_document_management_phase1_1.md`)
- Phase 1.2: 모델 생성 (별도 문서 없음, 커밋 참조)
- 계획 문서: `docs/plans/document-management-system-plan.md`
- 계획 문서: `docs/dev_plans/document-management-system-plan.md`

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-28
**작업자:** Claude Code
**관련 문서:** docs/plans/kd-items-migration-plan.md
**관련 문서:** docs/dev_plans/kd-items-migration-plan.md
## 📋 변경 개요

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-01-28
**작업자:** Claude Code
**관련 문서:** docs/plans/kd-items-migration-plan.md
**관련 문서:** docs/dev_plans/kd-items-migration-plan.md
## 📋 변경 개요
@@ -13,7 +13,7 @@
| 파일 | 설명 |
|------|------|
| `api/database/seeders/Kyungdong/KyungdongItemSeeder.php` | Phase 3.1, 3.2 메서드 추가 |
| `docs/plans/kd-items-migration-plan.md` | Phase 3 완료 상태 업데이트 |
| `docs/dev_plans/kd-items-migration-plan.md` | Phase 3 완료 상태 업데이트 |
## 🔧 상세 변경 사항

View File

@@ -2,7 +2,7 @@
**날짜:** 2026-02-05
**작업자:** Claude Code
**관련 계획:** docs/plans/incoming-inspection-templates-plan.md
**관련 계획:** docs/dev_plans/incoming-inspection-templates-plan.md
## 📋 변경 개요
5130 레거시 수입검사 양식 전환 작업 - Phase 1 완료
@@ -18,7 +18,7 @@
- `document_template_columns` - 84건 INSERT (7개 컬럼 × 12개 템플릿 19-30)
### 문서 변경
- `docs/plans/incoming-inspection-templates-plan.md` - 진행 상태 업데이트
- `docs/dev_plans/incoming-inspection-templates-plan.md` - 진행 상태 업데이트
## 🔧 상세 변경 사항
@@ -102,5 +102,5 @@
4. React resolve API 테스트
## 🔗 관련 문서
- 계획 문서: `docs/plans/incoming-inspection-templates-plan.md`
- 계획 문서: `docs/dev_plans/incoming-inspection-templates-plan.md`
- 레거시 참조: `5130/instock/i_SUSplate.php`

View File

@@ -0,0 +1,133 @@
# 자금일보 바로빌 자동동기화 및 계정과목 데이터 정리
**날짜:** 2026-03-11
**작업자:** Claude Code
---
## 변경 개요
두 가지 문제를 수정한다:
1. **자금일보 출금 내역 누락**`periodReport()`가 DB 캐시만 조회하고 바로빌 API 동기화를 트리거하지 않아, 최신 거래내역이 반영되지 않는 문제
2. **홈택스 분개 계정과목 오류** — 드롭다운에 2,549개 코드 표시(정상: 163개), 분개 기본값에 존재하지 않는 코드 사용
---
## 수정된 파일
| 파일 | 프로젝트 | 변경 내용 |
|------|---------|----------|
| `app/Services/Barobill/BarobillBankSyncService.php` | MNG (신규) | 바로빌 계좌 거래내역 동기화 서비스 |
| `app/Http/Controllers/Finance/DailyFundController.php` | MNG | `periodReport()`에 자동 동기화 호출 추가 |
| `resources/views/barobill/hometax/index.blade.php` | MNG | 분개 기본 계정과목 코드 수정 |
| `database/migrations/2026_03_11_101502_fix_account_codes_duplicate_data.php` | API (신규) | 중복 계정과목 비활성화 + 분개 코드 일괄 수정 |
---
## 상세 변경 사항
### 1. 바로빌 자동 동기화 서비스 (MNG)
**문제**: `DailyFundController::periodReport()``barobill_bank_transactions` 테이블만 조회한다. 바로빌 API에서 데이터를 가져오는 동기화는 `EaccountController`에서만 수행되어, 자금일보 페이지에서는 캐시가 갱신되지 않으면 최신 거래가 누락된다.
**해결**: `EaccountController`의 동기화 로직을 `BarobillBankSyncService`로 분리하여 재사용 가능하게 한다.
```
DailyFundController::periodReport()
├── BarobillBankSyncService::syncIfNeeded() ← 신규
│ ├── BarobillMember 조회 (바로빌 인증)
│ ├── SOAP 클라이언트 초기화
│ ├── 등록 계좌 목록 조회
│ └── 월별 청크 순회
│ ├── BankSyncStatus 캐시 판단
│ │ ├── 과거 월: 항상 캐시 (API 호출 안 함)
│ │ └── 현재 월: 10분 이내면 캐시
│ └── 필요 시 API 호출 → DB 캐시 저장
└── DB에서 거래내역 조회 (기존 로직)
```
**캐시 정책**:
| 조건 | 동작 |
|------|------|
| 과거 월 + 동기화 이력 있음 | 캐시 사용 (API 호출 안 함) |
| 현재 월 + 10분 이내 동기화 | 캐시 사용 |
| 현재 월 + 10분 초과 | API에서 갱신 |
| 동기화 이력 없음 | API에서 갱신 |
**실패 처리**: 동기화 실패 시 예외를 catch하고 로그만 남기며, 기존 DB 캐시로 응답을 계속한다.
---
### 2. 계정과목 중복 데이터 정리 (API 마이그레이션)
**문제**: `account_codes` 테이블에 비표준 코드가 대량 등록되어 드롭다운이 오염되었다.
| 코드 유형 | 건수 | 예시 | 상태 |
|----------|------|------|------|
| 3자리 더존 표준 코드 | 163개 | `101` 현금, `108` 외상매출금 | ✅ 정상 |
| 5자리 KIS 코드 (중복) | ~2,290개 | `10100` Cash, `10800` Accounts Receivable | ❌ 비활성화 |
| 1~2자리 카테고리 헤더 | ~96개 | `1` Assets, `10` Current Assets | ❌ 비활성화 |
**해결**: `LENGTH(code) != 3`인 코드를 `is_active = false`로 비활성화한다. 데이터는 삭제하지 않으며 필요 시 복원 가능하다.
---
### 3. 홈택스 분개 기본 코드 수정
**문제**: `getDefaultLines()` 함수에서 하드코딩된 계정과목 코드가 실제 DB 코드와 불일치한다.
| 거래 유형 | 항목 | 기존 코드 | 수정 코드 | 비고 |
|----------|------|----------|----------|------|
| 매출 | 부가세예수금 | `255` (장기미지급금) | `208` | 코드 불일치 |
| 매입 | 부가세대급금 | `135` (미존재) | `117` | DB에 없는 코드 |
| 매입 | 외상매입금 | `251` (장기차입금) | `201` | 코드 불일치 |
| 매입 | 적요명 | 상품매입 | 상품매출원가 | `501` 코드에 맞는 명칭 |
**API 마이그레이션으로 기존 분개 데이터도 일괄 수정**:
```sql
-- 135 → 117 (부가세대급금)
UPDATE hometax_invoice_journals SET account_code='117', account_name='부가세대급금' WHERE account_code='135';
-- 251 → 201 (외상매입금)
UPDATE hometax_invoice_journals SET account_code='201' WHERE account_code='251' AND account_name='외상매입금';
-- 255 → 208 (부가세예수금)
UPDATE hometax_invoice_journals SET account_code='208' WHERE account_code='255' AND account_name='부가세예수금';
```
---
## 배포
| 프로젝트 | 커밋 | develop | main |
|---------|------|---------|------|
| MNG | `ca36e8e5` (동기화 서비스), `afa64280` (계정과목 수정) | ✅ 푸시 완료 | ✅ 체리픽 완료 |
| API | `6f48b86` (데이터 마이그레이션) | ✅ 푸시 완료 | ✅ 체리픽 완료 |
Jenkins가 양쪽 서버에서 자동 배포 및 마이그레이션 실행을 완료했다.
---
## 테스트 체크리스트
- [x] 로컬 DB에서 `account_codes` 비표준 코드 비활성화 확인
- [x] 바로빌 동기화 후 2026-03-10 거래내역 10건 정상 조회
- [x] 홈택스 분개 기본값에 올바른 코드(`117`, `201`, `208`) 반영
- [x] 개발 서버 마이그레이션 실행 확인
- [x] 운영 서버 마이그레이션 자동 실행 확인
---
## 관련 문서
- [재무 관리](../../features/finance/README.md)
- [DB 스키마 - 재무](../../system/database/finance.md)
---
**최종 업데이트**: 2026-03-11

View File

@@ -0,0 +1,136 @@
# 전자서명 체크박스, 전표 적요 동기화, 거래처 드롭다운, 바로빌 중복 키 수정
**날짜:** 2026-03-11
**작업자:** Claude Code
---
## 변경 개요
네 가지 개선/수정 사항:
1. **전자서명 템플릿 체크박스** — 체크박스 필드에 변수 연결 UI를 추가했다가, "배치 위치에 무조건 체크 표시" 방식으로 단순화
2. **전표 적요 → 자금일보 동기화** — 일반전표 적요 수정 시 일일자금일보에 반영되지 않던 문제 해결
3. **거래처 드롭다운 클릭 버그** — 다른 요소에서 포커스 이동 후 클릭 시 드롭다운이 즉시 닫히는 문제 해결
4. **바로빌 은행거래 중복 키 에러**`EaccountController` 동기화 시 `insert``insertOrIgnore` 변경
---
## 수정된 파일
| 파일 | 프로젝트 | 변경 내용 |
|------|---------|----------|
| `resources/views/esign/template-fields.blade.php` | MNG | 체크박스 필드 속성 패널에 안내 문구 + PDF 오버레이에 ☑ 표시 |
| `app/Http/Controllers/Finance/JournalEntryController.php` | MNG | `update()``BankTransactionOverride` 동기화 추가 |
| `resources/views/finance/journal-entries.blade.php` | MNG | `TradingPartnerSelect``justFocusedRef` 플래그 추가 |
| `app/Http/Controllers/Barobill/EaccountController.php` | MNG | `insert``insertOrIgnore` 변경 |
---
## 상세 변경 사항
### 1. 전자서명 템플릿 체크박스 단순화
**문제**: 체크박스 필드를 템플릿에 배치할 때 변수 연결 드롭다운이 표시되었으나, 선택 가능한 체크박스 변수가 없어 사용 불가.
**해결**: 체크박스는 "이 위치에 체크 표시를 넣겠다"는 의미이므로 변수 연결 자체가 불필요. 다음과 같이 단순화:
- 변수 연결 UI 제거 → "☑ 이 위치에 체크 표시가 렌더링됩니다" 안내 문구 표시
- PDF 오버레이에서 체크박스 필드는 ☑ 아이콘으로 시각적 표시
- 커스텀 변수의 체크박스 타입 옵션 제거
```
체크박스 필드 배치 → 해당 위치에 무조건 ☑ 렌더링
(변수 연결 불필요, 위치 정보만 저장)
```
---
### 2. 전표 적요 수정 → 자금일보 반영
**문제**: 일반전표의 적요를 수정하면 `journal_entries.description`만 업데이트되고, 일일자금일보가 참조하는 `barobill_bank_transactions.summary`는 변경되지 않음.
```
JournalEntry.description 수정
↓ (기존: 연결 없음)
일일자금일보 → barobill_bank_transactions.summary (이전 값 그대로)
```
**해결**: `JournalEntryController::update()` 트랜잭션 안에서, `source_type = 'bank_transaction'`인 전표의 적요 수정 시 `BankTransactionOverride``modified_summary`를 저장.
```
JournalEntry.description 수정
↓ (신규: 자동 동기화)
BankTransactionOverride.modified_summary 저장
일일자금일보 periodReport() → override 적용 → 수정된 적요 표시
```
**기존 `modified_cast` 보존**: override 저장 시 기존 `modified_cast` 값을 조회하여 유지.
---
### 3. 거래처 드롭다운 클릭 버그 수정
**문제**: `TradingPartnerSelect` 컴포넌트에서 다른 요소에 포커스가 있을 때 클릭하면 드롭다운이 열렸다가 즉시 닫힘.
**원인**: 이벤트 순서 — `onFocus` → 드롭다운 열림 → `onClick``setIsOpen(!isOpen)` 토글로 다시 닫힘. React 렌더 타이밍에 따라 `onClick``isOpen = true` 상태에서 실행되어 `false`로 전환.
**해결**: `justFocusedRef` 플래그 추가.
```javascript
onFocus justFocusedRef = true, setIsOpen(true)
onClick justFocusedRef가 true면 토글 건너뜀 (이미 열림)
justFocusedRef가 false면 정상 토글 (이미 포커스된 상태에서 클릭)
```
---
### 4. 바로빌 은행거래 동기화 중복 키 에러
**문제**: `EaccountController`의 거래내역 저장 시 `Duplicate entry` 에러 발생.
**원인**: 기존 레코드 조회 WHERE에 `summary`를 포함하지만, DB unique index(`barobill_bank_trans_unique`)에는 `summary`가 없음.
| 구분 | 포함 컬럼 |
|------|----------|
| WHERE 조회 | `tenant_id`, `bank_account_num`, `trans_dt`, `deposit`, `withdraw`, `balance`, **`summary`** |
| DB unique index | `tenant_id`, `bank_account_num`, `trans_dt`, `deposit`, `withdraw`, `balance` |
같은 거래인데 `summary`만 다른 경우(전각/반각 문자 차이 등) → WHERE에서 기존 레코드 못 찾음 → INSERT 시도 → unique index 위반.
**해결**: `DB::table()->insert()``DB::table()->insertOrIgnore()` 변경.
---
## 배포
| 커밋 | 내용 | develop | main |
|------|------|---------|------|
| `f11b1238` | 체크박스 변수 연결 추가 | ✅ | ✅ |
| `4f033172` | 체크박스 단순화 | ✅ | ✅ |
| `a97396df` | 전표 적요 → 자금일보 동기화 | ✅ | ✅ |
| `0be1fe7a` | 거래처 드롭다운 버그 수정 | ✅ | ✅ |
| `2d3f915a` | 바로빌 중복 키 수정 | ✅ | ✅ |
---
## 테스트 체크리스트
- [x] 전자서명 템플릿에서 체크박스 필드 배치 시 ☑ 안내 표시
- [x] 일반전표 적요 수정 후 저장 → 자금일보에서 수정된 적요 반영
- [x] 거래처 드롭다운을 마우스 클릭으로 열기 정상 동작
- [x] Tab 키로 거래처 이동 시 자동 열림 정상 동작
- [x] 바로빌 동기화 시 중복 거래에서 에러 없이 처리
---
## 관련 문서
- [전자서명](../../features/esign/README.md)
- [재무 관리](../../features/finance/README.md)
- [자금일보 동기화 변경](20260311_daily_fund_sync_and_account_codes_fix.md)
---
**최종 업데이트**: 2026-03-11

View File

@@ -0,0 +1,86 @@
# 연봉이력 삭제 기능 추가
**날짜:** 2026-03-11
**작업자:** Claude Code
## 변경 개요
사원관리 연봉 정보에서 잘못 입력된 연봉 이력을 삭제할 수 있는 기능을 추가했다.
기존에는 연봉 이력이 자동 누적만 되고 삭제가 불가능하여, 잘못 입력한 경우 수정할 수 없었다.
## 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `mng/resources/views/hr/employees/partials/salary-info.blade.php` | 이력 테이블에 삭제 버튼 추가, `deleteHistory()` Alpine.js 메서드 추가 |
## 상세 변경 사항
### 1. 이력 테이블 삭제 컬럼 추가
- 연봉 변경 이력 테이블에 "삭제" 컬럼 추가
- 각 이력 행에 휴지통 아이콘 버튼 배치
- 클릭 시 `confirm()` 확인 다이얼로그 표시 후 API 호출
### 2. Alpine.js `deleteHistory()` 메서드 추가
```javascript
async deleteHistory(originalIndex) {
// DELETE /api/admin/hr/employees/{id}/salary/history/{historyIndex}
}
```
- 프론트엔드에서 역순(reverse) 표시 인덱스를 원본 배열 인덱스로 변환하여 API 전달
- 변환 공식: `salaryData.history.length - 1 - idx`
- 삭제 성공 시 `salaryData` 즉시 갱신 (페이지 새로고침 불필요)
### 3. 기존 API 활용
- `EmployeeSalaryController@deleteHistory` 메서드는 이미 구현되어 있었음
- `DELETE /api/admin/hr/employees/{id}/salary/history/{historyIndex}` 라우트도 이미 등록됨
- 프론트엔드 UI만 누락되어 있었으므로 뷰 파일만 수정
## 접근 권한
연봉 정보 접근은 다음 사용자만 허용 (hardcoded):
- 이의찬, 전진선, 김보곤
## 테스트 체크리스트
- [x] 연봉 이력 삭제 버튼 표시 확인
- [x] 삭제 확인 다이얼로그 동작
- [x] API 호출 후 이력 목록 즉시 갱신
- [x] 권한 없는 사용자 접근 차단 (기존 로직)
- [x] 개발/운영 서버 배포 완료
---
## 추가: 전자계약 근로계약서 최신 연봉정보 반영
### 변경 개요
근로계약서 사원불러오기에서 연봉 이력이 많을 때 최신 연봉정보를 정확히 반환하도록 개선했다.
매년 연봉 갱신 시 연봉계약 기간이 자동으로 최신 적용일 기준으로 계산된다.
### 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `mng/app/Http/Controllers/ESign/EsignApiController.php` | `salary_effective_date` 추가 반환, 이력 fallback 로직 |
| `mng/resources/views/esign/create.blade.php` | 연봉계약/근로계약 날짜 분리 계산 |
### 상세
1. **백엔드**: `annual_salary`가 null이면 history에서 `effective_date` 기준 최신 탐색
2. **프론트엔드**: 연봉계약 시작/종료일 = 연봉 적용일 기준, 근로계약 = 입사일 기준
3. 일반 `계약.*` 패턴은 연봉 적용일 우선, 없으면 입사일 fallback
---
## 관련 문서
- [Employee API 규칙](../../rules/employee-api.md) — 연봉 정보 관리 섹션 추가
- [HR 데이터베이스](../../system/database/hr.md) — salary_info JSON 구조 추가
- [E-Sign 기능 문서](../../features/esign/README.md) — 근로계약서 사원 연동 섹션 추가
- [E-Sign Changelog](../../projects/e-sign/changelog.md) — v1.1.1 추가

View File

@@ -0,0 +1,327 @@
# API 품질 개선 — 테스트 인프라 + 56개 테스트 + N+1 최적화
**날짜:** 2026-03-14
**작업자:** R&D 개발실장 + Claude Code
**배포 대상:** 개발 서버 (API develop 브랜치)
---
## 변경 개요
API 프로젝트의 기술 부채 분석 결과(D1~D2)에 따라 **테스트 커버리지 확충**과 **N+1 쿼리 최적화**를 수행했다. 비즈니스 핵심 흐름(수주→재고→결재→작업지시)에 대한 안전망을 확보하고, 대량 처리 시 쿼리 95%를 절감했다.
---
## 1. 왜 이 작업을 했는가 (근거)
### 1.1 기술 부채 분석 (근거 문서)
`system/api-analysis-report.md`에서 식별한 8건의 기술 부채 중 최우선 2건을 착수했다.
| ID | 영역 | 현황 (수정 전) | 영향도 |
|:--:|------|-------------|:------:|
| **D1** | 테스트 부재 | 165개 (1,400 EP 대비 부족), 핵심 도메인 미커버 | 높음 |
| **D2** | N+1 쿼리 | 루프 내 개별 DB 조회 3건 발견 | 높음 |
### 1.2 D1이 먼저인 이유
테스트가 없으면 코드 수정 후 "고쳐도 안전한가?"를 검증할 수 없다. D2(N+1 최적화) 같은 성능 개선을 안전하게 수행하려면 테스트 안전망이 선행되어야 한다.
### 1.3 D2 수정 대상 선정 근거
`app/Services/` 전체를 정적 분석하여 **foreach 루프 안에서 DB 쿼리를 실행하는 패턴**을 검색했다. 발견된 3건 모두 데이터 양에 비례하여 쿼리가 선형 증가하는 구조였다.
---
## 2. D1: 테스트 커버리지 확충
### 2.1 테스트 인프라 정비
기존 11개 테스트 파일이 동일한 setUp 코드(약 40줄)를 매번 복붙하고 있었다.
**수정 내용:**
| 파일 | 변경 | 이유 |
|------|------|------|
| `tests/TestCase.php` | 공통 메서드 4개 추가 | 중복 setUp 코드 제거, 신규 테스트 작성 속도 향상 |
| 기존 테스트 11개 | `private` 프로퍼티 → TestCase 상속 | TestCase 공통화에 따른 호환성 |
**추가된 공통 메서드:**
| 메서드 | 역할 |
|--------|------|
| `setUpAuthenticatedUser()` | API Key + Tenant + User + 로그인 토큰 일괄 생성 |
| `api($method, $uri, $data)` | 인증된 API 요청 헬퍼 |
| `assertApiSuccess($response)` | 표준 응답 구조 검증 |
| `assertApiPaginated($response)` | 페이지네이션 응답 검증 |
### 2.2 Factory 생성
테스트 데이터를 간편하게 생성하기 위해 Factory 5개를 추가했다.
| Factory | 모델 | 이유 |
|---------|------|------|
| `TenantFactory` | Tenant | 모든 테스트의 기본 |
| `ClientFactory` | Client | 수주 테스트에 거래처 필요 |
| `OrderFactory` | Order | 수주 CRUD + 상태전이 테스트 |
| `StockFactory` | Stock | 재고 FIFO 테스트 |
| `StockLotFactory` | StockLot | LOT 단위 입출고 테스트 |
### 2.3 신규 테스트 56개
| 도메인 | 파일 | 테스트 수 | 검증 내용 |
|--------|------|:--------:|---------|
| **수주 (Order)** | `tests/Feature/Orders/OrderApiTest.php` | 12 | CRUD, 상태변경(DRAFT→CONFIRMED→CANCELLED), 일괄삭제, 인증 |
| **재고 (Stock)** | `tests/Feature/Inventory/StockApiTest.php` | 13 | API 목록/통계, FIFO 차감, LOT 걸침 처리, 예약/해제, 거래이력, 상태 자동계산 |
| **결재 (Approval)** | `tests/Feature/Approval/ApprovalApiTest.php` | 15 | CRUD, 상신→승인/반려/회수 워크플로우, 결재자 별도 로그인, 결재함/참조함/완료함 |
| **작업지시 (WorkOrder)** | `tests/Feature/Production/WorkOrderApiTest.php` | 16 | CRUD, 상태전이 4단계(미배정→대기→준비→진행→완료), 담당자배정, 공정단계, 자재조회 |
**커버된 핵심 비즈니스 흐름:**
```
견적 → 수주(12) → 재고예약(13) → 작업지시(16) → 결재(15)
FIFO 검증 상태전이 검증 워크플로우 검증
```
### 2.4 테스트 실행 결과
```
수정 전: 165개 테스트
수정 후: 221개 테스트 (+56개, +34%)
최종 실행: 164개 통과 / 3개 Skip (기존 라우트 충돌)
실행 시간: ~12초
```
### 2.5 테스트 중 발견된 문제
| 발견 | 내용 | 후속 조치 |
|------|------|----------|
| 빈 데이터 수주 생성 허용 | `POST /api/v1/orders` 에 빈 body 전송 시 200 반환 | `StoreOrderRequest` 검증 강화 필요 (D4) |
| 기존 테스트 실패 3건 | `PrefixResolverTest`, `BendingLotPipelineTest` — 이번 변경과 무관 | 별도 수정 필요 |
| `ItemMasterApiTest` 에러 | `section_id` 컬럼 미존재 — 마이그레이션 불일치 | 별도 수정 필요 |
---
## 3. D2: N+1 쿼리 최적화
### 3.1 수정 대상 3건
| # | 파일 | 메서드 | 문제 | 쿼리 수 (수정 전) |
|:-:|------|--------|------|:-----------------:|
| 1 | `WorkOrderService.php` | `getMaterials()` | 루프 내 `Item::find()` + 중첩 루프 내 `Item::find()` | 1 + N + M |
| 2 | `OrderService.php` | `createWorkOrderFromOrder()` | 루프 내 `DB::table('items')->value()` + `DB::table('process_items')->value()` | 1 + 2N |
| 3 | `OrderService.php` | `checkBendingStockForOrder()` | 루프 내 `StockService::getAvailableStock()` 개별 호출 | 1 + N |
### 3.2 수정 방법 — 배치 사전 조회 패턴
모든 수정에 동일한 패턴을 적용했다:
```
수정 전: foreach (items) { DB::find(id); } ← N+1
수정 후: map = DB::whereIn(ids)->keyBy('id'); ← 1회 배치
foreach (items) { map[id]; } ← 메모리 참조
```
### 3.3 수정 상세
**수정 1: `WorkOrderService::getMaterials()` (라인 1470~1500)**
```php
// 수정 전: 루프 안에서 개별 조회
foreach ($workOrder->items as $woItem) {
$item = Item::find($woItem->item_id); // N+1
foreach ($item->bom as $bomItem) {
$childItem = Item::find($childItemId); // N+1 (중첩)
}
}
// 수정 후: 루프 전 배치 조회
$bomItemsMap = Item::whereIn('id', $parentIds)->get()->keyBy('id');
$bomChildItemsMap = Item::whereIn('id', $childIds)->get()->keyBy('id');
foreach ($workOrder->items as $woItem) {
$item = $bomItemsMap[$woItem->item_id]; // 메모리 참조
foreach ($item->bom as $bomItem) {
$childItem = $bomChildItemsMap[$childItemId]; // 메모리 참조
}
}
```
**수정 2: `OrderService::createWorkOrderFromOrder()` (라인 1239~1297)**
```php
// 수정 전: fallback에서 루프마다 DB 쿼리 x2
foreach ($order->items as $orderItem) {
$resolvedId = DB::table('items')->where('code', $code)->value('id'); // N+1
$pi = DB::table('process_items')->where('item_id', $id)->value('pid'); // N+1
}
// 수정 후: 루프 전 모든 item_code, process_items 일괄 조회
$codeToIdMap = DB::table('items')->whereIn('code', $allCodes)->get()->keyBy('code');
$itemProcessMap = DB::table('process_items')->whereIn('item_id', $allIds)->get()->keyBy('item_id');
foreach ($order->items as $orderItem) {
$resolvedId = $codeToIdMap[$code] ?? null; // 메모리 참조
$processId = $itemProcessMap[$resolvedId] ?? null; // 메모리 참조
}
```
**수정 3: `OrderService::checkBendingStockForOrder()` (라인 1880~1885)**
```php
// 수정 전: 루프마다 StockService 호출 (내부에서 DB 쿼리)
foreach ($bendingItems as $item) {
$stockInfo = $stockService->getAvailableStock($item->id); // N+1
}
// 수정 후: 배치 조회 후 맵 참조
$stocksMap = Stock::whereIn('item_id', $ids)->get()->keyBy('item_id');
foreach ($bendingItems as $item) {
$stock = $stocksMap->get($item->id); // 메모리 참조
}
```
### 3.4 성능 개선 효과
| 시나리오 | 수정 전 쿼리 | 수정 후 쿼리 | 절감률 |
|---------|:----------:|:----------:|:-----:|
| 수주 50개 품목 → 작업지시 생성 | ~150 | ~8 | **95%** |
| 작업지시 자재 조회 (BOM 20개) | ~45 | ~3 | **93%** |
| 벤딩 재고 확인 (30개 품목) | ~31 | ~2 | **94%** |
### 3.5 회귀 테스트 결과
수정 후 전체 테스트 164개 통과, 기존 기능에 영향 없음 확인.
---
## 수정된 파일 전체 목록
### 신규 생성 (10개)
| 파일 | 설명 |
|------|------|
| `tests/Feature/Orders/OrderApiTest.php` | 수주 API 테스트 12개 |
| `tests/Feature/Inventory/StockApiTest.php` | 재고 API + FIFO 테스트 13개 |
| `tests/Feature/Approval/ApprovalApiTest.php` | 결재 워크플로우 테스트 15개 |
| `tests/Feature/Production/WorkOrderApiTest.php` | 작업지시 테스트 16개 |
| `database/factories/TenantFactory.php` | Tenant 모델 Factory |
| `database/factories/ClientFactory.php` | Client 모델 Factory |
| `database/factories/OrderFactory.php` | Order 모델 Factory (상태 빌더 포함) |
| `database/factories/StockFactory.php` | Stock 모델 Factory |
| `database/factories/StockLotFactory.php` | StockLot 모델 Factory |
### 수정 (14개)
| 파일 | 변경 내용 |
|------|----------|
| `tests/TestCase.php` | 공통 헬퍼 4개 추가 (인증, API 호출, 응답 검증) |
| `tests/Feature/Account/AccountApiTest.php` | `private` → TestCase 상속, 중복 제거 |
| `tests/Feature/BadDebt/BadDebtApiTest.php` | 동일 |
| `tests/Feature/Category/CategoryApiTest.php` | 동일 |
| `tests/Feature/Company/CompanyApiTest.php` | 동일 |
| `tests/Feature/ItemMaster/ItemMasterApiTest.php` | 동일 |
| `tests/Feature/Payment/PaymentApiTest.php` | 동일 |
| `tests/Feature/Popup/PopupApiTest.php` | 동일 |
| `tests/Feature/Production/BendingLotPipelineTest.php` | `use DatabaseTransactions` 중복 제거 |
| `tests/Feature/Subscription/SubscriptionApiTest.php` | 동일 |
| `tests/Feature/User/NotificationSettingApiTest.php` | 동일 |
| `tests/Feature/User/UserInvitationApiTest.php` | 동일 |
| `app/Services/WorkOrderService.php` | N+1 수정 — BOM 배치 사전 로드 |
| `app/Services/OrderService.php` | N+1 수정 — item_code/process_items 배치 조회, Stock 배치 조회 |
---
## 4. 운영 코드 안전성 검토
배포 후 수정된 운영 코드(테스트 파일 제외)가 기존 API 동작에 영향을 미치는지 코드 리뷰 + 전체 테스트로 검증했다.
### 4.1 검토 대상
실제 운영 코드를 수정한 파일은 **2개뿐**이다. 나머지 22개는 모두 테스트/Factory 파일이다.
| 파일 | 수정 메서드 | 수정 내용 |
|------|-----------|----------|
| `WorkOrderService.php` | `getMaterials()` | BOM 루프 내 `find()` → 배치 사전 로드 |
| `OrderService.php` | `createWorkOrderFromOrder()` | fallback 루프 내 DB 쿼리 → 배치 사전 조회 |
| `OrderService.php` | `checkBendingStockForOrder()` | StockService 루프 호출 → 배치 조회 |
### 4.2 동작 동등성 검증 (수정 전 = 수정 후)
| 수정 | 판정 | 근거 |
|------|:----:|------|
| `getMaterials()` BOM 배치 | **동등** | null 처리, 빈 배열, BOM 없는 경우 모두 동일. `$bomItemsMap[$id] ?? null``find($id)`와 동일한 null 반환 |
| `createWorkOrderFromOrder()` fallback | **동등** | 사전 배치 조회 결과가 즉석 조회와 동일. `DB::transaction` 내부이므로 중간 데이터 변경 없음. 캐시(`codeToIdMap`) 동작도 동일 |
| `checkBendingStockForOrder()` Stock | **동등** | `Stock::whereIn()` 결과가 `StockService::getAvailableStock()` 결과와 동일. `BelongsToTenant` 스코프 + 명시적 `tenant_id` 조건으로 격리 보장 |
### 4.3 엣지 케이스 검증
| 케이스 | 수정 전 | 수정 후 | 동일? |
|--------|--------|--------|:-----:|
| `item_id`가 null인 품목 | `if ($woItem->item_id)` skip | 맵에 포함되지 않아 동일하게 skip | ✅ |
| BOM JSON이 비어있는 품목 | `empty($item->bom)` skip | 동일 | ✅ |
| DB에 없는 `item_code` | `find()` → null | `$map[$code] ?? null` → null | ✅ |
| 재고가 0인 품목 | Stock 없음 → available_qty=0 | `$stocksMap->get($id)` → null → 0 | ✅ |
| 빈 주문 (items 0건) | 루프 미실행 | 배치 조회도 빈 배열, 루프 미실행 | ✅ |
### 4.4 전체 테스트 실행 결과
```
PHPUnit 11.5.27 / PHP 8.4.18
전체: 256개 테스트 실행
통과: 243개
실패: 7개 (모두 수정 전부터 존재하던 기존 문제)
Skip: 6개
이번 수정으로 인한 실패: 0건
```
**실패 7건 상세 (모두 기존 문제):**
| 테스트 | 원인 | 이번 수정과 관계 |
|--------|------|:--------------:|
| `PrefixResolverTest` (1건) | Unit 로직 불일치 (XX vs CF) | 무관 |
| `BendingLotPipelineTest` (3건) | TENANT_ID=287 고정, 로컬 DB 데이터 없음 | 무관 |
| `ItemMasterApiTest` (3건) | `section_id` 컬럼 미존재 (마이그레이션 불일치) | 무관 |
### 4.5 발견된 기존 문제 (수정과 무관, 별도 대응 필요)
`process_items` 테이블 조회에 `tenant_id` 필터가 없다. 수정 전부터 존재하던 문제이며 이번 수정으로 악화되지 않았다. 멀티테넌트 격리가 필요하면 별도 수정이 필요하다.
```php
// OrderService.php — tenant_id 조건 누락 (수정 전/후 동일)
DB::table('process_items')
->whereIn('item_id', $ids)
->where('is_active', true) // tenant_id 없음
->get();
```
### 4.6 결론
**이번 수정으로 기존 API 동작이 깨지는 경우는 없다.** 수정 전과 후의 결과가 정확히 동일하며, 쿼리 수만 줄어든 순수 성능 개선이다.
---
## 테스트 체크리스트
- [x] TestCase 공통 헬퍼 작성 및 기존 11개 테스트 호환 확인
- [x] Factory 5개 생성 (Tenant, Client, Order, Stock, StockLot)
- [x] Order API 테스트 12개 통과
- [x] Stock API + FIFO 테스트 13개 통과
- [x] Approval 워크플로우 테스트 15개 통과
- [x] WorkOrder API 테스트 16개 통과
- [x] N+1 쿼리 3건 배치 조회로 최적화
- [x] 전체 테스트 164개 회귀 없음 확인
- [x] 개발 서버 배포 완료 (2026-03-14)
---
## 관련 문서
- [API 구조 분석 및 개선 로드맵](../../system/api-analysis-report.md) — D1~D8 기술 부채 정의
- [API 개발 규칙](../standards/api-rules.md) — Service-First, FormRequest 컨벤션
- [품질 체크리스트](../standards/quality-checklist.md)
---
**최종 업데이트**: 2026-03-14

View File

@@ -0,0 +1,186 @@
# API 테스트 인프라 정비 및 수주 API 테스트 추가
**날짜:** 2026-03-14
**작업자:** R&D 개발실장 + Claude Code
## 변경 개요
API 프로젝트의 테스트 기반을 체계적으로 정비하고, 미커버 핵심 도메인인 수주(Order) API에 대한 Feature 테스트를 신규 작성했다. 기술 부채 분석(D1: 테스트 커버리지 확충)의 첫 번째 실행 단계이다.
---
## 1. 테스트 인프라 정비
### 1.1 TestCase 공통화
기존 11개 테스트 파일이 동일한 setUp 코드(약 40줄)를 매번 복붙하고 있었다. `tests/TestCase.php`에 공통 메서드를 추가하여 중복을 제거했다.
**추가된 공통 메서드:**
| 메서드 | 용도 |
|--------|------|
| `setUpAuthenticatedUser()` | API Key + Tenant + User + 로그인 토큰 일괄 생성 |
| `api($method, $uri, $data)` | 인증된 API 요청 (X-API-KEY + Bearer 자동 포함) |
| `assertApiSuccess($response)` | 표준 응답 구조 검증 (`success`, `message`, `data`) |
| `assertApiPaginated($response)` | 페이지네이션 응답 구조 검증 |
**Before (각 테스트 파일마다 반복):**
```php
private Tenant $tenant;
private User $user;
private string $apiKey;
private string $token;
protected function setUp(): void {
// 40줄의 동일한 초기화 코드...
}
protected function loginAndGetToken(): void { ... }
protected function authenticatedRequest(...) { ... }
```
**After (한 줄 호출):**
```php
protected function setUp(): void {
parent::setUp();
$this->setUpAuthenticatedUser();
}
// api(), assertApiSuccess() 등 TestCase에서 상속
```
### 1.2 기존 테스트 파일 정리
11개 기존 테스트 파일에서 `private` 프로퍼티 선언, `use DatabaseTransactions`, 중복 헬퍼 메서드를 제거하고 TestCase 상속으로 전환했다.
### 1.3 Factory 신규 생성
기존에 `UserFactory` 1개만 존재했다. 핵심 도메인 테스트에 필요한 Factory 3개를 추가했다.
| Factory | 모델 | 주요 필드 |
|---------|------|----------|
| `TenantFactory` | `Tenant` | company_name, code, email, phone, business_num |
| `ClientFactory` | `Client` | name, client_code, contact_person, phone, business_no |
| `OrderFactory` | `Order` | order_no, order_type_code, status_code, quantity, supply_amount |
`OrderFactory`에는 상태별 빌더 메서드도 포함:
```php
OrderFactory::new()->confirmed() // 확정 상태
OrderFactory::new()->inProduction() // 생산중 상태
OrderFactory::new()->completed() // 완료 상태
OrderFactory::new()->cancelled() // 취소 상태
```
---
## 2. 수주(Order) API 테스트
### 2.1 테스트 목록 (12개)
| 테스트 | 검증 내용 | 결과 |
|--------|----------|:----:|
| `test_수주_목록_조회` | GET `/api/v1/orders` 페이지네이션 응답 | ✅ |
| `test_수주_통계_조회` | GET `/api/v1/orders/stats` 집계 데이터 | ✅ |
| `test_수주_생성_성공` | POST `/api/v1/orders` + items 배열 | ✅ |
| `test_수주_생성_빈_데이터_허용_확인` | 빈 데이터 생성 허용 여부 확인 | ✅ |
| `test_수주_상세_조회` | GET `/api/v1/orders/{id}` 단건 | ✅ |
| `test_존재하지_않는_수주_조회시_404` | 없는 ID 조회 → 404 | ✅ |
| `test_수주_수정_성공` | PUT `/api/v1/orders/{id}` 필드 변경 | ✅ |
| `test_수주_삭제_성공` | DELETE → SoftDelete 확인 | ✅ |
| `test_수주_일괄_삭제` | DELETE `/api/v1/orders/bulk` | ✅ |
| `test_수주_상태_등록에서_확정으로_변경` | PATCH `/{id}/status` DRAFT→CONFIRMED | ✅ |
| `test_수주_상태_취소` | PATCH `/{id}/status` DRAFT→CANCELLED | ✅ |
| `test_미인증_요청시_401` | Bearer 토큰 없이 요청 → 401 | ✅ |
### 2.2 테스트 실행 결과
```
PHPUnit 11.5.27
PHP 8.4.18
전체: 120개 통과, 3개 Skip (기존 라우트 충돌 이슈)
신규: 12개 전부 통과 (46 assertions)
실행 시간: ~8초
```
---
## 3. 발견된 문제
### 3.1 빈 데이터로 수주 생성 허용
```
POST /api/v1/orders (body: {})
→ 200 OK (수주가 생성됨)
```
`StoreOrderRequest`의 검증 규칙이 느슨하여 필수 필드 없이도 수주가 생성된다. FormRequest 검증 강화가 필요하다 (D4 개선 대상).
### 3.2 기존 테스트 실패 (변경 전부터 존재)
| 테스트 | 원인 | 영향 |
|--------|------|------|
| `PrefixResolverTest` | Unit 테스트 로직 불일치 (XX vs CF) | Production 도메인 |
| `BendingLotPipelineTest` (3개) | TENANT_ID=287 고정, 로컬 DB에 해당 데이터 없음 | Production 도메인 |
| `ItemMasterApiTest` (3개) | `section_id` 컬럼 미존재 (마이그레이션 불일치) | ItemMaster 도메인 |
> 이 실패들은 이번 변경과 무관한 기존 문제이다.
---
## 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `tests/TestCase.php` | 공통 헬퍼 메서드 4개 추가 (`setUpAuthenticatedUser`, `api`, `assertApiSuccess`, `assertApiPaginated`) |
| `tests/Feature/Account/AccountApiTest.php` | `private` → TestCase 상속, 중복 제거 |
| `tests/Feature/BadDebt/BadDebtApiTest.php` | 동일 |
| `tests/Feature/Category/CategoryApiTest.php` | 동일 |
| `tests/Feature/Company/CompanyApiTest.php` | 동일 |
| `tests/Feature/ItemMaster/ItemMasterApiTest.php` | 동일 |
| `tests/Feature/Payment/PaymentApiTest.php` | 동일 |
| `tests/Feature/Popup/PopupApiTest.php` | 동일 |
| `tests/Feature/Production/BendingLotPipelineTest.php` | `use DatabaseTransactions` 중복 제거 |
| `tests/Feature/Subscription/SubscriptionApiTest.php` | 동일 |
| `tests/Feature/User/NotificationSettingApiTest.php` | 동일 |
| `tests/Feature/User/UserInvitationApiTest.php` | 동일 |
| `database/factories/TenantFactory.php` | **신규** — Tenant 모델 Factory |
| `database/factories/ClientFactory.php` | **신규** — Client 모델 Factory |
| `database/factories/OrderFactory.php` | **신규** — Order 모델 Factory (상태 빌더 포함) |
| `tests/Feature/Orders/OrderApiTest.php` | **신규** — 수주 API 테스트 12개 |
---
## 테스트 체크리스트
- [x] TestCase 공통 헬퍼 작성
- [x] 기존 11개 테스트 파일 중복 제거
- [x] Factory 3개 생성 (Tenant, Client, Order)
- [x] Order API 테스트 12개 작성 및 통과
- [x] 기존 테스트 회귀 없음 확인 (기존 실패는 변경 전부터 존재)
- [ ] StockService 테스트 (다음 단계)
- [ ] ApprovalService 테스트 (다음 단계)
- [ ] WorkOrderService 테스트 (다음 단계)
---
## 다음 단계
기술 부채 D1(테스트 커버리지 확충) 로드맵에 따라 다음 서비스 테스트를 순차 진행한다:
1. **StockService** — 재고 관리 (FIFO, LOT 추적)
2. **ApprovalService** — 전자결재 워크플로우
3. **WorkOrderService** — 작업지시 (가장 큰 서비스, 4,097줄)
---
## 관련 문서
- [API 구조 분석 및 개선 로드맵](../../system/api-analysis-report.md)
- [API 개발 규칙](../standards/api-rules.md)
- [품질 체크리스트](../standards/quality-checklist.md)
---
**최종 업데이트**: 2026-03-14

View File

@@ -0,0 +1,229 @@
# API 보안 개선 — eval() 제거, SafeMathEvaluator 도입
**날짜:** 2026-03-15
**작업자:** R&D 개발실장 + Claude Code
**배포 대상:** API develop 브랜치
---
## 변경 개요
API 프로젝트의 보안 감사에서 CRITICAL 등급으로 식별된 `eval()` 코드 인젝션 취약점 3건을 제거했다. PHP `eval()` 대신 Shunting-yard 알고리즘 기반의 `SafeMathEvaluator` 유틸리티를 신규 구현하여 교체했다. 외부 라이브러리 의존 없이 동일한 계산 결과를 보장한다.
---
## 1. 왜 이 작업을 했는가 (근거)
### 1.1 보안 감사 결과
API 코드베이스 전체 보안 감사에서 `eval()` 사용 3건이 발견되었다.
| 심각도 | 파일 | 위치 | 용도 |
|:------:|------|:----:|------|
| **CRITICAL** | `Services/Calculation/FormulaParser.php` | 234행 | BOM 산술 수식 계산 |
| **CRITICAL** | `Services/Calculation/FormulaParser.php` | 279행 | 조건식 비교 평가 |
| **CRITICAL** | `Services/Quote/FormulaEvaluatorService.php` | 316행 | 견적 수식 계산 |
### 1.2 위험성
- `eval()`은 문자열을 PHP 코드로 실행하므로 **원격 코드 실행(RCE)** 위험 존재
- 기존 코드에 정규식 기반 화이트리스트 필터(`isSafeMathExpression`)가 있었으나, 정규식 우회 가능성 상존
- `FormulaParser::testFormula()` 엔드포인트를 통해 인증된 사용자가 임의 수식을 전달할 수 있는 구조
- OWASP A03:2021 Injection, CWE-95 Eval Injection 해당
### 1.3 교체 전략
| 방안 | 장점 | 단점 | 채택 |
|------|------|------|:----:|
| `symfony/expression-language` | 검증된 라이브러리 | 외부 의존성 추가, 오버킬 | ❌ |
| Shunting-yard 직접 구현 | 의존성 없음, 필요한 기능만 포함 | 직접 구현 필요 | ✅ |
| `eval()` 유지 + 필터 강화 | 변경 최소 | 근본적 해결 아님 | ❌ |
실제 `eval()`이 처리하는 연산이 **숫자 + 사칙연산 + 비교 연산**뿐이므로, 외부 라이브러리 없이 직접 구현이 가장 적합했다.
---
## 2. 영향 분석
### 2.1 eval() 사용 위치 (3곳 모두 private 메서드)
```
FormulaParser (eval 2곳)
← CalculationEngine.calculateBOM()
← BomCalculationService
← BomCalculationController (설계 BOM 계산)
← BomCalculationController.testFormula() (수식 테스트)
FormulaEvaluatorService (eval 1곳)
← QuoteCalculationService
← QuoteController (견적 자동산출)
← Verify5130Calculation (artisan 커맨드)
```
### 2.2 영향도
- 3곳 모두 **private 메서드** 내부에서만 `eval()` 사용
- public 인터페이스(`execute()`, `calculateExpression()`)의 입출력 시그니처 **변경 없음**
- 호출하는 Controller, Service에 **수정 불필요**
- 계산 결과 **동일** (검증 완료)
---
## 3. 수정 내용
### 3.1 신규 파일
| 파일 | 설명 |
|------|------|
| `app/Helpers/SafeMathEvaluator.php` | Shunting-yard 알고리즘 기반 안전한 수식 평가기 |
**SafeMathEvaluator 지원 기능:**
| 기능 | 메서드 | 예시 |
|------|--------|------|
| 산술 계산 | `calculate()` | `(3160 * 4350) / 1000000``13.746` |
| 비교 평가 | `compare()` | `3000 <= 6000``true` |
| 단항 마이너스 | `calculate()` | `-5 + 10``5` |
| 나머지 연산 | `calculate()` | `10 % 3``1` |
| 논리 연산 | `compare()` | `5 > 3 && 2 < 4``true` |
| 중첩 괄호 | `calculate()` | `((2 + 3) * 4) / 2``10` |
| 0 나누기 방어 | `calculate()` | `10 / 0` → 예외 발생 |
### 3.2 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `app/Services/Calculation/FormulaParser.php` | `eval("return {$expression};")` 2곳 → `SafeMathEvaluator::calculate()`, `::compare()` |
| `app/Services/Quote/FormulaEvaluatorService.php` | `eval("return {$expression};")` 1곳 → `SafeMathEvaluator::calculate()` |
### 3.3 변경 전후 비교
**FormulaParser::executeSimpleMath() (234행)**
```php
// Before
return eval("return {$expression};");
// After
return SafeMathEvaluator::calculate($expression);
```
**FormulaParser::evaluateCondition() (279행)**
```php
// Before
return eval("return {$expression};");
// After
return SafeMathEvaluator::compare($expression);
```
**FormulaEvaluatorService::calculateExpression() (316행)**
```php
// Before
// TODO: 프로덕션에서는 symfony/expression-language 등 안전한 라이브러리 사용 권장
return (float) eval("return {$expression};");
// After
return \App\Helpers\SafeMathEvaluator::calculate($expression);
```
---
## 4. Shunting-yard 알고리즘 개요
```
입력: "3160 * 4350 / 1000000"
1. 토큰화
[3160] [*] [4350] [/] [1000000]
2. 중위 → 후위(RPN) 변환
[3160] [4350] [*] [1000000] [/]
3. RPN 스택 계산
3160 * 4350 = 13,746,000
13,746,000 / 1,000,000 = 13.746
결과: 13.746
```
**연산자 우선순위:**
| 우선순위 | 연산자 |
|:--------:|--------|
| 4 | 단항 마이너스 |
| 3 | `*`, `/`, `%` |
| 2 | `+`, `-` |
---
## 5. 검증 결과
### 5.1 SafeMathEvaluator 단위 테스트
```
1) 2+3 = 5 ✅
2) 10*5-3 = 47 ✅
3) (2+3)*4 = 20 ✅
4) 3160*4350/1000000 = 13.746 ✅ (BOM 면적 계산)
5) -5+10 = 5 ✅ (단항 마이너스)
6) 14.17*3.0 = 42.51 ✅ (소수점)
7) ((2+3)*4)/2 = 10 ✅ (중첩 괄호)
8) 10%3 = 1 ✅ (나머지)
9) 3000<=6000 = true ✅ (비교)
10) 7000<=6000 = false ✅
11) 100==100 = true ✅
12) 5>3&&2<4 = true ✅ (논리 AND)
```
### 5.2 FormulaParser 통합 테스트
```
1) screen_size: W1=3160 H1=4350 ✅ (미리 정의된 함수)
2) area: 13.746 ✅ (산술 수식 → SafeMathEvaluator)
3) bracket_qty (W1=5000): 3 ✅ (조건식 → SafeMathEvaluator)
4) bracket_qty (W1=2000): 2 ✅
5) bracket (predefined, W1=5500): 3 ✅
6) weight: 70.002 ✅ (중량 계산)
```
### 5.3 FormulaEvaluatorService 통합 테스트
```
1) validateFormula('W * H + 100'): valid ✅
2) validateFormula(''): invalid ✅
3) validateFormula('(W + H'): invalid ✅ (괄호 불일치)
```
### 5.4 eval() 잔존 확인
```bash
grep -r "eval(" app/ # 결과: 0건 (주석 제외)
```
---
## 테스트 체크리스트
- [x] SafeMathEvaluator 기본 사칙연산
- [x] SafeMathEvaluator 비교 연산 + 논리 연산
- [x] SafeMathEvaluator 단항 마이너스, 소수점, 중첩 괄호
- [x] FormulaParser 미리 정의된 함수 (eval 미사용 경로)
- [x] FormulaParser 산술 수식 (eval → SafeMathEvaluator 경로)
- [x] FormulaParser 조건식 (eval → SafeMathEvaluator 경로)
- [x] FormulaEvaluatorService 수식 검증
- [x] app/ 전체 eval() 잔존 검사: 0건
- [x] Pint 코드 포맷팅 통과
---
## 관련 문서
- OWASP A03:2021 Injection — [https://owasp.org/Top10/A03_2021-Injection/](https://owasp.org/Top10/A03_2021-Injection/)
- CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (Eval Injection)
---
**최종 업데이트**: 2026-03-15

View File

@@ -0,0 +1,173 @@
# 재고생산관리 기능 추가
**날짜:** 2026-03-16
**작업자:** Claude Code
---
## 변경 개요
수주 없이 재고 목적으로 생산하는 경우를 관리하는 **재고생산관리** 기능을 추가했다.
기존 `orders` 테이블을 공유하며, `order_type_code = 'STOCK'`으로 일반 수주와 구분한다.
### 설계 원칙
- **내부 오더(Internal Order)** 패턴 — 재고생산도 수주로 취급
- 기존 테이블/API 재사용 — 별도 테이블/엔드포인트 없음
- 하류 시스템(작업지시, 생산, 출하, 품질검사) 변경 없이 동작
---
## 수정된 파일
### 커밋 1: `feat: [order] 재고생산관리(STOCK) 타입 추가`
| 파일 | 변경 내용 |
|------|----------|
| `app/Models/Orders/Order.php` | `TYPE_STOCK = 'STOCK'` 상수 추가 |
| `app/Http/Requests/Order/StoreOrderRequest.php` | STOCK validation 허용, `production_reason`/`target_stock_qty` 옵션 추가 |
| `app/Http/Requests/Order/UpdateOrderRequest.php` | 동일 |
| `app/Services/OrderService.php` | STK 채번, stats `order_type` 필터, 매출 생성 스킵 |
| `app/Http/Controllers/Api/V1/OrderController.php` | stats에 `order_type` 파라미터 전달 |
### 커밋 2: `feat: [order] 재고생산 생산지시 자동 처리`
| 파일 | 변경 내용 |
|------|----------|
| `app/Services/OrderService.php` | `store()`: STOCK → `site_name='재고생산'` 자동 설정 |
| `app/Services/OrderService.php` | `createProductionOrder()`: STOCK 분기 추가 (절곡 자동, project_name, scheduled_date) |
| `lang/ko/error.php` | `bending_process_not_found` 에러 메시지 추가 |
| `lang/en/error.php` | 동일 (영문) |
---
## 상세 변경 사항
### 1. Order 모델 — 타입 상수
```php
public const TYPE_ORDER = 'ORDER'; // 수주
public const TYPE_PURCHASE = 'PURCHASE'; // 발주
public const TYPE_STOCK = 'STOCK'; // 재고생산 (신규)
```
### 2. 채번 규칙
| 타입 | 접두사 | 형식 | 예시 |
|------|--------|------|------|
| ORDER | `ORD` | `ORD{YYYYMMDD}{NNNN}` | `ORD202603160001` |
| STOCK | `STK` | `STK{YYYYMMDD}{NNNN}` | `STK202603160001` |
### 3. store() — STOCK 자동 처리
```php
if ($isStock) {
$data['site_name'] = '재고생산';
}
```
### 4. createProductionOrder() — STOCK 분기
| 항목 | ORDER (기존) | STOCK (신규) |
|------|-------------|-------------|
| 공정 매칭 | BOM item_id → process_items 매핑 | **절곡 공정 직접 할당** (BOM 스킵) |
| project_name | `order.site_name ?? client_name` | `'재고생산'` 고정 |
| scheduled_date | `order.delivery_date` | `now()` |
| 매출 생성 | `sales_recognition` 정책 적용 | **생성 안 함** |
절곡 공정 조회:
```php
$bendingProcess = Process::where('tenant_id', $tenantId)
->where('process_name', '절곡')
->where('is_active', true)
->first();
```
### 5. stats() — order_type 필터
```php
public function stats(?string $orderType = null): array
```
`GET /api/v1/orders/stats?order_type=STOCK` 으로 재고생산 전용 통계 조회 가능.
### 6. 매출 생성 스킵
```php
if ($status === Order::STATUS_CONFIRMED
&& $order->order_type_code !== Order::TYPE_STOCK // STOCK 제외
&& $order->shouldCreateSaleOnConfirm()) {
```
---
## 영향범위 분석
| 영역 | 영향 | 이유 |
|------|------|------|
| 기존 수주(ORDER) | ❌ 없음 | `$isStock` 조건 분기, else 블록에서 기존 코드 그대로 실행 |
| 기존 발주(PURCHASE) | ❌ 없음 | 동일 |
| 작업지시(WorkOrder) | ✅ 정상 동작 | `sales_order_id` FK로 연결, 절곡 공정 할당됨 |
| 생산/품질검사 | ❌ 없음 | WorkOrder 기반 하류 시스템, Order 타입 무관 |
| 출하(Shipment) | ❌ 없음 | WorkOrder 참조, Order.site_name 미사용 |
| 캘린더 | ✅ 표시됨 | `project_name='재고생산'`, `scheduled_date=now()` |
| 생산지시 목록 | ✅ 표시됨 | `site_name='재고생산'`으로 현장명 표시 |
---
## 버그 수정 (2026-03-17)
### 커밋 3: `fix: [production] 생산지시 생성 시 $isStock 미정의 오류 및 수량 정수 변환`
| 파일 | 변경 내용 |
|------|----------|
| `app/Services/OrderService.php` | `DB::transaction` 클로저 `use`절에 `$isStock` 변수 추가 |
| `app/Services/OrderService.php` | `work_order_items.quantity``(int)` 캐스팅하여 정수로 저장 |
**원인**: `$isStock`가 line 1242에서 정의되지만, `DB::transaction` 클로저의 `use`절에 포함되지 않아 클로저 내부에서 참조 불가 → 500 에러 발생
### 커밋 4: `fix: [production] 생산지시 생성 시 $process 미정의 오류 수정`
| 파일 | 변경 내용 |
|------|----------|
| `app/Services/OrderService.php` | `$process = null;` 초기화 추가 (if 블록 밖에서도 참조 가능하도록) |
**원인**: `$process``if ($processId)` 블록 안에서만 정의되지만, 블록 밖 line 1420에서 team_id 결정 시 참조 → 공정 없는 품목 처리 시 500 에러 발생
### 커밋 5 (React): `fix: [stocks] 재고생산 수량을 정수로 표시`
| 파일 | 변경 내용 |
|------|----------|
| `src/components/stocks/actions.ts` | `transformItemApiToFrontend`에서 `Math.floor(Number())` 적용 |
| `src/components/stocks/actions.ts` | 금액 필드도 `Number()`로 안전한 형변환 적용 |
**원인**: API의 Eloquent `decimal:4` 캐스트가 수량을 `"1.0000"` 문자열로 반환하여 프론트엔드에서 소수점 그대로 표시
---
## 테스트 체크리스트
- [x] STOCK 수주 생성 → `order_no` STK 접두사 확인
- [x] STOCK 수주 생성 → `site_name='재고생산'` 자동 설정 확인
- [ ] STOCK 수주 확정 → 매출 자동 생성 안 됨 확인
- [x] STOCK 생산지시 생성 → 절곡 공정 자동 선택 확인
- [x] STOCK 생산지시 생성 → `project_name='재고생산'` 확인
- [x] STOCK 생산지시 생성 → `scheduled_date=today` 확인
- [ ] 기존 ORDER 수주 생산지시 → 기존 BOM 매칭 정상 동작 확인
- [ ] 생산지시 목록에서 STOCK 건 표시 확인
- [x] 생산지시 생성 시 `$isStock` 미정의 오류 수정 확인
- [x] 생산지시 생성 시 `$process` 미정의 오류 수정 확인
- [x] `work_order_items.quantity` 정수 저장 확인
- [x] 프론트엔드 수량 정수 표시 확인
---
## 관련 문서
- [재고생산관리 기능 설명](../../features/sales/stock-production.md)
- [재고생산관리 API 명세](../../frontend/api-specs/stock-production-api.md)
- [프론트엔드 구현 요청서](../../frontend/requests/stock-production-react-request.md)
---
**최종 업데이트**: 2026-03-17

View File

@@ -209,4 +209,4 @@ BOM 산출 로직에서 단가를 가져오는 5130 테이블:
| `api/app/Services/Quote/QuoteCalculationService.php` | 자동산출 실행 |
| `api/app/Models/Items/Item.php` | Items 모델 |
| `docs/features/quotes/README.md` | 견적 시스템 문서 |
| `docs/plans/bom-item-mapping-plan.md` | 후속 작업 계획 |
| `docs/dev_plans/bom-item-mapping-plan.md` | 후속 작업 계획 |

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Some files were not shown because too many files have changed in this diff Show More