[BE-05] PartnerDomainService (생성·발급·재발급·폐기·상태 전이·인증)

작업 내용 (설계 의도)

변경 사항

근거 TDD: ../TDD.md “인터페이스 시그니처”·“상태 전이 표”·ADR-008. Partner 라이프사이클 도메인 로직.

  • domain/partner/service/PartnerDomainService.kt — BE-01의 Repository·ApiKeyGenerator 조율.
    • createPartner(name, linkedUserId): Pair<Partner, IssuedApiKey> — Partner 저장 후 최초 키 발급(2-step: id 확보 → partner_<id>_<random> hash 갱신, mcp 방식).
    • issueKey(partnerId): IssuedApiKey.
    • reissueKey(partnerId): IssuedApiKeyfindActiveByPartnerId 구 키 revoke() + 신규 발급.
    • revokeKey(partnerId, keyId).
    • changeStatus(partnerId, active) — Partner suspend()/activate().
    • authenticate(keyId, plainKey): AuthenticatedPartner — 키 조회·matches·키 isActive·Partner validateActive 검증 후 (partnerId, linkedUserId) 반환. 실패 시 도메인 예외(401/403 매핑).
  • IssuedApiKey(plainKey, apiKey)·AuthenticatedPartner(partnerId, linkedUserId) data class.

롤백: 재발급 실패 시 UseCase 트랜잭션 롤백으로 구 키 ACTIVE 유지(호출부 BE-06).

의존

  • BE-01

다이어그램

처리 흐름 (재발급)

sequenceDiagram
    participant S as PartnerDomainService
    participant KR as PartnerApiKeyRepository
    participant G as ApiKeyGenerator
    S->>KR: findActiveByPartnerId(partnerId)
    S->>S: oldKey.revoke()
    S->>KR: save(oldKey)
    S->>G: generateRandomPart / hash
    S->>KR: save(newKey)

테스트 케이스

  • createPartner는 Partner 저장 후 ACTIVE 키 1개를 발급하고 평문 키를 반환한다.
  • reissueKey는 기존 ACTIVE 키를 REVOKED로 만들고 새 ACTIVE 키를 발급한다.
  • authenticate는 유효 키·ACTIVE 파트너면 (partnerId, linkedUserId)를 반환한다.
  • authenticate는 REVOKED 키면 PartnerApiKeyInactiveException(401)을 던진다.
  • authenticate는 SUSPENDED 파트너면 PartnerSuspendedException(403)을 던진다.
  • authenticate는 hash 불일치면 예외를 던진다.
  • changeStatus(false)는 Partner를 SUSPENDED로 전이한다.