Files
sam-docs/front/erp-api-detail.md
hskwon 1066ea25b2 docs: Phase 5 API 문서 추가 (사용자 초대, 알림설정, 계정관리)
- erp-api-list.md: Phase 5 섹션 추가 (12개 API)
- erp-api-detail.md: Phase 5 상세 스펙 추가
  - 13. 사용자 초대 (5개): 목록, 발송, 수락, 취소, 재발송
  - 14. 알림 설정 (3개): 조회, 수정, 일괄수정
  - 15. 계정 관리 (4개): 탈퇴, 사용중지, 약관조회, 약관수정
2025-12-19 15:35:41 +09:00

26 KiB

ERP API 상세 스펙

작성일: 2025-12-19 기준 문서: erp-api-development-plan.md Swagger UI: http://sam.kr/api-docs/index.html


📋 공통 사항

인증

모든 API는 다음 인증이 필요합니다:

  • API Key: Header X-Api-Key 필수
  • Bearer Token: Header Authorization: Bearer {token} (인증 필요 API)

공통 Response 형식

{
  "success": true,
  "message": "message.key",
  "data": { ... }
}

페이지네이션 Response

{
  "success": true,
  "message": "message.fetched",
  "data": {
    "items": [...],
    "meta": {
      "current_page": 1,
      "per_page": 20,
      "total": 100,
      "last_page": 5
    }
  }
}

공통 Query Parameters (LIST API)

파라미터 타입 설명 기본값
page integer 페이지 번호 1
per_page integer 페이지당 개수 20
sort string 정렬 필드 created_at
order string 정렬 방향 (asc/desc) desc
search string 검색어 -

1. 휴가 관리 (Leaves)

1.1 휴가 목록 조회

GET /v1/leaves

Query Parameters:

파라미터 타입 필수 설명
status string - pending/approved/rejected/cancelled
leave_type string - annual/sick/personal/special
user_id integer - 특정 사용자 필터
start_date date - 시작일 필터 (from)
end_date date - 종료일 필터 (to)

Response:

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 1,
        "user_id": 10,
        "user_name": "홍길동",
        "leave_type": "annual",
        "leave_type_name": "연차",
        "start_date": "2025-12-20",
        "end_date": "2025-12-22",
        "days": 3,
        "reason": "개인 사유",
        "status": "pending",
        "created_at": "2025-12-19T10:00:00Z"
      }
    ],
    "meta": {...}
  }
}

1.2 휴가 신청

POST /v1/leaves

Request Body:

{
  "leave_type": "annual",
  "start_date": "2025-12-20",
  "end_date": "2025-12-22",
  "reason": "개인 사유"
}

1.3 잔여휴가 조회

GET /v1/leaves/balance

Response:

{
  "success": true,
  "data": {
    "annual": { "total": 15, "used": 5, "remaining": 10 },
    "sick": { "total": 3, "used": 0, "remaining": 3 },
    "special": { "total": 5, "used": 2, "remaining": 3 }
  }
}

2. 근무/출퇴근 설정

2.1 근무 설정 조회/수정

GET /v1/settings/work
PUT /v1/settings/work

Request/Response:

{
  "work_start_time": "09:00",
  "work_end_time": "18:00",
  "lunch_start_time": "12:00",
  "lunch_end_time": "13:00",
  "work_days": ["mon", "tue", "wed", "thu", "fri"],
  "overtime_rate": 1.5,
  "night_rate": 2.0
}

2.2 출퇴근 설정 조회/수정

GET /v1/settings/attendance
PUT /v1/settings/attendance

Request/Response:

{
  "gps_required": true,
  "gps_radius": 100,
  "late_threshold_minutes": 10,
  "early_leave_threshold_minutes": 30,
  "allow_remote_check": false
}

2.3 현장 관리 (Sites)

현장 목록

GET /v1/sites

Query Parameters:

파라미터 타입 설명
is_active boolean 활성 상태 필터
search string 현장명 검색

