Replace compact fallback with slide-style regeneration
This commit is contained in:
@@ -22,6 +22,7 @@ from src.renderer import render_slide_from_html # type: ignore
|
||||
from src.slide_measurer import measure_rendered_heights # type: ignore
|
||||
|
||||
COMPARISON_MARKER = "comparison-summary-card"
|
||||
RELATION_MARKER = "relation-diagram-card"
|
||||
COMPARE_KEYS = ["범위", "프로세스", "성과품", "확장성"]
|
||||
CORE_MESSAGE_KEYS = ["DX는 상위 개념", "BIM은 핵심 기술"]
|
||||
IMAGE_REFERENCE_KEY = "DX와 핵심기술간 상호관계"
|
||||
@@ -57,51 +58,84 @@ def inject_visible_comparison_summary(generated: dict) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def build_compact_generated(context: dict) -> dict:
|
||||
def build_slide_regenerated(context: dict) -> dict:
|
||||
title = context.get("analysis", {}).get("title", "건설산업 DX의 올바른 이해")
|
||||
core_message = context.get("analysis", {}).get(
|
||||
"core_message",
|
||||
"건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.",
|
||||
)
|
||||
core_message = context.get(
|
||||
"analysis", {}
|
||||
).get("core_message", "건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.")
|
||||
|
||||
body_html = f"""
|
||||
<div style="width:100%; background:linear-gradient(135deg,#1e293b 0%,#0f172a 100%); border-radius:8px; padding:16px 20px; color:#ffffff; box-sizing:border-box; margin-bottom:10px;">
|
||||
<div style="font-size:12px; font-weight:700; color:#93c5fd; margin-bottom:6px;">문제 인식</div>
|
||||
<div style="font-size:12px; line-height:1.5;">건설산업에서는 DX와 BIM이 자주 혼용되며, BIM 도입이 곧 DX 완성이라는 오해가 생긴다.</div>
|
||||
</div>
|
||||
<div style="width:100%; background:#f8fafc; border:1px solid #cbd5e1; border-radius:8px; padding:14px 16px; box-sizing:border-box; margin-bottom:10px;">
|
||||
<div style="font-size:13px; font-weight:700; color:#1d4ed8; margin-bottom:8px;">{title}</div>
|
||||
<div style="font-size:12px; line-height:1.55; color:#0f172a; margin-bottom:6px;">• DX는 산업 전반의 업무방식과 가치 창출 구조를 바꾸는 상위 개념</div>
|
||||
<div style="font-size:12px; line-height:1.55; color:#0f172a; margin-bottom:6px;">• BIM은 시설물 정보를 3D 기반으로 통합·관리하는 핵심 기술</div>
|
||||
<div style="font-size:12px; line-height:1.55; color:#0f172a;">• GIS·BIM·디지털 트윈의 결합으로 건설산업 DX가 구현된다</div>
|
||||
</div>
|
||||
<div style="width:100%; background:#f0fdf4; border:1px solid #86efac; border-radius:8px; padding:12px 16px; box-sizing:border-box; margin-bottom:10px;">
|
||||
<div style="font-size:11px; font-weight:700; color:#166534; margin-bottom:6px;">이미지 참조</div>
|
||||
<div style="font-size:11px; color:#14532d; line-height:1.45;">[그림 1] {IMAGE_REFERENCE_KEY}</div>
|
||||
</div>
|
||||
<div style="width:100%; background:linear-gradient(135deg,#2563eb 0%,#1d4ed8 100%); border-radius:8px; padding:14px 18px; color:#fff; box-sizing:border-box; text-align:center;">
|
||||
<div style="font-size:13px; font-weight:700; line-height:1.45;">{core_message}</div>
|
||||
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:12px;">
|
||||
<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:14px;">
|
||||
<div style="flex:1; background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:14px; padding:18px 20px; box-sizing:border-box; box-shadow:0 12px 28px rgba(15,23,42,0.18);">
|
||||
<div style="font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;">Core Message</div>
|
||||
<div style="font-size:23px; font-weight:800; line-height:1.22; margin-bottom:8px;">DX는 상위 개념, BIM은 핵심 기술</div>
|
||||
<div style="font-size:12px; line-height:1.55; color:rgba(255,255,255,0.92);">{core_message}</div>
|
||||
</div>
|
||||
<div style="width:170px; background:#fff7ed; border:1px solid #fdba74; border-radius:14px; padding:14px 14px 12px; box-sizing:border-box;">
|
||||
<div style="font-size:10px; font-weight:700; color:#c2410c; margin-bottom:8px; text-transform:uppercase; letter-spacing:0.06em;">Problem</div>
|
||||
<div style="font-size:11px; line-height:1.55; color:#7c2d12;">건설산업에서는 DX와 BIM이 자주 혼용되며, BIM 도입이 곧 DX 완성이라는 오해가 생긴다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relation-diagram-card" style="background:linear-gradient(180deg,#eff6ff 0%,#f8fafc 100%); border:1px solid #bfdbfe; border-radius:16px; padding:18px; box-sizing:border-box; box-shadow:0 8px 18px rgba(59,130,246,0.10);">
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:14px;">
|
||||
<div>
|
||||
<div style="font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Relation Map</div>
|
||||
<div style="font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;">건설산업 DX를 이루는 핵심 기술 관계</div>
|
||||
</div>
|
||||
<div style="font-size:11px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:6px 10px; white-space:nowrap;">[그림 1] {IMAGE_REFERENCE_KEY}</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; flex-direction:column; align-items:center; gap:10px;">
|
||||
<div style="min-width:190px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 18px; font-size:16px; font-weight:800; box-shadow:0 8px 18px rgba(37,99,235,0.22);">DX</div>
|
||||
<div style="width:2px; height:20px; background:linear-gradient(180deg,#60a5fa 0%,#94a3b8 100%);"></div>
|
||||
<div style="width:100%; display:flex; justify-content:center; gap:12px;">
|
||||
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
|
||||
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">GIS</div>
|
||||
<div style="font-size:10px; line-height:1.45; color:#475569;">공간정보와 위치기반 분석</div>
|
||||
</div>
|
||||
<div style="flex:1; max-width:170px; background:linear-gradient(180deg,#dbeafe 0%,#eff6ff 100%); border:2px solid #3b82f6; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box; box-shadow:0 10px 22px rgba(59,130,246,0.16); transform:translateY(-2px);">
|
||||
<div style="font-size:12px; font-weight:800; color:#1d4ed8; margin-bottom:4px;">BIM</div>
|
||||
<div style="font-size:10px; line-height:1.45; color:#334155;">형상+내용정보 기반 핵심 기술</div>
|
||||
</div>
|
||||
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
|
||||
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">Digital Twin</div>
|
||||
<div style="font-size:10px; line-height:1.45; color:#475569;">가상환경 기반 통합 운영</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
""".strip()
|
||||
|
||||
sidebar_html = f"""
|
||||
<div style="width:100%; background:#ffffff; border:1px solid #dbeafe; border-radius:8px; padding:14px 16px; box-sizing:border-box; margin-bottom:10px;">
|
||||
<div style="font-size:11px; font-weight:700; color:#1e40af; margin-bottom:6px;">정책 혼용 사례</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 스마트 건설 활성화 방안: 디지털화 방향 아래 BIM 전면 도입 제시</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 제7차 건설기술진흥 기본계획: DX 추진 방향 아래 BIM 도입 실행 과제 제시</div>
|
||||
</div>
|
||||
<div class="comparison-summary-card" style="background:#eff6ff; border:1px solid #bfdbfe; border-radius:8px; padding:12px; box-sizing:border-box;">
|
||||
<div style="font-size:11px; font-weight:700; color:#1e3a8a; margin-bottom:6px;">DX와 BIM 핵심 비교</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 범위: DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 프로세스: DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 성과품: DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
|
||||
<div style="font-size:10px; color:#334155; line-height:1.5;">• 확장성: DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
|
||||
sidebar_html = """
|
||||
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;">
|
||||
<div class="comparison-summary-card" style="background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden; box-shadow:0 10px 22px rgba(15,23,42,0.08);">
|
||||
<div style="padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;">
|
||||
<div style="font-size:11px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;">Comparison</div>
|
||||
<div style="font-size:16px; font-weight:800; color:#0f172a;">DX와 BIM 핵심 비교</div>
|
||||
</div>
|
||||
<div style="padding:10px 14px 12px; display:grid; grid-template-columns:80px 1fr; row-gap:8px; column-gap:10px; font-size:10px; line-height:1.45; color:#334155;">
|
||||
<div style="font-weight:800; color:#0f172a;">범위</div><div>DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>
|
||||
<div style="font-weight:800; color:#0f172a;">프로세스</div><div>DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>
|
||||
<div style="font-weight:800; color:#0f172a;">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
|
||||
<div style="font-weight:800; color:#0f172a;">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;">
|
||||
<div style="font-size:11px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Evidence</div>
|
||||
<div style="font-size:14px; font-weight:800; color:#0f172a; margin-bottom:8px;">정책 문서에서도 혼용</div>
|
||||
<div style="font-size:10px; line-height:1.55; color:#475569;">• 스마트 건설 활성화 방안: 디지털화 방향 아래 BIM 전면 도입 제시</div>
|
||||
<div style="font-size:10px; line-height:1.55; color:#475569;">• 제7차 건설기술진흥 기본계획: DX 추진 방향 아래 BIM 도입 실행 과제 제시</div>
|
||||
</div>
|
||||
</div>
|
||||
""".strip()
|
||||
|
||||
footer_html = """
|
||||
<div style="background:linear-gradient(135deg,#0f766e 0%,#0ea5a3 100%); border-radius:8px; padding:12px 22px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box;">
|
||||
<div style="font-size:13px; font-weight:700; line-height:1.4;">DX는 상위 개념, BIM은 핵심 기술</div>
|
||||
<div style="font-size:10px; line-height:1.35; opacity:0.95;">BIM은 건설산업 DX 수행 과정의 가장 기초가 되는 일부분</div>
|
||||
<div style="background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box; box-shadow:0 10px 24px rgba(15,118,110,0.20);">
|
||||
<div style="font-size:14px; font-weight:800; line-height:1.35;">결론: BIM은 DX 수행 과정의 가장 기초가 되는 일부분</div>
|
||||
</div>
|
||||
""".strip()
|
||||
|
||||
@@ -109,7 +143,7 @@ def build_compact_generated(context: dict) -> dict:
|
||||
"body_html": body_html,
|
||||
"sidebar_html": sidebar_html,
|
||||
"footer_html": footer_html,
|
||||
"reasoning": "auto_loop_runner compact rewrite for visible core message and overflow reduction",
|
||||
"reasoning": "auto_loop_runner slide-style regeneration with relation map, visible comparison, and strong conclusion",
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +173,7 @@ def validate_outputs(generated: dict, measurement: dict) -> tuple[str, list[str]
|
||||
body_html = generated.get("body_html", "")
|
||||
sidebar_html = generated.get("sidebar_html", "")
|
||||
footer_html = generated.get("footer_html", "")
|
||||
text = strip_tags("\n".join([body_html, sidebar_html, footer_html]))
|
||||
visible_text = strip_tags("\n".join([body_html, sidebar_html, footer_html]))
|
||||
|
||||
failures: list[str] = []
|
||||
actions: list[str] = []
|
||||
@@ -155,19 +189,23 @@ def validate_outputs(generated: dict, measurement: dict) -> tuple[str, list[str]
|
||||
failures.append("Verify-RenderZone")
|
||||
actions.append(f"overflow가 발생한 zone({', '.join(zone_overflows)})의 content budget, block 수, typography를 재조정한다.")
|
||||
|
||||
if not all(key in text for key in CORE_MESSAGE_KEYS):
|
||||
if not all(key in visible_text for key in CORE_MESSAGE_KEYS):
|
||||
failures.append("Verify-CoreMessage")
|
||||
actions.append("핵심 메시지 `DX는 상위 개념`, `BIM은 핵심 기술`을 가시 텍스트에 직접 노출한다.")
|
||||
|
||||
if IMAGE_REFERENCE_KEY not in text:
|
||||
if IMAGE_REFERENCE_KEY not in visible_text:
|
||||
failures.append("Verify-ImageRef")
|
||||
actions.append("이미지/도해 참조 문구 `DX와 핵심기술간 상호관계`를 숨김 영역이 아닌 가시 블록으로 유지한다.")
|
||||
|
||||
comparison_visible = COMPARISON_MARKER in sidebar_html and all(key in text for key in COMPARE_KEYS)
|
||||
comparison_visible = COMPARISON_MARKER in sidebar_html and all(key in visible_text for key in COMPARE_KEYS)
|
||||
if not comparison_visible:
|
||||
failures.append("Verify-ComparisonVisible")
|
||||
actions.append("비교 핵심 4축(범위, 프로세스, 성과품, 확장성)을 화면에 바로 보이는 요약 블록으로 강제한다.")
|
||||
|
||||
if RELATION_MARKER not in body_html:
|
||||
failures.append("Verify-DesignStructure")
|
||||
actions.append("핵심 관계를 설명하는 시각적 관계도 블록을 본문 중심 구조로 유지한다.")
|
||||
|
||||
if failures:
|
||||
return "revise", sorted(set(failures)), list(dict.fromkeys(actions))
|
||||
return "pass", [], []
|
||||
@@ -337,7 +375,7 @@ KPI / 판정 결과
|
||||
generated = read_json(generated_path)
|
||||
context = read_json(context_path)
|
||||
changed = inject_visible_comparison_summary(generated)
|
||||
compact_applied = False
|
||||
redesign_applied = False
|
||||
if changed:
|
||||
write_json(generated_path, generated)
|
||||
final_html = rerender_final_html(generated, context)
|
||||
@@ -348,9 +386,9 @@ KPI / 판정 결과
|
||||
measurement = read_json(measurement_path)
|
||||
|
||||
status, failures, actions = validate_outputs(generated, measurement)
|
||||
if status != "pass" and any(f in failures for f in ["Verify-RenderZone", "Verify-CoreMessage", "Verify-ComparisonVisible", "Verify-ImageRef"]):
|
||||
generated = build_compact_generated(context)
|
||||
compact_applied = True
|
||||
if status != "pass" and any(f in failures for f in ["Verify-RenderZone", "Verify-CoreMessage", "Verify-ComparisonVisible", "Verify-ImageRef", "Verify-DesignStructure"]):
|
||||
generated = build_slide_regenerated(context)
|
||||
redesign_applied = True
|
||||
write_json(generated_path, generated)
|
||||
final_html = rerender_final_html(generated, context)
|
||||
final_html_path.write_text(final_html, encoding="utf-8")
|
||||
@@ -370,7 +408,7 @@ KPI / 판정 결과
|
||||
- 입력: `docs/{args.run_id}/01-input/{input_file.name}`
|
||||
- 산출물: `final.html`, `generated_html.json`, `measurement.json`, `context.json`
|
||||
- 비교 요약 가시 블록 보강: {'적용' if changed else '기존 유지'}
|
||||
- 컴팩트 재구성 적용: {'예' if compact_applied else '아니오'}
|
||||
- 슬라이드형 재생성 적용: {'예' if redesign_applied else '아니오'}
|
||||
|
||||
산출물 경로
|
||||
- `docs/{args.run_id}/05-execution/final.html`
|
||||
@@ -399,7 +437,7 @@ KPI / 판정 결과
|
||||
- iteration {iteration} 기준으로 최종 산출물과 측정 결과를 다시 검증했다.
|
||||
- slide overflow: {measurement.get('slide', {}).get('overflowed')}
|
||||
- zone overflow: {', '.join(zone_names) if zone_names else '없음'}
|
||||
- 컴팩트 재구성 적용: {'예' if compact_applied else '아니오'}
|
||||
- 슬라이드형 재생성 적용: {'예' if redesign_applied else '아니오'}
|
||||
- 최종 판정은 `{status}`이다.
|
||||
|
||||
산출물 경로
|
||||
|
||||
Reference in New Issue
Block a user