# TheRoad Scene Lab — 아키텍처 리팩토링 **기록 (아카이브)**

> ⚠️ **이 문서 세트는 리팩토링 기록(아카이브)입니다.**
> 현재 저장소 상태는 **[`docs/review-codex-1/`](../review-codex-1/)** (Codex 전수 리뷰)와
> [`docs/architecture/`](../architecture/) (현행 아키텍처 설명)에서 확인하세요.
> - Phase 0~5 "완료"는 **subset 성과** (refactor subset 256p green)이며 저장소 전체 품질 게이트는 아직 green 아님 (repo 전체 637p / 56f, 2026-04-21).
> - 프런트 `/analyze` vs `/steps/run-all` 공개 API 병존, `_needs_presync` 하드코딩, `image_service.py` shim 잔존 등 이월 과제는 [`docs/review-codex-1/11-fix-plan.md`](../review-codex-1/11-fix-plan.md) 참조.
> - **📍 이 문서 세트의 모든 `파일:line` 라인 번호는 당시 코드 기준이며 현재 코드와 drift합니다.** (예: `EpisodeDetail.tsx:821` → 현재 파일 149 LOC, `steps.py:768-1487` → 현재 384 LOC, `image_service.py:4471` → 파일 자체가 3-way split됨). 최신 line은 직접 `grep` 권장. 심볼 이름 기준으로 읽으세요.
>
> 작성: 2026-04-17 (v0.5.3) / 최종 갱신: 2026-04-21 (v0.6.0) / 아카이브 배너 + line drift 경고: 2026-04-22 (W0-F03, W0-F05)

## 리팩토링 subset 완료 요약 (v0.6.0, 2026-04-21)

> 본 표는 **이번 리팩토링 작업 묶음(subset) 기준의 성과**이며, repo 전체 품질 상태와는 분리해서 읽어야 합니다.

| Phase | 상태 | 주요 산출 | 유의사항 |
|-------|------|----------|----------|
| **Phase 0** (현행 계약) | ✅ | test baseline 복구, docs 수치 갱신, AnalysisService 경로 정리 | 문서 drift는 W0에서 재교정 |
| **Phase 1** (Step Catalog) | ✅ | step_manifest 필드 확장 (lifecycle/step_type/resume_sensitive), ApplicabilityValidator, checkpoint_io 유틸 | `STEP_MANIFEST` 직참조가 StepRunner/steps.py에 잔존 (W1 이월) |
| **Phase 2** (Checkpoint Sync) | ✅ | 5개 Sync Service 분해 (Entity/Relation/SceneStill/Outlook/EpisodeProjection) | `scene_still_sync_service.py` 399 LOC — W4에서 3-way 분해 예정 |
| **Phase 3** (Image Domain) | ⚠️ 진행 중 | ImageService 5,281 → 3-way split (`image_service` 1,228 + `reference` 1,150 + `scene` 2,936 = **5,314 LOC**) | "완전 제거"가 아니라 **helper shim 잔존 상태**. W5에서 facade-first로 축소 예정 |
| **Phase 4** (Legacy Convergence) | ⚠️ 부분 | `AnalysisService` 내부 폐기 (1,137줄 제거), StepRunner가 내부 실행 단일 수렴 | `/episodes/{id}/analyze`, `/reanalyze-scenes` **공개 API는 여전히 live**. 프런트 `Episodes.tsx`가 legacy 경로 사용 — W1에서 단일화 |
| **Phase 5** (Frontend) | ✅ | React Query 전환 완료, EpisodeDetail 1,358→148 (-89%), useState 34→1 (-97%) | `SceneVariationCard.tsx` 1,606 LOC, `Entities.tsx` 1,258 LOC 등 하위 hotspot 잔존 — W6 이월 |
| **세션 E** (Observability) | ✅ | Backend `except: pass` 38→0 (silent failure 제거) | ✅ 유일하게 repo-wide 달성 |