현장 등록

POST /v1/sites

Request Body:

{
  "name": "강남 현장",
  "address": "서울시 강남구 ...",
  "latitude": 37.5172,
  "longitude": 127.0473,
  "radius": 100,
  "is_active": true,
  "manager_id": 5,
  "description": "신축 공사 현장"
}

3. 카드/계좌 관리

3.1 카드 등록

POST /v1/cards

Request Body:

{
  "card_name": "법인카드1",
  "card_number": "1234-5678-9012-3456",
  "card_company": "신한카드",
  "holder_name": "홍길동",
  "expiry_date": "2028-12",
  "limit_amount": 5000000,
  "is_active": true
}

Note: 카드번호는 암호화되어 저장됩니다 (Laravel Crypt)

3.2 계좌 등록

POST /v1/bank-accounts

Request Body:

{
  "bank_name": "신한은행",
  "account_number": "110-123-456789",
  "account_holder": "주식회사 SAM",
  "account_type": "business",
  "balance": 10000000,
  "is_primary": false,
  "is_active": true
}

3.3 대표계좌 설정

PATCH /v1/bank-accounts/{id}/set-primary

Note: 기존 대표계좌는 자동으로 해제됩니다.


4. 입금/출금 관리

4.1 입금 등록

POST /v1/deposits

Request Body:

{
  "deposit_date": "2025-12-19",
  "amount": 1000000,
  "client_id": 5,
  "bank_account_id": 1,
  "payment_method": "transfer",
  "description": "12월 매출 입금",
  "reference_no": "DEP-2025-001"
}

payment_method 옵션: transfer(계좌이체), cash(현금), card(카드), check(수표)

4.2 입금 요약 조회

GET /v1/deposits/summary

Query Parameters:

파라미터 타입 설명
start_date date 조회 시작일
end_date date 조회 종료일

Response:

{
  "success": true,
  "data": {
    "total_amount": 50000000,
    "by_payment_method": {
      "transfer": 30000000,
      "cash": 15000000,
      "card": 5000000
    },
    "count": 45
  }
}

4.3 출금 등록

POST /v1/withdrawals

Request Body:

{
  "withdrawal_date": "2025-12-19",
  "amount": 500000,
  "client_id": 10,
  "bank_account_id": 1,
  "payment_method": "transfer",
  "category": "expense",
  "description": "사무용품 구입",
  "reference_no": "WDR-2025-001"
}

5. 매출/매입 관리

5.1 매출 등록

POST /v1/sales

Request Body:

{
  "sale_date": "2025-12-19",
  "client_id": 5,
  "items": [
    {
      "item_name": "상품A",
      "quantity": 10,
      "unit_price": 50000,
      "tax_rate": 10
    }
  ],
  "supply_amount": 500000,
  "tax_amount": 50000,
  "total_amount": 550000,
  "status": "draft",
  "due_date": "2025-12-30",
  "description": "12월 매출"
}

5.2 매출 확정

POST /v1/sales/{id}/confirm

Note: 확정 후에는 수정/삭제가 제한됩니다.

5.3 거래명세서 조회

GET /v1/sales/{id}/statement

Response:

{
  "success": true,
  "data": {
    "statement_number": "STSL202512190001",
    "issued_at": null,
    "sale": { "id": 1, "sale_number": "SL202512190001", ... },
    "seller": {
      "name": "(주)테스트회사",
      "business_number": "123-45-67890",
      "representative": "홍길동",
      "address": "서울시 강남구",
      "tel": "02-1234-5678",
      "email": "company@example.com"
    },
    "buyer": {
      "name": "(주)거래처",
      "business_number": "987-65-43210",
      "representative": "김철수",
      "address": "서울시 서초구",
      "tel": "02-9876-5432",
      "email": "client@example.com"
    },
    "items": [
      {
        "description": "12월 매출",
        "quantity": 1,
        "unit_price": 1000000,
        "supply_amount": 1000000,
        "tax_amount": 100000,
        "total_amount": 1100000
      }
    ],
    "summary": {
      "supply_amount": 1000000,
      "tax_amount": 100000,
      "total_amount": 1100000
    }
  }
}

