[BE-30] JOBKOREA 겸용 플랫폼 표현 — SourceType 고정 해소 (모델링)

상태: 설계 완료 (designed). robots 게이트 통과 + 방안 A 채택. 근거 TDD: 20260727-jobkorea-dual-source-type-tdd.md. robots 실측(2026-07-27): jrs.jobkorea.co.kr/robots.txt = User-agent: * / Allow: / (전면 허용). 애그리게이터 www.jobkorea.co.kr의 AI 크롤러 차단과 다른 호스트라 회사 종속형은 규약 청정 → 방안 C(축소) 폐기.

작업 내용 (설계 의도)

근거 TDD: /Users/biuea/Desktop/dpdpdndn/프로젝트/공고알림앱/20260727-jobkorea-dual-source-type-tdd.md

변경 사항

JobPlatform이 소스 유형을 1개로 고정하던 것을 지원 집합(Set<SourceType>) 으로 완화해, JOBKOREA가 AGGREGATOR·COMPANY_BOUND를 겸용하게 합니다. 이 티켓은 모델링(도메인 계층)만 담당하며, BE-21 케이스 6(우리은행 잡코리아 회사 종속형 등록 400)을 해소하는 즉시 배포 가능한 단독 언블로커입니다.

  • domain/common/JobPlatform.ktenum class JobPlatform(val sourceType: SourceType)enum class JobPlatform(val supportedSourceTypes: Set<SourceType>). JOBKOREA(setOf(AGGREGATOR, COMPANY_BOUND)), 나머지는 단일 원소 집합. fun supports(sourceType): Boolean = sourceType in supportedSourceTypes 추가.
  • domain/company/JobSource.ktforCompanyrequire(platform.sourceType == COMPANY_BOUND)require(platform.supports(COMPANY_BOUND)), forAggregator 대칭. 잘못된 조합 거부 불변식은 유지(SARAMIN을 회사 종속형으로 금지) — 겸용(JOBKOREA)만 신규 통과.
  • 스키마 변경 0건job_sources.source_type이 이미 행 단위 컬럼이고 유니크 제약이 (platform, source_slug) / (platform, category, keyword)로 분리돼 겸용을 이미 수용. 마이그레이션·데이터 백필 불필요.

롤백: 하위 호환(검증 완화만)이라 코드 revert로 즉시 롤백, 데이터 정리 불필요.

의존

  • 없음 (기존 JobPlatform·JobSource만 수정)

다이어그램

처리 흐름

sequenceDiagram
    participant S as JobSource.forCompany
    participant P as JobPlatform
    S->>P: supports(COMPANY_BOUND)
    P-->>S: true (JOBKOREA 겸용)
    S-->>S: JobSource(sourceType=COMPANY_BOUND)

클래스 의존

flowchart LR
    Source[JobSource] --> Platform[JobPlatform supports]
    Platform --> SType[SourceType]

테스트 케이스

  • JobPlatform.JOBKOREA.supports(COMPANY_BOUND)supports(AGGREGATOR)가 모두 true다
  • JobPlatform.INCRUIT.supports(AGGREGATOR)가 false, SARAMIN.supports(COMPANY_BOUND)가 false다
  • JobSource.forCompany(JOBKOREA, "wooribank")가 성공하고 sourceType=COMPANY_BOUND다 (BE-21 케이스 6 해소)
  • JobSource.forAggregator(JOBKOREA, ...)도 여전히 성공한다 (겸용)
  • forCompany(SARAMIN)·forAggregator(INCRUIT)는 여전히 IllegalArgumentException이다 (회귀 방어)
  • Testcontainers: 겸용 JOBKOREA 회사 종속형 소스를 저장·복원 왕복하면 필드가 일치한다
  • Testcontainers: (JOBKOREA, wooribank) 회사 종속형 행과 애그리게이터 JOBKOREA 행이 유니크 제약 충돌 없이 공존한다