**최종 태그**: `v0.6.0` (커밋 `631a082`)

**누적 성과** (subset 기준):
- Backend: **subset 256 tests passed** (repo 전체 637p / 56f / 2e / 1s — legacy contract drift 56건 W3/W5에서 정리 예정)
- Image 도메인: image_service 5,281 → shim 1,228 + reference 1,150 + scene 2,936 (W5 facade-first 대기)
- Frontend: 17 Query 훅 + 7 Mutation 파일 (27 mutation) + 4 sub-component (Header/WorldGuide/ActionBar/Stills)
- Docs: `docs/architecture/` 7개 + `docs/architecture-easy/` 8개 (비전문가용 신설) + `pipeline_explained.html` + product roadmap discussion + **`docs/review-codex-1/` (Codex 10개 리뷰 + 통합 수정 계획서)**

---

---

## 이 폴더의 위치

이 문서 세트는 세 개의 조사 결과를 **통합·검증·확정한 최종 설계**다.

| 입력 | 성격 | 출력 |
|---|---|---|
| `docs/architecture-refactor/` | Claude 초안 (3-agent + 직접 분석) | 10개 결함, Phase 1–4, 2개월 로드맵 |
| `docs/architecture-refactor-codex/` | Codex 타당성 검토 | Phase 0 추가 제안, 원칙 3건 보정, 일정 보수화 |
| **`docs/architecture-refactor-final/` (이 폴더)** | **통합 확정안** | **13개 결함, Phase 0–5, ~3개월 로드맵** |

본 문서는 **이전 두 문서 세트를 대체하지 않는다**. 근거는 두 곳에 남기고, 이 폴더는 **당시 실행 기준이었다** (현재는 아카이브).

> **📍 현재 세션 시작 시에는 이 폴더가 아니라 다음 문서를 먼저 읽으세요**:
> - 현재 실행 계획: [`docs/review-codex-1/11-fix-plan.md`](../review-codex-1/11-fix-plan.md) (Wave 0~7 + Gate G0~G6)
> - 현재 아키텍처 설명: [`docs/architecture/`](../architecture/)
> - 저장소 전수 리뷰: [`docs/review-codex-1/01~10`](../review-codex-1/)

---

## 문서 구성 (역사 기록)

### 당시 실행 상태 스냅샷
| 파일 | 내용 | 현행 대체 |
|---|---|---|
| [`progress.md`](progress.md) | **Phase 0~5 완료 기록 상세** (커밋, 작업, 리뷰 반영) | — (기록 보존용) |
| [`next-steps.md`](next-steps.md) | **당시 다음 할 일** (Phase 4 / 3b / 5) | [`docs/review-codex-1/11-fix-plan.md`](../review-codex-1/11-fix-plan.md) W1~W7 |
| [`test-plan.md`](test-plan.md) | 테스트 현황 + 계획 (subset 256 / W0에서 repo 기준선 추가됨) | 상단 "Repo 전체 기준선" 참조 |
| [`baseline.md`](baseline.md) | 당시 지표 추적 | `docs/architecture/_step_manifest.generated.md` (실측 baseline) |

### 설계 기반 (거의 불변, 참조용)
| 파일 | 내용 | 읽는 시점 |
|---|---|---|
| [`00-integrated-analysis.md`](00-integrated-analysis.md) | 두 분석 통합 + 코드 재검증, 13개 결함 | 리팩토링 근거 이해 시 |
| [`01-principles-revised.md`](01-principles-revised.md) | 보정된 원칙 (3-tier 진실원, 4-type step 설계 초안, Step Catalog) | 원칙 근거 확인 시 |
| [`02-final-roadmap.md`](02-final-roadmap.md) | Phase 0–5 실행 로드맵 (원본 계획) | 역사적 roadmap |
| [`03-comparison.md`](03-comparison.md) | 초안 ↔ Codex ↔ 최종안 차이 비교표 | 차이 근거 확인 시 |
| [`04-next-session-brief.md`](04-next-session-brief.md) | 초기 Phase 0 brief (역사적 기록) | 참조용 |