5.4 거래명세서 발행

POST /v1/sales/{id}/statement/issue

Note: 확정(confirmed) 상태의 매출만 발행 가능합니다.

Response:

{
  "success": true,
  "message": "message.sale.statement_issued",
  "data": {
    "statement_number": "STSL202512190001",
    "issued_at": "2025-12-19T10:30:00+09:00"
  }
}

5.5 거래명세서 이메일 발송

POST /v1/sales/{id}/statement/send

Request Body:

{
  "email": "buyer@example.com",
  "message": "거래명세서를 발송합니다."
}

Note: email 미입력 시 거래처 이메일로 발송됩니다.

Response:

{
  "success": true,
  "message": "message.sale.statement_sent",
  "data": {
    "sent_to": "buyer@example.com",
    "sent_at": "2025-12-19T10:35:00+09:00",
    "statement_number": "STSL202512190001"
  }
}

5.6 매출 요약

GET /v1/sales/summary

Response:

{
  "success": true,
  "data": {
    "total_supply_amount": 10000000,
    "total_tax_amount": 1000000,
    "total_amount": 11000000,
    "confirmed_amount": 8000000,
    "pending_amount": 3000000,
    "by_client": [
      { "client_id": 5, "client_name": "거래처A", "total": 5000000 }
    ]
  }
}

6. 보고서

6.1 일일 일보

GET /v1/reports/daily

Query Parameters:

파라미터 타입 필수 설명
date date O 조회 기준일

Response:

{
  "success": true,
  "data": {
    "date": "2025-12-19",
    "previous_balance": 50000000,
    "deposits": {
      "total": 5000000,
      "items": [...]
    },
    "withdrawals": {
      "total": 2000000,
      "items": [...]
    },
    "current_balance": 53000000
  }
}

6.2 일일 일보 엑셀 다운로드

GET /v1/reports/daily/export?date=2025-12-19

Response: Excel 파일 다운로드

6.3 지출 예상 내역서

GET /v1/reports/expense-estimate

Query Parameters:

파라미터 타입 설명
year integer 조회 연도
month integer 조회 월

7. 전자결재

7.1 결재 양식 스키마

{
  "id": 1,
  "name": "휴가신청서",
  "code": "LEAVE",
  "category": "hr",
  "fields": [
    { "key": "leave_type", "label": "휴가유형", "type": "select", "required": true },
    { "key": "start_date", "label": "시작일", "type": "date", "required": true },
    { "key": "end_date", "label": "종료일", "type": "date", "required": true },
    { "key": "reason", "label": "사유", "type": "textarea", "required": true }
  ],
  "is_active": true
}

7.2 결재 문서 작성

POST /v1/approvals

Request Body:

{
  "form_id": 1,
  "title": "연차 휴가 신청",
  "content": {
    "leave_type": "annual",
    "start_date": "2025-12-20",
    "end_date": "2025-12-22",
    "reason": "개인 사유"
  },
  "approval_line": [
    { "user_id": 10, "type": "approval", "order": 1 },
    { "user_id": 20, "type": "approval", "order": 2 },
    { "user_id": 30, "type": "reference", "order": 3 }
  ]
}

7.3 결재 상신

POST /v1/approvals/{id}/submit

7.4 결재 승인/반려

POST /v1/approvals/{id}/approve
POST /v1/approvals/{id}/reject

Request Body:

{
  "comment": "승인합니다" // 또는 "반려 사유"
}

7.5 결재 상태 흐름

draft → pending → approved/rejected
                    ↓
                 cancelled (회수)

8. 급여 관리

8.1 급여 등록

POST /v1/payrolls

Request Body:

{
  "user_id": 10,
  "pay_year": 2025,
  "pay_month": 12,
  "base_salary": 3500000,
  "allowances": {
    "position": 200000,
    "meal": 100000,
    "transport": 100000
  },
  "deductions": {
    "health_insurance": 125000,
    "long_term_care": 16000,
    "national_pension": 157500,
    "employment_insurance": 32000,
    "income_tax": 85000,
    "local_tax": 8500
  }
}

8.2 급여 일괄 계산

POST /v1/payrolls/calculate

Request Body:

{
  "pay_year": 2025,
  "pay_month": 12,
  "user_ids": [10, 11, 12] // 빈 배열이면 전체 직원
}

8.3 급여명세서 조회

GET /v1/payrolls/{id}/payslip

Response:

{
  "success": true,
  "data": {
    "employee": {
      "name": "홍길동",
      "department": "개발팀",
      "position": "대리"
    },
    "pay_period": "2025-12",
    "earnings": {
      "base_salary": 3500000,
      "allowances": [...]
    },
    "deductions": {
      "insurance": [...],
      "tax": [...]
    },
    "gross_pay": 3900000,
    "total_deductions": 424000,
    "net_pay": 3476000
  }
}

8.4 급여 설정 (4대보험 요율)

GET /v1/settings/payroll
PUT /v1/settings/payroll

Request/Response:

{
  "health_insurance_rate": 3.545,
  "long_term_care_rate": 12.81,
  "national_pension_rate": 4.5,
  "employment_insurance_rate": 0.9,
  "income_tax_table": "2025"
}

9. 대시보드

9.1 대시보드 요약

GET /v1/dashboard/summary

Response:

{
  "success": true,
  "data": {
    "today": {
      "attendance_count": 45,
      "leave_count": 3,
      "late_count": 2
    },
    "finance": {
      "current_balance": 150000000,
      "today_deposits": 5000000,
      "today_withdrawals": 2000000
    },
    "sales": {
      "month_total": 50000000,
      "month_confirmed": 40000000
    },
    "approvals": {
      "pending": 5,
      "my_turn": 2
    }
  }
}

9.2 차트 데이터

GET /v1/dashboard/charts

Query Parameters:

파라미터 타입 설명
period string week/month/quarter/year

Response:

{
  "success": true,
  "data": {
    "cash_flow": [
      { "date": "2025-12-13", "deposits": 1000000, "withdrawals": 500000 },
      { "date": "2025-12-14", "deposits": 2000000, "withdrawals": 800000 }
    ],
    "top_clients": [
      { "client_name": "거래처A", "total": 10000000 },
      { "client_name": "거래처B", "total": 8000000 }
    ]
  }
}

10. AI 리포트

10.1 AI 리포트 생성

POST /v1/reports/ai/generate

Request Body:

{
  "report_type": "financial_analysis",
  "analysis_areas": ["revenue", "expense", "cash_flow"],
  "period": {
    "start_date": "2025-12-01",
    "end_date": "2025-12-31"
  }
}

report_type 옵션:

  • financial_analysis - 재무 분석
  • cash_flow_analysis - 현금 흐름 분석
  • revenue_analysis - 매출 분석

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "status": "completed",
    "report_type": "financial_analysis",
    "content": {
      "summary": "12월 재무 현황 분석 결과...",
      "insights": [...],
      "recommendations": [...]
    },
    "created_at": "2025-12-19T10:00:00Z"
  }
}

11. 가지급금 관리

11.1 가지급금 등록

POST /v1/loans

Request Body:

{
  "user_id": 10,
  "loan_date": "2025-12-19",
  "amount": 5000000,
  "purpose": "업무 관련 선지급",
  "due_date": "2026-01-31",
  "interest_rate": 4.6,
  "status": "active"
}

11.2 인정이자 계산

POST /v1/loans/calculate-interest

Request Body:

{
  "loan_ids": [1, 2, 3],
  "calculation_date": "2025-12-31"
}

