---
name: project-insuro-drive-proxy-fcpa-gap1-task2929-260809
description: InsuRo P0-1 Drive 프록시 Gap 1 보완 — FCPA drive_file_id 일관성(task-2929) 완료·finalize-only·머지HOLD
metadata:
  type: project
---

# InsuRo P0-1 Drive 프록시 Gap 1: FCPA drive_file_id 일관성 (task-2929, 260809)

Codex 교차검증 **Gap 1** 보완: FCPA 가이드 업로드가 `fcpa_config.pdf_url`만 저장하고 `drive_file_id` 미기입 → 다른 3테이블(newsletters/premium_data/policy_analyses)과 일관성 통일. 기존 pdf_url 실시간추출 매칭은 하위호환 폴백 유지.

## 변경 (4파일, +135/-4) — base=task-2928 HEAD `22c3f3c`
1. 신규 마이그레이션 `supabase/migrations/20260809120000_fcpa_drive_file_id.sql`: `fcpa_config.drive_file_id text` ADD IF NOT EXISTS + `pdf_url` 백필(`substring(... '/file/d/([^/]+)')`) + 인덱스. 멱등.
2. `server/main.py:959` `upload_fcpa_pdf` upsert_payload에 `"drive_file_id": gdrive.extract_drive_file_id(drive_url)` 추가.
3. `server/main.py:5915~` file-ticket FCPA 공개등급 인가: `select("drive_file_id,pdf_url")` → `row_fid = row.get("drive_file_id") or gdrive.extract_drive_file_id(pdf_url)`, `if row_fid and row_fid == file_id`. drive_file_id 우선·pdf_url 폴백·None 우연매칭 이중방어(create_file_ticket 진입 시 `if not file_id: 400` 이미 보장).
4. 테스트 4건: drive_file_id 우선 인가 200 / pdf_url 폴백 인가 200 / FCPA 업로드 upsert insert·update 배선.

## 검증
- 전체 회귀 **1381 passed, 1 skipped**(회귀 0). CORS pre-existing 테스트 이 환경선 PASS. py_compile OK.
- L1 실서버(uvicorn :8097): /api/status 200, /file/{bogus} 404, file-ticket 무인증 401. 좀비 0.

## 상태 = finalize-only·머지HOLD (ANU 소유)
- 브랜치 `task/task-2929-dev1` HEAD **a87b77e**(원격 동기 push). base=`task/task-2928-dev1` 22c3f3c.
- **머지 금지** — ANU가 **task-2928 + task-2929 함께 머지** + 마이그레이션 2건(20260808120000·20260809120000) Management API 적용 + systemd insuro-api 재배포. 회장 지시="codex 합의 시 go".
- 남은 절차: ANU 독립검증 → Codex 재조율(Gap 1 해소 확인 합의) → 합의 시 함께 배포.
- result.json authoritative=false·owner_pickup_required=true. p0b_inbox 프로젝트경로→workspace 정규위치 `cp` 보정함(worktree cwd gotcha).

## 교훈 (scope-guard stale base)
worktree를 `git worktree add`로 수동생성(dispatch 미경유)→worktree-base.json 마커 부재→scope-guard가 merge-base(origin/main)=f2b282e(task-2925)로 폴백→task-2928 파일(file_ticket_store.py·gdrive.py)을 task-2929로 오귀속→FAIL(오탐). 해소=`events/task-2929.worktree-base.json`에 실 fork point base_sha 22c3f3c 기록→재실행 PASS(4 files in scope). origin/main 뒤처진 로컬 arc(task-2927~2929) 위 작업 시 주의. 관련=[[project-insuro-drive-public-removal-proxy-p0-1-phase1-task2927]]