**읽는 순서 권장** (역사 기록 목적으로 읽을 때)
- 리팩토링 과정 궤적: `progress.md` → `next-steps.md` → `test-plan.md`
- 설계 근거 회고: `README` → `03` → `00` → `01` → `02`

**현재 실행 중인 세션이라면**: 이 폴더가 아니라 [`docs/review-codex-1/11-fix-plan.md`](../review-codex-1/11-fix-plan.md)부터 시작.

---

## 핵심 변경 요약 (초안 대비)

### 1. Phase 0 신설 — 현행 계약 정리

초안은 바로 "빠른 승리"부터 시작했다. Codex 지적을 수용해 **Phase 0 (현행 계약 정리)**을 앞에 둔다.

- AnalysisService vs StepRunner 이중 경로의 공식 경로 결정 (→ **StepRunner**)
- `test_step_manifest_v3.py` baseline 복구 (26단계 가정 → 현재 **49단계**)
- 문서 수치 일괄 갱신 (overview, data-contracts) — 실측 baseline `docs/architecture/_step_manifest.generated.md`

### 2. 공식 경로는 StepRunner

근거 (**Phase 0 작성 시점 기준, v0.5.3**): `frontend/src/pages/EpisodeDetail.tsx`, `frontend/src/components/shared/PipelineStepsPanel.tsx` 모두 `/steps/run-all`만 호출한다. `/episodes/{id}/analyze` (AnalysisService)는 당시 UI 버튼 없는 dead endpoint로 판단했다.

→ AnalysisService 내부 구현(1,137줄)은 **Phase 4에서 폐기**되었다.

**⚠️ 2026-04-21 현재 상태**: 내부 engine은 단일화됐지만, `/episodes/{id}/analyze` 공개 API는 shim으로 살아 있으며 `frontend/src/pages/Episodes.tsx`가 `useAnalyzeEpisode` 훅을 통해 legacy 경로를 호출한다. 이 외부 계약 이중화는 W1(공개 계약 수렴)에서 닫는다. 자세한 내용은 `docs/review-codex-1/11-fix-plan.md` §W1 참조.

### 3. 진실원 원칙을 3-tier로 분해

초안의 "DB Primary, 체크포인트 Backup"은 과감했다. 현재 실행 엔진이 checkpoint-first 구조이므로 **데이터 종류별 3-tier**로 정의한다.

| 티어 | 예시 | 진실원 |
|---|---|---|
| 실행 상태 | `step_run`, `is_selected`, `image_generated` | **DB primary** |
| 분석 산출물 | `entity_t2i`, `scene_detail`, `outlook_phase3` | **checkpoint canonical + DB projection** |
| 이미지 자산 | 씬/참조/합성 이미지 | **DB 메타 + filesystem 파일 동시 소유** |

### 4. Step을 4가지 유형으로 분류

"Step은 Pure Transformation"을 모든 step에 강제하면 이미지/세트/검수 step이 무너진다. Codex 제안을 수용해 **4-type 분류**로 전환.

| 유형 | 예시 | 규칙 |
|---|---|---|
| transform | `scene_camera_flow`, `scene_consistency`, `scene_detail` | pure transformation, DB 쓰기 금지 |
| projection | `_sync_*` 계열 | DB projection 전담 |
| asset | `ref_image_gen`, `composite_image_gen`, `set_design`, `character_state_variant`, `scene_image_pipeline` | side effect(파일/DB) 허용 |
| editorial | `t2i_review` | 타 step 체크포인트 수정 명시 |

### 5. Step Catalog 개념 도입

"중앙 레지스트리 = manifest"라는 초안은 부족하다. 현재 레지스트리는 4곳에 분산:
- `STEP_MANIFEST` (메타)
- `STEP_CLASSES` (class binding)
- applicability resolver (StepRunner, run_all_steps, get_all_steps, UI 각각)
- UI visibility (`PipelineStepsPanel.tsx`)