Response:

{
  "success": true,
  "data": [
    {
      "loan_id": 1,
      "principal": 5000000,
      "days": 12,
      "interest_rate": 4.6,
      "calculated_interest": 7562
    }
  ]
}

11.3 연도별 인정이자 리포트

GET /v1/loans/interest-report/2025

12. 바로빌 세금계산서

12.1 바로빌 설정

PUT /v1/barobill-settings

Request Body:

{
  "corp_num": "1234567890",
  "cert_key": "encrypted_key",
  "is_test_mode": false,
  "auto_issue": true,
  "default_email": "tax@company.com"
}

12.2 세금계산서 발행

POST /v1/tax-invoices/{id}/issue

Response:

{
  "success": true,
  "message": "message.tax_invoice.issued",
  "data": {
    "id": 1,
    "issue_no": "20251219-12345678",
    "status": "issued",
    "nts_status": "pending",
    "issued_at": "2025-12-19T10:00:00Z"
  }
}

12.3 국세청 전송 상태 조회

GET /v1/tax-invoices/{id}/check-status

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "nts_status": "transmitted",
    "nts_message": "국세청 전송 완료",
    "checked_at": "2025-12-19T11:00:00Z"
  }
}

nts_status 옵션:

  • pending - 전송 대기
  • transmitted - 전송 완료
  • failed - 전송 실패

13. 사용자 초대 (Invitations)

Phase 5에서 추가된 API입니다.

13.1 초대 목록 조회

GET /v1/users/invitations

Query Parameters:

파라미터 타입 필수 설명
status string - pending/accepted/expired/cancelled
search string - 이메일 검색
sort_by string - created_at/expires_at/email
sort_dir string - asc/desc
per_page integer - 페이지당 개수 (기본 20)
page integer - 페이지 번호

Response:

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 1,
        "email": "invited@example.com",
        "role_id": 2,
        "role_name": "일반 사용자",
        "message": "팀에 초대합니다",
        "status": "pending",
        "invited_by": 10,
        "invited_by_name": "홍길동",
        "expires_at": "2025-12-26T00:00:00Z",
        "created_at": "2025-12-19T10:00:00Z"
      }
    ],
    "meta": {...}
  }
}

status 옵션:

  • pending - 대기 중
  • accepted - 수락됨
  • expired - 만료됨
  • cancelled - 취소됨

13.2 사용자 초대 발송

POST /v1/users/invite

Request Body:

{
  "email": "newuser@example.com",
  "role_id": 2,
  "message": "우리 팀에 초대합니다!",
  "expires_days": 7
}
필드 타입 필수 설명
email string 초대할 이메일
role_id integer - 부여할 역할 ID
message string - 초대 메시지 (최대 1000자)
expires_days integer - 만료일 (1~30일, 기본 7일)

Response:

{
  "success": true,
  "message": "message.invitation.sent",
  "data": {
    "id": 1,
    "email": "newuser@example.com",
    "token": "abc123xyz",
    "expires_at": "2025-12-26T10:00:00Z"
  }
}

13.3 초대 수락

POST /v1/users/invitations/{token}/accept

Request Body:

{
  "name": "김철수",
  "password": "securePassword123",
  "password_confirmation": "securePassword123",
  "phone": "010-1234-5678"
}
필드 타입 필수 설명
name string 사용자 이름 (최대 100자)
password string 비밀번호 (최소 8자)
password_confirmation string 비밀번호 확인
phone string - 전화번호 (최대 20자)

Response:

{
  "success": true,
  "message": "message.invitation.accepted",
  "data": {
    "user_id": 25,
    "tenant_id": 1,
    "email": "newuser@example.com",
    "token": "sanctum_access_token..."
  }
}

13.4 초대 취소

DELETE /v1/users/invitations/{id}

Response:

{
  "success": true,
  "message": "message.invitation.cancelled",
  "data": {
    "id": 1,
    "cancelled_at": "2025-12-19T15:00:00Z"
  }
}

