본문으로 건너뛰기

합의(Agreements) 도메인 API 엔드포인트

목차

접근 권한 매트릭스

엔드포인트System AdminIAM AdminService AccountRegular User비고
POST /v1/agreements/terms
POST /v1/agreements/terms/{termsId}/translations
PATCH /v1/agreements/terms/{termsId}/status
GET /v1/agreements/terms
GET /v1/agreements/terms/{termsId}
GET /v1/agreements/terms/history
GET /v1/agreements/users/{userId}/history자신만
POST /v1/agreements/terms/agreement
POST /v1/agreements/consents/definitions
PATCH /v1/agreements/consents/definitions/{definitionId}
POST /v1/agreements/consents/users
PATCH /v1/agreements/consents/users/{userId}/{consentKey}자신만
GET /v1/agreements/consents/definitions
GET /v1/agreements/consents/users/{userId}자신만
POST /v1/agreements/validate
GET /v1/agreements/active
POST /v1/agreements/batch

참고:

  • ✓: 접근 가능
  • ✘: 접근 불가
  • (범위 내): 할당된 조직/팀 범위 내에서만 접근 가능
  • (자신만): 자신의 데이터에만 접근 가능

약관(Term) 관리 프로세스

합의 도메인의 약관 관리 API는 서비스 이용을 위한 약관의 버전 관리와 활성화 상태 관리, 다국어 지원 및 사용자 동의 이력 관리를 담당합니다.

2.1 약관 생성

  • HTTP 메서드: POST
  • 경로: /v1/agreements/terms
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {adminToken}

요청 (Request)

{
"title": "서비스 이용약관",
"type": "service",
"required": true,
"defaultLanguage": "ko",
"contentUrl": "https://external-service.com/terms/service/v1.0.0/ko",
"validFrom": 1709251200000,
"validUntil": 1735689599000
}

응답 (Response)

  • 성공 응답 (201 Created)
{
"id": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"type": "service",
"required": true,
"defaultLanguage": "ko",
"status": "DRAFT",
"validFrom": 1709251200000,
"validUntil": 1735689599000,
"createdAt": 1711011600000,
"updatedAt": 1711011600000
}
  • 오류 응답 (400 Bad Request - 입력값 오류)
{
"code": 2000,
"message": "BAD_REQUEST",
"detail": "요청 본문이 유효하지 않습니다."
}
  • 오류 응답 (401 Unauthorized - 토큰 오류)
{
"code": 2050,
"message": "INVALID_APP_TOKEN",
"detail": "토큰이 유효하지 않습니다"
}
  • 오류 응답 (403 Forbidden - 권한 없음)
{
"code": 2060,
"message": "PERMISSION_DENIED",
"detail": "요청한 작업에 대한 권한이 없습니다"
}

2.2 약관 번역 추가

  • HTTP 메서드: POST
  • 경로: /v1/agreements/terms/{termsId}/translations
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {adminToken}

요청 (Request)

{
"language": "en",
"contentUrl": "https://external-service.com/terms/service/v1.0.0/en",
"title": "Terms of Service"
}

응답 (Response)

  • 성공 응답 (201 Created)
{
"termsId": 1,
"language": "en",
"title": "Terms of Service",
"createdAt": 1711011900000,
"updatedAt": 1711011900000
}
  • 오류 응답 (400 Bad Request - 입력값 오류)
{
"code": 2000,
"message": "BAD_REQUEST",
"detail": "요청 본문이 유효하지 않습니다."
}
  • 오류 응답 (404 Not Found - 약관 없음)
{
"code": 2080,
"message": "TERMS_NOT_FOUND",
"detail": "요청한 약관을 찾을 수 없습니다"
}
  • 오류 응답 (409 Conflict - 번역 중복)
{
"code": 2081,
"message": "TERMS_ALREADY_EXISTS",
"detail": "해당 언어의 번역이 이미 존재합니다"
}

2.3 약관 활성화

  • HTTP 메서드: PATCH
  • 경로: /v1/agreements/terms/{termsId}/status
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {adminToken}

요청 (Request)

