# Phase 2 테스트 체크리스트

실제 구현 기준 재작성 (2026-03-12).
Phase 2에서 실제 구현된 기능 3가지 + Phase 1 Gap Coverage 기준.

> Phase 2 원안(raw/staging/structured/checkpoint 아키텍처)은 채택되지 않음.
> 실제 구현은 Stock Oracle intermediary 아키텍처를 유지하며 아래 기능이 추가됨.

---

## 1. Backfill CLI

**대상:** `apps/pipeline/filing_poller/main.py`, `apps/sync/*.main.py`
**기능:** `--start-date` / `--end-date` 범위 지정 backfill 실행

### 단위 테스트

- [ ] `--start-date` / `--end-date` 파싱이 올바르게 동작한다
- [ ] 날짜 범위가 역순이면 ValidationError가 발생한다
- [ ] `--dry-run` 플래그가 실제 write를 억제한다

### 통합 테스트 (Docker postgres 필요)

- [ ] `--start-date 2026-01-01 --end-date 2026-01-31`으로 polling이 수행된다
- [ ] 이미 존재하는 구간을 재실행해도 중복 row가 없다
- [ ] backfill 완료 후 job_runs 테이블에 succeeded 상태가 기록된다

### 수동 점검

- [ ] 로컬에서 샘플 symbol 1개로 backfill 1주 실행 성공
- [ ] job_run_id가 로그에 일관되게 출력됨

---

## 2. with_retry 적용 (OracleClient.get / OracleClient.post)

**대상:** `libs/oracle_client/client.py`
**기능:** `@with_retry(max_attempts=3)` 데코레이터 적용

### 단위 테스트

- [x] ConnectError 시 3회 재시도 후 OracleConnectionError가 발생한다 — `test_connection_error_raises_oracle_connection_error`
- [x] ReadTimeout 시 3회 재시도 후 OracleTimeoutError가 발생한다 — `test_timeout_raises_oracle_timeout_error`
- [x] 2회 실패 후 3회째 성공 시 정상 응답을 반환한다 — `test_get_retries_on_transient_error_then_succeeds`
- [x] 500 응답 3회 후 OracleServerError가 발생한다 — `test_server_error_raises_oracle_server_error`
- [x] context manager 없이 get() 호출 시 RuntimeError가 발생한다 — `test_client_without_context_manager_raises`
- [x] retry exhaustion 후 RetryableError가 최종 raise된다 — `test_with_retry_exhaustion`

---

## 3. Financial Features

**대상:** `libs/features/financial_features.py`, `libs/features/builder.py`
**기능:** `compute_financial_features` + `build_features_for_event`에 `financial_service` 연동

### 단위 테스트

- [x] 최신 period의 eps/gross_margin/operating_margin이 올바르게 추출된다
- [x] 2개 period 기준 eps_growth_qoq가 올바르게 계산된다
- [x] 2개 period 기준 revenue_growth_qoq가 올바르게 계산된다
- [x] periods가 비어 있으면 빈 dict가 반환된다
- [x] prior eps == 0 이면 eps_growth_qoq가 None이다

### 통합 테스트 (Docker postgres 필요)

- [x] financial_service 제공 시 financial_v1 스냅샷이 추가 생성된다 — `test_financial_v1_snapshot_created`
- [x] financial_v1에 latest_eps / revenue_growth_qoq 필드가 포함된다

### 수동 점검

- [ ] 실제 Oracle에서 AAPL financial data를 받아 financial_v1 스냅샷 생성 확인
- [ ] financial service 불가 시 market_v1/event_v1은 정상 생성됨을 확인

---

## 4. Gap Coverage (Phase 1 검증에서 발견된 미비 사항)

Phase 1 테스트 작성 과정에서 커버되지 않았거나 버그가 발견된 항목.

### 4.1 발견된 버그 수정

- [x] `FredService.get_observations`: `FredProxyResponse(series_id=series_id, **data)` 에서 series_id 중복 keyword argument 버그 수정 (`**{**data, "series_id": series_id}` 로 변경)

### 4.2 신규 테스트로 커버된 항목

- [x] logging 모듈 3개 테스트 추가 (`tests/unit/test_logging.py`)
- [x] FredService 2개 테스트 추가 (`tests/unit/test_fred_service.py`)
- [x] LLMParserStub 2개 테스트 추가 (`tests/unit/test_llm_parser_stub.py`)
- [x] with_retry exhaustion 테스트 추가 (`tests/unit/test_retries.py`)
- [x] OracleClient connection/timeout/no-context-manager 테스트 추가 (`tests/unit/test_oracle_client.py`)

---

## 5. 운영 전 점검

- [ ] 모든 sync job에 대해 sample run 로그가 있다
- [ ] job_runs 테이블에 상태 전이(pending → running → succeeded/failed)가 정상 기록된다
- [ ] Oracle 응답 실패 시 partial success가 명확히 기록된다
- [ ] backfill과 poll 모드가 모두 성공한다
- [ ] runbook(`dev/phase2_deliverables/operator_runbook.md`)에 있는 재시도 명령이 실제로 동작한다
- [ ] 환경변수 누락 시 fail-fast 한다

---

## 6. 승인 기준

| 항목 | 상태 | 비고 |
|---|---|---|
| Backfill CLI 구현 | ⬜ | CLI 테스트 작성 및 통합 검증 필요 |
| with_retry 단위 테스트 | ✅ | 6개 테스트 통과 |
| Financial Features 단위 테스트 | ✅ | 5개 테스트 통과 |
| financial_v1 통합 테스트 | ✅ | Docker postgres 실제 연동, Oracle은 httpx_mock |
| Gap Coverage 버그 수정 | ✅ | FredService 버그 수정 + 12개 신규 테스트 |
| 운영 전 점검 | ⬜ | 실제 Oracle 환경에서 수행 필요 |