→ Phase 1에서 **Step Catalog**라는 단일 계약으로 통합한다.

### 6. 일정 보수화

Codex 지적 "초안 일정은 낙관적"을 수용. 각 Phase를 **3~5일 ~ 2~4주**로 확대.

| Phase | 초안 | 최종 |
|---|---|---|
| 0 | — | **3~5일** (신규) |
| 1 | 1~2일 | 3~5일 |
| 2 | 1주 | 1~2주 |
| 3 | 2주 | 2~3주 |
| 4 | 2~4주 | 1~2주 (legacy convergence만) |
| 5 | — (Phase 4에 통합) | **2~4주** (frontend 분리) |

**전체: 약 3개월** (초안 2개월 → 30% 보수화)

### 7. "번역 warning 전파"는 bugfix 트랙으로 분리

Codex 지적대로 아키텍처 리팩토링과 구분. `track: production-hardening`으로 이동, 병렬 진행 가능.

---

## 13개 결함 (통합)

| # | 결함 | 심각도 | 초안 | Codex | 통합 |
|---|---|---|---|---|---|
| 1 | 진실원 이중화 | Critical | ✓ | (원칙 보정) | ✓ 3-tier로 정리 |
| 2 | `_sync_checkpoints_to_db` 722줄 | Critical | ✓ | ✓ 강화 제안 | ✓ 5개 Service 분해 |
| 3 | 하드코딩 downstream | Critical | ✓ 3곳 | ✓ | ✓ **실제 3곳 + 신규 1곳(steps.py:658)** |
| 4 | ImageService 5,281줄 | Critical | ✓ | ✓ 강화 제안 | ✓ Service 분할 + step 경계 재정의 |
| 5 | **AnalysisService/StepRunner 이중 실행** | **Critical (신규)** | ✗ | ✓ | ✓ Phase 4 수렴 |
| 6 | Applicability 런타임 미검증 | High | ✓ | ✓ 강화 (4곳 resolver 통합) | ✓ Step Catalog로 |
| 7 | run-all 재시도 계약 | High | ✓ | — | ✓ Phase 2 |
| 8 | `detail_steps::_execute` closure 공유 | High | ✓ | — | ✓ DTO 전환 |
| 9 | API 책임 오염 | High | ✓ | ✓ | ✓ Service 이전 |
| 10 | **Image step 경계 붕괴** | **High (신규)** | ✗ | ✓ (ref_image_gen → composite_image_gen 완료 처리) | ✓ Phase 3 |
| 11 | 체크포인트 원자성 부분 적용 | Medium | ✓ | — | ✓ 공통 유틸 |
| 12 | Legacy 관리 체계 | Medium | ✓ | ✓ (파일 이동은 후순위) | ✓ Phase 1 lifecycle 필드만 |
| 13 | **테스트 baseline 붕괴** | **Medium (신규)** | ✗ | ✓ | ✓ Phase 0 |

기타 (frontend 상태, 설정 분산, 에러 처리)는 위 항목에 포함되어 각 Phase로 분산.

---

## 최종 Phase 요약

### Phase 0 (3~5일) — 현행 계약 정리 🆕

- AnalysisService 경로 deprecate 선언 (제거는 Phase 4)
- `test_step_manifest_v3.py` 26단계 → 48단계 갱신 + scene_director/scene_detail 의존성 최신화
- `docs/architecture/00-overview.md`, `06-data-contracts.md` 현행 반영
- baseline metrics 일괄 재측정 → 문서 표 갱신

### Phase 1 (3~5일) — Step Catalog 통합