{
"status": "ACTIVE"
}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"type": "service",
"status": "ACTIVE",
"previousStatus": "DRAFT",
"activatedAt": 1711015200000,
"updatedAt": 1711015200000
}
  • 오류 응답 (400 Bad Request - 잘못된 상태값)
{
"code": 2000,
"message": "BAD_REQUEST",
"detail": "유효하지 않은 상태 값입니다."
}
  • 오류 응답 (409 Conflict - 활성 약관 중복)
{
"code": 2081,
"message": "TERMS_ALREADY_EXISTS",
"detail": "동일한 유형의 활성화된 약관이 이미 존재합니다."
}

2.4 약관 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/terms/{termsId}
  • Headers:
    • Accept-Language: ko-KR (기본값) 또는 en-US
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"contentUrl": "https://external-service.com/terms/service/v1.0.0/ko",
"type": "service",
"required": true,
"status": "ACTIVE",
"language": "ko",
"availableLanguages": ["ko", "en"],
"validFrom": 1709251200000,
"validUntil": 1735689599000,
"createdAt": 1711011600000,
"updatedAt": 1711015200000,
"activatedAt": 1711015200000
}
  • 오류 응답 (404 Not Found - 약관 없음)
{
"code": 2080,
"message": "TERMS_NOT_FOUND",
"detail": "요청한 약관을 찾을 수 없습니다"
}

2.5 약관 목록 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/terms
  • Headers:
    • Accept-Language: de-DE (기본값), ko-KR, en-US 등
    • Authorization: Bearer {appToken 또는 accessToken}
  • Query Parameters:
    • status: 약관 상태 (선택 사항, 예: 'ACTIVE', 'DRAFT', 'INACTIVE', 'EXPIRED')
    • type: 약관 유형 (선택 사항, 예: 'service', 'privacy', 'marketing')
    • page: 페이지 번호 (기본값: 1)
    • pageSize: 페이지 크기 (기본값: 10)

응답 (Response)

  • 성공 응답 (200 OK)
{
"items": [
{
"id": 1,
"version": "1.0.0",
"title": "Ich stimme den Nutzungsbedingungen gemäß der DiGAV § 4 Abs. 2 zu.",
"contentUrl": "https://external-service.com/terms/service/v1.0.0/de",
"type": "service",
"required": true,
"status": "ACTIVE",
"language": "de",
"availableLanguages": ["de", "ko", "en"],
"validFrom": 1709251200000,
"validUntil": 1735689599000,
"createdAt": 1711011600000,
"updatedAt": 1711015200000,
"activatedAt": 1711015200000
},
{
"id": 2,
"version": "1.1.0",
"title": "Ich erlaube die Verarbeitung der zu der dauerhaften Gewährleistung der technischen Funktionsfähigkeit, der Nutzerfreundlichkeit und der Weiterentwicklung der digitalen Gesundheitsanwendung. (optional)",
"contentUrl": "https://external-service.com/terms/privacy/v1.1.0/de",
"type": "privacy",
"required": false,
"status": "ACTIVE",
"language": "de",
"availableLanguages": ["de", "ko", "en"],
"validFrom": 1711929600000,
"validUntil": null,
"createdAt": 1711929600000,
"updatedAt": 1711929600000,
"activatedAt": 1711929600000
}
],
"metadata": {
"totalCount": 2,
"currentPage": 1,
"pageSize": 10,
"totalPages": 1
}
}

2.6 약관 버전 이력 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/terms/history
  • Headers:
    • Accept-Language: ko-KR (기본값) 또는 en-US
    • Authorization: Bearer {token}
  • Query Parameters:
    • type: 약관 유형 (필수, 예: 'service', 'privacy', 'marketing')

응답 (Response)

  • 성공 응답 (200 OK)
{
"type": "service",
"currentVersion": "1.0.0",
"versions": [
{
"id": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"status": "ACTIVE",
"validFrom": 1709251200000,
"validUntil": 1735689599000,
"createdAt": 1711011600000,
"activatedAt": 1711015200000
}
]
}

