From d9d2bbdacf084326377542e135308b585b457942 Mon Sep 17 00:00:00 2001 From: hskwon Date: Tue, 9 Dec 2025 20:27:54 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20API=20=EB=AC=B8=EC=84=9C=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/INDEX.md 업데이트 - API 테스트 플로우 파일 추가 - LOGICAL_RELATIONSHIPS.md 업데이트 --- LOGICAL_RELATIONSHIPS.md | 10 +- docs/INDEX.md | 57 +++--- docs/flow-tests/attendance-api-crud.json | 227 +++++++++++++++++++++++ docs/flow-tests/department-tree-api.json | 87 +++++++++ docs/flow-tests/employee-api-crud.json | 188 +++++++++++++++++++ 5 files changed, 542 insertions(+), 27 deletions(-) create mode 100644 docs/flow-tests/attendance-api-crud.json create mode 100644 docs/flow-tests/department-tree-api.json create mode 100644 docs/flow-tests/employee-api-crud.json diff --git a/LOGICAL_RELATIONSHIPS.md b/LOGICAL_RELATIONSHIPS.md index 4256f30..28f754b 100644 --- a/LOGICAL_RELATIONSHIPS.md +++ b/LOGICAL_RELATIONSHIPS.md @@ -1,6 +1,6 @@ # 논리적 데이터베이스 관계 문서 -> **자동 생성**: 2025-12-08 20:14:33 +> **자동 생성**: 2025-12-09 11:02:18 > **소스**: Eloquent 모델 관계 분석 ## 📊 모델별 관계 현황 @@ -364,6 +364,13 @@ ### quote_revisions - **quote()**: belongsTo → `quotes` - **reviser()**: belongsTo → `users` +### attendances +**모델**: `App\Models\Tenants\Attendance` + +- **user()**: belongsTo → `users` +- **creator()**: belongsTo → `users` +- **updater()**: belongsTo → `users` + ### departments **모델**: `App\Models\Tenants\Department` @@ -438,4 +445,5 @@ ### tenant_user_profiles - **user()**: belongsTo → `users` - **department()**: belongsTo → `departments` +- **manager()**: belongsTo → `users` diff --git a/docs/INDEX.md b/docs/INDEX.md index 2b59058..948fb65 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -1,12 +1,13 @@ # API 프로젝트 문서 -> 📌 **SAM API 전용 문서 허브** +> API 구성 및 설정에 관한 문서만 포함합니다. +> 프로젝트 관련 문서는 `/SAM/docs/`를 참조하세요. --- ## 📋 Swagger 문서 -API 엔드포인트별 Swagger 문서입니다. +API 엔드포인트별 Swagger 스펙 문서입니다. - **[Audit Log API](swagger/SWAGGER_AUDIT.md)** - 감사 로그 API 스펙 - **[Product API](swagger/SWAGGER_PHASE3_1_PRODUCT.md)** - 제품 관리 API @@ -15,35 +16,39 @@ ## 📋 Swagger 문서 --- -## 🔍 분석 문서 - -Item 관리 시스템 분석 문서입니다. - -- **[Item DB 분석 v3 (최신)](analysis/SAM_Item_DB_API_Analysis_v3_FINAL.md)** - Item DB 최종 분석 -- **[Item DB 분석 v2](analysis/SAM_Item_DB_API_Analysis_v2.md)** - Item DB 분석 v2 -- **[Item 관리 모델링](analysis/SAM_Item_Management_DB_Modeling_Analysis.md)** - Item DB 모델링 분석 - ---- - -## 🔗 관련 문서 - -- **[API Rules](../docs/reference/api-rules.md)** - API 개발 규칙 -- **[Swagger Guide](../docs/guides/swagger-guide.md)** - Swagger 작성 가이드 -- **[Database Schema](../docs/specs/database-schema.md)** - 전체 DB 스키마 - ---- - ## 🧪 API Flow 테스트 API Flow Tester용 테스트 시나리오입니다. -- **[ItemField is_active 테스트](api-flows/item-fields-is-active-test.json)** - item_fields is_active 컬럼 검증 +### api-flows/ +- **[item-fields-is-active-test.json](api-flows/item-fields-is-active-test.json)** - item_fields is_active 검증 +- **[pricing-crud-flow.json](api-flows/pricing-crud-flow.json)** - 단가 CRUD 플로우 + +### flow-tests/ +- **[attendance-api-crud.json](flow-tests/attendance-api-crud.json)** - 근태 API CRUD +- **[department-tree-api.json](flow-tests/department-tree-api.json)** - 부서 트리 API +- **[employee-api-crud.json](flow-tests/employee-api-crud.json)** - 직원 API CRUD --- -## 📝 문서 추가 +## 🔗 프로젝트 문서 (SAM/docs로 이동됨) -새로운 API 문서는 다음 디렉토리에 추가: -- Swagger 문서 → `swagger/` -- 분석 문서 → `analysis/` -- API Flow 테스트 → `api-flows/` +다음 문서들은 `/SAM/docs/`로 이동되었습니다: + +| 이전 위치 | 새 위치 | 설명 | +|-----------|---------|------| +| `analysis/` | `docs/data/analysis/` | Item DB 분석 문서 | +| `front/` | `docs/front/` | 프론트엔드 요청 문서 | +| `specs/` | `docs/specs/` | 기능 스펙 문서 | + +--- + +## 📝 문서 추가 가이드 + +| 문서 유형 | 저장 위치 | +|-----------|-----------| +| Swagger 스펙 | `api/docs/swagger/` | +| API Flow 테스트 | `api/docs/api-flows/` 또는 `flow-tests/` | +| 프로젝트 분석 | `SAM/docs/data/` | +| 기능 스펙 | `SAM/docs/specs/` | +| 프론트 요청 | `SAM/docs/front/` | diff --git a/docs/flow-tests/attendance-api-crud.json b/docs/flow-tests/attendance-api-crud.json new file mode 100644 index 0000000..4ebbc9d --- /dev/null +++ b/docs/flow-tests/attendance-api-crud.json @@ -0,0 +1,227 @@ +{ + "name": "Attendance API 근태관리 테스트", + "description": "근태 CRUD, 출퇴근 기록, 월간 통계 테스트", + "version": "1.0", + "config": { + "baseUrl": "", + "timeout": 30000, + "stopOnFailure": true + }, + "variables": { + "user_id": "{{$env.FLOW_TESTER_USER_ID}}", + "user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}", + "test_date": "{{$date}}" + }, + "steps": [ + { + "id": "login", + "name": "로그인", + "method": "POST", + "endpoint": "/login", + "body": { + "user_id": "{{user_id}}", + "user_pwd": "{{user_pwd}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.message": "로그인 성공", + "$.access_token": "@isString" + } + }, + "extract": { + "token": "$.access_token", + "current_user_id": "$.user.id" + } + }, + { + "id": "check_in", + "name": "출근 기록", + "method": "POST", + "endpoint": "/attendances/check-in", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "check_in": "09:00:00", + "gps_data": { + "latitude": 37.5665, + "longitude": 126.978, + "accuracy": 10 + } + }, + "expect": { + "status": [200, 201], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber", + "$.data.status": "@isString" + } + }, + "extract": { + "attendance_id": "$.data.id" + } + }, + { + "id": "show_attendance", + "name": "근태 상세 조회", + "method": "GET", + "endpoint": "/attendances/{{check_in.attendance_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.id": "{{check_in.attendance_id}}", + "$.data.base_date": "@isString" + } + } + }, + { + "id": "check_out", + "name": "퇴근 기록", + "method": "POST", + "endpoint": "/attendances/check-out", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "check_out": "18:00:00", + "gps_data": { + "latitude": 37.5665, + "longitude": 126.978, + "accuracy": 15 + } + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber" + } + } + }, + { + "id": "list_attendances", + "name": "근태 목록 조회", + "method": "GET", + "endpoint": "/attendances", + "query": { + "page": 1, + "per_page": 10, + "date": "{{test_date}}" + }, + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.data": "@isArray" + } + } + }, + { + "id": "monthly_stats", + "name": "월간 통계 조회", + "method": "GET", + "endpoint": "/attendances/monthly-stats", + "query": { + "year": 2025, + "month": 12 + }, + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "create_attendance", + "name": "근태 수동 등록 (관리자)", + "method": "POST", + "endpoint": "/attendances", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "user_id": "{{login.current_user_id}}", + "base_date": "2025-12-01", + "status": "onTime", + "json_details": { + "check_in": "09:00:00", + "check_out": "18:00:00", + "work_minutes": 480 + }, + "remarks": "Flow Tester 테스트 데이터" + }, + "expect": { + "status": [200, 201], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber" + } + }, + "extract": { + "manual_attendance_id": "$.data.id" + } + }, + { + "id": "update_attendance", + "name": "근태 수정", + "method": "PATCH", + "endpoint": "/attendances/{{create_attendance.manual_attendance_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "status": "late", + "remarks": "수정된 테스트 데이터" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.status": "late" + } + } + }, + { + "id": "delete_manual_attendance", + "name": "수동 등록 근태 삭제", + "method": "DELETE", + "endpoint": "/attendances/{{create_attendance.manual_attendance_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "delete_checkin_attendance", + "name": "출퇴근 기록 삭제 (정리)", + "method": "DELETE", + "endpoint": "/attendances/{{check_in.attendance_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + } + ] +} diff --git a/docs/flow-tests/department-tree-api.json b/docs/flow-tests/department-tree-api.json new file mode 100644 index 0000000..503e11c --- /dev/null +++ b/docs/flow-tests/department-tree-api.json @@ -0,0 +1,87 @@ +{ + "name": "Department Tree API 테스트", + "description": "부서 트리 조회 테스트", + "version": "1.0", + "config": { + "baseUrl": "", + "timeout": 30000, + "stopOnFailure": true + }, + "variables": { + "user_id": "{{$env.FLOW_TESTER_USER_ID}}", + "user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}" + }, + "steps": [ + { + "id": "login", + "name": "로그인", + "method": "POST", + "endpoint": "/login", + "body": { + "user_id": "{{user_id}}", + "user_pwd": "{{user_pwd}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.message": "로그인 성공", + "$.access_token": "@isString" + } + }, + "extract": { + "token": "$.access_token" + } + }, + { + "id": "get_tree", + "name": "부서 트리 조회", + "method": "GET", + "endpoint": "/departments/tree", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data": "@isArray" + } + } + }, + { + "id": "get_tree_with_users", + "name": "부서 트리 조회 (사용자 포함)", + "method": "GET", + "endpoint": "/departments/tree", + "query": { + "with_users": true + }, + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data": "@isArray" + } + } + }, + { + "id": "list_departments", + "name": "부서 목록 조회", + "method": "GET", + "endpoint": "/departments", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data": "@isArray" + } + } + } + ] +} diff --git a/docs/flow-tests/employee-api-crud.json b/docs/flow-tests/employee-api-crud.json new file mode 100644 index 0000000..9eaf608 --- /dev/null +++ b/docs/flow-tests/employee-api-crud.json @@ -0,0 +1,188 @@ +{ + "name": "Employee API CRUD 테스트", + "description": "사원 관리 API 전체 CRUD 및 계정 생성 테스트", + "version": "1.0", + "config": { + "baseUrl": "", + "timeout": 30000, + "stopOnFailure": true + }, + "variables": { + "user_id": "{{$env.FLOW_TESTER_USER_ID}}", + "user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}", + "test_email": "test.employee.{{$timestamp}}@example.com", + "test_name": "테스트사원{{$random:4}}" + }, + "steps": [ + { + "id": "login", + "name": "로그인", + "method": "POST", + "endpoint": "/login", + "body": { + "user_id": "{{user_id}}", + "user_pwd": "{{user_pwd}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.message": "로그인 성공", + "$.access_token": "@isString" + } + }, + "extract": { + "token": "$.access_token", + "current_user_id": "$.user.id" + } + }, + { + "id": "get_stats", + "name": "사원 통계 조회", + "method": "GET", + "endpoint": "/employees/stats", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.total": "@isNumber", + "$.data.active": "@isNumber", + "$.data.leave": "@isNumber", + "$.data.resigned": "@isNumber" + } + } + }, + { + "id": "list_employees", + "name": "사원 목록 조회", + "method": "GET", + "endpoint": "/employees", + "query": { + "page": 1, + "per_page": 10 + }, + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.data": "@isArray" + } + } + }, + { + "id": "create_employee", + "name": "사원 등록", + "method": "POST", + "endpoint": "/employees", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "name": "{{test_name}}", + "email": "{{test_email}}", + "phone": "010-1234-5678", + "employee_number": "EMP{{$random:6}}", + "employee_status": "active", + "position": "사원", + "hire_date": "{{$date}}", + "json_extra": { + "emergency_contact": "010-9999-8888", + "address": "서울시 강남구" + } + }, + "expect": { + "status": [200, 201], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber", + "$.data.user.name": "{{test_name}}" + } + }, + "extract": { + "employee_id": "$.data.id", + "user_id": "$.data.user_id" + } + }, + { + "id": "show_employee", + "name": "사원 상세 조회", + "method": "GET", + "endpoint": "/employees/{{create_employee.employee_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.id": "{{create_employee.employee_id}}", + "$.data.employee_status": "active" + } + } + }, + { + "id": "update_employee", + "name": "사원 정보 수정", + "method": "PATCH", + "endpoint": "/employees/{{create_employee.employee_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "body": { + "position": "대리", + "employee_status": "active", + "json_extra": { + "emergency_contact": "010-1111-2222", + "address": "서울시 서초구", + "skills": ["Laravel", "React"] + } + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true, + "$.data.id": "@isNumber" + } + } + }, + { + "id": "list_filtered", + "name": "사원 필터 조회 (재직자)", + "method": "GET", + "endpoint": "/employees", + "query": { + "status": "active", + "q": "{{test_name}}" + }, + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + }, + { + "id": "delete_employee", + "name": "사원 삭제", + "method": "DELETE", + "endpoint": "/employees/{{create_employee.employee_id}}", + "headers": { + "Authorization": "Bearer {{login.token}}" + }, + "expect": { + "status": [200], + "jsonPath": { + "$.success": true + } + } + } + ] +}