# [Lv.3] PR-E1 — consultation-history/v1 LIST 에 옵션 reference_id 필터

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "server/routes/consultation_history_v1.py"
    - "server/tests/**"
  forbidden_paths:
    - "src/**"
    - "extension/**"
    - ".github/**"
    - "server/migrations/**"
    - "supabase/**"
  commands:
    - "pytest"
    - "python"
    - "git"
  merge_policy: "none"
  ttl_hours: 8
```
> ★ merge_policy=none — PR OPEN 유지(자동머지 금지). base=현 origin/main(6f26ccc). 신규 브랜치.

## 배경·단일소스
- 설계: `/home/jay/workspace/memory/plans/insuro-composite-design/integration-design-260721.md`.
- 아키텍처 X: 확장이 캡처→매칭→동의→ingest, **웹앱은 나중 조회/뷰**. 이 PR-E1 = 웹앱(PR-E2)이 **고객별 상담이력**을 조회할 수 있도록 서버 LIST 에 `reference_id` 필터 추가(선행).
- 현 `GET /api/insuro/consultation-history/v1`(LIST, `server/routes/consultation_history_v1.py:500`)은 per-FA·ok-only 뷰·`created_at desc`·`DEFAULT_LIST_LIMIT=100`·projection 화이트리스트. **필터 파라미터 없음** → 고객별 조회 불가.
- Codex 조율 결론(B): 클라 필터는 100 cap 로 오래된 레코드 누락 + 전 고객 데이터 브라우저 노출 → **서버 `reference_id` 필터가 정답**. 테이블에 `reference_id` 인덱스 존재(`013_...sql:64-67`), V1 은 `reference_type='CUSTOMER'` 만.

## 작업 (surgical — LIST 만)
1. `list_consultation_history_v1`(LIST 핸들러)에 **옵션 쿼리 파라미터 `reference_id: str | None = None`** 추가(FastAPI `Query(None)`).
2. `reference_id` 가 주어지면 기존 쿼리에 **`.eq("reference_id", reference_id)`** 추가. **per-FA scope·`OK_ONLY_VIEW`·`.order(created_at desc)`·limit·projection(`_ALLOWED_RESPONSE_FIELDS`) 전부 그대로 유지** — 필터만 얹는다.
3. `reference_id` 형식 검증: **UUID 파싱 실패 시 fail-closed** — `422`(FastAPI 검증) 또는 빈 결과. **malformed 를 무필터로 흘려 전체 반환 절대 금지**(더 넓게 노출되면 안 됨). 안전한 쪽 택: 검증 실패 → 422 또는 `{records:[],count:0}`.
4. `reference_id` 없으면 **기존 동작 100% 동일**(회귀 0).
5. feature flag(`_require_feature_enabled`)·pilot allowlist dependency **그대로**. flag 켜지 마라.
6. DETAIL 엔드포인트·ingest(POST)·마이그레이션·뷰 **건드리지 마라.**

## 제약
- `server/routes/consultation_history_v1.py`(+ `server/tests/`) 외 변경 0. 마이그레이션/스키마 불변.
- projection 화이트리스트에 필드 추가/제거 금지. raw 테이블 직접 접근 금지(뷰 유지).
- per-FA 스코프 절대 완화 금지(다른 FA 레코드 노출 = 치명).

## 검증 (전부 통과)
- `reference_id=<uuid>` → **그 고객의 OK 레코드만** 반환(created_at desc, ≤limit).
- **per-FA 격리**: FA-A 가 FA-B 소유 reference_id 로 조회 → 0 건(타 FA 레코드 노출 0).
- **ok-only**: REQUIRES_REVIEW 레코드는 reference_id 일치해도 제외(뷰 필터 유지).
- **malformed reference_id**(비-UUID) → 422 또는 빈 결과(전체 반환 아님).
- `reference_id` 미지정 → 기존 LIST 동작 회귀 0.
- feature flag OFF → 기존대로 차단(403/feature-disabled) 유지.
- 기존 `server/tests/` consultation history GET 테스트 회귀 0. `pytest server/tests/ -k consultation` (또는 해당 경로).

## 완료
- 변경 파일 = `server/routes/consultation_history_v1.py` + `server/tests/` 만 (`git diff --stat`)
- **dev6 금지** — dev1. worktree finish → PR(**OPEN 유지·머지 금지** merge_policy none) → ANU 독립검증.
- **ANU callback**(UTF-8 ≤3900 bytes, envelope). ⚠️ 세션 사망 대비: 완료 즉시 finish-task(push) 우선.
