Phase N+O: 컨테이너 기반 레이아웃 + Step B 제거 + 전면 정리
- Phase N: catalog 개선, fallback 전면 제거, Kei API 무한 재시도, topic_id 버그 수정 - Phase O: 컨테이너 스펙 계산(비중→px), 블록 스펙 확정, 렌더러 container div - Step B(Sonnet) 제거: Kei(A-2)+코드로 대체. STEP_B_PROMPT/fallback/DOWNGRADE_MAP 삭제 - Selenium: container div 감지 추가 - catalog.yaml: ref_chars 구조 변환 + FAISS 재빌드 - 문서 전면 갱신: README, PROGRESS, IMPROVEMENT, Phase I~O md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
539
COMPREHENSIVE_VALIDATION_REPORT.md
Normal file
539
COMPREHENSIVE_VALIDATION_REPORT.md
Normal file
@@ -0,0 +1,539 @@
|
||||
# Design Agent — 3건 수정사항 종합 검증 보고서
|
||||
|
||||
**검증 일시:** 2026-03-28 10:00
|
||||
**검증 범위:** space_allocator.py, slide_measurer.py, catalog.yaml 연계 파이프라인
|
||||
**방법론:** 코드 추적 + 파이프라인 시뮬레이션 + MD 문서 동기화 확인
|
||||
|
||||
---
|
||||
|
||||
## 📊 검증 결과 요약
|
||||
|
||||
| # | 항목 | 구현 | 통합 | 문서 | 종합 |
|
||||
|---|------|------|------|------|------|
|
||||
| **1** | space_allocator.py: topic당 높이 판단 | ✅ | ✅ | 🟡 | ✅ 95% |
|
||||
| **2** | slide_measurer.py: container 감지 | ✅ | ✅ | ✅ | ✅ 100% |
|
||||
| **3** | catalog.yaml: schema 글자수 구조 | ✅ | 🔴 | 🟡 | ⚠️ 60% |
|
||||
|
||||
**전체 평가:** ✅ **수정 의도는 정확하나 #3 catalog schema가 실제로 파이프라인에서 사용되지 않음**
|
||||
|
||||
---
|
||||
|
||||
## 🔍 상세 검증
|
||||
|
||||
### 1️⃣ space_allocator.py: topic당 높이 기반 height_cost 판단
|
||||
|
||||
#### ✅ 구현 상태
|
||||
|
||||
**파일:** `src/space_allocator.py` 라인 51-61
|
||||
|
||||
```python
|
||||
# 블록 내부 제약 계산 — topic당 높이로 판단
|
||||
topic_count = max(1, len(topic_ids))
|
||||
per_topic_px = height_px // topic_count # ← 컨테이너 높이 / topic 개수
|
||||
|
||||
# height_cost 허용 범위: topic당 높이 기준 (컨테이너 전체가 아님)
|
||||
max_cost = _max_allowed_height_cost(per_topic_px) # ← 핵심 함수 호출
|
||||
# ...
|
||||
```
|
||||
|
||||
**함수 정의 (라인 129-137):**
|
||||
```python
|
||||
def _max_allowed_height_cost(container_height_px: int) -> str:
|
||||
"""컨테이너 높이에서 허용되는 최대 height_cost."""
|
||||
if container_height_px >= 350:
|
||||
return "xlarge"
|
||||
elif container_height_px >= 200:
|
||||
return "large"
|
||||
elif container_height_px >= 80:
|
||||
return "medium"
|
||||
else:
|
||||
return "compact"
|
||||
```
|
||||
|
||||
#### ✅ 파이프라인 통합
|
||||
|
||||
**pipeline.py 라인 68-82에서 호출:**
|
||||
```python
|
||||
container_specs = calculate_container_specs(
|
||||
page_structure=page_struct, # Kei 비중 판단 {"본심": {"topic_ids": [3], "weight": 0.6}, ...}
|
||||
topics=analysis.get("topics", []), # 5개 topic 정보
|
||||
preset=preset,
|
||||
...
|
||||
)
|
||||
```
|
||||
|
||||
**데이터 흐름:**
|
||||
```
|
||||
1. Kei: page_structure 판단
|
||||
↓ (page_structure = {"본심": {"topic_ids": [3], "weight": 0.6}}, ...)
|
||||
2. O-1: calculate_container_specs()
|
||||
- per_topic_px = 180 // 1 = 180px (본심 컨테이너 180px / 1개 topic)
|
||||
- max_cost = _max_allowed_height_cost(180) = "medium" ✅
|
||||
↓
|
||||
3. O-3: finalize_block_specs()
|
||||
- 블록에 _container_height_px=180, _max_items=2, _max_chars_total=320 설정
|
||||
↓
|
||||
4. 편집자 (stage 3):
|
||||
- "최대 글자 수: 320자, 항목 수: 2개" 가이드 전달
|
||||
```
|
||||
|
||||
#### 🟡 문서 동기화 상태
|
||||
|
||||
**ARCHITECTURE_OVERVIEW.md 라인 156-170:**
|
||||
```
|
||||
Phase O-1 과정:
|
||||
3. 비중 비율로 높이 할당 (zone 예산 복분)
|
||||
4. 높이 → height_cost 매핑 (compact/medium/large/xlarge)
|
||||
```
|
||||
|
||||
**문제:**
|
||||
- "height_cost 매핑"만 기술되어 있음
|
||||
- **"topic당 높이로 판단"이 명시되지 않음** ← 개선 필요
|
||||
|
||||
**개선된 설명:**
|
||||
> Phase O-1 과정:
|
||||
> 3. 비중으로 컨테이너 높이 할당 (ex. 180px)
|
||||
> 4. **topic당 높이로 max_height_cost 판단** (180px / 1 topic = 180px → **medium**) ← 중요
|
||||
> 5. 글자 수/항목 수 제약 계산
|
||||
|
||||
#### ✅ 검증 결과
|
||||
|
||||
| 항목 | 상태 | 근거 |
|
||||
|------|------|------|
|
||||
| 코드 구현 | ✅ | _max_allowed_height_cost() 함수 정확 |
|
||||
| 파이프라인 호출 | ✅ | pipeline.py 68-82줄 O-1 통합 |
|
||||
| 데이터 흐름 | ✅ | per_topic_px 계산 후 height_cost 결정 |
|
||||
| 문서 정확도 | 🟡 | "topic당 판단" 명시 필요 |
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ slide_measurer.py: container 감지 및 overflow 체크
|
||||
|
||||
#### ✅ 구현 상태
|
||||
|
||||
**파일:** `src/slide_measurer.py` 라인 14-62
|
||||
|
||||
**JavaScript 측정 스크립트:**
|
||||
```javascript
|
||||
// Phase O: 컨테이너 측정 (container-* 클래스)
|
||||
var containerDivs = slide.querySelectorAll('[class*="container-"]');
|
||||
for (var k = 0; k < containerDivs.length; k++) {
|
||||
var container = containerDivs[k];
|
||||
var containerMatch = container.className.match(/container-(.+)/);
|
||||
if (!containerMatch) continue;
|
||||
var containerName = containerMatch[1];
|
||||
|
||||
result.containers[containerName] = {
|
||||
scrollHeight: Math.round(container.scrollHeight),
|
||||
clientHeight: Math.round(container.clientHeight),
|
||||
allocatedHeight: parseInt(container.style.height) || 0,
|
||||
overflowed: container.scrollHeight > container.clientHeight + 2,
|
||||
excess_px: Math.max(0, Math.round(container.scrollHeight - container.clientHeight)),
|
||||
...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**측정 결과 구조:**
|
||||
```json
|
||||
{
|
||||
"containers": {
|
||||
"본심": {
|
||||
"scrollHeight": 190,
|
||||
"clientHeight": 180,
|
||||
"allocatedHeight": 180,
|
||||
"overflowed": true,
|
||||
"excess_px": 10,
|
||||
"blocks": [
|
||||
{"block_type": "topic-left-right", "scrollHeight": 95, "overflowed": false},
|
||||
{"block_type": "topic-left-right", "scrollHeight": 95, "overflowed": false}
|
||||
]
|
||||
},
|
||||
"배경": {
|
||||
"scrollHeight": 50,
|
||||
"clientHeight": 180,
|
||||
"allocatedHeight": 180,
|
||||
"overflowed": false,
|
||||
"excess_px": 0,
|
||||
"blocks": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ✅ 파이프라인 통합
|
||||
|
||||
**pipeline.py 라인 177-202 (Phase L):**
|
||||
```python
|
||||
# Phase L: 렌더링 측정 + 피드백 루프 (최대 3회)
|
||||
for measure_round in range(MAX_MEASURE_ROUNDS):
|
||||
measurement = await asyncio.to_thread(measure_rendered_heights, html)
|
||||
|
||||
# overflow 감지 — zone + container 양쪽 체크
|
||||
has_overflow = False
|
||||
for zone_name, zone_data in measurement.get("zones", {}).items():
|
||||
if zone_data.get("overflowed"):
|
||||
has_overflow = True
|
||||
break
|
||||
# Phase O: container 레벨 overflow도 체크 ← 핵심
|
||||
for cont_name, cont_data in measurement.get("containers", {}).items():
|
||||
if cont_data.get("overflowed"):
|
||||
has_overflow = True
|
||||
logger.warning(
|
||||
f"[측정] container-{cont_name}: "
|
||||
f"scroll={cont_data.get('scrollHeight')}px > "
|
||||
f"allocated={cont_data.get('allocatedHeight')}px "
|
||||
f"(+{cont_data.get('excess_px')}px)"
|
||||
)
|
||||
break
|
||||
|
||||
if not has_overflow:
|
||||
logger.info(f"[측정] 모든 zone/container 정상 (round {measure_round + 1})")
|
||||
break
|
||||
```
|
||||
|
||||
**overflow 감지 후 조치 (라인 203-230):**
|
||||
```python
|
||||
# 추출: container overflow 정보
|
||||
for cont_name, cont_data in measurement.get("containers", {}).items():
|
||||
if cont_data.get("overflowed"):
|
||||
for block_m in cont_data.get("blocks", []): # ← container 내 블록 단위
|
||||
if block_m.get("overflowed"):
|
||||
trim_chars = calculate_trim_chars(
|
||||
block_m.get("excess_px", excess),
|
||||
width_px,
|
||||
)
|
||||
# 해당 블록의 _max_chars_total 축소
|
||||
```
|
||||
|
||||
### 📊 시뮬레이션: container overflow 피드백 루프
|
||||
|
||||
**시나리오:**
|
||||
- 본심 컨테이너 할당 높이: 180px
|
||||
- 실제 렌더링 높이: 190px (overflow +10px)
|
||||
- 블록 1: topic-left-right (95px, 정상)
|
||||
- 블록 2: card-icon-desc (120px, +15px 초과)
|
||||
|
||||
**동작 순서:**
|
||||
|
||||
```
|
||||
Round 1: 측정
|
||||
├─ measurement.containers["본심"] = {
|
||||
│ ├─ allocatedHeight: 180,
|
||||
│ ├─ scrollHeight: 190,
|
||||
│ ├─ overflowed: true,
|
||||
│ ├─ excess_px: 10,
|
||||
│ └─ blocks: [{...95px...}, {...120px...}] ← 블록 2가 +15px 초과
|
||||
│
|
||||
├─ Phase L 감지: "container-본심에서 +10px overflow"
|
||||
│
|
||||
├─ 조치: card-icon-desc의
|
||||
│ └─ _max_chars_total: 300 → 285 (15자 축약)
|
||||
|
||||
Round 2: 재렌더링 + 재측정
|
||||
├─ content_editor 재호출 (글자 수 제약 적용)
|
||||
├─ 블록 2 텍스트 축약됨
|
||||
│
|
||||
├─ 재측정 결과:
|
||||
│ └─ container
|
||||
|
||||
-본심: scrollHeight 185px / allocatedHeight 180px
|
||||
│ → 여전히 +5px overflow
|
||||
|
||||
Round 3: 재조치
|
||||
├─ 추가 5자 축약
|
||||
├─ 재렌더링 + 재측정
|
||||
│
|
||||
└─ OK: container-본심 정상 (scrollHeight == allocatedHeight)
|
||||
```
|
||||
|
||||
#### ✅ 문서 동기화 상태
|
||||
|
||||
**PROGRESS.md 라인 xxx (Selenium container 감지):**
|
||||
```
|
||||
Phase L: 렌더링 측정 + feedback loop
|
||||
- zone 레벨 overflow 감지 ✅
|
||||
- container 레벨 overflow 감지 ✅ (NEW)
|
||||
```
|
||||
|
||||
**ARCHITECTURE_OVERVIEW.md 라인 xxx:**
|
||||
```
|
||||
Phase L (Measurement):
|
||||
1. Selenium headless Chrome으로 렌더링
|
||||
2. JavaScript로 zone 높이 측정
|
||||
3. NEW: container-* 클래스로 역할별 높이 측정 ← 개선됨
|
||||
4. 초과분 감지 → 피드백 루프
|
||||
5. 최대 3회 재조정
|
||||
```
|
||||
|
||||
#### ✅ 검증 결과
|
||||
|
||||
| 항목 | 상태 | 근거 |
|
||||
|------|------|------|
|
||||
| 코드 구현 | ✅ | slide_measurer.py 14-62줄 |
|
||||
| JavaScript 정확성 | ✅ | container-* 셀렉터 + overflow 계산 정확 |
|
||||
| 파이프라인 호출 | ✅ | pipeline.py 177-202줄 |
|
||||
| 피드백 루프 | ✅ | 재렌더링 + 재측정 최대 3회 |
|
||||
| 문서 정확도 | ✅ | PROGRESS.md, ARCHITECTURE_OVERVIEW.md 반영됨 |
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ catalog.yaml: schema 글자수 필드 추가
|
||||
|
||||
#### ✅ 구현 상태
|
||||
|
||||
**파일:** `templates/catalog.yaml` 라인 44-46 (예. section-header-bar)
|
||||
|
||||
```yaml
|
||||
- id: section-header-bar
|
||||
name: 섹션 헤더 바
|
||||
height_cost: compact
|
||||
...
|
||||
schema: # ← NEW: 글자수 가이드 구조화
|
||||
title: {max_lines: 1, font_size: 18, ref_chars: {body: 25, sidebar: 20}, note: '18px bold white, 중앙정렬'}
|
||||
subtitle: {max_lines: 1, font_size: 13, ref_chars: {body: 40, sidebar: 30}, note: '13px, 1줄'}
|
||||
|
||||
- id: topic-left-right
|
||||
name: 좌우 꼭지 헤더
|
||||
height_cost: compact
|
||||
...
|
||||
schema:
|
||||
title: {max_lines: 2, font_size: 24, ref_chars: {body: 20}, note: '24px bold, 240px 고정폭'}
|
||||
description: {max_lines: 2, font_size: 16, ref_chars: {body: 100}, note: '16px, 510px 너비'}
|
||||
```
|
||||
|
||||
**schema 필드 구조:**
|
||||
```
|
||||
schema:
|
||||
{slot_name}:
|
||||
max_lines: N # 텍스트 라인 수 (줄바꿈 횟수)
|
||||
font_size: N # 픽셀 단위
|
||||
ref_chars: # zone별 글자 수 가이드
|
||||
body: N # body zone(65% 너비)에서의 한 줄 글자 수
|
||||
sidebar: N # sidebar(35%)에서의 글자 수
|
||||
note: "..." # 추가 설명
|
||||
```
|
||||
|
||||
#### 🔴 파이프라인 통합 **실패**
|
||||
|
||||
**문제 1: catalog 로더가 schema를 읽지 않음**
|
||||
|
||||
`src/block_search.py` 라인 xxx에서:
|
||||
```python
|
||||
with open(META_PATH, encoding="utf-8") as f:
|
||||
_metadata = json.load(f) # ← block_metadata.json에서 로드
|
||||
|
||||
# block_metadata.json 생성 스크립트: scripts/build_block_index.py
|
||||
# 이 스크립트가 catalog.yaml의 schema를 추출하여 metadata에 포함하는가? → 불명
|
||||
```
|
||||
|
||||
**문제 2: metadata가 content_editor에 전달되지 않음**
|
||||
|
||||
`src/content_editor.py` 라인 xxx:
|
||||
```python
|
||||
# BLOCK_SLOTS를 사용 (설계 단계에 정의)
|
||||
slots = BLOCK_SLOTS.get(block_type, {}) # ← catalog.yaml 아님
|
||||
|
||||
# catalog.yaml의 schema는 사용되지 않음!
|
||||
```
|
||||
|
||||
**문제 3: 글자 수 가이드 전달 경로 불명**
|
||||
|
||||
현재 flow:
|
||||
```
|
||||
1. BLOCK_SLOTS (design_director.py에 하드코딩)
|
||||
↓ (slot_desc만 전달, schema 아님)
|
||||
2. content_editor.py (slot requirements 생성)
|
||||
├─ slot_desc 포함
|
||||
├─ char_guide 포함 (block에 설정되어 있으면)
|
||||
└─ schema (catalog에만 있음, 사용 안 됨!)
|
||||
↓
|
||||
3. Kei 프롬프트에 전달
|
||||
```
|
||||
|
||||
#### 🟡 코드 검증: schema 실제 접근 시도
|
||||
|
||||
**전체 grep으로 schema 사용 검색:**
|
||||
```bash
|
||||
grep -r "schema" src/*.py templates/*.yaml
|
||||
|
||||
Result:
|
||||
- templates/catalog.yaml: 37개 블록에 schema 정의 ✅
|
||||
- src/*.py: 검색 결과 0 ❌
|
||||
```
|
||||
|
||||
**결론:** schema 필드가 catalog.yaml에 정의되어 있지만 **코드에서 사용하지 않음**
|
||||
|
||||
#### ⚠️ 문서 동기화 상태
|
||||
|
||||
**PROGRESS.md (라인 xxx):**
|
||||
> Phase O-3: finalize_block_specs()로 블록 내부 제약 계산
|
||||
> - max_items, max_chars_total, font_size 등
|
||||
|
||||
**문제:**
|
||||
- catalog.yaml schema 필드 추가를 기록하지 않음
|
||||
- "schema 글자수 구조 변환"이 완료된 것처럼 보이지만 실제로는 미사용
|
||||
|
||||
**ARCHITECTURE_OVERVIEW.md:**
|
||||
- catalog.yaml schema에 대한 언급 없음
|
||||
- "catalog 37개 블록" 기술만 있음
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 문제점 분석
|
||||
|
||||
### Issue #1: catalog.yaml schema가 파이프라인에서 사용되지 않음
|
||||
|
||||
**근본 원인:**
|
||||
1. BLOCK_SLOTS가 설계 단계 (design_director.py)에서 하드코딩됨
|
||||
2. catalog.yaml은 렌더러에서만 사용 (템플릿 경로 매핑)
|
||||
3. schema 필드: 메타데이터로 정의되었으나 **읽는 함수 없음**
|
||||
|
||||
**현재 상태:**
|
||||
```
|
||||
catalog.yaml (37개 블록)
|
||||
├─ id, name, template ✅ (renderer.py에서 사용)
|
||||
├─ height_cost ✅ (design_director.py에서 사용)
|
||||
├─ visual, when, not_for, purpose_fit ❓ (사용 불명)
|
||||
└─ schema ❌ (완전히 미사용)
|
||||
```
|
||||
|
||||
**개선 필요 사항:**
|
||||
|
||||
#### 옵션 A: catalog 로더 추가 (권장)
|
||||
```python
|
||||
# src/catalog_loader.py (신규)
|
||||
def load_catalog_schema() -> dict[str, dict]:
|
||||
"""catalog.yaml에서 블록별 schema 추출"""
|
||||
catalog_path = Path(__file__).parent.parent / "templates" / "catalog.yaml"
|
||||
with open(catalog_path, encoding="utf-8") as f:
|
||||
data = yaml.safe_load(f)
|
||||
return {
|
||||
b["id"]: b.get("schema", {})
|
||||
for b in data.get("blocks", [])
|
||||
}
|
||||
|
||||
# src/content_editor.py에서
|
||||
schema_map = load_catalog_schema()
|
||||
schema = schema_map.get(block_type, {})
|
||||
# schema를 Kei 프롬프트에 전달
|
||||
```
|
||||
|
||||
#### 옵션 B: BLOCK_SLOTS에 schema 병합
|
||||
```python
|
||||
# design_director.py
|
||||
BLOCK_SLOTS = {
|
||||
"topic-left-right": {
|
||||
"required": [...],
|
||||
"optional": [...],
|
||||
"schema": { # ← catalog.yaml과 동기화
|
||||
"title": {"max_lines": 2, "font_size": 24, ...},
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 종합 평가
|
||||
|
||||
### 수정 의도 분석
|
||||
|
||||
| 수정 | 의도 | 실제 | 평가 |
|
||||
|------|------|------|------|
|
||||
| **#1** | topic당 높이로 height_cost 판단하여 블록 선택 정확도↑ | ✅ 정확히 구현됨 | ✅ 완성 |
|
||||
| **#2** | container 레벨 overflow 감지 → 피드백 루프로 정확도↑ | ✅ 정확히 구현됨 | ✅ 완성 |
|
||||
| **#3** | schema로 글자수 메타데이터 구조화 → content_editor 정확도↑ | ✅ 작성됨 / ❌ 미사용 | ⚠️ 불완전 |
|
||||
|
||||
### 수정율 (완성도)
|
||||
|
||||
- **#1 space_allocator:** 100% ✅
|
||||
- **#2 slide_measurer:** 100% ✅
|
||||
- **#3 catalog schema:** 60% ⚠️ (정의만 함, 사용 안 함)
|
||||
|
||||
### 다음 단계
|
||||
|
||||
🔴 **즉시 필요:**
|
||||
```python
|
||||
# src/content_editor.py에 schema 로더 추가
|
||||
def _load_block_schema() -> dict[str, dict]:
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
catalog_path = Path(__file__).parent.parent / "templates" / "catalog.yaml"
|
||||
with open(catalog_path, encoding="utf-8") as f:
|
||||
data = yaml.safe_load(f)
|
||||
return {
|
||||
b["id"]: b.get("schema", {})
|
||||
for b in data.get("blocks", [])
|
||||
}
|
||||
|
||||
# fill_content() 함수에서 schema 전달
|
||||
schema = _load_block_schema().get(block_type, {})
|
||||
if schema:
|
||||
req_text += f"\n 슬롯 상세 스키마:\n"
|
||||
for slot, spec in schema.items():
|
||||
req_text += (
|
||||
f" {slot}: "
|
||||
f"{spec.get('max_lines', '?')}줄, "
|
||||
f"{spec.get('font_size', '?')}px, "
|
||||
f"본심:{spec.get('ref_chars', {}).get('body', '?')}자\n"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 검증 체크리스트
|
||||
|
||||
```
|
||||
[✅] 1. space_allocator.py _max_allowed_height_cost() 함수 구현
|
||||
[✅] 2. pipeline.py에서 O-1로 호출
|
||||
[✅] 3. container_specs 결과가 O-3에 전달
|
||||
[✅] 4. finalize_block_specs()에서 _container_height_px 설정
|
||||
[✅] 5. content_editor에서 char_guide로 사용
|
||||
|
||||
[✅] 6. slide_measurer.py container-* 셀렉터 추가
|
||||
[✅] 7. measure_rendered_heights()에서 containers 반환
|
||||
[✅] 8. pipeline.py Phase L에서 overflow 감지
|
||||
[✅] 9. 피드백 루프: 재렌더링 + 재측정
|
||||
|
||||
[✅] 10. catalog.yaml schema 필드 37개 블록 모두 작성
|
||||
[❌] 11. catalog 로더에서 schema 읽기 ← 미구현
|
||||
[❌] 12. content_editor에서 schema 전달 ← 미구현
|
||||
[❌] 13. Kei 프롬프트에 schema 포함 ← 미구현
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 매트릭스: MD 문서 vs 코드 동기화
|
||||
|
||||
| 파일 | 항목 | MD 기재 | 코드 | 동기화 |
|
||||
|------|------|--------|------|--------|
|
||||
| PROGRESS.md | BF-4 해결 | ✅ | ✅ | ✅ |
|
||||
| ARCHITECTURE_OVERVIEW.md | Phase O-1 설명 | ✅ 기본 | ✅ 상세 | 🟡 |
|
||||
| ARCHITECTURE_OVERVIEW.md | Phase L 측정 | ✅ 기본 | ✅ 상세(container 추가) | 🟡 |
|
||||
| ARCHITECTURE_OVERVIEW.md | catalog schema | ❌ | ✅ | ❌ |
|
||||
| README.md | catalog 필드 | 언급 없음 | 37개 블록 정의 | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## 권고사항
|
||||
|
||||
### 🔴 우선순위 1 (즉시)
|
||||
**catalog schema를 content_editor에 통합**
|
||||
- 파일: `src/content_editor.py`
|
||||
- 작업: `_load_block_schema()` 함수 추가 + fill_content()에서 호출
|
||||
- 소요시간: 30분
|
||||
- 영향: #3 완성도 60% → 100%
|
||||
|
||||
### 🟡 우선순위 2 (이번 주)
|
||||
**MD 문서 업데이트**
|
||||
- ARCHITECTURE_OVERVIEW.md: Phase O container 로직 상세 기술
|
||||
- PROGRESS.md: catalog schema 활용 추가 기록
|
||||
- 소요시간: 1시간
|
||||
|
||||
### 🟢 우선순위 3 (다음 주)
|
||||
**통합 테스트**
|
||||
- 3개 수정사항 end-to-end 테스트
|
||||
- 컨테이너 overflow 시나리오 검증
|
||||
- catalog schema 가이드 실제 사용 확인
|
||||
Reference in New Issue
Block a user