# [task-2929] InsuRo P0-1 Drive 프록시 Gap 1(FCPA drive_file_id 일관성) — ANU검증+Codex합의 완료·프로덕션 배포 BLOCKED (DDL 툴 부재)

- 작업일: 2026-08-09 (KST)
- 팀: dev1-team(bot-b). 브랜치 `task/task-2929-dev1` head **a87b77e**, base `task/task-2928-dev1` **22c3f3c**.
- 워크트리: `/home/jay/projects/InsuRo/.worktrees/task-2929-dev1`
- 회장 지시: **"codex cc와 조율해 합일되면 go"** (재확인 없이 머지+마이그레이션+재배포+L1 스모크). 콜백 수신 후 ANU가 검증→Codex 재조율 실행.

## 델타 (4파일 +135/-4)
Gap 1 = FCPA 업로드가 `fcpa_config.pdf_url`만 저장·`drive_file_id` 미기록(다른 3테이블은 이미 통일). 수정:
- `server/main.py` upload_fcpa_pdf upsert_payload에 `"drive_file_id": gdrive.extract_drive_file_id(drive_url)` 추가(L957).
- create_file_ticket FCPA 인가(L5915~): `select("drive_file_id,pdf_url")` + `row_fid = row.get("drive_file_id") or extract(pdf_url)` + `if row_fid and row_fid==file_id` (빈컬럼 우연매칭 방어, defense-in-depth. 단 file_id는 L5867서 이미 400 가드).
- 신규 마이그레이션 `supabase/migrations/20260809120000_fcpa_drive_file_id.sql`: `ADD COLUMN IF NOT EXISTS drive_file_id text` + pdf_url 백필 + `CREATE INDEX IF NOT EXISTS` (멱등·additive·no-drop).
- 신규 테스트 4(drive_file_id 우선 200 / pdf_url 폴백 200 / insert·update 배선).

## ANU 독립검증 결과 — GREEN
- clean **/tmp** worktree(CI parity, a87b77e): 전체 회귀 **1381 passed, 1 skipped, 0 fail** (147s). FCPA 신규 24 PASS. pre-existing CORS 테스트도 clean에선 PASS.
- diff 직접 정독: small·backward-compatible·잘 가드됨. 회귀 0.
- 회귀는 2929 브랜치=2928 커밋 위 → **2928+2929 스택 전체 커버**.

## Codex 재조율 결과 — 합의(AGREE-TO-MERGE)
- Gap 1: **RESOLVED** (write path·authz read path·마이그레이션 백필 end-to-end). upload_pdf가 full Drive URL(`/file/d/{id}/view`) 반환 → extract_drive_file_id 정합.
- 신규 회귀: **NONE**. 마이그레이션 멱등·additive. SQL 정규식 `substring(pdf_url from '/file/d/([^/]+)')`과 파이썬 파서(`/file/d/([^/?#]+)`) URL 형태 일치.
- (참고) OLD 코드 false-match 없음 — file_id는 상류 400 가드로 falsy 차단. 새 truthiness 가드는 방어적·비필수.

## ★ 프로덕션 DB 상태 (read-only 실측, service key)
- newsletters.drive_file_id ✅ / premium_data.drive_file_id ✅ / policy_analyses.**drive_file_ids**(복수 text[]) ✅ → **task-2927 마이그레이션(20260808120000) 완전 적용됨**.
- fcpa_config.drive_file_id ❌ (미존재) / fcpa_config.pdf_url ✅ → **유일 미적용 = 20260809120000(fcpa)**.
- ⚠ 함정: policy_analyses는 단수 `drive_file_id`가 아니라 **복수 `drive_file_ids` text[]** (코드 main.py:5872 `.contains()`). 단수명 조회는 42703 오탐.

## ★★ 배포 BLOCKED — DDL 적용 툴 부재 (미해결)
- `psql` 미설치. `.env`에 Management API 토큰/`DATABASE_URL`/postgres 접속문자열 **없음** (오직 `INSURO_NEW_SERVICE_ROLE_KEY`=PostgREST 데이터키, DDL 불가).
- `exec_sql` RPC → 404 PGRST202(미존재). `/pg/query` → 404. `scripts/run_migrations.py`도 동일 404 엔드포인트 의존 → 작동 불가.
- 결론: **이 환경에서 fcpa 마이그레이션 DDL 적용 불가.** 머지 코드가 `fcpa_config.drive_file_id` 조회 → 마이그레이션 없이 머지+재시작 시 FCPA 인가경로 손상. 따라서 GO 완결 불가.
- 배포 모델 재확인: systemd `insuro-api.service` WorkingDirectory=`/home/jay/projects/InsuRo/server`, EnvironmentFile 루트 `.env`, 로컬 main 체크아웃 구동(PID 라이브·api.insuro.biz 200). 즉 **로컬 main ff-merge + systemd restart = 배포**. `Restart=always`라 마이그레이션 전 머지 시 크래시 재기동으로 깨진 코드 픽업 = 랜드마인 → **머지도 HOLD**.

## 현재 조치 (staged, no production touch)
- 로컬 main **f81085f 무변경**. 어떤 브랜치도 머지 안 함. /tmp verify 워크트리 정리. task-2929.done→.done.acked.

## 남은 절차 (회장 결정/실행 필요)
1. **fcpa 마이그레이션 적용**: 회장이 Supabase Studio SQL editor로 `20260809120000_fcpa_drive_file_id.sql` 실행(멱등, 안전). 또는 Management access를 ANU에 제공하면 ANU 적용.
2. 적용 확인 후 → ANU가 **로컬 main ff-merge(f81085f→a87b77e, 2928+2929 함께) + systemd insuro-api restart + L1 스모크(api.insuro.biz 200 + file-ticket 401/404 + FCPA 200)**.
3. 원격 main(f2b282e=task-2925)은 이 체인에서 로컬-머지 배포라 lag — 별도 정리 대상.

관련: [[project_insuro_drive_public_removal_proxy_p0_1_phase1_task2927_260808]]
보고서: `memory/reports/task-2929.md`