2.7 사용자 약관 동의 이력 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/users/{userId}/history
  • Headers:
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"agreements": [
{
"termsId": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"type": "service",
"isAgreed": true,
"agreedAt": 1711011600000
}
]
}
  • 오류 응답 (403 Forbidden - 권한 없음)
{
"code": 2060,
"message": "PERMISSION_DENIED",
"detail": "다른 사용자의 동의 이력을 조회할 권한이 없습니다"
}

합의 도메인의 동의 관리 API는 데이터 처리 동의 항목 정의와 사용자 동의 상태를 관리하고 검증합니다.

3.1 동의 항목 정의 생성

  • HTTP 메서드: POST
  • 경로: /v1/agreements/consents/definitions
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {adminToken}

요청 (Request)

{
"key": "dataProcessingForImprovement",
"title": "데이터 처리 동의",
"description": "서비스 개선을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선",
"scope": "사용자 활동 데이터",
"required": false
}

응답 (Response)

  • 성공 응답 (201 Created)
{
"id": 1,
"key": "dataProcessingForImprovement",
"title": "데이터 처리 동의",
"description": "서비스 개선을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선",
"scope": "사용자 활동 데이터",
"required": false,
"createdAt": 1711011600000,
"updatedAt": 1711011600000
}
  • 오류 응답 (400 Bad Request - 입력값 오류)
{
"code": 2000,
"message": "BAD_REQUEST",
"detail": "요청 본문이 유효하지 않습니다."
}
  • 오류 응답 (409 Conflict - 중복 키)
{
"code": 2090,
"message": "CONSENT_ALREADY_EXISTS",
"detail": "동일한 키를 가진 동의 항목이 이미 존재합니다"
}

3.2 동의 항목 정의 업데이트

  • HTTP 메서드: PATCH
  • 경로: /v1/agreements/consents/definitions/{definitionId}
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {adminToken}

요청 (Request)

{
"title": "데이터 처리 및 분석 동의",
"description": "서비스 개선 및 분석을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선 및 분석",
"scope": "사용자 활동 데이터, 사용 패턴"
}

응답 (Response)

  • 성공 응답 (200 OK)
{
"id": 1,
"key": "dataProcessingForImprovement",
"title": "데이터 처리 및 분석 동의",
"description": "서비스 개선 및 분석을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선 및 분석",
"scope": "사용자 활동 데이터, 사용 패턴",
"required": false,
"createdAt": 1711011600000,
"updatedAt": 1711015200000
}
  • 오류 응답 (404 Not Found - 동의 항목 없음)
{
"code": 2091,
"message": "CONSENT_NOT_FOUND",
"detail": "요청한 동의 항목을 찾을 수 없습니다"
}

3.3 사용자 동의 상태 기록

  • HTTP 메서드: POST
  • 경로: /v1/agreements/consents/users
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"userId": "user_123",
"consentKey": "dataProcessingForImprovement",
"isAgreed": true
}

응답 (Response)

  • 성공 응답 (201 Created)
{
"userId": "user_123",
"consentKey": "dataProcessingForImprovement",
"isAgreed": true,
"agreedAt": 1711011600000
}
  • 오류 응답 (400 Bad Request - 잘못된 동의 키)
{
"code": 2092,
"message": "INVALID_CONSENT_KEY",
"detail": "유효하지 않은 동의 항목 키입니다"
}

3.4 사용자 동의 상태 업데이트

  • HTTP 메서드: PATCH
  • 경로: /v1/agreements/consents/users/{userId}/{consentKey}
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"isAgreed": false
}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"consentKey": "dataProcessingForImprovement",
"isAgreed": false,
"agreedAt": null,
"updatedAt": 1711015200000
}
  • 오류 응답 (403 Forbidden - 권한 없음)
{
"code": 2060,
"message": "PERMISSION_DENIED",
"detail": "다른 사용자의 동의 상태를 변경할 권한이 없습니다"
}
  • 오류 응답 (404 Not Found - 동의 상태 없음)
{
"code": 2093,
"message": "USER_CONSENT_NOT_FOUND",
"detail": "요청한 사용자의 동의 상태를 찾을 수 없습니다"
}

