[BE-79] 단계 3 통합 · E2E 시나리오 테스트

작업 내용 (설계 의도)

근거 TDD: 20260808-지원관리-확장-tdd.md — “Testing Plan 시나리오 E2E”, “Release Scenario 3단계”

변경 사항

단계 3 완료 판정 기준(PRD Milestones: “Gmail 웹훅 1건 수신→검토 화면 반영까지 1회 왕복 성공, 소급 재평가 후 신규 매칭 공고에 알림이 발송되지 않음을 확인, 사용자 가중치 수정 후 재평가 결과가 반영됨”)을 실 DB 기반 시나리오 1본으로 검증합니다.

  1. Stage3ContactMatchingScenarioTest를 신설합니다. 기존 시나리오 파일을 수정하지 않습니다(Single Writer).
  2. 시나리오: 서명된 웹훅 1건 수신 → 후보 계산 → Discord 검토 요청 알림 발송 확인 → 검토 화면 조회 → 반영 → 지원 상태 전이 + 면접 등록 확인 → dryRun 백필로 오탐 사전 점검 → 실백필 실행 → 신규 매칭 공고에 알림 미발송 확인 → 축 가중치 수정 → 재평가 결과 반영 확인 → 소스 레지스트리 상태 전이 확인.
  3. FR-87의 핵심 보장(소급 재평가로 알림이 나가지 않음)을 반드시 검증합니다 — 백필 직후 09:00 알림 배치를 실행해 신규 매칭 공고에 대한 발송 이력이 0건임을 확인합니다.
  4. 피처 플래그 전환 순서(3-3·3-6·3-8·3-10·3-11)를 검증합니다.
  5. 단계 1·2 회귀가 깨지지 않았는지 확인합니다.
  6. 릴리즈 체크리스트 문서화 — “인증 ON이 터널 ON보다 먼저”(1-9 → 1-10), “dryRun 점검이 실백필보다 먼저”(3-5 → 3-7) 두 순서 제약을 /private-release 체크리스트에 남깁니다.

의존

  • BE-69, BE-70, BE-71, BE-72, BE-73, BE-74, BE-75, BE-76, BE-77, BE-78, BE-80 (단계 3 전량)

다이어그램

처리 흐름

sequenceDiagram
    participant T as Stage3ScenarioTest
    participant Hook as WebhookApi
    participant Noti as NotificationBatch
    participant Review as ContactEventApi
    participant App as ApplicationApi
    participant Match as BackfillApi
    participant Rec as WeightApi
    T->>Hook: POST /api/webhooks/contact-events (서명)
    T->>Noti: 검토 요청 알림 발송 확인
    T->>Review: GET /contact-events/{id} 후보 확인
    T->>Review: POST /decisions (APPLY)
    T->>App: 상태 전이 + 면접 등록 확인
    T->>Match: POST /field-scope-backfills (dryRun=true)
    T->>Match: POST /field-scope-backfills (dryRun=false)
    T->>Noti: 09:00 배치 실행 → 신규 매칭 알림 0건 확인
    T->>Rec: PUT /recommendations/weights → 재평가 반영 확인

클래스 의존

flowchart LR
    subgraph Test["src/test scenario"]
        Scenario[Stage3ContactMatchingScenarioTest]
        Fixture[Stage3ScenarioFixtures]
    end
    subgraph Api["presentation"]
        HookApi[ContactEventWebhookApiController]
        ReviewApi[ContactEventApiController]
        EvalApi[JobPostingEvaluationApiController]
        WeightApi[RecommendationWeightApiController]
        OpApi[OperationApiController]
    end
    Scenario --> Fixture
    Scenario --> HookApi
    Scenario --> ReviewApi
    Scenario --> EvalApi
    Scenario --> WeightApi
    Scenario --> OpApi

테스트 케이스

  • 서명된 웹훅 수신부터 검토 반영까지 전 흐름이 실 DB로 1회 왕복 성공한다
  • 검토 요청 알림이 1건 발송되고 링크가 포함된다
  • 반영 후 지원 상태가 전이되고 면접 회차가 최대+1로 등록된다
  • 종료 상태 지원에 반영하면 409이고 상태가 변하지 않는다
  • dryRun 백필이 revision을 만들지 않고 통계만 반환한다
  • 실백필 후 신규 매칭 공고의 notification_eligible이 0이다
  • 백필 직후 09:00 알림 배치를 돌려도 신규 매칭 공고 알림이 0건이다 (FR-87 핵심)
  • 백필 전 이미 매칭이던 공고의 알림 동작은 변하지 않는다
  • 축 가중치 수정 후 재평가하면 새 비중으로 점수가 바뀐다
  • 수집 성공 후 소스 레지스트리 상태가 ACTIVE로 전이된다
  • 같은 웹훅 메시지를 두 번 보내면 이벤트 1건·알림 1건이다
  • matching.field-weighted-scope 플래그 OFF면 제목 단독 매칭으로 복귀한다
  • contact.inbound-webhook 플래그 OFF면 웹훅이 404이고 이벤트가 저장되지 않는다
  • 웹훅으로 받은 첨부 메타데이터가 검토 화면 상세에 그대로 노출된다 (B-1)
  • 공고 상세에 매칭 근거(matchFieldEvidences)와 matchScore·matchThreshold가 노출된다 (C-2)
  • 미매칭 공고의 상세에 매칭 근거가 채워져 “왜 임계치에 못 미쳤는지”가 설명된다 (A-2)
  • 제외 키워드 미매칭과 점수 미달 미매칭이 excludedByKeyword로 구분된다 (A-2)
  • 단계 1·2 경로(인증·관리 상태·교차 목록·서류·추천도)가 회귀 없이 동작한다