13.5 초대 재발송

POST /v1/users/invitations/{id}/resend

Response:

{
  "success": true,
  "message": "message.invitation.resent",
  "data": {
    "id": 1,
    "new_expires_at": "2025-12-26T15:00:00Z",
    "resent_at": "2025-12-19T15:00:00Z"
  }
}

14. 알림 설정 (Notification Settings)

Phase 5에서 추가된 API입니다. 모든 API는 auth:sanctum 인증이 필요합니다.

14.1 알림 설정 조회

GET /v1/users/me/notification-settings

Response:

{
  "success": true,
  "data": {
    "settings": [
      {
        "notification_type": "approval",
        "type_label": "전자결재",
        "push_enabled": true,
        "email_enabled": false,
        "sms_enabled": false,
        "in_app_enabled": true,
        "kakao_enabled": false,
        "settings": {}
      },
      {
        "notification_type": "order",
        "type_label": "수주",
        "push_enabled": true,
        "email_enabled": false,
        "sms_enabled": false,
        "in_app_enabled": true,
        "kakao_enabled": false,
        "settings": {}
      }
    ],
    "types": {
      "approval": "전자결재",
      "order": "수주",
      "deposit": "입금",
      "withdrawal": "출금",
      "notice": "공지사항",
      "system": "시스템",
      "marketing": "마케팅",
      "security": "보안"
    },
    "channels": {
      "push": "푸시 알림",
      "email": "이메일",
      "sms": "SMS",
      "in_app": "인앱 알림",
      "kakao": "카카오 알림톡"
    }
  }
}

14.2 알림 설정 수정 (단일)

PUT /v1/users/me/notification-settings

Request Body:

{
  "notification_type": "marketing",
  "push_enabled": true,
  "email_enabled": true,
  "sms_enabled": false,
  "in_app_enabled": true,
  "kakao_enabled": false,
  "settings": {
    "frequency": "daily"
  }
}
필드 타입 필수 설명
notification_type string 알림 유형
push_enabled boolean - 푸시 알림
email_enabled boolean - 이메일 알림
sms_enabled boolean - SMS 알림
in_app_enabled boolean - 인앱 알림
kakao_enabled boolean - 카카오 알림톡
settings object - 추가 설정

notification_type 옵션:

  • approval - 전자결재
  • order - 수주
  • deposit - 입금
  • withdrawal - 출금
  • notice - 공지사항
  • system - 시스템
  • marketing - 마케팅
  • security - 보안

Response:

{
  "success": true,
  "message": "message.updated",
  "data": {
    "notification_type": "marketing",
    "push_enabled": true,
    "email_enabled": true,
    "sms_enabled": false,
    "in_app_enabled": true,
    "kakao_enabled": false,
    "settings": {
      "frequency": "daily"
    }
  }
}

14.3 알림 일괄 설정

PUT /v1/users/me/notification-settings/bulk

Request Body:

{
  "settings": [
    {
      "notification_type": "approval",
      "push_enabled": true,
      "email_enabled": true,
      "in_app_enabled": true
    },
    {
      "notification_type": "marketing",
      "push_enabled": false,
      "email_enabled": false,
      "in_app_enabled": false
    }
  ]
}

Response:

{
  "success": true,
  "message": "message.bulk_upsert",
  "data": {
    "updated_count": 2,
    "settings": [...]
  }
}

15. 계정 관리 (Account)

Phase 5에서 추가된 API입니다. 모든 API는 auth:sanctum 인증이 필요합니다.

15.1 회원 탈퇴 (SAM 완전 탈퇴)

POST /v1/account/withdraw

Request Body:

{
  "password": "currentPassword123",
  "reason": "not_using",
  "detail": "서비스를 더 이상 사용할 계획이 없습니다"
}
필드 타입 필수 설명
password string 현재 비밀번호 (확인용)
reason string - 탈퇴 사유 코드
detail string - 상세 사유 (최대 500자)