3.5 동의 항목 정의 목록 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/consents/definitions
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}
  • Query Parameters:
    • required: 필수 여부 (선택 사항, 예: 'true', 'false')
    • page: 페이지 번호 (기본값: 1)
    • pageSize: 페이지 크기 (기본값: 10)

응답 (Response)

  • 성공 응답 (200 OK)
{
"items": [
{
"id": 1,
"key": "dataProcessingForImprovement",
"title": "데이터 처리 및 분석 동의",
"description": "서비스 개선 및 분석을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선 및 분석",
"scope": "사용자 활동 데이터, 사용 패턴",
"required": false,
"createdAt": 1711011600000,
"updatedAt": 1711015200000
},
{
"id": 2,
"key": "termsOfServiceDiGAV",
"title": "DiGAV § 4 Abs. 2에 따른 이용 약관 동의",
"description": "DiGAV § 4 Abs. 2에 따른 이용 약관에 동의합니다",
"purpose": "서비스 이용",
"scope": "사용자 정보",
"required": true,
"createdAt": 1711011600000,
"updatedAt": 1711011600000
}
],
"metadata": {
"totalCount": 2,
"currentPage": 1,
"pageSize": 10,
"totalPages": 1
}
}

3.6 사용자 동의 상태 목록 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/consents/users/{userId}
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"consents": [
{
"key": "dataProcessingForImprovement",
"title": "데이터 처리 및 분석 동의",
"isAgreed": false,
"required": false,
"agreedAt": null,
"updatedAt": 1711015200000
},
{
"key": "termsOfServiceDiGAV",
"title": "DiGAV § 4 Abs. 2에 따른 이용 약관 동의",
"isAgreed": true,
"required": true,
"agreedAt": 1711011600000,
"updatedAt": 1711011600000
}
]
}
  • 오류 응답 (403 Forbidden - 권한 없음)
{
"code": 2060,
"message": "PERMISSION_DENIED",
"detail": "다른 사용자의 동의 상태를 조회할 권한이 없습니다"
}

3.7 합의 상태 검증

  • HTTP 메서드: POST
  • 경로: /v1/agreements/validate
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"userId": "user_123",
"requiredConsents": ["termsOfServiceDiGAV"],
"requiredTermsTypes": ["service"]
}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"validated": true,
"missingTerms": [],
"missingConsents": []
}
  • 실패 응답 (검증 실패, 200 OK)
{
"userId": "user_123",
"validated": false,
"missingTerms": [
{
"type": "privacy",
"title": "개인정보 처리방침",
"required": true
}
],
"missingConsents": [
{
"key": "marketingConsent",
"title": "마케팅 정보 수신 동의",
"required": false
}
]
}

통합 프로세스

합의 도메인은 약관과 동의를 통합 관리하기 위한 API를 제공합니다.

4.1 모든 활성 약관 및 동의 항목 조회

  • HTTP 메서드: GET
  • 경로: /v1/agreements/active
  • Headers:
    • Accept-Language: ko-KR (기본값) 또는 en-US
    • Authorization: Bearer {accessToken}

응답 (Response)

  • 성공 응답 (200 OK)
{
"terms": [
{
"id": 1,
"version": "1.0.0",
"title": "서비스 이용약관",
"contentUrl": "https://external-service.com/terms/service/v1.0.0/ko",
"type": "service",
"required": true,
"status": "ACTIVE",
"language": "ko",
"availableLanguages": ["ko", "en"],
"orderIndex": 0
},
{
"id": 2,
"version": "1.1.0",
"title": "개인정보 처리방침",
"contentUrl": "https://external-service.com/terms/privacy/v1.1.0/ko",
"type": "privacy",
"required": true,
"status": "ACTIVE",
"language": "ko",
"availableLanguages": ["ko", "en", "de"],
"orderIndex": 1
}
],
"consents": [
{
"key": "dataProcessingForImprovement",
"title": "데이터 처리 및 분석 동의",
"description": "서비스 개선 및 분석을 위한 데이터 처리에 동의합니다",
"purpose": "서비스 개선 및 분석",
"scope": "사용자 활동 데이터, 사용 패턴",
"required": false,
"orderIndex": 2
},
{
"key": "termsOfServiceDiGAV",
"title": "DiGAV § 4 Abs. 2에 따른 이용 약관 동의",
"description": "DiGAV § 4 Abs. 2에 따른 이용 약관에 동의합니다",
"purpose": "서비스 이용",
"scope": "사용자 정보",
"required": true,
"orderIndex": 3
}
]
}

