[BE-30C] JobkoreaCompanyBoundAdapter 조립 — JRS 회사 채용관 수집

상태: 설계 완료 (designed). 근거 TDD: 20260727-jobkorea-dual-source-type-tdd.md.

작업 내용 (설계 의도)

근거 TDD: 20260727-jobkorea-dual-source-type-tdd.md “시스템 역할 경계”

변경 사항

BE-30B 파서와 SourceRequestExecutor(BE-02 규약 강제)를 결선해 jrs.jobkorea.co.kr/{slug} 회사 채용관을 수집하는 어댑터를 SPI에 등록합니다.

  • JobkoreaCompanyBoundAdaptersupports(JOBKOREA, COMPANY_BOUND)=true. fetchList(CompanyBound descriptor)에서 SourceRequestExecutorjrs.jobkorea.co.kr/{slug} 호출 → BE-30B 파서 → RawJobPosting[].
  • SourceCapabilities 선언: sourceType=COMPANY_BOUND, providesDeadline=true(목록 마감일), requiresDetailFetch(파서 확정 결과), changeSignalKind(BodyHash 또는 FieldHash).
  • SourceCompliancePolicy: jrs.jobkorea.co.kr는 robots 전면 허용이나 UA 일반 식별자·요청 지연은 예의상 적용. 허용 경로 prefix는 채용관 경로.
  • supportedCategories() = emptyList()(회사 종속형).
  • KDoc에 robots 실측 결과(jrs. 전면 허용, www.와 다른 호스트) 근거 명시(NFR-9).

롤백: disable_at 소프트 비활성화 — robots 정책 변경·파서 고장 시 즉시 중단.

의존

  • BE-30A (SPI (platform, sourceType) 디스패치)
  • BE-30B (JRS 파서·마감일 정규화 — 게이트 통과 전제)
  • BE-02 (SourceRequestExecutor·SourceCapabilities·CollectionDescriptor)

다이어그램

처리 흐름

sequenceDiagram
    participant G as JobSourceGatewayImpl
    participant A as JobkoreaCompanyBoundAdapter
    participant E as SourceRequestExecutor
    participant L as JobkoreaCompanyBoundListParser
    G->>A: fetchList(CompanyBound wooribank)
    A->>E: get(jrs.jobkorea.co.kr/wooribank)
    E-->>A: HTML
    A->>L: parse(html)
    L-->>A: List(RawJobPosting)
    A-->>G: Fetched(RawJobPosting[])

클래스 의존

flowchart LR
    Ad[JobkoreaCompanyBoundAdapter] --> Exec[SourceRequestExecutor]
    Ad --> ListP[JobkoreaCompanyBoundListParser]
    Ad --> Cap[SourceCapabilities]
    Ad -->|supports JOBKOREA COMPANY_BOUND| Gateway[JobSourceGatewayImpl]

테스트 케이스

  • supports(JOBKOREA, COMPANY_BOUND)가 true, supports(JOBKOREA, AGGREGATOR)가 false다
  • CompanyBound(wooribank) descriptor로 목록을 수집해 RawJobPosting[]을 반환한다
  • 마감일이 목록에서 정규화되고 상시채용은 deadlineAt=null이다
  • 목록 조회가 실패하면 Failed를 반환하고 예외를 전파하지 않는다(소스 가드 대상)
  • UA가 일반 식별자로 부착되고 요청 지연이 적용된다
  • supportedCategories()가 빈 목록을 반환한다(회사 종속형)
  • 애그리게이터 descriptor(AGGREGATOR)가 오면 명시적 예외를 던진다