reason 옵션:

  • not_using - 서비스를 더 이상 사용하지 않음
  • difficult - 사용하기 어려움
  • alternative - 다른 서비스 이용
  • privacy - 개인정보 보호 우려
  • other - 기타

Response:

{
  "success": true,
  "message": "message.account.withdrawn",
  "data": {
    "withdrawn_at": "2025-12-19T16:00:00Z"
  }
}

⚠️ 주의: 회원 탈퇴 시 모든 테넌트에서 탈퇴되며, 계정은 Soft Delete 처리됩니다.

15.2 사용 중지 (특정 테넌트에서만 탈퇴)

POST /v1/account/suspend

Response:

{
  "success": true,
  "message": "message.account.suspended",
  "data": {
    "suspended": true,
    "new_default_tenant_id": 2
  }
}

다른 활성 테넌트가 있으면 해당 테넌트가 기본 테넌트로 설정됩니다.

15.3 약관 동의 정보 조회

GET /v1/account/agreements

Response:

{
  "success": true,
  "data": {
    "agreements": {
      "terms": {
        "type": "terms",
        "label": "이용약관",
        "required": true,
        "agreed": true,
        "agreed_at": "2025-01-01T00:00:00Z"
      },
      "privacy": {
        "type": "privacy",
        "label": "개인정보 처리방침",
        "required": true,
        "agreed": true,
        "agreed_at": "2025-01-01T00:00:00Z"
      },
      "marketing": {
        "type": "marketing",
        "label": "마케팅 정보 수신",
        "required": false,
        "agreed": false,
        "agreed_at": null
      },
      "push": {
        "type": "push",
        "label": "푸시 알림 수신",
        "required": false,
        "agreed": true,
        "agreed_at": "2025-06-15T10:00:00Z"
      },
      "email": {
        "type": "email",
        "label": "이메일 수신",
        "required": false,
        "agreed": false,
        "agreed_at": null
      },
      "sms": {
        "type": "sms",
        "label": "SMS 수신",
        "required": false,
        "agreed": false,
        "agreed_at": null
      }
    },
    "types": {
      "terms": "이용약관",
      "privacy": "개인정보 처리방침",
      "marketing": "마케팅 정보 수신",
      "push": "푸시 알림 수신",
      "email": "이메일 수신",
      "sms": "SMS 수신"
    }
  }
}

15.4 약관 동의 정보 수정

PUT /v1/account/agreements

Request Body:

{
  "agreements": [
    {
      "type": "marketing",
      "agreed": true
    },
    {
      "type": "email",
      "agreed": true
    }
  ]
}
필드 타입 필수 설명
agreements array 약관 동의 배열
agreements[].type string 약관 유형
agreements[].agreed boolean 동의 여부

type 옵션:

  • terms - 이용약관 (필수)
  • privacy - 개인정보 처리방침 (필수)
  • marketing - 마케팅 정보 수신
  • push - 푸시 알림 수신
  • email - 이메일 수신
  • sms - SMS 수신

Response:

{
  "success": true,
  "message": "message.updated",
  "data": {
    "agreements": {
      "terms": {...},
      "privacy": {...},
      "marketing": {
        "type": "marketing",
        "label": "마케팅 정보 수신",
        "required": false,
        "agreed": true,
        "agreed_at": "2025-12-19T16:30:00Z"
      },
      "email": {
        "type": "email",
        "label": "이메일 수신",
        "required": false,
        "agreed": true,
        "agreed_at": "2025-12-19T16:30:00Z"
      },
      "sms": {...}
    }
  }
}

📝 에러 코드

코드 설명
400 잘못된 요청 (validation 실패)
401 인증 실패
403 권한 없음
404 리소스 없음
409 충돌 (중복 등)
422 처리 불가 (비즈니스 로직 오류)
500 서버 오류

🔗 관련 문서