diff --git a/specs/erp-analysis/00-overview.md b/specs/erp-analysis/00-overview.md new file mode 100644 index 0000000..14c35ce --- /dev/null +++ b/specs/erp-analysis/00-overview.md @@ -0,0 +1,155 @@ +# SAM ERP 스토리보드 분석 개요 + +> 분석 대상: SAM_ERP_Storyboard_D0.8_251216 (113 슬라이드) +> 분석일: 2025-12-17 +> 버전: D0.8 + +## 1. 문서 개요 + +### 1.1 버전 히스토리 +| 날짜 | 버전 | 내용 | +|------|------|------| +| 2025.12.01 | D0.6 | 프론트 초안 - 인사관리 & 전자결재 작성 | +| 2025.12.01 | D0.7 | 프론트 작성 - 인사관리 & 전자결재 피드백 반영 | +| 2025.12.16 | D0.8 | 회계 & 보고서 작성, GPS 출퇴근, 카드/계좌관리, 보고서 추가 | + +### 1.2 슬라이드 구성 +- **총 113 슬라이드** +- 공통 UI 가이드 + 8개 주요 기능 모듈 + +## 2. 메뉴 구조 (GNB/LNB) + +``` +SAM ERP +├── 대시보드 +├── MES 메뉴 (영업관리, 판매관리, 구매관리 등) +├── 인사관리 +│ ├── 부서관리 +│ ├── 사원관리 +│ ├── 근태관리 +│ └── 휴가관리 +├── 전자결재 +│ ├── 기안함 +│ ├── 결재함 +│ └── 참조함 +├── 게시판 +├── 회계관리 +│ ├── 거래처관리 +│ ├── 매출관리 +│ ├── 매입관리 +│ ├── 입금관리 +│ ├── 출금관리 +│ ├── 어음관리 +│ ├── 거래처원장 +│ ├── 일일 일보 +│ ├── 지출 예상 내역서 +│ ├── 미수금 현황 +│ ├── 악성채권 추심관리 +│ ├── 입출금 계좌 조회 +│ └── 카드 내역 조회 +├── 기준정보 +│ ├── 직급관리 +│ ├── 직책관리 +│ ├── 권한관리 +│ ├── 근무관리 +│ ├── 출퇴근관리 +│ ├── 휴가관리 +│ ├── 카드관리 +│ ├── 계좌관리 +│ ├── 팝업관리 +│ ├── 게시판관리 +│ ├── 일반설정 +│ └── 알림설정 +├── 보고서 및 분석 +├── 계정정보 +├── 회사정보 +├── 구독관리 +├── 결제내역 +└── 고객센터 +``` + +## 3. 기능 그룹별 슬라이드 매핑 + +| 그룹 | 슬라이드 범위 | 주요 내용 | 분석 문서 | +|------|---------------|----------|----------| +| 공통 | 3-13 | UI 컴포넌트, 인터랙션, 알림 | [01-common.md](./01-common.md) | +| 인증/영업 | 14-22 | 가입, 로그인, 약관동의 | [02-auth.md](./02-auth.md) | +| GPS 출퇴근 | 23-27 | 모바일 출퇴근 | [03-gps-attendance.md](./03-gps-attendance.md) | +| 인사관리 | 28-46 | 부서/사원/근태/휴가 | [04-hr-management.md](./04-hr-management.md) | +| 전자결재 | 47-59 | 기안/결재/참조함 | [05-approval.md](./05-approval.md) | +| 회계관리 | 60-91 | 거래처/매출/매입/입출금 | [06-accounting.md](./06-accounting.md) | +| 기준정보 | 92-104 | 직급/직책/휴가/카드/계좌 | [07-master-data.md](./07-master-data.md) | +| 보고서 | 105-113 | 분석/AI 리포트 | [08-reports.md](./08-reports.md) | + +## 4. 사용자 역할 + +### 4.1 영업사원 (Sales) +- 운영 로그인 +- 회사 등록 신청 +- 테넌트 추가 알림 + +### 4.2 관리자 (Admin) +- 자료 확인 +- 가입 승인/거절 +- 이메일로 URL 발송 + +### 4.3 고객사 (Customer/Tenant) +- 약관 동의 +- 비밀번호 설정 +- SAM 로그인 +- 테넌트 추가 + +## 5. 핵심 비즈니스 플로우 + +### 5.1 가입 및 로그인 플로우 (슬라이드 15) +``` +영업사원: 운영 로그인 → 사업자등록번호 입력 → 회사정보 등록 → 가입신청 완료 + ↓ (거절) +관리자: 자료 확인 → 승인? → 이메일로 URL 발송 거절 알림 + ↓ +고객사: 약관 동의 → 비밀번호 설정 → SAM 로그인 → 테넌트 추가? + ↓ +매니저: 테넌트 추가 알림 → 사업자등록번호 입력 +``` + +### 5.2 회계관리 플로우 (슬라이드 61) +``` +매출: 거래처 선택 → 매출 등록 → 세금계산서 발행 +입금: 입금 등록 → 전액 입금? → 어음 수취? +매입: 거래처 선택 → 매입 등록 → 세금계산서 수취 +출금: 출금 등록 → 전액 출금? → 어음 발행? +추심: 미수금 현황 → 연체? → 악성주심? → 악성 추심 +조회: 입출금 계좌 조회, 카드 내역 조회 +장부/보고서: 거래처원장, 지출 예상 내역서, 일일 일보 +``` + +## 6. 기술 스펙 + +### 6.1 반응형 웹 브레이크포인트 +- 모바일: < 640px (기본) +- 태블릿: 768px ~ 1023px (md) +- 데스크탑: 1024px+ (lg) +- 대형 모니터: 1280px+ (xl) + +### 6.2 인터랙션 +| 타입 | 적용 | +|------|------| +| Tap | Yes | +| Touch & Hold | No | +| Double Tap | No | +| Drag & Drop | Yes | +| Scroll Up/Down | Yes | +| Swipe Left/Right | Yes | +| Pinch Zoom In/Out | Yes | + +### 6.3 알림 타입 +- Alert (알림): 사용자에게 상황 알림 +- Confirm Alert (확인): 확인/취소 선택 +- Toast Message: 2-3초 후 Fade out + +## 7. 다음 단계 + +1. 각 기능 그룹별 상세 분석 문서 작성 +2. API 엔드포인트 도출 +3. 데이터 모델 설계 +4. 개발 우선순위 결정 \ No newline at end of file diff --git a/specs/erp-analysis/01-common.md b/specs/erp-analysis/01-common.md new file mode 100644 index 0000000..f78e1f9 --- /dev/null +++ b/specs/erp-analysis/01-common.md @@ -0,0 +1,143 @@ +# 공통 UI 컴포넌트 (슬라이드 3-13) + +## 1. 화면 템플릿 (슬라이드 6) + +### 1.1 모바일 화면 구조 +``` +┌─────────────────────────────┐ +│ A. Status bar (OS 관리) │ +├─────────────────────────────┤ +│ B. Browser 영역 │ +├──────┬──────────────────────┤ +│Button│ Title │Button│ C. Title 영역 +├──────┴──────────────────────┤ +│ │ +│ D. Content 영역 │ +│ │ +├─────────────────────────────┤ +│ E. Browser bar 영역 │ +├─────────────────────────────┤ +│ F. Keypad 영역 (입력 시) │ +└─────────────────────────────┘ +``` + +### 1.2 영역 설명 +- **A. Status bar**: 안테나, 통화, 배터리 등 시스템 OS 관리 영역 +- **B. Browser 영역**: 브라우저 기능 영역 +- **C. Title 영역**: 텍스트 또는 기능 버튼으로 구현, 텍스트 기본 가운데 정렬 +- **D. Content 영역**: 컨텐츠 내용 표시, 컨텐츠 길이가 길어질 경우 스크롤 제공 +- **E. Browser bar 영역**: 브라우저 유틸 바 영역 +- **F. Keypad 영역**: 키보드 입력할 때 활성화, 모든 페이지 위에 덮어쓰기 구현 + +## 2. GNB/LNB/푸터 (슬라이드 8) + +### 2.1 알림 버튼 +- 클릭: 알림 팝업 표시 + +### 2.2 개인 정보 버튼 +- 등록: 디폴트 이미지, 이름, 직급 +- 클릭: 마이페이지 팝업 표시 + +### 2.3 회사 로고 +- 회사정보 화면에서 등록한 로고 표시 +- 회사 변경 선택 시 해당 로고 변경 + +### 2.4 메뉴 영역 +- 메뉴 클릭: + - 하위 메뉴가 있을 경우: 하위 메뉴 하단에 표시 + - 하위 메뉴 없을 경우: 해당 메뉴 화면으로 이동 + - 목록 길 경우 해당 영역 내 스크롤 처리 + +### 2.5 MES 메뉴 영역 +- 영업관리, 판매관리, 구매관리 등 해당하는 MES 메뉴 영역 표시 + +### 2.6 푸터 영역 +- 모든 화면 하단 공통 표시 + +## 3. 알림 팝업 (슬라이드 9) + +### 3.1 알림 목록 +- 항목: 디폴트 원형일, 종류(공지사항), 안내/제목/내용, 전송일시 표시 +- 클릭: 해당 상세 화면으로 이동 +- 최신순 10개까지 표시 + +### 3.2 New 아이콘 +- 새 알림일 경우 New 아이콘 표시 +- 해당 알림 클릭 시 사라짐 + +### 3.3 빨간 점 아이콘 +- 새 알림이 있을 경우 표시 +- 해당 알림 모두 클릭 시 사라짐 + +## 4. 마이페이지 팝업 (슬라이드 10) + +### 4.1 계정 아이디 (이메일) 표시 + +### 4.2 회사 셀렉트 박스 +- 종류: 회사명, 회사명... (해당 계정이 생성한 회사(테넌트) 목록 표시) +- 정렬: 등록순 +- 한 회사만 소유중일 경우에는 해당 영역 숨김 + +### 4.3 로그아웃 버튼 +- 클릭: "정말 로그아웃하시겠습니까?" 로그아웃 확인 Alert 표시 +- 확인 버튼 클릭 시 로그아웃 처리 + +## 5. 셀렉트 박스 (슬라이드 11) + +### 5.1 기본 셀렉트 박스 +- 클릭: 하단에 종류 목록 표시 + +### 5.2 종류 목록 +- 목록 중 하나만 선택 가능 + +### 5.3 다중 선택 셀렉트 박스 +- 선택된 첫번째 항목명 + 추가 수 표시 +- 텍스트 영역 부족할 경우 '항목..+3' 형태로 표시 + +### 5.4 다중 선택 종류 목록 +- 목록 중 복수 선택 가능 +- 전체 선택 시 전체 선택/해제 토글 + +### 5.5 검색 영역 +- 검색어 입력 후 엔터 또는 검색 아이콘 클릭 시 (5-1) 형태로 표시되며 (5-2) 영역에 검색 결과 표시 + +### 5.6 삭제 버튼 +- 클릭: 검색어 삭제 처리, 전체 종류 목록 표시 + +## 6. 입력 필드 가이드 메시지 (슬라이드 12) + +### 6.1 가이드 메시지 표시 위치 +- 상황에 따라 입력 필드 하단 또는 Alert에 표시 + +### 6.2 가이드 메시지 색상 +- 긍정일 경우: 녹색 +- (1-1) 부정일 경우: 붉은색 + +## 7. 공지 팝업 (슬라이드 13) + +### 7.1 대상 +- 전체, 설정 부서 +- 내용: 설정 기간동안 대상에게 팝업 표시 + +### 7.2 팝업 내용 영역 +- 이미지, 텍스트 + +### 7.3 "1일간 이 창을 열지 않음" 체크박스 +- 클릭: 체크 설정/해제 토글 +- 디폴트: 체크 해제 상태 +- 체크 설정 시 1일 동안 팝업 미표시 (차정 기준) + +--- + +## API 도출 + +### 공통 API +``` +GET /api/notifications # 알림 목록 조회 +POST /api/notifications/{id}/read # 알림 읽음 처리 +GET /api/user/profile # 마이페이지 정보 +GET /api/user/companies # 사용자 소속 회사 목록 +POST /api/auth/logout # 로그아웃 +GET /api/announcements # 공지 팝업 조회 +POST /api/announcements/{id}/dismiss # 공지 팝업 닫기 (1일간 안보기) +``` \ No newline at end of file diff --git a/specs/erp-analysis/02-auth.md b/specs/erp-analysis/02-auth.md new file mode 100644 index 0000000..1d9728d --- /dev/null +++ b/specs/erp-analysis/02-auth.md @@ -0,0 +1,205 @@ +# 인증/영업 (슬라이드 14-22) + +## 1. 가입 및 로그인 플로우차트 (슬라이드 15) + +### 1.1 영업사원 플로우 +``` +운영 로그인 → 사업자등록번호 입력 → 사업자번호 조회? + ↓ Yes + 회사정보 등록 → 가입신청 완료 + ↓ (거절) + 거절 알림 +``` + +### 1.2 관리자 플로우 +``` +자료 확인 → 승인? → (Yes) → 이메일로 URL 발송 + ↓ (No) + 계약금50% 결제 확인 +``` + +### 1.3 고객사 플로우 +``` +약관 동의 → 비밀번호 설정 → SAM 로그인 → 테넌트 추가? + ↓ (Yes) + 매니저: 테넌트 추가 알림 + ↓ + 사업자등록번호 입력 +``` + +## 2. 운영 로그인 (슬라이드 16) + +### 2.1 아이디 인풋박스 +- 테넌트 생성자일 경우 이메일 +- 사용자일 경우 이메일 또는 아이디 +- (1-1) 상황별 가이드 메시지 + +### 2.2 비밀번호 인풋박스 +- 입력 시 마지막 글자 제외 후 마스킹 처리 +- (2-1) 상황별 가이드 메시지 + +### 2.3 열람 버튼 +- 클릭: 열람/숨김 토글 +- 디폴트: 숨김 상태 +- 열람 상태일 시 (2) 영역 마스킹 해제 처리 + +### 2.4 자동 로그인 체크박스 +- 클릭: 체크 설정/해제 토글 +- 체크 시 로그아웃 전까지 세션 유지 + +### 2.5 로그인 버튼 +- 클릭: 유효할 경우 대시보드 화면으로 이동 + +### 2.6 가이드 메시지 +| 상황 | 가이드 메시지 | +|------|---------------| +| 필수 정보 미 입력 시 | 필수 정보입니다. | +| 4글자 미만 입력 시 | 이메일은 4자 이상 가능합니다 | +| 이메일 형식에 유효 하지 않을 경우 | 이메일 주소를 다시 확인해주세요. | +| 8자 미만 입력 시 | 8자 이상으로 만들어주세요. | +| 영문+숫자+특수문자 조합이 아닐 경우 | 영문, 숫자, 특수문자를 포함해주세요. 다음의 특수기호는 보안 사항을 가능합니다., ; - @ ! | + +## 3. 사업자등록번호 조회 (슬라이드 17) + +### 3.1 제조 데모 +- 클릭: 제조 데모 화면으로 이동 + +### 3.2 시공 데모 +- 클릭: 시공 데모 화면으로 이동 + +### 3.3 사업자등록번호 인풋박스 +- 숫자만 가능, 10자리 + +### 3.4 다음 버튼 +- 클릭: + 1. 바로 빌 사업자등록번호 조회 후 사용 불가 경우: "중복된 사업자등록번호입니다." 알림 Alert 표시 + 2. 바로 빌 사업자등록번호 조회 후 사용 가능한 경우: + - [1] 테넌트 등록된 사업자등록번호일 경우: 테넌트 등록 전이어도 다른 영업사원이 등록중을 경우에는 사업자등록번호 사용 불가 (어드민에서는 해제 가능) + - "등록된 사업자등록번호 입니다." 알림 Alert 표시 + - [2] 등록되지 않은 사업자등록번호일 경우: 회사정보 등록 화면으로 이동 + +## 4. 회사정보 등록 (슬라이드 18) + +### 4.1 회사(테넌트) 상태 +- 신청: 신청 완료 입력 +- 승인: 자동 입금 외 계약금 50% 입금, 이메일로 URL 발송 선택 +- 최초 로그인 시 ERP만 표시 +- 거절: 프로젝트 설정 완료, 잔금 50% 입금 및 인도, 당월 말일까지는 무료, 익월부터 익월말까지 사용하고 구독료 청구 +- 만료: 기간 종료, 안료외 연체 상태 구분?? 영업사원에게 알림, 서비스에는 접근 불가, 배너 +- 해지: 오퍼 대기기간 단계 필요?? +- 해지: 서비스 이용 불가 +- 탈퇴: 로그인 불가, 복구 불가?? +- 미사: 서비스 이용 불가 + +### 4.2 회사 로고 이미지 영역 +- 디폴드 이미지 표시 +- 클릭: 파일탐색기 팝업 표시, 10MB 이하의 PNG, JPEG, GIF 중 하나 선택 가능 + +### 4.3 우편번호 찾기 버튼 +- 클릭: 선정한 주소 팝업 표시 + +### 4.4 찾기 버튼 +- 클릭: 파일탐색기 팝업 표시, 이미지 또는 파일 하나 선택 가능 + +### 4.5 가입 신청 버튼 +- 클릭: 사업자등록번호 조회 화면으로 이동 +- 회사 로고만 선택, 나머지는 필수 정보 +- 클릭: 가입 신청 완료 화면으로 이동 + +### 4.6 입력 필드 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 회사 로고 | N | 750x250px, 10MB 이하 PNG, JPEG, GIF | +| 회사명 | Y | | +| 대표자명 | Y | | +| 업태 | Y | | +| 업종 | Y | | +| 주소 | Y | 우편번호 찾기 + 상세주소 | +| 이메일 (아이디) | Y | | +| 세금계산서 이메일 | Y | | +| 담당자명 | Y | | +| 담당자 연락처 | Y | | +| 사업자등록증 | Y | 파일 첨부 | + +## 5. 가입 신청 완료 (슬라이드 19) + +### 5.1 가입 신청 완료 안내 문구 표시 +- SAM은 폐쇄형 네트워크이므로 플랫폼의 무결성을 보장하기 위해 모든 계정을 검토해야 합니다. +- (회사명)의 계정 세부 정보를 추가로 확인하기 위해 추가 정보를 요청할 수 있습니다. +- 영업일 기준 3일 이내에 계정에 대한 업데이트를 받게 됩니다. + +### 5.2 가입 신청 취소 버튼 +- 클릭: "가입 신청 취소 시 등록한 모든 정보가 삭제됩니다. 정말 가입 신청을 취소하시겠습니까?" 확인 Alert 표시 + +## 6. 가입 신청 승인 성공 이메일 (슬라이드 20) + +### 6.1 계정 활성화 버튼 +- 클릭: 약관 동의 화면으로 이동 + +### 6.2 지원, 블로그 버튼 +- 클릭: 해당 운영 노션 링크로 이동 + +## 7. 약관 동의 (슬라이드 21) + +### 7.1 약관 영역 +- 클릭: (1-1) 약관 내용 영역 열림/닫힘 토글 +- 디폴트: 닫힘 + +### 7.2 체크박스 +- 클릭: 체크 설정/해제 토글 +- 디폴트: 체크 설정 해제 + +### 7.3 약관에 동의합니다 버튼 +- 모든 필수 약관 동의 시 버튼 활성화 +- 클릭: 비밀번호 설정 화면으로 이동 + +### 7.4 약관에 동의합니다 버튼 +- 클릭: 모든 필수, 선택 약관에 동의 처리, 비밀번호 설정 화면으로 이동 + +### 7.5 약관 목록 +| 약관명 | 필수 | +|--------|------| +| [필수] 서비스 이용약관 | Y | +| [필수] 개인정보 취급방침 | Y | +| [필수] 약관명 | Y | +| 마케팅 정보 수신 동의 (선택) | N | +| - 이메일 수신 동의 | N | +| - SMS 수신 동의 | N | + +## 8. 비밀번호 설정 (슬라이드 22) + +### 8.1 계정 활성화 버튼 +- 클릭: 로그인 화면으로 이동 + +### 8.2 비밀번호 요구사항 +- 최소 8자 이상 영문+숫자+특수문자 조합 + +--- + +## API 도출 + +### 인증 API +``` +POST /api/auth/login # 로그인 +POST /api/auth/logout # 로그아웃 +POST /api/auth/password/reset # 비밀번호 재설정 +POST /api/auth/password/change # 비밀번호 변경 +``` + +### 회원가입/영업 API +``` +GET /api/business-registration/verify # 사업자등록번호 조회 +POST /api/registration/company # 회사정보 등록 +POST /api/registration/cancel # 가입신청 취소 +GET /api/terms # 약관 목록 조회 +POST /api/terms/agree # 약관 동의 +POST /api/account/activate # 계정 활성화 +``` + +### 테넌트 API +``` +GET /api/tenants # 테넌트 목록 +POST /api/tenants # 테넌트 추가 +PUT /api/tenants/{id} # 테넌트 수정 +GET /api/tenants/{id}/switch # 테넌트 전환 +``` diff --git a/specs/erp-analysis/03-gps-attendance.md b/specs/erp-analysis/03-gps-attendance.md new file mode 100644 index 0000000..4903e27 --- /dev/null +++ b/specs/erp-analysis/03-gps-attendance.md @@ -0,0 +1,144 @@ +# GPS 출퇴근 (슬라이드 23-27) + +## 1. 개요 + +GPS 기반 모바일 출퇴근 관리 시스템으로, 위치 정보를 활용하여 출근/퇴근을 기록합니다. + +## 2. 마이페이지 팝업 > 출퇴근하기 (슬라이드 24) + +### 2.1 출퇴근 버튼 +- GPS 출퇴근 사용 시에만 표시 +- 모바일일 경우에만 버튼 활성화 +- 클릭: 출퇴근하기 화면으로 이동 + +### 2.2 출퇴근 허용 반경 +- 기준 화표로부터의 출퇴근 허용 반경을 m 형으로 표시 (기준정보 > 출퇴근관리에서 설정) + +### 2.3 현재 위치 버튼 +- 클릭: (3-1) 해당 현재 위치를 지도 중심으로 표시 + +### 2.4 [+] 버튼 +- 클릭: 지도 영역 확대 + +### 2.5 확대/축소 슬라이드바 +- 드래그&드랍 또는 클릭: 지도 영역 확대/축소 + +### 2.6 [-] 버튼 +- 클릭: 지도 영역 축소 + +### 2.7 개인 정보 영역 +- 항목: 프로필 이미지, 이름, 부서명, 직급명 + +### 2.8 현재 시:분:초 표시 +- HH:MM:SS + +### 2.9 출근하기 버튼 +- 클릭: + 1) 출근 위치 미설정 상태일 경우: "출근 위치를 설정해주세요." 알림 Alert 표시 + 2) 출근 위치 설정 상태일 경우: + - (1) 출근 위치가 기준 설정 반경 초과일 경우: "출근 가능 위치가 아닙니다. 출근 위치를 확인해주세요." 알림 Alert 표시 + - [2] GPS 출근 위치 기준 설정 반경 이내: 출근하기 화면으로 이동 (출근 기록 저장) + +## 3. 출근하기 (슬라이드 25) + +### 3.1 퇴근하기 버튼 +- 클릭: + 1) 퇴근 위치 미설정 상태일 경우: "퇴근 위치를 설정해주세요." 알림 Alert 표시 + 2) 퇴근 위치 설정 상태일 경우: + - (1) 퇴근 위치가 기준 설정 반경 초과일 경우: "퇴근 가능 위치가 아닙니다. 퇴근 위치를 확인해주세요." 알림 Alert 표시 + - [2] GPS 퇴근 위치 기준 설정 반경 이내: 퇴근하기 화면으로 이동 (퇴근 기록 저장) + +### 3.2 출근 완료 아이콘 이미지 표시 + +### 3.3 출근 완료 정보 +- 항목: 출근 완료 문구, 시:분:초, 일자(요일) + +### 3.4 출근 화표의 본사/현장명 표시 + +### 3.5 확인 버튼 +- 클릭: 대시보드로 이동 + +## 4. 퇴근하기 (슬라이드 26) + +### 4.1 퇴근 완료 아이콘 이미지 표시 + +### 4.2 퇴근 완료 정보 +- 항목: 퇴근 완료 문구, 시:분:초, 일자(요일) + +### 4.3 퇴근 화표의 본사/현장명 표시 + +### 4.4 확인 버튼 +- 클릭: 대시보드로 이동 + +## 5. 현장 등록 (슬라이드 27) + +### 5.1 위치 정보 설정 +- 각 현장의 GPS 중심값으로 설정 + +### 5.2 입력 필드 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 주소 | Y | 우편번호 찾기 + 상세주소 | +| 경도 | Y | | +| 위도 | Y | | +| 첨부파일 | N | | + +--- + +## 데이터 모델 + +### Attendance (출퇴근 기록) +``` +- id: bigint +- user_id: bigint (FK) +- tenant_id: bigint (FK) +- type: enum('check_in', 'check_out') +- check_time: datetime +- latitude: decimal(10,8) +- longitude: decimal(11,8) +- location_id: bigint (FK, nullable) # 본사/현장 +- location_name: string +- is_valid: boolean # 유효 위치 여부 +- created_at: timestamp +``` + +### Location (본사/현장) +``` +- id: bigint +- tenant_id: bigint (FK) +- name: string +- address: string +- detail_address: string +- latitude: decimal(10,8) +- longitude: decimal(11,8) +- allowed_radius: int # 허용 반경 (m) +- is_active: boolean +- created_at: timestamp +``` + +--- + +## API 도출 + +### GPS 출퇴근 API +``` +POST /api/attendance/check-in # 출근 기록 +POST /api/attendance/check-out # 퇴근 기록 +GET /api/attendance/today # 오늘 출퇴근 현황 +GET /api/attendance/status # 현재 출퇴근 상태 +GET /api/attendance/location/validate # 위치 유효성 검증 +``` + +### 현장 관리 API +``` +GET /api/locations # 현장 목록 +POST /api/locations # 현장 등록 +PUT /api/locations/{id} # 현장 수정 +DELETE /api/locations/{id} # 현장 삭제 +``` + +### 출퇴근 설정 API +``` +GET /api/settings/attendance # 출퇴근 설정 조회 +PUT /api/settings/attendance # 출퇴근 설정 수정 +``` diff --git a/specs/erp-analysis/04-hr-management.md b/specs/erp-analysis/04-hr-management.md new file mode 100644 index 0000000..f70a093 --- /dev/null +++ b/specs/erp-analysis/04-hr-management.md @@ -0,0 +1,381 @@ +# 인사관리 (슬라이드 28-46) + +## 1. 개요 + +인사관리 모듈은 부서, 사원, 근태, 휴가를 관리합니다. + +## 2. 부서관리 (슬라이드 30-31) + +### 2.1 전체 선택 체크박스 +- 클릭: 전체 선택 설정/해제 토글 +- 디폴트: 설정 해제 상태 + +### 2.2 개별 선택 체크박스 +- 클릭: 개별 선택 설정/해제 토글 +- 디폴트: 설정 해제 상태 + +### 2.3 추가 버튼 +- 클릭: 선택된 부서의 하위 부서 일괄 생성 +- 관리 권한이 없을 경우 숨김 + +### 2.4 삭제 버튼 +- 클릭: "선택한 부서 N개를 삭제하시겠습니까?" 확인 Alert 표시 +- 확인 선택 시 삭제된 부서 사원의 인원은 회사(기본) 인원으로 변경 + +### 2.5 확대 버튼 +- 클릭: (6) 확대 버튼으로 변경, 하위 부서 숨김 처리 + +### 2.6 축소 버튼 +- 클릭: (5) 축소 버튼으로 변경, 하위 부서 표시 처리 + +### 2.7 추가 버튼 +- 클릭: 부서 추가 팝업 표시 + +### 2.8 수정 버튼 +- 클릭: 부서 수정 팝업 표시 + +### 2.9 부서 추가/수정 팝업 +- 부서명 인풋박스: 기존 부서명 표시, 수정 가능 + +## 3. 사원관리 (슬라이드 32-40) + +### 3.1 기간 설정 영역 +- 입사일 기준 + +### 3.2 기간 설정 버튼 영역 +- 종류: 당해년도, 전전월, 전월, 당월, 어제, 오늘 +- 클릭: 해당 기간이 (1) 영역에 설정되며 화면 전체에 적용 처리 + +### 3.3 CSV 일괄 등록 버튼 +- 클릭: CSV 일괄 등록 화면으로 이동 + +### 3.4 사원 등록 버튼 +- 클릭: 사원 상세 화면으로 이동 + +### 3.5 사용자 초대 버튼 +- 클릭: 사용자 초대 팝업 표시 + +### 3.6 필터 셀렉트 박스 +- 종류: 전체, 사용자 아이디 보유, 사용자 아이디 미보유, 재직, 휴직, 퇴직 +- 디폴트: 전체 + +### 3.7 정렬 셀렉트 박스 +- 종류: 직급순, 부서 오름차순, 부서 내림차순, 이름 오름차순, 이름 내림차순 +- 디폴트: 직급순 + +### 3.8 현황 카드 +| 항목 | 설명 | +|------|------| +| 현직 | 전체 현직 사원 수 | +| 휴직 | 전체 휴직 사원 수 | +| 퇴직 | (1) 해당 기간의 퇴직 사원 수 | +| 평균근속년수 | 전체 현직 사원 기준 | + +## 4. 사원 상세 (슬라이드 33-36) + +### 4.1 사원 정보 영역 (필수) +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 이름 | Y | | +| 주민등록번호 | Y | | +| 휴대폰 | Y | | +| 이메일 | Y | | +| 연봉 | N | | +| 급여계좌 은행 | N | 은행 선택 | +| 계좌 | N | | +| 예금주 | N | | + +### 4.2 사용자 정보 영역 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 아이디 | N | 이메일 또는 아이디 | +| 비밀번호 | N | 최소 8자 이상 영문+숫자+특수문자 조합 | +| 권한 | N | 권한관리의 목록 표시 | +| 상태 | N | 종류: 정상, 재직, 중지. 재직 상태인 경우 로그아웃 처리, 로그인 시 '재정중인 아이디입니다.' 팝업 | + +### 4.3 사원 상세 영역 (선택) +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 프로필 사진 | N | 1250x250px, 10MB 이하 PNG, JPEG, GIF | +| 사원코드 | N | | +| 성별 | N | 남성/여성 | +| 주소 | N | 우편번호 찾기 + 상세주소 | + +### 4.4 인사 정보 영역 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 입사일 | N | | +| 고용 형태 | N | 종류: 정규직, 계약직, 파견직, 용역직, 시간제 근로자 | +| 직급 | N | 직급관리 화면에서 설정 | +| 상태 | N | 종류: 재직, 병가휴직, 육아휴직, 개인사정휴직, 무급휴직, 퇴사, 해고, 권고사직, 계약만료, 정년퇴직 | +| 부서 | N | 부서관리 화면에서 설정 | +| 직책 | N | 직책관리 화면에서 설정 | +| 출근 위치 | N | 본사, 현장 목록 | +| 퇴근 위치 | N | 본사, 현장 목록 | +| 퇴사일 | N | | +| 퇴사 사유 | N | | + +### 4.5 항목 설정 버튼 +- 클릭: 항목 설정 팝업 표시 + +### 4.6 항목 설정 팝업 (슬라이드 34) +- 전체 설정 ON/OFF 버튼 +- 개별 설정 ON/OFF 버튼 +- 디폴트: 설정 OFF 상태 + +## 5. CSV 일괄 등록 (슬라이드 39-40) + +### 5.1 양식 다운로드 버튼 +- 클릭: 등록된 양식 CSV 다운로드 + +### 5.2 파일 선택 버튼 +- 클릭: 파일 탐색기 팝업, CSV 1개만 등록 + +### 5.3 파일 변환 버튼 +- 클릭: CSV 데이터를 (3-1) 정보 등록 영역에 변환값 표시 +- 범위: 사원 상세 화면의 전체 항목 + +### 5.4 등록 버튼 +- 파일변환 완료 & (2) 체크 설정 항목 있을 경우에만 버튼 활성화 +- 클릭: "(등록)의 정보를 정말 등록하시겠습니까?" 확인 Alert 표시 +- 확인 클릭 시 (2) 체크 된 정보만 등록, "정보 등록이 완료되었습니다." 알림 Alert 표시 + +## 6. 사용자 초대 (슬라이드 37-38) + +### 6.1 사용자 초대 프로세스 +- 초대 이메일로 발송 → 약관 동의 (아이디를 이메일로 사용) → 비밀번호 설정 → 로그인 + +### 6.2 초대할 이메일 주소 인풋박스 +- ','로 구분하여 여러 주소 입력 가능 + +### 6.3 권한 셀렉트 박스, 검색 +- 종류: 권한관리의 목록 표시 + +### 6.4 초대 메시지 인풋박스 + +### 6.5 초대 버튼 +- 클릭: 사용자 초대 이메일 발송 +- 이메일 주소 기준 사원 정보가 있을 경우에는 대량하여 사용자 등록 처리 +- 없을 경우에는 사용자에만 등록하고 나머지 사원 정보는 직접 입력 필요 +- 사용자 아이디 중복 불가 + +## 7. 근태관리 (슬라이드 41-42) + +### 7.1 근태관리 현황 카드 +| 항목 | 설명 | +|------|------| +| 정시 출근 | 전체 정시 출근 수 | +| 지각 | 전체 지각 수 | +| 결근 | 전체 결근 수 | +| 휴가 | 전체 휴가 수 | + +### 7.2 기간 설정 버튼 영역 +- 종류: 당해년도, 전전월, 전월, 당월, 어제, 오늘 +- 클릭: 해당 기간이 설정되며 화면 전체에 적용 처리 +- 근태관리 자동 설정 시: 모든 사원이 정시 출퇴근한 것으로 기록, 예외사항만 경우 작성 + +### 7.3 근태 등록 버튼 +- 클릭: 근태 정보 팝업 표시 + +### 7.4 사유 등록 버튼 +- 클릭: 사유 정보 팝업 표시 + +### 7.5 필터 셀렉트 박스 +- 종류: 전체, 정시 출근, 지각, 결근, 휴가, 출장, 외근, 연장근무 +- 디폴트: 전체 + +### 7.6 정렬 셀렉트 박스 +- 종류: 직급순, 부서 오름차순, 부서 내림차순, 이름 오름차순, 이름 내림차순 +- 디폴트: 직급순 + +### 7.7 근태 정보 팝업 +| 필드명 | 설명 | +|--------|------| +| 대상 | 사원 셀렉트 박스, 검색&다중 선택 | +| 기준일 | 달력 팝업 표시, 일자 다중 선택 가능, 디폴트: 당일 | +| 출근 시간 | 시/분 선택 | +| 퇴근 시간 | 시/분 선택 | +| 야간 연장 시간 | 주당 연장 근로 시간에서 주말 연장 시간을 차감한 이내에만 설정 가능 | +| 주말 연장 시간 | 주당 연장 근로 시간에서 야간 연장 시간을 차감한 이내에만 설정 가능 | + +### 7.8 사유 정보 팝업 +| 필드명 | 설명 | +|--------|------| +| 대상 | 사원 셀렉트 박스 | +| 기준일 | 달력 팝업 | +| 내용 | 내용 입력 | + +## 8. 휴가관리 (슬라이드 43-46) + +### 8.1 휴가관리 탭 +- 휴가 사용 현황 +- 휴가 부여 현황 +- 휴가 신청 현황 + +### 8.2 휴가관리 현황 카드 +| 항목 | 설명 | +|------|------| +| 휴가 승인 대기 | | +| 연차 | 전체 연차 사원 수 | +| 결조사 | | +| 연간 연차 사용률 | | + +### 8.3 필터 셀렉트 박스 +- 종류: 전체, 모든 사원 목록 +- 항목: 부서명, 직급명, 사원명 표시 +- 디폴트: 전체 + +### 8.4 정렬 셀렉트 박스 +- 종류: 직급순, 부서 오름차순, 부서 내림차순, 이름 오름차순, 이름 내림차순 +- 디폴트: 직급순 + +### 8.5 휴가 부여 팝업 +| 필드명 | 설명 | +|--------|------| +| 유형 | 종류: 연차, 보상, 경조, 보건, 병가, 반차, 반수 선택 | +| 사유 | | +| 일수 | 개월/일/시간 선택 | + +### 8.6 휴가 신청 팝업 +| 필드명 | 설명 | +|--------|------| +| 잔여 | 잔여 일수 표시 | +| 유형 | 종류: 연차, 보상, 경조, 보건, 병가, 반차 | +| 기간 | 날짜 선택, (5) 반차 선택 시에는 시간으로 변경 | + +### 8.7 휴가 신청 현황 필터 +- 종류: 승인, 거절 +- 1/3 완료: 결재선 승인 진행도에 따라 표시 + +--- + +## 데이터 모델 + +### Department (부서) +``` +- id: bigint +- tenant_id: bigint (FK) +- parent_id: bigint (FK, nullable) +- name: string +- order: int +- is_active: boolean +- created_at: timestamp +``` + +### Employee (사원) +``` +- id: bigint +- tenant_id: bigint (FK) +- user_id: bigint (FK, nullable) +- department_id: bigint (FK, nullable) +- employee_code: string +- name: string +- resident_number: string (encrypted) +- phone: string +- email: string +- salary: decimal +- bank_code: string +- account_number: string +- account_holder: string +- profile_image: string +- gender: enum('male', 'female') +- address: string +- hire_date: date +- employment_type: enum('regular', 'contract', 'dispatch', 'service', 'part_time') +- position_id: bigint (FK) +- job_title_id: bigint (FK) +- status: enum('active', 'leave', 'sick_leave', 'parental_leave', 'personal_leave', 'unpaid_leave', 'resigned', 'dismissed', 'recommended_resignation', 'contract_expired', 'retired') +- check_in_location_id: bigint (FK, nullable) +- check_out_location_id: bigint (FK, nullable) +- resignation_date: date +- resignation_reason: text +- created_at: timestamp +``` + +### AttendanceRecord (근태 기록) +``` +- id: bigint +- tenant_id: bigint (FK) +- employee_id: bigint (FK) +- date: date +- check_in_time: time +- check_out_time: time +- status: enum('on_time', 'late', 'absent', 'leave', 'business_trip', 'outside_work', 'overtime') +- night_overtime_hours: decimal +- weekend_overtime_hours: decimal +- reason: text +- created_at: timestamp +``` + +### Leave (휴가) +``` +- id: bigint +- tenant_id: bigint (FK) +- employee_id: bigint (FK) +- type: enum('annual', 'reward', 'congratulation', 'health', 'sick', 'half_day', 'half_day_am', 'half_day_pm') +- start_date: date +- end_date: date +- days: decimal +- reason: text +- status: enum('pending', 'approved', 'rejected') +- created_at: timestamp +``` + +### LeaveBalance (휴가 잔여) +``` +- id: bigint +- tenant_id: bigint (FK) +- employee_id: bigint (FK) +- year: int +- type: enum('annual', 'reward', ...) +- granted: decimal +- used: decimal +- remaining: decimal +``` + +--- + +## API 도출 + +### 부서관리 API +``` +GET /api/departments # 부서 목록 (트리 구조) +POST /api/departments # 부서 추가 +PUT /api/departments/{id} # 부서 수정 +DELETE /api/departments/{id} # 부서 삭제 +DELETE /api/departments/bulk # 부서 일괄 삭제 +``` + +### 사원관리 API +``` +GET /api/employees # 사원 목록 +POST /api/employees # 사원 등록 +GET /api/employees/{id} # 사원 상세 +PUT /api/employees/{id} # 사원 수정 +DELETE /api/employees/{id} # 사원 삭제 +POST /api/employees/import # CSV 일괄 등록 +GET /api/employees/template # CSV 템플릿 다운로드 +POST /api/employees/invite # 사용자 초대 +``` + +### 근태관리 API +``` +GET /api/attendance # 근태 목록 +POST /api/attendance # 근태 등록 +PUT /api/attendance/{id} # 근태 수정 +GET /api/attendance/summary # 근태 현황 요약 +POST /api/attendance/reason # 사유 등록 +``` + +### 휴가관리 API +``` +GET /api/leaves # 휴가 목록 +POST /api/leaves # 휴가 신청 +PUT /api/leaves/{id} # 휴가 수정 +DELETE /api/leaves/{id} # 휴가 취소 +POST /api/leaves/{id}/approve # 휴가 승인 +POST /api/leaves/{id}/reject # 휴가 거절 +GET /api/leaves/balance/{employee_id} # 휴가 잔여 조회 +POST /api/leaves/grant # 휴가 부여 +GET /api/leaves/summary # 휴가 현황 요약 +``` \ No newline at end of file diff --git a/specs/erp-analysis/05-approval.md b/specs/erp-analysis/05-approval.md new file mode 100644 index 0000000..5f31d96 --- /dev/null +++ b/specs/erp-analysis/05-approval.md @@ -0,0 +1,296 @@ +# 전자결재 (슬라이드 47-59) + +## 1. 개요 + +전자결재 모듈은 기안함, 결재함, 참조함으로 구성되며, 품의서, 지출결의서, 지출 예상 내역서 등의 문서를 처리합니다. + +## 2. 기안함 (슬라이드 48-54) + +### 2.1 문서 상태 +| 상태 | 설명 | +|------|------| +| 임시저장 | 문서 작성 중, 임시저장된 상태 | +| 진행 | 모든 결재자 중 일부 승인된 상태, 결재 요청을 받은 상태 | +| 결재요청 | 결재 요청을 받은 상태 | +| 반려 | 결재자 중 반려한 사람이 있는 상태 | + +### 2.2 기안함 현황 카드 +| 항목 | 설명 | +|------|------| +| 진행 | 진행 중인 문서 수 | +| 전체 | 전체 문서 수 | +| 반려 | 반려된 문서 수 | +| 임시 저장 | 임시저장 문서 수 | + +### 2.3 문서 작성 버튼 +- 클릭: 문서 작성 화면으로 이동 + +### 2.4 상세 버튼 +- 클릭: 문서 상세 팝업 표시 + +### 2.5 삭제 버튼 +- 클릭: + 1) 임시저장 상태일 경우: "정말 이(1)건을 삭제 처리하시겠습니까?" 확인 Alert 표시, 확인 시 해당 문서 삭제 처리 + 2) 임시저장 상태가 아닐 경우: "임시저장 상태만 삭제가 가능합니다." 알림 Alert 표시 + +### 2.6 수정 버튼 +- 클릭: + 1) 임시저장 상태일 경우: 문서 작성 화면으로 이동 + 2) 임시저장 상태가 아닐 경우: 문서 상세 팝업 표시 + +### 2.7 필터 셀렉트 박스 +- 종류: 전체, 임시저장, 진행, 완료, 반려 +- 디폴트: 전체 + +### 2.8 정렬 셀렉트 박스 +- 종류: 최신순, 등록순 +- 디폴트: 최신순 + +## 3. 문서 작성 (슬라이드 49-54) + +### 3.1 상세 버튼 +- 클릭: 문서 상세 팝업 표시 + +### 3.2 문서 유형 셀렉트 박스, 검색 +- 종류: 품의서, 지출결의서, 지출 예상 내역서 +- 선택한 문서 유형의 화면으로 변경 표시 + +### 3.3 결재자 셀렉트 박스, 검색&다중 선택 +- 항목: 부서명, 직책명, 사원명 표시 +- 종류: 전체, 모든 사원 목록 +- 디폴트: 전체 + +### 3.4 참조자 셀렉트 박스, 검색&다중 선택 +- 항목: 부서명, 직책명, 사원명 표시 +- 종류: 전체, 모든 사원 목록 +- 디폴트: 전체 + +### 3.5 버튼 영역 +| 버튼 | 설명 | +|------|------| +| 상세 | 문서 상세 팝업 표시 | +| 삭제 | 임시저장 상태만 삭제 가능 | +| 삼신 | 결재선 마감 경우 숨김 | +| 임시저장 | 임시저장 처리 | + +## 4. 품의서 (슬라이드 50) + +### 4.1 구매처 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 구매처 | Y | | +| 구매처 결제일 | Y | | + +### 4.2 품의서 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 제목 | Y | | +| 품의 내역 | Y | 녹음 버튼: 마이크 사용 가능할 경우에만 버튼 활성화, 녹음 중지 버튼으로 변경, 음성 내용을 텍스트로 변경하여 (1-1) 인풋박스 영역에 표시 | +| 품의 사유 | Y | | +| 예상 비용 | Y | | + +### 4.3 참고 이미지 정보 +- 첨부파일 찾기 + +## 5. 지출결의서 (슬라이드 51-52) + +### 5.1 지출 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 지출 요청일 | Y | | +| 결제일 | Y | | + +### 5.2 지출결의서 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 적요 | Y | | +| 금액 | Y | | +| 비고 | N | | + +### 5.3 결제 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 카드 | Y | 종류: 등록된 카드 목록, 디폴트: 첫번째 카드 | +| 총 비용 | - | 지출결의서 정보의 금액 합계 표시 | + +### 5.4 참고 이미지 정보 +- 첨부파일 찾기 + +## 6. 지출 예상 내역서 (슬라이드 53-54) + +### 6.1 지출 예상 내역서 목록 +- 체크 설정/해제 토글 +- 1) 지출 예상 내역서 화면에서 찾을 경우: 설정된 체크 상태 유지 +- 2) 문서 작성 화면에서 설정했을 경우: 모든 체크 항목 설정된 상태 + +### 6.2 항목 +| 필드명 | 설명 | +|--------|------| +| 예상 지급일 | | +| 품목 | | +| 지출금액 | | +| 거래처 | | +| 계좌 | | + +### 6.3 합계 +| 항목 | 설명 | +|------|------| +| 지출 합계 | | +| 계좌 잔액 | | +| 최종 차액 | | + +## 7. 결재함 (슬라이드 55-58) + +### 7.1 상태 +| 상태 | 설명 | +|------|------| +| 진행 | 결재 하위 상태 | +| 예정 | 결재 순번에 의한 대기 | +| 결재요청 | 결재 요청을 받은 상태 | + +### 7.2 결재함 현황 카드 +| 항목 | 설명 | +|------|------| +| 결재 요청 | 결재 요청 문서 수 | +| 완료 | 완료 문서 수 | +| 반려 | 반려 문서 수 | +| 예정 | 예정 문서 수 | + +### 7.3 승인 버튼 +- 클릭: "정말 (1)건을 승인하시겠습니까?" 확인 Alert 표시 +- 확인 버튼 클릭 시 "승인이 완료되었습니다." 알림 Alert 표시 + +### 7.4 반려 버튼 +- 클릭: "정말 (1)건을 반려하시겠습니까?" 확인 Alert 표시 +- 확인 버튼 클릭 시 "반려가 완료되었습니다." 알림 Alert 표시 + +### 7.5 필터 셀렉트 박스 +- 종류: 전체, 결재 요청, 예정, 완료, 반려 +- 1/3 완료: 결재선 승인 진행도에 따라 표시 +- 디폴트: 전체 + +### 7.6 수정 버튼 +- 클릭: 문서 상세 팝업 표시 + +## 8. 참조함 (슬라이드 59) + +### 8.1 열람 버튼 +- 클릭: "정말 (1)건을 열람 처리하시겠습니까?" 확인 Alert 표시 +- 확인 버튼 클릭 시 "열람 처리가 완료되었습니다." 알림 Alert 표시 + +### 8.2 미열람 버튼 +- 클릭: "정말 (1)건을 미열람 처리하시겠습니까?" 확인 Alert 표시 +- 확인 버튼 클릭 시 "미열람 처리가 완료되었습니다." 알림 Alert 표시 + +### 8.3 필터 셀렉트 박스 +- 종류: 전체, 열람, 미열람 +- 디폴트: 전체 + +## 9. 문서 상세 팝업 (슬라이드 56-58) + +### 9.1 버튼 영역 +| 버튼 | 설명 | +|------|------| +| 복제 | 문서 작성 화면으로 이동 (새글) | +| 수정 | 결재선 중에서는 누구나 수정 가능, 해당 문서 작성 화면으로 이동 | +| 반려 | 결재선 마감 경우 숨김 | +| 승인 | 결재선 마감 경우 숨김 | +| 인쇄 | | +| 공유 | (5-1) 팝업 표시 | +| 닫기 | | + +### 9.2 결재선 영역 +- 승인/반려 시 해당 아이콘 표시 + +### 9.3 공유 버튼 +| 공유 방식 | 설명 | +|-----------|------| +| PDF | | +| 이메일 | | +| 카카오톡 | | + +--- + +## 데이터 모델 + +### ApprovalDocument (결재 문서) +``` +- id: bigint +- tenant_id: bigint (FK) +- document_number: string +- document_type: enum('request', 'expense', 'expense_estimate') +- title: string +- status: enum('draft', 'pending', 'in_progress', 'approved', 'rejected') +- drafter_id: bigint (FK) # 기안자 +- content: json # 문서 내용 +- attachments: json +- created_at: timestamp +- submitted_at: timestamp +``` + +### ApprovalLine (결재선) +``` +- id: bigint +- document_id: bigint (FK) +- approver_id: bigint (FK) +- order: int +- status: enum('pending', 'approved', 'rejected') +- comment: text +- approved_at: timestamp +``` + +### ApprovalReference (참조자) +``` +- id: bigint +- document_id: bigint (FK) +- referee_id: bigint (FK) +- is_read: boolean +- read_at: timestamp +``` + +### ExpenseItem (지출 항목) +``` +- id: bigint +- document_id: bigint (FK) +- description: string +- amount: decimal +- note: text +``` + +--- + +## API 도출 + +### 기안함 API +``` +GET /api/approvals/drafts # 기안 목록 +POST /api/approvals # 문서 작성 +PUT /api/approvals/{id} # 문서 수정 +DELETE /api/approvals/{id} # 문서 삭제 +POST /api/approvals/{id}/submit # 문서 제출 (결재 요청) +POST /api/approvals/{id}/save-draft # 임시저장 +GET /api/approvals/{id} # 문서 상세 +GET /api/approvals/drafts/summary # 기안함 현황 +``` + +### 결재함 API +``` +GET /api/approvals/inbox # 결재함 목록 +POST /api/approvals/{id}/approve # 승인 +POST /api/approvals/{id}/reject # 반려 +GET /api/approvals/inbox/summary # 결재함 현황 +``` + +### 참조함 API +``` +GET /api/approvals/references # 참조함 목록 +POST /api/approvals/{id}/mark-read # 열람 처리 +POST /api/approvals/{id}/mark-unread # 미열람 처리 +``` + +### 문서 공유 API +``` +GET /api/approvals/{id}/pdf # PDF 다운로드 +POST /api/approvals/{id}/share/email # 이메일 공유 +POST /api/approvals/{id}/share/kakao # 카카오톡 공유 +``` \ No newline at end of file diff --git a/specs/erp-analysis/06-accounting.md b/specs/erp-analysis/06-accounting.md new file mode 100644 index 0000000..abe4c9d --- /dev/null +++ b/specs/erp-analysis/06-accounting.md @@ -0,0 +1,427 @@ +# 회계관리 (슬라이드 60-91) + +## 1. 개요 + +회계관리 모듈은 거래처, 매출, 매입, 입금, 출금, 어음, 거래처원장, 미수금 현황, 입출금 계좌 조회 등을 관리합니다. + +## 2. 회계관리 플로우차트 (슬라이드 61) + +### 2.1 매출 플로우 +``` +거래처 선택 → 매출 등록 → 세금계산서 발행 +``` + +### 2.2 입금 플로우 +``` +입금 등록 → 전액 입금? → 어음 수취? + ↓ ↓ + 입출금 계좌 조회 어음관리 +``` + +### 2.3 매입 플로우 +``` +거래처 선택 → 매입 등록 → 세금계산서 수취 +``` + +### 2.4 출금 플로우 +``` +출금 등록 → 전액 출금? → 어음 발행? + ↓ ↓ + 입출금 계좌 조회 어음관리 +``` + +### 2.5 추심 플로우 +``` +미수금 현황 → 연체? → 악성주심? → 악성 추심 + ↓ + 미지급 알림 +``` + +### 2.6 조회 +- 입출금 계좌 조회 +- 카드 내역 조회 + +### 2.7 장부/보고서 +- 거래처원장 +- 지출 예상 내역서 +- 일일 일보 + +## 3. 거래처관리 (슬라이드 62-65) + +### 3.1 현황 카드 +| 항목 | 설명 | +|------|------| +| 전체 거래처 | | +| 매출 거래처 | | +| 매입 거래처 | | + +### 3.2 삭제 버튼 +- 관리 권한이 없을 경우 숨김 +- 클릭: "선택한 거래처 N개를 삭제하시겠습니까?" 확인 Alert 표시 +- 확인 선택 시 삭제 + +### 3.3 구분 필터 셀렉트 박스 +- 종류: 전체, 매출, 매입, 매입매출 +- 디폴트: 전체 + +### 3.4 신용등급 필터 셀렉트 박스 +- 종류: 전체, AAA, AA, A, BBB, BB, B, CCC, CC, C, D +- 디폴트: 전체 + +### 3.5 거래등급 필터 셀렉트 박스 +- 종류: 전체, A(우수), B(양호), C(보통), D(주의), E(위험) +- 디폴트: 전체 + +### 3.6 약정체결 필터 셀렉트 박스 +- 종류: 전체, 약정체결, 정상 +- 디폴트: 전체 + +### 3.7 정렬 셀렉트 박스 +- 종류: 최신순, 등록순, 거래처명 오름차순, 거래처명 내림차순, 미수금 높은순, 미수금 낮은순 +- 디폴트: 최신순 + +## 4. 거래처 상세 (슬라이드 63-65) + +### 4.1 기본 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 사업자등록번호 | Y | | +| 거래처 코드 | N | | +| 거래처명 | Y | | +| 대표자명 | Y | | +| 거래처 유형 | Y | 매출매입 선택 | +| 업태 | N | | +| 업종 | N | | + +### 4.2 연락처 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 주소 | N | 우편번호 찾기 + 상세주소 | +| 전화번호 | N | | +| 모바일 | N | | +| 팩스 | N | | +| 이메일 | N | | + +### 4.3 담당자 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 담당자명 | N | | +| 담당자 전화 | N | | + +### 4.4 시스템 관리자 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 관리자명 | N | | + +### 4.5 회사 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 회사 로고 | N | 750x250px, 10MB 이하 PNG, JPEG, GIF | + +### 4.6 결제 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 매입 결제일 | N | 종류: 1일~31일, 말일. 디폴트: 10일. 거래처 유형이 '매입' 또는 '매입매출'일 경우 해당 | +| 매출 결제일 | N | 종류: 1일~31일, 말일. 디폴트: 15일. 거래처 유형이 '매출' 또는 '매입매출'일 경우 표시 | + +### 4.7 신용 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 신용등급 | N | 외부 신용평가 등급 표시. 예: AAA, AA, A, BBB, BB, B, CCC, CC, C, D | +| 거래등급 | N | 종류: A(우수), B(양호), C(보통), D(주의), E(위험). 디폴트: A(우수). 자사 기준 거래처 평가 등급 | + +### 4.8 계좌 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 세금계산서 이메일 | N | | +| 입금계좌 은행 | N | 은행 선택 | +| 계좌 | N | | +| 예금주 | N | | + +### 4.9 추가 정보 +| 필드명 | 설명 | +|--------|------| +| 미수금 | 해당 거래처의 현재 미수금 잠게 표시. 읽기 전용 | +| 연체 | - ON: 연체 상태로 표시, 연체일수 표시 | +| | - OFF: 정상 상태 | +| | - 거래처 상세에서 연체 설정과 연동 | +| | - (4-1) 연체 등록 이후부터 경과일 표시 | +| 미지급 | 해당 거래처에 대한 미지급금 잠게 표시. 읽기 전용 | +| 악성채권 | - ON: 악성채권으로 등록, 악성채권 추심관리 목록에 표시 | +| | - OFF: 정상 상태 | +| | - 디폴트: OFF | +| 메모 | 추가 버튼 클릭 시 목록 최상단에 추가 | + +## 5. 매출관리 (슬라이드 66-71) + +### 5.1 매출 유형 +- 필드 매출 시 매출 직접 등록 (삭제 가능) +- 필드 매출: 용역 매출, 공사 매출, 임대 수익, 기타 매출 + +### 5.2 매출 상세 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 매출번호 | - | 자동 채번 | +| 매출일 | Y | | +| 거래처명 | Y | 거래처 선택 | +| 매출 유형 | Y | 선택 | + +### 5.3 품목 정보 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 품목명 | Y | | +| 수량 | Y | | +| 단가 | Y | | +| 공급가액 | - | 자동 계산 | +| 부가세 | - | 자동 계산 | +| 적요 | N | | + +### 5.4 세금계산서 +| 필드명 | 설명 | +|--------|------| +| 세금계산서 발행 | 토글 | + +### 5.5 거래명세서 +| 필드명 | 설명 | +|--------|------| +| 거래명세서 | 토글 | + +## 6. 입금관리 (슬라이드 74-76) + +### 6.1 입금 유형 +- 종류: 매출대금, 선수금, 가수금, 입대수익, 미자수익, 보증금 반환, 차입금, 자본금, 부가세 환급, 기타, 미상정 + +### 6.2 입금 상세 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 입금일 | Y | | +| 입금계좌 | Y | 국민은행 1234 (계좌명) | +| 입금자명 | Y | | +| 입금금액 | Y | | +| 적요 | N | | +| 거래처 | N | 선택 | +| 입금 유형 | Y | | + +## 7. 출금관리 (슬라이드 77-79) + +### 7.1 출금 유형 +- 종류: 매입대금, 선급금, 가지급금, 임대비용, 보증금 지급, 차입금 상환, 배당금 지급, 세금, 공과금, 경비, 4대보험, 급여 + +### 7.2 출금 상세 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 출금일 | Y | | +| 출금계좌 | Y | | +| 받는 분 | Y | | +| 출금금액 | Y | | +| 적요 | N | | +| 거래처 | N | | +| 출금 유형 | Y | | + +## 8. 거래처원장 (슬라이드 80) + +### 8.1 현황 카드 +| 항목 | 설명 | +|------|------| +| 전기 이월 | | +| 매출 | | +| 수금 | | +| 잔액 | | + +### 8.2 거래처원장 목록 +- 거래처별 기간별 합계 금액 표시 +- 클릭: 거래처원장 상세 화면으로 이동 + +### 8.3 엑셀 다운로드 버튼 +- 클릭: 엑셀 파일 다운로드 + +## 9. 미수금 현황 (슬라이드 85) + +### 9.1 미수금 현황 목록 +- 거래처별 월별 미수금 현황 (매출, 입금, 어음, 미수금, 메모) + +### 9.2 수취 어음 등록 시 표시 +- 회계에는 미반영 + +### 9.3 연체 표시 +- ON: 연체 상태로 표시, 연체일수 표시 +- OFF: 정상 상태 +- 거래처 상세에서 연체 설정과 연동 + +### 9.4 엑셀 다운로드 버튼 + +### 9.5 저장 버튼 + +## 10. 입출금 계좌 조회 (슬라이드 90) + +### 10.1 설명 +- 기준 정보 > 계좌 관리에 등록된 계좌의 자동 입출금 내역 수집 + +### 10.2 새로고침 버튼 +- 클릭: 은행 계좌 입출금 내역 최신 데이터 조회 +- 바로빌 API 연동 시 실시간 조회 + +### 10.3 구분 필터 셀렉트 박스 +- 종류: 전체, 출금, 입금 +- 디폴트: 전체 + +### 10.4 계정과목 필터 셀렉트 박스, 검색&다중 선택 +- (2) 선택에 따른 계정과목 목록 표시 +- 입금 종류: 전체, 매출대금, 선수금, 가수금, 임대수익, 이자수익, 보증금 반환, 차입금, 자본금, 부가세 환급, 기타, 미상정 +- 출금 종류: 전체, 매입대금, 선급금, 가지급금, 임대비용, 이자비용, 보증금 지급, 차입금 상환, 배당금 지급, 세금, 공과금, 경비, 4대보험, 급여 +- 디폴트: 전체 + +### 10.5 정렬 셀렉트 박스 +- 종류: 최신순, 등록순, 금액순 +- 디폴트: 최신순 + +### 10.6 수정 버튼 +- 클릭: 해당 입금/출금 상세 화면으로 이동 + +--- + +## 데이터 모델 + +### Vendor (거래처) +``` +- id: bigint +- tenant_id: bigint (FK) +- business_number: string +- vendor_code: string +- name: string +- representative: string +- type: enum('sales', 'purchase', 'both') +- business_type: string +- business_category: string +- address: string +- phone: string +- mobile: string +- fax: string +- email: string +- manager_name: string +- manager_phone: string +- logo: string +- purchase_payment_day: int +- sales_payment_day: int +- credit_rating: enum('AAA', 'AA', 'A', 'BBB', 'BB', 'B', 'CCC', 'CC', 'C', 'D') +- trade_rating: enum('A', 'B', 'C', 'D', 'E') +- tax_invoice_email: string +- bank_code: string +- account_number: string +- account_holder: string +- is_overdue: boolean +- overdue_start_date: date +- is_bad_debt: boolean +- notes: json +- created_at: timestamp +``` + +### Sales (매출) +``` +- id: bigint +- tenant_id: bigint (FK) +- vendor_id: bigint (FK) +- sales_number: string +- sales_date: date +- sales_type: enum('product', 'service', 'construction', 'rental', 'other') +- total_amount: decimal +- tax_amount: decimal +- is_tax_invoice_issued: boolean +- is_statement_issued: boolean +- created_at: timestamp +``` + +### SalesItem (매출 품목) +``` +- id: bigint +- sales_id: bigint (FK) +- item_name: string +- quantity: int +- unit_price: decimal +- supply_amount: decimal +- tax_amount: decimal +- description: string +``` + +### Deposit (입금) +``` +- id: bigint +- tenant_id: bigint (FK) +- vendor_id: bigint (FK, nullable) +- account_id: bigint (FK) +- deposit_date: date +- depositor_name: string +- amount: decimal +- description: string +- deposit_type: enum('sales', 'advance', 'suspense', 'rental', 'interest', 'deposit_return', 'loan', 'capital', 'vat_refund', 'other', 'unidentified') +- created_at: timestamp +``` + +### Withdrawal (출금) +``` +- id: bigint +- tenant_id: bigint (FK) +- vendor_id: bigint (FK, nullable) +- account_id: bigint (FK) +- withdrawal_date: date +- recipient_name: string +- amount: decimal +- description: string +- withdrawal_type: enum('purchase', 'advance', 'suspense', 'rental', 'interest', 'deposit', 'loan_repayment', 'dividend', 'tax', 'utility', 'expense', 'insurance', 'salary') +- created_at: timestamp +``` + +--- + +## API 도출 + +### 거래처 API +``` +GET /api/vendors # 거래처 목록 +POST /api/vendors # 거래처 등록 +GET /api/vendors/{id} # 거래처 상세 +PUT /api/vendors/{id} # 거래처 수정 +DELETE /api/vendors/{id} # 거래처 삭제 +DELETE /api/vendors/bulk # 거래처 일괄 삭제 +GET /api/vendors/summary # 거래처 현황 +``` + +### 매출 API +``` +GET /api/sales # 매출 목록 +POST /api/sales # 매출 등록 +GET /api/sales/{id} # 매출 상세 +PUT /api/sales/{id} # 매출 수정 +DELETE /api/sales/{id} # 매출 삭제 +POST /api/sales/{id}/tax-invoice # 세금계산서 발행 +GET /api/sales/summary # 매출 현황 +``` + +### 입금 API +``` +GET /api/deposits # 입금 목록 +POST /api/deposits # 입금 등록 +GET /api/deposits/{id} # 입금 상세 +PUT /api/deposits/{id} # 입금 수정 +DELETE /api/deposits/{id} # 입금 삭제 +``` + +### 출금 API +``` +GET /api/withdrawals # 출금 목록 +POST /api/withdrawals # 출금 등록 +GET /api/withdrawals/{id} # 출금 상세 +PUT /api/withdrawals/{id} # 출금 수정 +DELETE /api/withdrawals/{id} # 출금 삭제 +``` + +### 장부/보고서 API +``` +GET /api/ledger/vendor # 거래처원장 +GET /api/ledger/vendor/{vendor_id} # 거래처원장 상세 +GET /api/ledger/vendor/export # 거래처원장 엑셀 다운로드 +GET /api/receivables # 미수금 현황 +GET /api/receivables/export # 미수금 현황 엑셀 다운로드 +GET /api/bank-transactions # 입출금 계좌 조회 +POST /api/bank-transactions/sync # 입출금 내역 동기화 +``` \ No newline at end of file diff --git a/specs/erp-analysis/07-master-data.md b/specs/erp-analysis/07-master-data.md new file mode 100644 index 0000000..daa9182 --- /dev/null +++ b/specs/erp-analysis/07-master-data.md @@ -0,0 +1,332 @@ +# 기준정보 (슬라이드 92-104) + +## 1. 개요 + +기준정보 모듈은 직급, 직책, 권한, 근무, 출퇴근, 휴가, 카드, 계좌, 팝업, 게시판, 일반설정, 알림설정을 관리합니다. + +## 2. 직급관리 (슬라이드 93, 95) + +### 2.1 직급 인풋박스 +- 직급 입력 후 추가 버튼 클릭 + +### 2.2 추가 버튼 +- 클릭: (2-1) 직급 목록 최하단에 표시 + +### 2.3 직급 목록 +- 디폴트: 사원, 대리, 과장, 차장, 부장, 이사, 상무, 전무, 부사장, 사장 + +### 2.4 순서 변경 버튼 +- 드래그&드랍: 해당 위치로 순서 변경 + +### 2.5 수정 버튼 +- 클릭: 직급 수정 팝업 표시 + +### 2.6 삭제 버튼 +- 클릭: + 1) 해당 직급으로 사원 설정된 경우: "'직급명'을 사용하고 있는 사원이 있습니다. 다 변경 후 삭제가 가능합니다." 알림 Alert 표시 + 2) 해당 직급으로 사원 미설정된 경우: "정말 삭제하시겠습니까?" 확인 Alert 표시, 확인 클릭 시 "삭제가 완료되었습니다." 알림 Alert 표시 + +### 2.7 직급 수정 팝업 +- 직급명 인풋박스: 기존 직급명 표시, 수정 가능 + +## 3. 직책관리 (슬라이드 94-95) + +### 3.1 기능 +- 직급관리와 동일한 구조 + +### 3.2 디폴트 직책 +- (없음) + +### 3.3 직책 수정 팝업 +- 직책명 인풋박스: 기존 직책명 표시, 수정 가능 + +## 4. 권한관리 (슬라이드 96) + +### 4.1 관리자 +- 디폴트: 모든 메뉴 권한 설정 +- 수정 불가, 삭제 불가 + +### 4.2 일반 +- 디폴트: 대시보드 제외 모든 메뉴 접근 불가 + +### 4.3 추가 버튼 +- 클릭: 권한 추가 팝업 표시 + +### 4.4 삭제 버튼 +- 클릭: + 1) 해당 권한으로 사원 설정된 경우: "'권한명'을 사용하고 있는 사원이 있습니다. 다 변경 후 삭제가 가능합니다." 알림 Alert 표시 + 2) 해당 권한으로 사원 미설정된 경우: "정말 삭제하시겠습니까?" 확인 Alert 표시 + +### 4.5 체크박스 +- 클릭: 체크 설정/해제 토글 +- 디폴트: 체크 해제 상태 + +### 4.6 관리 +- 읽기 및 수정 권한 + +### 4.7 읽기 +- 읽기만 권한 + +## 5. 근무관리 (슬라이드 97) + +### 5.1 근무 정보 +| 필드명 | 설명 | +|--------|------| +| 근무 유형 | 종류: 고정형, 변형, 맞춤형 | +| 기본 소정 근로 시간 | 주 00시간 | +| 연장 근로 시간 | 주 00시간 | +| 연장 근로 한도 | 52시간 미만 | +| 근무 요일 설정 | 클릭: 설정된 체크 활성/비활성 토글, 디폴트: 월~금 활성 | + +### 5.2 출근 시간 +- 09:00 + +### 5.3 퇴근 시간 +- 18:00 + +### 5.4 휴게 시간 +| 필드명 | 설명 | +|--------|------| +| 총 휴게 시간 | 1시간 | +| 휴게 시간 | 12:00 ~ 13:00 | + +## 6. 출퇴근관리 (슬라이드 99) + +### 6.1 출퇴근 설정 +| 필드명 | 설명 | +|--------|------| +| GPS 출퇴근 | 토글: 기준 좌표로 정해진 거리 기준 이내에 있을 때만 출근/퇴근 등록 가능 | +| 허용 반경 | 주 00m | + +### 6.2 본사 위치 정보 +| 필드명 | 설명 | +|--------|------| +| 본사 주소 | 우편번호 찾기 + 상세주소 | +| 경도 | | +| 위도 | | + +### 6.3 현장 목록 +- 추가 버튼: 현장 등록 팝업 표시 +- 현장명, 주소, 삭제 버튼 + +## 7. 휴가관리 (슬라이드 100) + +### 7.1 기준 셀렉트 박스 +- 종류: 회계연도, 입사일 +- 디폴트: 회계연도 +- 입사일 선택 시 (2) 영역 비활성화 +- 회계연도 기준: 회사의 회계연도를 기준으로 휴가를 부여하고 조회할 수 있습니다. +- 입사일 기준: 사원의 입사일 회계연도 기준으로 휴가를 부여하고 조회할 수 있습니다. + +### 7.2 기준일 월/일 설정 영역 +- 회계연도 기준 시에만 활성화 + +### 7.3 기본 연차 설정 +- 1년간 출근율 80% 이상이면 15일 +- 3년 이상 근속 시 2년에 1일 추가 (최대 25일) +- 1년 미만 또는 출근율 80% 이하인 경우 1일 + - 입사일~회계연도 기준일 사정: 회년도 출근율로 판정 80% 이상이면 15일 + - (3-1) 연차+1년+1일 시작, 이후 2년에 1일 추가 + - 입사일~회계연도 기준으로 전환할 때는 취업규칙 변경, 노사 의견수렴, 전환 시 충북 연차 정산(입사일 기준 vs 회계연도 기준 비교 후 부족분 보전)을 반드시 검토 필요 + +## 8. 카드관리 (슬라이드 101-102) + +### 8.1 카드 목록 +| 필드명 | 설명 | +|--------|------| +| 카드사 | | +| 카드번호 | 앞4자리, 끝4자리 표시 | +| 카드명 | | +| 상태 | | +| 사용자 | 부서명 / 이름 / 직책 | +| 작업 | 상세 버튼 | + +### 8.2 필터 +- 종류: 전체, 사용, 정지 +- 디폴트: 전체 + +### 8.3 카드 상세 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 카드사 | Y | 카드사명 선택 | +| 카드번호 | Y | 1234-1234-1234-1234 | +| 유효기간 | Y | MM/YY | +| 카드 비밀번호 앞 2자리 | Y | 입력 시 마스킹 처리 | +| 카드명 | Y | | +| 상태 | Y | 종류: 사용, 정지. 정지 시 해당 카드의 자동 조회 중단 | +| 사용자 | N | 부서명 / 이름 / 직책. 선택 시 해당 카드의 사용자로 설정 | + +## 9. 계좌관리 (슬라이드 103-104) + +### 9.1 계좌 목록 +| 필드명 | 설명 | +|--------|------| +| 은행 | | +| 계좌번호 | | +| 예금주 | | +| 상태 | | +| 사용자 | 부서명 / 이름 / 직책 | +| 작업 | 상세 버튼 | + +### 9.2 필터 +- 종류: 전체, 사용, 정지 +- 디폴트: 전체 + +### 9.3 계좌 상세 +| 필드명 | 필수 | 설명 | +|--------|------|------| +| 은행 | Y | 은행 선택 | +| 계좌번호 | Y | | +| 예금주 | Y | | +| 계좌명 | Y | | +| 상태 | Y | 종류: 사용, 정지. 정지 시 해당 계좌의 자동 조회 중단 | +| 사용자 | N | 부서명 / 이름 / 직책. 선택 시 해당 계좌의 사용자로 설정 | + +--- + +## 데이터 모델 + +### Position (직급) +``` +- id: bigint +- tenant_id: bigint (FK) +- name: string +- order: int +- created_at: timestamp +``` + +### JobTitle (직책) +``` +- id: bigint +- tenant_id: bigint (FK) +- name: string +- order: int +- created_at: timestamp +``` + +### Role (권한) +``` +- id: bigint +- tenant_id: bigint (FK) +- name: string +- is_system: boolean # 시스템 기본 권한 여부 +- permissions: json # 메뉴별 권한 설정 +- created_at: timestamp +``` + +### WorkSetting (근무 설정) +``` +- id: bigint +- tenant_id: bigint (FK) +- work_type: enum('fixed', 'flexible', 'custom') +- standard_hours: int # 주당 소정 근로 시간 +- overtime_hours: int # 주당 연장 근로 시간 +- overtime_limit: int # 연장 근로 한도 +- work_days: json # ['mon', 'tue', 'wed', 'thu', 'fri'] +- start_time: time +- end_time: time +- break_hours: int +- break_start: time +- break_end: time +``` + +### AttendanceSetting (출퇴근 설정) +``` +- id: bigint +- tenant_id: bigint (FK) +- use_gps: boolean +- allowed_radius: int # 허용 반경 (m) +- headquarters_address: string +- headquarters_latitude: decimal(10,8) +- headquarters_longitude: decimal(11,8) +``` + +### LeaveSetting (휴가 설정) +``` +- id: bigint +- tenant_id: bigint (FK) +- base_type: enum('fiscal_year', 'hire_date') +- fiscal_start_month: int +- fiscal_start_day: int +``` + +### Card (카드) +``` +- id: bigint +- tenant_id: bigint (FK) +- card_company: string +- card_number: string (encrypted) +- expiry_date: string +- card_password: string (encrypted) +- card_name: string +- status: enum('active', 'inactive') +- user_id: bigint (FK, nullable) +- created_at: timestamp +``` + +### BankAccount (계좌) +``` +- id: bigint +- tenant_id: bigint (FK) +- bank_code: string +- account_number: string +- account_holder: string +- account_name: string +- status: enum('active', 'inactive') +- user_id: bigint (FK, nullable) +- created_at: timestamp +``` + +--- + +## API 도출 + +### 직급/직책 API +``` +GET /api/positions # 직급 목록 +POST /api/positions # 직급 추가 +PUT /api/positions/{id} # 직급 수정 +DELETE /api/positions/{id} # 직급 삭제 +PUT /api/positions/reorder # 직급 순서 변경 + +GET /api/job-titles # 직책 목록 +POST /api/job-titles # 직책 추가 +PUT /api/job-titles/{id} # 직책 수정 +DELETE /api/job-titles/{id} # 직책 삭제 +PUT /api/job-titles/reorder # 직책 순서 변경 +``` + +### 권한 API +``` +GET /api/roles # 권한 목록 +POST /api/roles # 권한 추가 +GET /api/roles/{id} # 권한 상세 +PUT /api/roles/{id} # 권한 수정 +DELETE /api/roles/{id} # 권한 삭제 +GET /api/menus # 메뉴 목록 (권한 설정용) +``` + +### 설정 API +``` +GET /api/settings/work # 근무 설정 조회 +PUT /api/settings/work # 근무 설정 수정 +GET /api/settings/attendance # 출퇴근 설정 조회 +PUT /api/settings/attendance # 출퇴근 설정 수정 +GET /api/settings/leave # 휴가 설정 조회 +PUT /api/settings/leave # 휴가 설정 수정 +``` + +### 카드/계좌 API +``` +GET /api/cards # 카드 목록 +POST /api/cards # 카드 등록 +GET /api/cards/{id} # 카드 상세 +PUT /api/cards/{id} # 카드 수정 +DELETE /api/cards/{id} # 카드 삭제 + +GET /api/bank-accounts # 계좌 목록 +POST /api/bank-accounts # 계좌 등록 +GET /api/bank-accounts/{id} # 계좌 상세 +PUT /api/bank-accounts/{id} # 계좌 수정 +DELETE /api/bank-accounts/{id} # 계좌 삭제 +``` diff --git a/specs/erp-analysis/08-reports.md b/specs/erp-analysis/08-reports.md new file mode 100644 index 0000000..51e9597 --- /dev/null +++ b/specs/erp-analysis/08-reports.md @@ -0,0 +1,225 @@ +# 보고서 및 분석 (슬라이드 105-113) + +## 1. 개요 + +보고서 및 분석 모듈은 일일 일보, 지출 예상 내역서, 가지급금 인정이자 계산, AI 리포트 생성 등을 제공합니다. + +## 2. 일일 일보 (슬라이드 106-107) + +### 2.1 일일 일보 조회 +- 매일 전일의 입출금 및 매출 매입 현황 자동 집계 + +### 2.2 현황 카드 +| 항목 | 설명 | +|------|------| +| 전일 잔액 | 조회 기준일 전일 잔액 | +| 당일 입금액 | 전일 입금 합계 | +| 당일 출금액 | 전일 출금 합계 | +| 당일 잔액 | 조회 기준일 잔액 | + +### 2.3 일일 일보 목록 +| 필드명 | 설명 | +|--------|------| +| 구분 | 입금/출금 | +| 거래처명 | | +| 계정과목 | | +| 입금액 | | +| 출금액 | | +| 적요 | | + +### 2.4 엑셀 다운로드 버튼 + +## 3. 지출 예상 내역서 (슬라이드 108-109) + +### 3.1 지출 예상 내역서 조회 +- 예상 지출 금액 및 일정 조회 + +### 3.2 현황 카드 +| 항목 | 설명 | +|------|------| +| 예상 지출 합계 | 월별 예상 지출 합계 | +| 계좌 잔액 | 현재 계좌 잔액 | +| 예상 잔액 | 계좌 잔액 - 예상 지출 합계 | + +### 3.3 지출 예상 내역서 목록 +| 필드명 | 설명 | +|--------|------| +| 예상 지급일 | | +| 품목 | | +| 지출금액 | | +| 거래처 | | +| 계좌 | | + +### 3.4 엑셀 다운로드 버튼 + +### 3.5 월별 합계 +| 항목 | 설명 | +|------|------| +| 2025/11 계 | 11월 지출 합계 | +| 2025/12 계 | 12월 지출 합계 | +| 지출 합계 | 전체 지출 합계 | +| 계좌 잔액 | | +| 최종 차액 | | + +## 4. 가지급금 인정이자 계산 (슬라이드 110-112) + +### 4.1 가지급금 인정이자 계산 예시 (2024년 기준) +- 인정이자율 4.6% (당좌대출이자율 기준, 매년 고시) + +### 4.2 계산 예시 +| 항목 | 금액 | +|------|------| +| 가지급금 잔액 | 15,200,000원 | +| 인정이자 | 699,200원 | +| 법인세 추가 (19%) | 132,848원 | +| 대표자 소득세 추가 (35%) | 244,720원 | +| 대표자 지방소득세 (10%) | 24,472원 | +| **총 세금 부담** | **402,040원** | + +### 4.3 계산식 +``` +잔액 × 0.046 = 인정이자 +인정이자 × 0.19 = 법인세 추가 +인정이자 × 0.35 = 대표자 소득세 추가 +``` + +### 4.4 기본 정산 공식 +``` +정산차액 = 가지급금 총액 - 실사용 총액 +``` + +### 4.5 인정이자 계산 공식 (법인세법 기준) +``` +경과일수 = 정산일 - 지급일 +일이자율 = 연이자율 ÷ 365 +인정이자 = 가지급금 × 일이자율 × 경과일수 +``` + +## 5. AI 리포트 생성 (슬라이드 113) + +### 5.1 AI 리포트 생성 프롬프트 + +#### 작성 규칙 +1. 문장은 간결하고 명확하게 작성 +2. 숫자는 읽기 쉽게 "3,123,000원", "15%" 형식 사용 +3. 계정과목명, 거래처명은 구체적으로 명시 +4. 조치가 필요한 경우 구체적인 행동 권한 포함 +5. 긍정적 변화도 반드시 실상 포함 +6. 법인세, 소득세 영향이 있는 경우 세무 리스크 명시 + +#### 키워드 강조 규칙 +출력 메시지 내 다음 키워드는 프론트엔드에서 색상 강조됩니다: +- **빨간색(경고)**: 초과, 증가, 발생, 필요, 불가 +- **주황색(주의)**: 점검, 확인, 주의, 검토 +- **녹색(긍정)**: 감소, 완료, 정상 +- **파란색(양호)**: 여유, 적정, 양호 + +#### 예시 출력 +입력 데이터 예시에 대한 출력: + +```json +{"리포트": [ + {"영역": "지출분석", "상태": "경고", "메시지": "이번 달 예상 지출이 전월 대비 15% 증가했습니다.", "상세": "매입 비용 증가가 주요 원인입니다."}, + {"영역": "가지급금", "상태": "주의", "메시지": "50일 이상 잔기 미수금 3건(2,500만원) 발생.", "상세": "회수 조치가 필요합니다."}, + {"영역": "카드/계좌", "상태": "경고", "메시지": "법인카드 사용 한도 85% 도달, 잔여 한도 600만원입니다.", "상세": "사용 계획을 점검해 주세요."}, + {"영역": "미수금", "상태": "주의", "메시지": "미수금에 대한 관리가 필요한 상태입니다.", "상세": ""} +], +"요약": "지출 증가와 정기 미수금에 대한 관리가 필요한 상태입니다."} +``` + +--- + +## 데이터 모델 + +### DailyReport (일일 일보) +``` +- id: bigint +- tenant_id: bigint (FK) +- report_date: date +- previous_balance: decimal +- daily_deposit: decimal +- daily_withdrawal: decimal +- current_balance: decimal +- details: json # 입출금 상세 내역 +- created_at: timestamp +``` + +### ExpenseEstimate (지출 예상 내역서) +``` +- id: bigint +- tenant_id: bigint (FK) +- expected_date: date +- item_name: string +- amount: decimal +- vendor_id: bigint (FK, nullable) +- account_id: bigint (FK, nullable) +- created_at: timestamp +``` + +### LoanInterestCalculation (가지급금 인정이자 계산) +``` +- id: bigint +- tenant_id: bigint (FK) +- calculation_date: date +- loan_balance: decimal +- interest_rate: decimal +- recognized_interest: decimal +- corporate_tax_addition: decimal +- income_tax_addition: decimal +- local_tax_addition: decimal +- total_tax_burden: decimal +- created_at: timestamp +``` + +### AIReport (AI 리포트) +``` +- id: bigint +- tenant_id: bigint (FK) +- report_date: date +- report_type: string +- content: json # 리포트 내용 +- summary: text +- created_at: timestamp +``` + +--- + +## API 도출 + +### 일일 일보 API +``` +GET /api/reports/daily # 일일 일보 조회 +GET /api/reports/daily/export # 일일 일보 엑셀 다운로드 +``` + +### 지출 예상 내역서 API +``` +GET /api/reports/expense-estimate # 지출 예상 내역서 조회 +POST /api/reports/expense-estimate # 지출 예상 내역 등록 +PUT /api/reports/expense-estimate/{id}# 지출 예상 내역 수정 +DELETE /api/reports/expense-estimate/{id}# 지출 예상 내역 삭제 +GET /api/reports/expense-estimate/export # 지출 예상 내역서 엑셀 다운로드 +``` + +### 가지급금 인정이자 API +``` +GET /api/reports/loan-interest # 가지급금 인정이자 계산 조회 +POST /api/reports/loan-interest/calculate # 가지급금 인정이자 계산 실행 +``` + +### AI 리포트 API +``` +GET /api/reports/ai # AI 리포트 목록 +POST /api/reports/ai/generate # AI 리포트 생성 +GET /api/reports/ai/{id} # AI 리포트 상세 +DELETE /api/reports/ai/{id} # AI 리포트 삭제 +``` + +### 대시보드/분석 API +``` +GET /api/dashboard/summary # 대시보드 요약 +GET /api/dashboard/charts # 대시보드 차트 데이터 +GET /api/analytics/sales # 매출 분석 +GET /api/analytics/expense # 지출 분석 +GET /api/analytics/receivables # 미수금 분석 +``` \ No newline at end of file diff --git a/specs/erp-analysis/99-gap-analysis.md b/specs/erp-analysis/99-gap-analysis.md new file mode 100644 index 0000000..c068c27 --- /dev/null +++ b/specs/erp-analysis/99-gap-analysis.md @@ -0,0 +1,1048 @@ +# SAM ERP API 개발 명세서 + +> 기준 문서: SAM_ERP_Storyboard_D0.8_251216 +> 작성일: 2025-12-17 +> 상태: 개발 준비 완료 + +--- + +## 개발 범위 요약 + +| 구분 | 항목수 | 작업 | +|------|--------|------| +| 기존 API 활용 | 12개 | 프론트엔드 연동만 진행 | +| 확장 개발 | 6개 | 기존 구조 활용, API 추가 | +| 신규 개발 | 8개 | 테이블 + API 신규 생성 | + +--- + +# Part 1: 기존 API (프론트엔드 연동) + +> 아래 영역은 API 개발 완료. 프론트엔드 연동 시 참고. + +| 영역 | 기존 API | 스토리보드 참조 | +|------|----------|-----------------| +| 사원관리 | `/v1/employees/*` | 슬라이드 28-35 | +| 부서관리 | `/v1/departments/*` | 슬라이드 36-38 | +| 근태관리 | `/v1/attendances/*` | 슬라이드 23-27, 39-42 | +| 게시판 | `/v1/boards/*` | - | +| 권한관리 | `/v1/roles/*`, `/v1/permissions/*` | 슬라이드 96 | +| 테넌트 | `/v1/tenants/*` | 슬라이드 14-22 | +| 메뉴 | `/v1/menus/*` | 슬라이드 8-13 | +| 거래처 | `/v1/clients/*` | 슬라이드 60-67 | +| 공통코드 | `/v1/settings/common/*` | 슬라이드 93-95 | +| 파일 | `/v1/files/*` | - | +| 설정 | `/v1/settings/*` | - | +| 프로필 | `/v1/users/me/*`, `/v1/profiles/*` | - | + +--- + +# Part 2: 확장 개발 (기존 구조 활용) + +## 2.1 휴가 관리 + +### 스펙 +- 스토리보드: 슬라이드 43-46, 100 +- 의존성: `attendances` 테이블 참조 + +### 테이블: `leaves` +```sql +CREATE TABLE leaves ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + leave_type VARCHAR(20) NOT NULL COMMENT '연차/반차/병가/경조사/출산/육아', + start_date DATE NOT NULL, + end_date DATE NOT NULL, + days DECIMAL(3,1) NOT NULL COMMENT '사용일수', + reason TEXT, + status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/approved/rejected/cancelled', + approved_by BIGINT NULL, + approved_at TIMESTAMP NULL, + reject_reason TEXT NULL, + created_by BIGINT, + updated_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant_user (tenant_id, user_id), + INDEX idx_status (status), + INDEX idx_dates (start_date, end_date) +); +``` + +### 테이블: `leave_balances` +```sql +CREATE TABLE leave_balances ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + year INT NOT NULL, + total_days DECIMAL(4,1) NOT NULL DEFAULT 15 COMMENT '연간 부여일수', + used_days DECIMAL(4,1) NOT NULL DEFAULT 0 COMMENT '사용일수', + remaining_days DECIMAL(4,1) GENERATED ALWAYS AS (total_days - used_days) STORED, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_user_year (tenant_id, user_id, year) +); +``` + +### API 엔드포인트 +``` +GET /v1/leaves # 목록 (필터: status, user_id, date_range) +POST /v1/leaves # 신청 +GET /v1/leaves/{id} # 상세 +PATCH /v1/leaves/{id} # 수정 (pending 상태만) +DELETE /v1/leaves/{id} # 취소 (pending 상태만) +POST /v1/leaves/{id}/approve # 승인 +POST /v1/leaves/{id}/reject # 반려 (reject_reason 필수) + +GET /v1/leaves/balance # 내 잔여휴가 +GET /v1/leaves/balance/{userId} # 특정 사용자 잔여휴가 + +GET /v1/settings/leave # 휴가 설정 +PUT /v1/settings/leave # 휴가 설정 수정 +``` + +### Request/Response 예시 +```json +// POST /v1/leaves +{ + "leave_type": "annual", + "start_date": "2025-01-20", + "end_date": "2025-01-21", + "days": 2, + "reason": "개인 사유" +} + +// GET /v1/leaves/balance +{ + "year": 2025, + "total_days": 15, + "used_days": 3, + "remaining_days": 12 +} +``` + +--- + +## 2.2 근무/출퇴근 설정 + +### 스펙 +- 스토리보드: 슬라이드 97-99 +- 의존성: `tenant_field_settings` 활용 가능 + +### 테이블: `work_settings` +```sql +CREATE TABLE work_settings ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL UNIQUE, + work_type VARCHAR(20) DEFAULT 'fixed' COMMENT 'fixed/flexible/custom', + standard_hours INT DEFAULT 40 COMMENT '주당 소정근로시간', + overtime_hours INT DEFAULT 12 COMMENT '주당 연장근로시간', + overtime_limit INT DEFAULT 52 COMMENT '연장근로한도', + work_days JSON COMMENT '["mon","tue","wed","thu","fri"]', + start_time TIME DEFAULT '09:00:00', + end_time TIME DEFAULT '18:00:00', + break_minutes INT DEFAULT 60, + break_start TIME DEFAULT '12:00:00', + break_end TIME DEFAULT '13:00:00', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +``` + +### 테이블: `attendance_settings` +```sql +CREATE TABLE attendance_settings ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL UNIQUE, + use_gps BOOLEAN DEFAULT FALSE, + allowed_radius INT DEFAULT 100 COMMENT '허용반경(m)', + hq_address VARCHAR(255), + hq_latitude DECIMAL(10,8), + hq_longitude DECIMAL(11,8), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +``` + +### 테이블: `sites` (현장) +```sql +CREATE TABLE sites ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + name VARCHAR(100) NOT NULL, + address VARCHAR(255), + latitude DECIMAL(10,8), + longitude DECIMAL(11,8), + is_active BOOLEAN DEFAULT TRUE, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant (tenant_id) +); +``` + +### API 엔드포인트 +``` +GET /v1/settings/work # 근무 설정 조회 +PUT /v1/settings/work # 근무 설정 수정 + +GET /v1/settings/attendance # 출퇴근 설정 조회 +PUT /v1/settings/attendance # 출퇴근 설정 수정 + +GET /v1/sites # 현장 목록 +POST /v1/sites # 현장 등록 +GET /v1/sites/{id} # 현장 상세 +PUT /v1/sites/{id} # 현장 수정 +DELETE /v1/sites/{id} # 현장 삭제 +``` + +--- + +## 2.3 카드/계좌 관리 + +### 스펙 +- 스토리보드: 슬라이드 101-104 +- 보안: 카드번호/비밀번호 암호화 필수 + +### 테이블: `cards` +```sql +CREATE TABLE cards ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + card_company VARCHAR(50) NOT NULL COMMENT '카드사', + card_number_encrypted TEXT NOT NULL COMMENT '암호화된 카드번호', + card_number_last4 VARCHAR(4) NOT NULL COMMENT '끝 4자리', + expiry_date VARCHAR(5) NOT NULL COMMENT 'MM/YY', + card_password_encrypted TEXT COMMENT '암호화된 비밀번호 앞2자리', + card_name VARCHAR(100) NOT NULL, + status VARCHAR(20) DEFAULT 'active' COMMENT 'active/inactive', + assigned_user_id BIGINT NULL, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant (tenant_id), + INDEX idx_status (status) +); +``` + +### 테이블: `bank_accounts` +```sql +CREATE TABLE bank_accounts ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + bank_code VARCHAR(10) NOT NULL, + bank_name VARCHAR(50) NOT NULL, + account_number VARCHAR(30) NOT NULL, + account_holder VARCHAR(50) NOT NULL, + account_name VARCHAR(100) NOT NULL COMMENT '계좌별칭', + status VARCHAR(20) DEFAULT 'active' COMMENT 'active/inactive', + assigned_user_id BIGINT NULL, + is_primary BOOLEAN DEFAULT FALSE COMMENT '대표계좌', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant (tenant_id), + INDEX idx_status (status) +); +``` + +### API 엔드포인트 +``` +GET /v1/cards # 카드 목록 (필터: status) +POST /v1/cards # 카드 등록 +GET /v1/cards/{id} # 카드 상세 +PUT /v1/cards/{id} # 카드 수정 +DELETE /v1/cards/{id} # 카드 삭제 +PATCH /v1/cards/{id}/toggle # 사용/정지 토글 + +GET /v1/bank-accounts # 계좌 목록 (필터: status) +POST /v1/bank-accounts # 계좌 등록 +GET /v1/bank-accounts/{id} # 계좌 상세 +PUT /v1/bank-accounts/{id} # 계좌 수정 +DELETE /v1/bank-accounts/{id} # 계좌 삭제 +PATCH /v1/bank-accounts/{id}/toggle # 사용/정지 토글 +PATCH /v1/bank-accounts/{id}/set-primary # 대표계좌 설정 +``` + +--- + +## 2.4 입금/출금 관리 + +### 스펙 +- 스토리보드: 슬라이드 68-77 +- 의존성: `clients`, `bank_accounts` 참조 + +### 테이블: `deposits` (입금) +```sql +CREATE TABLE deposits ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + deposit_date DATE NOT NULL, + client_id BIGINT NULL, + client_name VARCHAR(100) COMMENT '비회원 거래처명', + bank_account_id BIGINT NULL, + amount DECIMAL(15,2) NOT NULL, + payment_method VARCHAR(20) NOT NULL COMMENT 'cash/transfer/card/check', + account_code VARCHAR(20) COMMENT '계정과목', + description TEXT, + reference_type VARCHAR(50) NULL COMMENT 'sales/receivable/etc', + reference_id BIGINT NULL, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant_date (tenant_id, deposit_date), + INDEX idx_client (client_id) +); +``` + +### 테이블: `withdrawals` (출금) +```sql +CREATE TABLE withdrawals ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + withdrawal_date DATE NOT NULL, + client_id BIGINT NULL, + client_name VARCHAR(100), + bank_account_id BIGINT NULL, + amount DECIMAL(15,2) NOT NULL, + payment_method VARCHAR(20) NOT NULL COMMENT 'cash/transfer/card/check', + account_code VARCHAR(20) COMMENT '계정과목', + description TEXT, + reference_type VARCHAR(50) NULL COMMENT 'purchase/payable/payroll/etc', + reference_id BIGINT NULL, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant_date (tenant_id, withdrawal_date), + INDEX idx_client (client_id) +); +``` + +### API 엔드포인트 +``` +GET /v1/deposits # 입금 목록 (필터: date_range, client_id, payment_method) +POST /v1/deposits # 입금 등록 +GET /v1/deposits/{id} # 입금 상세 +PUT /v1/deposits/{id} # 입금 수정 +DELETE /v1/deposits/{id} # 입금 삭제 +GET /v1/deposits/summary # 입금 요약 (기간별 합계) + +GET /v1/withdrawals # 출금 목록 +POST /v1/withdrawals # 출금 등록 +GET /v1/withdrawals/{id} # 출금 상세 +PUT /v1/withdrawals/{id} # 출금 수정 +DELETE /v1/withdrawals/{id} # 출금 삭제 +GET /v1/withdrawals/summary # 출금 요약 +``` + +--- + +## 2.5 매출/매입 관리 + +### 스펙 +- 스토리보드: 슬라이드 78-87 +- 의존성: `clients`, `deposits`, `withdrawals` 참조 + +### 테이블: `sales` (매출) +```sql +CREATE TABLE sales ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + sale_number VARCHAR(30) NOT NULL COMMENT '매출번호', + sale_date DATE NOT NULL, + client_id BIGINT NOT NULL, + supply_amount DECIMAL(15,2) NOT NULL COMMENT '공급가액', + tax_amount DECIMAL(15,2) NOT NULL COMMENT '세액', + total_amount DECIMAL(15,2) NOT NULL COMMENT '합계', + description TEXT, + status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/confirmed/invoiced', + tax_invoice_id BIGINT NULL COMMENT '세금계산서 ID', + deposit_id BIGINT NULL COMMENT '입금 연결', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_number (tenant_id, sale_number), + INDEX idx_tenant_date (tenant_id, sale_date), + INDEX idx_client (client_id) +); +``` + +### 테이블: `purchases` (매입) +```sql +CREATE TABLE purchases ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + purchase_number VARCHAR(30) NOT NULL, + purchase_date DATE NOT NULL, + client_id BIGINT NOT NULL, + supply_amount DECIMAL(15,2) NOT NULL, + tax_amount DECIMAL(15,2) NOT NULL, + total_amount DECIMAL(15,2) NOT NULL, + description TEXT, + status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/confirmed', + withdrawal_id BIGINT NULL COMMENT '출금 연결', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_number (tenant_id, purchase_number), + INDEX idx_tenant_date (tenant_id, purchase_date), + INDEX idx_client (client_id) +); +``` + +### API 엔드포인트 +``` +GET /v1/sales # 매출 목록 +POST /v1/sales # 매출 등록 +GET /v1/sales/{id} # 매출 상세 +PUT /v1/sales/{id} # 매출 수정 +DELETE /v1/sales/{id} # 매출 삭제 +POST /v1/sales/{id}/confirm # 매출 확정 +POST /v1/sales/{id}/tax-invoice # 세금계산서 발행 (바로빌 연동) + +GET /v1/purchases # 매입 목록 +POST /v1/purchases # 매입 등록 +GET /v1/purchases/{id} # 매입 상세 +PUT /v1/purchases/{id} # 매입 수정 +DELETE /v1/purchases/{id} # 매입 삭제 +POST /v1/purchases/{id}/confirm # 매입 확정 +``` + +--- + +## 2.6 보고서 + +### 스펙 +- 스토리보드: 슬라이드 106-109 +- 의존성: `deposits`, `withdrawals`, `sales`, `purchases` 집계 + +### API 엔드포인트 +``` +GET /v1/reports/daily # 일일 일보 + Query: date (기준일) + Response: { + previous_balance, daily_deposit, daily_withdrawal, current_balance, + details: [{ type, client_name, account_code, deposit_amount, withdrawal_amount, description }] + } + +GET /v1/reports/daily/export # 일일 일보 엑셀 다운로드 + Query: date + Response: Excel file + +GET /v1/reports/expense-estimate # 지출 예상 내역서 + Query: year_month + Response: { + total_estimate, account_balance, expected_balance, + items: [{ expected_date, item_name, amount, client_name, account_name }], + monthly_summary: [{ month, total }] + } + +GET /v1/reports/expense-estimate/export # 엑셀 다운로드 + Query: year_month + Response: Excel file +``` + +--- + +# Part 3: 신규 개발 + +## 3.1 전자결재 모듈 + +### 스펙 +- 스토리보드: 슬라이드 47-59 +- 핵심 기능: 기안/결재/반려/참조 + +### 테이블: `approval_forms` (결재 양식) +```sql +CREATE TABLE approval_forms ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + name VARCHAR(100) NOT NULL COMMENT '양식명', + code VARCHAR(50) NOT NULL COMMENT '양식코드', + category VARCHAR(50) COMMENT '분류', + template JSON NOT NULL COMMENT '양식 템플릿 (필드 정의)', + is_active BOOLEAN DEFAULT TRUE, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_code (tenant_id, code), + INDEX idx_tenant (tenant_id) +); +``` + +### 테이블: `approval_lines` (결재선 템플릿) +```sql +CREATE TABLE approval_lines ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + name VARCHAR(100) NOT NULL, + steps JSON NOT NULL COMMENT '[{order, type: approval/agreement/reference, user_id, position}]', + is_default BOOLEAN DEFAULT FALSE, + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant (tenant_id) +); +``` + +### 테이블: `approvals` (결재 문서) +```sql +CREATE TABLE approvals ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + document_number VARCHAR(50) NOT NULL, + form_id BIGINT NOT NULL, + title VARCHAR(200) NOT NULL, + content JSON NOT NULL COMMENT '양식 데이터', + status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/pending/approved/rejected/cancelled', + drafter_id BIGINT NOT NULL COMMENT '기안자', + drafted_at TIMESTAMP NULL, + completed_at TIMESTAMP NULL, + current_step INT DEFAULT 0, + attachments JSON COMMENT '첨부파일 IDs', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_number (tenant_id, document_number), + INDEX idx_tenant_status (tenant_id, status), + INDEX idx_drafter (drafter_id) +); +``` + +### 테이블: `approval_steps` (결재 단계) +```sql +CREATE TABLE approval_steps ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + approval_id BIGINT NOT NULL, + step_order INT NOT NULL, + step_type VARCHAR(20) NOT NULL COMMENT 'approval/agreement/reference', + approver_id BIGINT NOT NULL, + status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/approved/rejected/skipped', + comment TEXT, + acted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_approval (approval_id), + INDEX idx_approver_status (approver_id, status) +); +``` + +### API 엔드포인트 +``` +# 결재 문서 +GET /v1/approvals/drafts # 기안함 (내가 기안한 문서) +GET /v1/approvals/inbox # 결재함 (내 결재 대기) +GET /v1/approvals/completed # 결재 완료함 +GET /v1/approvals/reference # 참조함 +POST /v1/approvals # 문서 기안 +GET /v1/approvals/{id} # 문서 상세 +PUT /v1/approvals/{id} # 문서 수정 (draft만) +DELETE /v1/approvals/{id} # 문서 삭제/회수 +POST /v1/approvals/{id}/submit # 결재 상신 +POST /v1/approvals/{id}/approve # 승인 (comment 선택) +POST /v1/approvals/{id}/reject # 반려 (comment 필수) + +# 결재선 템플릿 +GET /v1/approval-lines # 결재선 목록 +POST /v1/approval-lines # 결재선 생성 +PUT /v1/approval-lines/{id} # 결재선 수정 +DELETE /v1/approval-lines/{id} # 결재선 삭제 + +# 결재 양식 +GET /v1/approval-forms # 양식 목록 +POST /v1/approval-forms # 양식 생성 +GET /v1/approval-forms/{id} # 양식 상세 +PUT /v1/approval-forms/{id} # 양식 수정 +DELETE /v1/approval-forms/{id} # 양식 삭제 +``` + +### 상태 전이 +``` +draft → pending (상신) → approved (전체 승인) + → rejected (반려) +pending → cancelled (회수, 기안자만) +rejected → draft (재기안 시 새 문서 생성) +``` + +--- + +## 3.2 급여 관리 + +### 스펙 +- 스토리보드: 미상세 (회계관리 연계) +- 의존성: `employees`, `attendances`, `leaves` + +### 테이블: `payrolls` +```sql +CREATE TABLE payrolls ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + pay_year INT NOT NULL, + pay_month INT NOT NULL, + base_salary DECIMAL(15,2) NOT NULL COMMENT '기본급', + overtime_pay DECIMAL(15,2) DEFAULT 0 COMMENT '연장근로수당', + bonus DECIMAL(15,2) DEFAULT 0 COMMENT '상여금', + allowances JSON COMMENT '수당 상세 [{name, amount}]', + gross_salary DECIMAL(15,2) NOT NULL COMMENT '총지급액', + income_tax DECIMAL(15,2) DEFAULT 0 COMMENT '소득세', + resident_tax DECIMAL(15,2) DEFAULT 0 COMMENT '주민세', + health_insurance DECIMAL(15,2) DEFAULT 0 COMMENT '건강보험', + pension DECIMAL(15,2) DEFAULT 0 COMMENT '국민연금', + employment_insurance DECIMAL(15,2) DEFAULT 0 COMMENT '고용보험', + deductions JSON COMMENT '공제 상세', + total_deductions DECIMAL(15,2) NOT NULL COMMENT '총공제액', + net_salary DECIMAL(15,2) NOT NULL COMMENT '실수령액', + status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/confirmed/paid', + paid_at TIMESTAMP NULL, + withdrawal_id BIGINT NULL COMMENT '출금 연결', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_tenant_user_month (tenant_id, user_id, pay_year, pay_month), + INDEX idx_tenant_month (tenant_id, pay_year, pay_month) +); +``` + +### API 엔드포인트 +``` +GET /v1/payrolls # 급여 목록 (필터: year, month, user_id, status) +POST /v1/payrolls # 급여 등록 +GET /v1/payrolls/{id} # 급여 상세 +PUT /v1/payrolls/{id} # 급여 수정 (draft만) +DELETE /v1/payrolls/{id} # 급여 삭제 (draft만) +POST /v1/payrolls/{id}/confirm # 급여 확정 +POST /v1/payrolls/{id}/pay # 지급 처리 (출금 연결) +GET /v1/payrolls/{id}/payslip # 급여명세서 조회 +GET /v1/payrolls/{id}/payslip/pdf # 급여명세서 PDF + +POST /v1/payrolls/calculate # 급여 일괄 계산 + Body: { year, month, user_ids?: [] } // user_ids 없으면 전체 + +GET /v1/settings/payroll # 급여 설정 (세율, 보험료율 등) +PUT /v1/settings/payroll # 급여 설정 수정 +``` + +--- + +## 3.3 대시보드 + +### 스펙 +- 스토리보드: 미상세 (진입점 화면) +- 의존성: 전 모듈 집계 + +### API 엔드포인트 +``` +GET /v1/dashboard/summary + Response: { + today: { date, attendances_count, leaves_count, approvals_pending }, + finance: { monthly_deposit, monthly_withdrawal, balance }, + sales: { monthly_sales, monthly_purchases }, + tasks: { pending_approvals, pending_leaves } + } + +GET /v1/dashboard/charts + Query: period (week/month/quarter) + Response: { + deposit_trend: [{ date, amount }], + withdrawal_trend: [{ date, amount }], + sales_by_client: [{ client_name, amount }] + } + +GET /v1/dashboard/notifications + Query: limit (default 10) + Response: { + items: [{ id, type, message, is_read, created_at }] + } + +GET /v1/dashboard/approvals + Response: { + items: [{ id, title, drafter_name, status, created_at }] + } +``` + +--- + +## 3.4 AI 리포트 + +### 스펙 +- 스토리보드: 슬라이드 113 +- 의존성: 전 모듈 데이터 분석 + +### 테이블: `ai_reports` +```sql +CREATE TABLE ai_reports ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + report_date DATE NOT NULL, + report_type VARCHAR(50) NOT NULL COMMENT 'daily/weekly/monthly', + content JSON NOT NULL COMMENT '리포트 내용', + summary TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_tenant_date (tenant_id, report_date) +); +``` + +### API 엔드포인트 +``` +GET /v1/reports/ai # AI 리포트 목록 +POST /v1/reports/ai/generate # AI 리포트 생성 + Body: { report_type: 'daily'|'weekly'|'monthly', target_date? } +GET /v1/reports/ai/{id} # AI 리포트 상세 +DELETE /v1/reports/ai/{id} # AI 리포트 삭제 +``` + +### AI 리포트 출력 형식 +```json +{ + "report": [ + { "area": "지출분석", "status": "warning", "message": "...", "detail": "..." }, + { "area": "미수금", "status": "caution", "message": "...", "detail": "..." } + ], + "summary": "전체 요약 메시지" +} +``` +- status: `warning`(빨강), `caution`(주황), `positive`(녹색), `normal`(파랑) + +--- + +## 3.5 가지급금 관리 + +### 스펙 +- 스토리보드: 슬라이드 110-112 +- 인정이자율: 4.6% (연도별 변동) + +### 테이블: `loans` (가지급금) +```sql +CREATE TABLE loans ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + user_id BIGINT NOT NULL COMMENT '가지급금 수령자', + loan_date DATE NOT NULL COMMENT '지급일', + amount DECIMAL(15,2) NOT NULL COMMENT '가지급금액', + purpose TEXT COMMENT '사용목적', + settlement_date DATE NULL COMMENT '정산일', + settlement_amount DECIMAL(15,2) NULL COMMENT '정산금액', + status VARCHAR(20) DEFAULT 'outstanding' COMMENT 'outstanding/settled/partial', + withdrawal_id BIGINT NULL COMMENT '출금 연결', + created_by BIGINT, + deleted_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant_user (tenant_id, user_id), + INDEX idx_status (status) +); +``` + +### API 엔드포인트 +``` +GET /v1/loans # 가지급금 목록 +POST /v1/loans # 가지급금 등록 +GET /v1/loans/{id} # 가지급금 상세 +PUT /v1/loans/{id} # 가지급금 수정 +DELETE /v1/loans/{id} # 가지급금 삭제 +POST /v1/loans/{id}/settle # 정산 처리 + Body: { settlement_date, settlement_amount } + +POST /v1/loans/calculate-interest # 인정이자 계산 + Body: { year, user_id? } + Response: { + balance, interest_rate, recognized_interest, + corporate_tax, income_tax, local_tax, total_tax + } + +GET /v1/reports/loan-interest # 인정이자 리포트 + Query: year +``` + +### 계산 공식 +``` +경과일수 = 정산일 - 지급일 +일이자율 = 연이자율 / 365 +인정이자 = 가지급금 × 일이자율 × 경과일수 +법인세추가 = 인정이자 × 0.19 +소득세추가 = 인정이자 × 0.35 +지방소득세 = 소득세추가 × 0.10 +``` + +--- + +## 3.6 구독/결제 관리 + +### 스펙 +- 스토리보드: 미상세 (SaaS 과금) +- 별도 결제 시스템 연동 필요 + +### 테이블: `subscriptions` +```sql +CREATE TABLE subscriptions ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL UNIQUE, + plan_code VARCHAR(50) NOT NULL COMMENT 'basic/standard/premium', + status VARCHAR(20) DEFAULT 'active' COMMENT 'trial/active/expired/cancelled', + started_at DATE NOT NULL, + expires_at DATE NOT NULL, + user_limit INT DEFAULT 5, + storage_limit_mb INT DEFAULT 1024, + auto_renew BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +); +``` + +### 테이블: `payments` +```sql +CREATE TABLE payments ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + subscription_id BIGINT NOT NULL, + amount DECIMAL(10,2) NOT NULL, + payment_method VARCHAR(20) COMMENT 'card/transfer', + status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/completed/failed/refunded', + paid_at TIMESTAMP NULL, + pg_transaction_id VARCHAR(100), + receipt_url VARCHAR(500), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_tenant (tenant_id), + INDEX idx_status (status) +); +``` + +### API 엔드포인트 +``` +GET /v1/subscriptions # 구독 정보 +POST /v1/subscriptions # 구독 신청/변경 +PUT /v1/subscriptions/{id} # 구독 수정 +DELETE /v1/subscriptions/{id} # 구독 해지 + +GET /v1/payments # 결제 내역 +GET /v1/payments/{id} # 결제 상세 +POST /v1/payments/retry/{id} # 결제 재시도 +``` + +--- + +## 3.7 고객센터 + +### 스펙 +- 스토리보드: 미상세 (CS 기능) + +### 테이블: `support_tickets` +```sql +CREATE TABLE support_tickets ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NULL COMMENT 'NULL이면 비회원 문의', + user_id BIGINT NULL, + ticket_number VARCHAR(20) NOT NULL, + category VARCHAR(50) NOT NULL COMMENT '문의유형', + title VARCHAR(200) NOT NULL, + content TEXT NOT NULL, + status VARCHAR(20) DEFAULT 'open' COMMENT 'open/in_progress/resolved/closed', + priority VARCHAR(20) DEFAULT 'normal' COMMENT 'low/normal/high/urgent', + assigned_to BIGINT NULL COMMENT '담당자', + resolved_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uk_ticket_number (ticket_number), + INDEX idx_status (status) +); +``` + +### 테이블: `support_ticket_replies` +```sql +CREATE TABLE support_ticket_replies ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + ticket_id BIGINT NOT NULL, + user_id BIGINT NULL COMMENT 'NULL이면 관리자 답변', + is_staff BOOLEAN DEFAULT FALSE, + content TEXT NOT NULL, + attachments JSON, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_ticket (ticket_id) +); +``` + +### 테이블: `faqs` +```sql +CREATE TABLE faqs ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + category VARCHAR(50) NOT NULL, + question VARCHAR(500) NOT NULL, + answer TEXT NOT NULL, + sort_order INT DEFAULT 0, + is_active BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_category (category) +); +``` + +### API 엔드포인트 +``` +GET /v1/support/tickets # 문의 목록 +POST /v1/support/tickets # 문의 등록 +GET /v1/support/tickets/{id} # 문의 상세 +PUT /v1/support/tickets/{id} # 문의 수정 +POST /v1/support/tickets/{id}/reply # 답변/추가문의 + +GET /v1/support/faq # FAQ 목록 (필터: category) +GET /v1/support/faq/{id} # FAQ 상세 +``` + +--- + +## 3.8 바로빌 연동 + +### 스펙 +- 스토리보드: 슬라이드 63, 78 +- 외부 API: 바로빌 (사업자조회, 세금계산서) + +### 테이블: `tax_invoices` +```sql +CREATE TABLE tax_invoices ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + tenant_id BIGINT NOT NULL, + invoice_type VARCHAR(20) NOT NULL COMMENT 'sales/purchase', + invoice_number VARCHAR(50) NOT NULL COMMENT '승인번호', + issue_date DATE NOT NULL, + supplier_business_no VARCHAR(20) NOT NULL, + supplier_name VARCHAR(100) NOT NULL, + buyer_business_no VARCHAR(20) NOT NULL, + buyer_name VARCHAR(100) NOT NULL, + supply_amount DECIMAL(15,2) NOT NULL, + tax_amount DECIMAL(15,2) NOT NULL, + total_amount DECIMAL(15,2) NOT NULL, + status VARCHAR(20) DEFAULT 'issued' COMMENT 'issued/cancelled', + barobill_id VARCHAR(100) COMMENT '바로빌 문서 ID', + reference_type VARCHAR(50) NULL COMMENT 'sales/purchases', + reference_id BIGINT NULL, + issued_at TIMESTAMP NULL, + cancelled_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_tenant_date (tenant_id, issue_date), + INDEX idx_invoice_number (invoice_number) +); +``` + +### API 엔드포인트 +``` +POST /v1/external/barobill/verify-business + Body: { business_number } + Response: { valid, company_name, ceo_name, business_type, ... } + +POST /v1/external/barobill/tax-invoice + Body: { invoice_type, supplier, buyer, items, ... } + Response: { id, invoice_number, barobill_id } + +GET /v1/external/barobill/tax-invoice/{id} + Response: 세금계산서 상세 + +POST /v1/external/barobill/tax-invoice/{id}/cancel + Response: 취소 결과 + +GET /v1/tax-invoices # 세금계산서 목록 (내부 조회용) +GET /v1/tax-invoices/{id} # 세금계산서 상세 +``` + +--- + +# Part 4: 기획 확인 필요 + +> 아래 항목은 API 구현 전 비즈니스 로직 확정 필요 + +## 4.1 상태 전이 조건 + +| 대상 | 확인 항목 | 기본값 (확정 전) | +|------|----------|------------------| +| 테넌트 | 신청→승인→만료→해지 전이 조건 | 수동 전환 | +| 사원 | 휴직→복직/퇴사 전이 조건 | 수동 전환 | +| 결재 | 반려 후 재기안 프로세스 | 새 문서 생성 | +| 미수금 | 연체 판정 기준일 | 30일 | +| 악성채권 | 악성채권 판정 조건 | 90일 + 수동 | + +## 4.2 모듈 간 연동 + +| 연동 | 확인 항목 | 기본값 | +|------|----------|--------| +| 전자결재→회계 | 지출결의서 승인 시 출금 자동 생성 | 수동 연결 | +| 휴가신청→결재 | 휴가가 결재 문서로 생성되는지 | 별도 관리 | +| 휴가승인→근태 | 승인 휴가가 근태 자동 반영 | 자동 반영 | +| GPS출퇴근→근태 | GPS 기록이 근태 자동 반영 | 자동 반영 | +| 급여→출금 | 급여 확정 시 출금 자동 생성 | 수동 연결 | + +## 4.3 외부 연동 + +| 항목 | 확인 필요 | +|------|----------| +| 바로빌 API 비용 | 호출당 비용, 월 한도 | +| 연동 은행 범위 | 지원 은행 목록 | +| 연동 실패 처리 | Retry 정책, fallback | + +## 4.4 MES 메뉴 + +| 메뉴 | 확인 필요 | +|------|----------| +| 영업관리 | 기존 Quote API 활용 여부 | +| 판매관리 | 상세 요구사항 | +| 구매관리 | 상세 요구사항 | + +## 4.5 어음관리 + +| 항목 | 확인 필요 | +|------|----------| +| 기능 필요성 | 사용 여부 | +| 상세 기능 | 등록/만기일/추심/부도 | + +--- + +# 개발 순서 + +``` +Phase 1: 확장 개발 (1-2주) +├── 2.1 휴가 관리 +├── 2.2 근무/출퇴근 설정 +├── 2.3 카드/계좌 관리 +├── 2.4 입금/출금 관리 +├── 2.5 매출/매입 관리 +└── 2.6 보고서 + +Phase 2: 핵심 신규 (2-4주) +├── 3.1 전자결재 모듈 ★ +├── 3.2 급여 관리 +└── 3.3 대시보드 + +Phase 3: 추가 기능 (4-6주) +├── 3.4 AI 리포트 +├── 3.5 가지급금 관리 +└── 3.8 바로빌 연동 + +Phase 4: SaaS 기능 (별도) +├── 3.6 구독/결제 관리 +└── 3.7 고객센터 +``` + +--- + +# 참고 문서 + +| 문서 | 경로 | +|------|------| +| DB 스키마 | `docs/specs/database-schema.md` | +| 시스템 아키텍처 | `docs/architecture/system-overview.md` | +| HR API 분석 | `docs/features/hr/hr-api-analysis.md` | +| 기존 API 라우트 | `api/routes/api.php` | +| 스토리보드 상세 | `docs/specs/erp-analysis/01-common.md` ~ `08-reports.md` | \ No newline at end of file