---
task_id: task-2278
type: context
scope: task
created: 2026-04-28
updated: 2026-04-28
status: completed
---

# 맥락 노트: task-2278

**task**: task-2278

---

## 결정 근거

### 1. 서버-사이드 원본 조회 (Codex critical 대응)
- 결정: revise-content에서 content_id 필수, 서버에서 content_id + user_id로 원본 조회
- 이유: 클라이언트에서 original_content를 보내면 조작 가능 → 보안 취약점
- 대안(기각): 클라이언트 전송 original_content 신뢰 → 소유권 위조 가능

### 2. parent_id 셀프 참조 방식
- 결정: contents 테이블에 parent_id (uuid, nullable, self-reference) 추가
- 이유: 별도 versions 테이블 대비 구현 간단, 기존 쿼리 호환
- 대안(기각): 별도 content_versions 테이블 → 스키마 복잡도 증가, JOIN 필요

### 3. 제어 컴포넌트 체크박스 (Codex medium 대응)
- 결정: useState로 선택 상태 관리하는 제어 컴포넌트
- 이유: defaultChecked는 재렌더링 시 상태 유실 위험
- 대안(기각): uncontrolled defaultChecked → 탭 전환/재검증 시 상태 초기화

### 4. generate-status 응답에 content_id 포함
- 결정: 생성 완료 시 저장된 content의 id를 응답에 포함
- 이유: 수정 반영 시 원본 content_id가 필수. 현재 미전달

## 3 Step Why

**1st Why**: "왜 이 설계가 필요한가?"
→ 금소법 warn 판정 시 사용자가 수정 제안을 선택하여 자동 재생성 + 재검증할 수 있어야 함. 현재는 경고만 표시하고 수정 경로가 없어 불완전.

**2nd Why**: "왜 서버-사이드 재생성 + 소유권 검증이 최선인가?"
→ 클라이언트에서 원본 전송 시 조작 가능(Codex critical). 서버에서 content_id로 원본 조회하면 소유권 + 무결성 보장.

**3rd Why**: "왜 parent_id 기반이 다른 대안보다 나은가?"
→ 별도 versions 테이블은 스키마 복잡도 증가. parent_id 셀프 참조는 기존 contents 테이블 활용, 쿼리 간단, 1:N 체인 자연스러움.

★ A-B-C 논리적 일관성 확인: 문제(수정 경로 없음) → 해결(서버-사이드 재생성, 보안 검증) → 구현 방식(parent_id 셀프 참조, 최소 스키마 변경) 일관됨.

## 참조 자료

- 태스크 파일: `/home/jay/workspace/memory/tasks/task-2278.md`
- Codex 리뷰: Codex gate check 결과 (critical: 소유권 검증 필수)
- 기존 코드: server/main.py:913 (_run_content_cli_async), :938 (_run_compliance_check_async)

## 주의사항

- contents 테이블 parent_id는 nullable (원본은 null)
- types.ts 수동 업데이트 필요 (supabase gen types 미실행 환경)
- revise-content에서 haiku 모델 사용 (비용 절감)
- 수정본 content_type은 "revision" 이 아닌 원본과 동일한 content_type 유지 (히스토리 필터 호환)