4.2 약관 및 동의 상태 일괄 기록

  • HTTP 메서드: POST
  • 경로: /v1/agreements/batch
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer {accessToken}

요청 (Request)

{
"userId": "user_123",
"termsAgreements": [
{
"termsId": 1,
"isAgreed": true
},
{
"termsId": 2,
"isAgreed": true
}
],
"consentAgreements": [
{
"consentKey": "dataProcessingForImprovement",
"isAgreed": true
},
{
"consentKey": "termsOfServiceDiGAV",
"isAgreed": true
}
]
}

응답 (Response)

  • 성공 응답 (200 OK)
{
"userId": "user_123",
"timestamp": 1711015200000,
"termsAgreements": [
{
"termsId": 1,
"isAgreed": true,
"agreedAt": 1711015200000
},
{
"termsId": 2,
"isAgreed": true,
"agreedAt": 1711015200000
}
],
"consentAgreements": [
{
"consentKey": "dataProcessingForImprovement",
"isAgreed": true,
"agreedAt": 1711015200000
},
{
"consentKey": "termsOfServiceDiGAV",
"isAgreed": true,
"agreedAt": 1711015200000
}
],
"requiredTermsComplete": true,
"requiredConsentsComplete": true
}
  • 오류 응답 (400 Bad Request - 필수 항목 동의 누락)
{
"code": 2095,
"message": "REQUIRED_AGREEMENT_MISSING",
"detail": "필수 약관 또는 동의 항목에 대한 동의가 누락되었습니다",
"missingRequired": {
"terms": [
{
"id": 2,
"type": "privacy",
"title": "개인정보 처리방침"
}
],
"consents": []
}
}

오류 코드

합의 도메인 API에서 사용하는 주요 오류 코드는 다음과 같습니다:

HTTP 상태 코드오류 코드메시지설명대응 방법
5002000SERVER_ERROR서버 내부 오류서버 로그를 확인하고 시스템 관리자에게 문의하세요.
4012050INVALID_APP_TOKEN유효하지 않은 토큰입니다올바른 토큰으로 다시 요청하거나 재로그인하세요.
4032060PERMISSION_DENIED요청한 작업에 대한 권한이 없습니다필요한 권한을 확인하고 적절한 권한을 가진 계정으로 요청하세요.
4042080TERMS_NOT_FOUND약관을 찾을 수 없습니다약관 ID를 확인하고 다시 시도하세요.
4092081TERMS_ALREADY_EXISTS이미 존재하는 약관입니다중복 여부를 확인하고 다시 시도하세요.
4092090CONSENT_ALREADY_EXISTS이미 존재하는 동의 항목입니다동의 항목 키를 확인하고 다시 시도하세요.
4042091CONSENT_NOT_FOUND동의 항목을 찾을 수 없습니다동의 항목 ID를 확인하고 다시 시도하세요.
4002092INVALID_CONSENT_KEY유효하지 않은 동의 항목 키입니다유효한 동의 항목 키를 사용하세요.
4042093USER_CONSENT_NOT_FOUND사용자 동의 상태를 찾을 수 없습니다사용자 ID와 동의 항목 키를 확인하세요.
4002094VALIDATION_FAILED합의 상태 검증에 실패했습니다필요한 약관 및 동의 항목을 확인하세요.
4002095REQUIRED_AGREEMENT_MISSING필수 약관 또는 동의 항목에 대한 동의가 누락되었습니다응답에서 제공하는 누락된 항목을 확인하고 동의를 요청하세요.

변경 이력

버전날짜작성자변경 내용
0.1.02025-05-08bok@weltcorp.com최초 작성 (약관 및 동의 도메인 통합 API 문서)