문서 정리: Phase 히스토리 md를 docs/history/로 이동 + 오래된 테스트/에셋 정리

- 루트의 IMPROVEMENT-PHASE-*.md, PHASE-*.md 등 45개 → docs/history/로 이동
- docs/block-tests/ 오래된 블록 테스트 HTML 삭제 (figma_to_html_agent로 대체)
- docs/figma-analysis/, docs/figma-assets/, docs/figma-screenshots/ 정리
- docs/test-*.html 등 초기 테스트 파일 정리
- 참고 페이지/ 스크린샷 정리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 10:56:23 +09:00
parent d57860578f
commit c42e01f060
206 changed files with 0 additions and 13498 deletions

View File

@@ -0,0 +1,276 @@
# Phase K-1: 파이프라인 스텝별 중간 산출물 로컬 저장
> 각 스텝에서 뭘 결정했고 왜 그렇게 했는지를 파일로 저장하여,
> 사용자가 확인하고 피드백할 수 있도록 한다.
> 당초부터 있어야 했던 기능.
---
## 문제
- 현재 파이프라인 중간 결과는 메모리에만 존재, 파이프라인 끝나면 사라짐
- 사용자가 "어디서 잘못됐는지" 확인할 방법이 없음
- 로그에 WARNING/INFO 한 줄만 남아서 판단 근거 부족
---
## 저장 구조
```
data/runs/{timestamp}/
├── step1_analysis.json # Kei 꼭지 추출 (topics, purpose, core_message)
├── step1b_concepts.json # Kei 컨셉 구체화 (relation_type, expression_hint)
├── step2_opus_recommendation.json # Opus 블록 추천
├── step2_sonnet_mapping.json # Sonnet 최종 블록 매핑
├── step2_validation.json # 높이 검증, 금지 블록 삭제, overflow 내역
├── step3_filled_blocks.json # 편집자가 채운 텍스트 (블록별 data + 글자 수)
├── step4_css_adjustment.json # CSS 변수 override 내역
├── step4_rendered.html # 렌더링된 HTML
├── step5_review_round1.json # Kei 1차 검수 결과 (issues + adjustments)
├── step5_review_round2.json # Kei 2차 검수 결과 (있으면)
└── final.html # 최종 HTML
```
---
## 각 파일 내용 상세
### step1_analysis.json
```json
{
"title": "건설산업 DX의 올바른 이해",
"core_message": "BIM은 DX의 기초적 일부분이다",
"total_pages": 1,
"info_structure": "...",
"topics": [
{
"id": 1,
"title": "DX와 BIM의 개념 혼용 현실",
"purpose": "문제제기",
"layer": "intro",
"role": "flow",
"emphasis": true,
"summary": "...",
"source_hint": "..."
}
],
"images": [],
"tables": []
}
```
### step1b_concepts.json
```json
{
"concepts": [
{
"topic_id": 1,
"relation_type": "cause_effect",
"expression_hint": "현상-문제 인과관계",
"source_data": "용어 혼용 현상..."
}
]
}
```
### step2_opus_recommendation.json
```json
{
"recommendations": [
{
"topic_id": 1,
"block_type": "quote-big-mark",
"area": "body",
"reason": "문제 제기를 임팩트 있게 강조"
}
]
}
```
### step2_sonnet_mapping.json
```json
{
"preset": "sidebar-right",
"blocks": [
{
"area": "body",
"type": "quote-big-mark",
"topic_id": 1,
"purpose": "문제제기",
"reason": "Opus 추천 유지",
"size": "medium",
"char_guide": {"quote_text": 150}
}
],
"opus_diff": [
"Opus 추천과 동일" "topic_id 4: card-tag-image → card-numbered (사유: ...)"
]
}
```
### step2_validation.json
```json
{
"forbidden_blocks_removed": ["section-header-bar (body)"],
"pill_pair_replaced": [],
"sidebar_column_override": [{"topic_id": 4, "column_override": 1}],
"overflow": [
{"area": "body", "total_px": 510, "budget_px": 490, "overflow_px": 20}
]
}
```
### step3_filled_blocks.json
```json
{
"blocks": [
{
"area": "body",
"type": "quote-big-mark",
"topic_id": 1,
"purpose": "문제제기",
"data": {"quote_text": "건설산업의 디지털 전환...", "source": ""},
"char_count": 95
}
]
}
```
### step4_css_adjustment.json
```json
{
"area_styles": {
"body": "--font-body: 0.85rem; --spacing-inner: 12px;",
"sidebar": "--font-body: 0.8rem;",
"footer": ""
}
}
```
### step5_review_round1.json
```json
{
"needs_adjustment": true,
"issues": ["body zone 높이 초과 (+20px)"],
"adjustments": [
{"block_area": "body", "action": "shrink", "target_ratio": 0.8, "detail": "..."}
],
"kei_overflow_judgment": null
}
```
---
## 구현 방안
### 반영 위치
`src/pipeline.py``generate_slide()` 함수에서 각 스텝 완료 시 저장
### 유틸 함수
```python
# pipeline.py 상단에 추가
import time
from pathlib import Path
def _save_step(run_dir: Path, filename: str, data: Any) -> None:
"""스텝 결과를 JSON 또는 HTML로 저장한다."""
run_dir.mkdir(parents=True, exist_ok=True)
filepath = run_dir / filename
if filename.endswith(".html"):
filepath.write_text(data, encoding="utf-8")
else:
with open(filepath, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
logger.info(f"[중간 산출물] {filename} 저장")
```
### 각 스텝 저장 시점
```python
async def generate_slide(content, manual_layout=None, base_path=""):
run_id = str(int(time.time() * 1000))
run_dir = Path("data/runs") / run_id
# Step 1-A
analysis = await classify_content(content)
_save_step(run_dir, "step1_analysis.json", analysis)
# Step 1-B
analysis = await refine_concepts(content, analysis)
_save_step(run_dir, "step1b_concepts.json", {
"concepts": [
{k: t.get(k) for k in ("id", "relation_type", "expression_hint", "source_data")}
for t in analysis.get("topics", []) if t.get("relation_type")
]
})
# Step 2 (Opus + Sonnet + validation)
layout_concept = await create_layout_concept(content, analysis)
_save_step(run_dir, "step2_sonnet_mapping.json", layout_concept)
# Step 3
layout_concept = await fill_content(content, layout_concept, analysis)
_save_step(run_dir, "step3_filled_blocks.json", {
"blocks": [
{
"area": b.get("area"),
"type": b.get("type"),
"topic_id": b.get("topic_id"),
"purpose": b.get("purpose"),
"data": b.get("data", {}),
"char_count": len(json.dumps(b.get("data", {}), ensure_ascii=False)),
}
for p in layout_concept.get("pages", [])
for b in p.get("blocks", [])
]
})
# Step 4
html = render_slide(layout_concept)
_save_step(run_dir, "step4_rendered.html", html)
# Step 5 (검수 결과는 루프 안에서)
# review_result 저장
# 최종
_save_step(run_dir, "final.html", html)
```
### Opus 추천 저장
현재 Opus 추천 결과가 `create_layout_concept()` 내부에서 소비되고 사라짐.
추천 결과를 반환값에 포함하거나, 별도로 저장하는 로직 필요.
**방법:** `create_layout_concept()` 반환값에 `"opus_recommendation"` 키 추가
---
## 충돌/회귀 검토
| 항목 | 영향 |
|------|------|
| pipeline.py | `_save_step()` 함수 추가 + 각 스텝 후 호출 |
| design_director.py | `create_layout_concept()` 반환값에 opus 추천 포함 (선택적) |
| 기존 기능 | 변경 없음 — 저장은 추가 기능이므로 기존 흐름에 영향 없음 |
| Phase I/J/K | 회귀 없음 |
| 성능 | JSON 저장은 ms 수준, HTML 저장도 ms 수준 — 영향 미미 |
---
## 실행 순서
1. `_save_step()` 유틸 함수 추가 (pipeline.py)
2. `data/runs/` 디렉토리 구조 설정
3. `generate_slide()` 각 스텝 완료 시점에 저장 호출 추가
4. Opus 추천 결과 반환값 포함 (design_director.py, 선택적)
5. 검증: 파이프라인 실행 후 `data/runs/{timestamp}/` 파일 확인
---
## 이력
| 날짜 | 내용 |
|------|------|
| 2026-03-26 | Phase K 완료 후. 사용자 피드백 확인을 위한 중간 산출물 저장 기능 계획. |