- `app/core/step_catalog.py` 신설 (manifest + class + applicability + UI visibility 통합)
- `ApplicabilityValidator` 레지스트리 (`if_planning_doc`, `if_has_outlooks`, `if_set_design_enabled`, `if_fal_enabled`)
- 하드코딩 downstream **4곳** 모두 `get_all_downstream_recursive` 기반으로 치환
- `app/core/checkpoint_io.py` 공통 유틸 (atomic_write_json, read_json_safe)
- `set_design` applicability `"always"` → `"if_set_design_enabled"` 변경
- manifest에 `lifecycle`, `step_type`(transform/projection/asset/editorial), `resume_sensitive` 필드 추가

### Phase 2 (1~2주) — Checkpoint Sync 분해

`_sync_checkpoints_to_db` 722줄을 5개 Service로 분해:
- `EntitySyncService`
- `RelationSyncService` (DELETE→INSERT → UPSERT)
- `SceneStillSyncService`
- `OutlookSyncService` (DELETE→INSERT → UPSERT)
- `EpisodeProjectionService`

그리고:
- `ShotSelectionService` (toggle 로직 이전)
- `SnapshotService` (스냅샷/복원 로직 이전)
- `@api_endpoint` 데코레이터

### Phase 3 (2~3주) — Image Domain 재구성

Step 경계 먼저 재정의한 뒤 Service 분할:
- `RefImageGenStep` — 자기 책임만, composite 완료 마킹 제거
- `CompositeImageGenStep` — 자기 책임만, reference 재호출 제거
- `ImageService` → 3개 Service (`PromptService`, `ReferenceImageService`, `SceneImageService`)
- `SceneAnalysisContext` DTO + `SceneContextLoader` (detail_steps closure 해소)

### Phase 4 (1~2주) — Legacy Analysis Convergence

- `AnalysisService` 폐기 (1,137줄 제거)
- `POST /episodes/{id}/analyze`, `/reanalyze-scenes` 내부를 `StepRunner run-all` 래퍼로 교체
- `outlook_dedup`의 6건 연쇄 DELETE 재설계 (UPSERT)

### Phase 5 (2~4주) — Frontend 서버 상태 재구성

- React Query 도입
- `EpisodeDetail.tsx`, `ProjectDetail.tsx`, `Episodes.tsx`, `Dashboard.tsx`의 19회+ 3-tuple 패턴 제거
- `EpisodeDetail.tsx` 1,358줄 → 5개 컴포넌트 분할 (~500줄)

---

## 결정 보류 항목

- **outlook 테이블 분리**: Phase 4 이후 독립 프로젝트로 평가 (3~4주 예상, DB 마이그레이션 동반)
- **PipelineRunner 클래스화**: Phase 5 이후 재평가
- **Opik 통합 재검토**: 리팩토링 완료 후

---

## 지금까지 내 분석이 틀렸던 부분

초안(`docs/architecture-refactor/`)이 틀렸던 수치/주장과 근거:

| 항목 | 초안 | 실제 | 출처 |
|---|---|---|---|
| Active step 수 | 33 | 48 (active ~40) | `step_manifest.py` 전수 조사 |
| `EpisodeDetail.tsx` useState | 51 | 13~34 (측정 방식 의존) | `grep -c useState` |
| AnalysisService 존재 인식 | 없음 | 1,137줄, 활성 엔드포인트 2개 | `episodes.py:134,237` |
| Image step 경계 | "ref/composite/scene 분할" | 경계 자체가 붕괴된 상태 | `image_steps.py:345-375` |
| 하드코딩 downstream 위치 | 3곳 | 최소 4곳 | Agent 전수 조사 |
| 일정 | 2개월 | 3개월 보수 | Codex 권고 |

이 수정을 반영한 것이 이 최종안이다.

---

## 참고

- 이전 분석: `docs/architecture-refactor/00-analysis.md`, `01-target-design.md`, `02-before-after.md`, `03-roadmap.md`, `04-next-session-brief.md`
- Codex 검토: `docs/architecture-refactor-codex/00-feasibility-review.md`
- 관련 메모리: `~/.claude/.../memory/project_architecture_refactor.md`
- 프로젝트 규칙: `/CLAUDE.md`
