{ "version": "1.1", "id": "composition-root-seam", "title": "테스트가 끊긴 곳과 실제 런타임이 지나는 합성 루트", "question": "게이트웨이 테스트와 화면 테스트가 통과했는데 왜 합성 루트의 credential 결함은 운영에서만 드러났는가?", "type": "component", "direction": "LR", "audience": [ "프론트엔드 개발자", "테스트 설계자" ], "summary": "화면 테스트는 게이트웨이를 스텁하고 게이트웨이 테스트는 실행기를 스텁해서, 실제 런타임만 지나는 합성 루트의 credential 결정이 두 테스트에서 빠졌다.", "alt": "화면, 게이트웨이, 합성 루트의 credential 결정, 실제 런타임 어댑터가 이어진 경로. 화면에는 게이트웨이 스텁, 게이트웨이에는 실행기 스텁이 표시되고 합성 루트가 테스트 공백으로 강조되어 있다.", "long_description": "왼쪽에서 오른쪽으로 실제 런타임 경로를 읽는다. 화면에서 게이트웨이로 가고 합성 루트에서 credential을 결정한 뒤 실제 런타임 어댑터가 배포된 백엔드의 실제 404 본문을 읽는다. 화면 테스트는 게이트웨이를 스텁하고 게이트웨이 테스트는 실행기를 스텁했기 때문에 가운데 합성 루트의 credential 결정은 두 테스트가 지나지 않았다.", "source_context": { "document": "docs/TechLog/final/document.md", "document_sha256": "c3a7de37b778fff7b6ea555a3ad7338c91c6fb15d685e7734f89472b4924d955", "anchor": { "kind": "heading", "value": "7. 테스트가 지나지 않는 이음매", "line": 690 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "본문은 화면·게이트웨이 테스트가 스텁에서 끊기는 반면 실제 런타임 어댑터가 합성 루트의 credential 결정을 지나가는 경로를 설명한다.", "focus_node": "composition-root" }, "groups": [], "nodes": [ { "id": "screen", "label": "화면", "kind": "component", "role": "source", "details": [ "화면 테스트: gateway stub" ], "evidence": [ { "start_line": 740, "end_line": 742 }, { "start_line": 770, "end_line": 771 } ], "assumption": false }, { "id": "gateway", "label": "Gateway", "kind": "service", "role": "service", "details": [ "gateway 테스트: executor stub" ], "evidence": [ { "start_line": 766, "end_line": 771 } ], "assumption": false }, { "id": "composition-root", "label": "Composition Root", "kind": "component", "role": "service", "details": [ "credential decision", "테스트 공백" ], "evidence": [ { "start_line": 748, "end_line": 767 } ], "assumption": false, "emphasis": "warning" }, { "id": "runtime-adapter", "label": "Runtime Adapter + 404", "kind": "service", "role": "sink", "details": [ "실제 어댑터", "배포된 백엔드 404 본문" ], "evidence": [ { "start_line": 769, "end_line": 771 } ], "assumption": false } ], "edges": [ { "id": "screen-gateway", "from": "screen", "to": "gateway", "label": "요청", "kind": "request", "evidence": [ { "start_line": 740, "end_line": 742 }, { "start_line": 766, "end_line": 771 } ], "assumption": false }, { "id": "gateway-root", "from": "gateway", "to": "composition-root", "label": "runtime 조립", "kind": "request", "evidence": [ { "start_line": 766, "end_line": 771 } ], "assumption": false }, { "id": "root-adapter", "from": "composition-root", "to": "runtime-adapter", "label": "credential 판정", "kind": "request", "evidence": [ { "start_line": 755, "end_line": 767 }, { "start_line": 769, "end_line": 771 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "테스트 두 개를 별도 카드로 다시 그리지 않고 실제 런타임 경로에 각 테스트가 어디에서 스텁되는지 details로 표시했다.", "layout_note": "선형 4단계라 LR을 유지한다. 테스트가 끊기는 두 지점과 가운데 composition-root 공백을 한 시야에서 비교하는 것이 목적이다." } }