init: llm-wiki-haness 하네스 설계

This commit is contained in:
DongHyeonka
2026-07-24 14:21:35 +09:00
parent 42bf3db4fd
commit 6c53ded9cb
2436 changed files with 194486 additions and 1 deletions
@@ -0,0 +1,52 @@
<mxfile host="Claude Code" agent="wiki-superpowers + diagram-standards v2 minimalist" version="24.0.0" type="device">
<diagram name="clean-architecture-concentric" id="clean">
<mxGraphModel dx="1100" dy="720" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1000" pageHeight="760" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" value="Clean Architecture — 4개 동심원과 The Dependency Rule" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#1F2937;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="920" height="32" as="geometry" />
</mxCell>
<mxCell id="subtitle" value="의존성은 바깥 → 안으로만 향한다. 안쪽 원은 바깥 원의 이름·타입·함수를 전혀 모른다." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" vertex="1" parent="1">
<mxGeometry x="40" y="52" width="920" height="20" as="geometry" />
</mxCell>
<mxCell id="ring4" value="&lt;b&gt;Frameworks &amp; Drivers&lt;/b&gt;&#10;DB · Web · UI · 외부 기기" style="ellipse;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#57606A;verticalAlign=top;align=center;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="330" y="110" width="540" height="470" as="geometry" />
</mxCell>
<mxCell id="ring3" value="&lt;b&gt;Interface Adapters&lt;/b&gt;&#10;Controller · Gateway · Presenter" style="ellipse;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#57606A;verticalAlign=top;align=center;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="400" y="165" width="400" height="360" as="geometry" />
</mxCell>
<mxCell id="ring2" value="&lt;b&gt;Use Cases&lt;/b&gt;&#10;application 규칙" style="ellipse;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#57606A;verticalAlign=top;align=center;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="465" y="220" width="270" height="250" as="geometry" />
</mxCell>
<mxCell id="ring1" value="&lt;b&gt;Entities&lt;/b&gt;&#10;핵심 규칙" style="ellipse;whiteSpace=wrap;html=1;fillColor=#EFF6FF;strokeColor=#1F6FEB;strokeWidth=2.5;fontSize=13;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;verticalAlign=middle;align=center;" vertex="1" parent="1">
<mxGeometry x="530" y="290" width="140" height="110" as="geometry" />
</mxCell>
<mxCell id="dep-arrow" value="" style="endArrow=classic;html=1;strokeColor=#1F6FEB;strokeWidth=3;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="150" y="345" as="sourcePoint" />
<mxPoint x="330" y="345" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="dep-label" value="&lt;b&gt;The Dependency Rule&lt;/b&gt;&#10;바깥 → 안으로만" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="90" y="285" width="180" height="40" as="geometry" />
</mxCell>
<mxCell id="callout" value="&lt;b&gt;안쪽일수록 순수, 바깥일수록 기술&lt;/b&gt;&#10;&#10;• 제어 흐름(호출)은 바깥→안, 소스 의존성도 바깥→안 (일치)&#10;• 흐름과 반대인 곳은 인터페이스(DIP)로 방향을 뒤집는다&#10;• 경계를 넘는 데이터는 단순 구조(DTO 등)로 전달&#10;• Hexagonal 과 규칙은 같고, 링을 4개로 더 세분화한 표현" style="rounded=8;whiteSpace=wrap;html=1;fillColor=#F6F8FA;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#374151;align=left;verticalAlign=top;spacingLeft=12;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="120" y="600" width="580" height="130" as="geometry" />
</mxCell>
<mxCell id="leg1" value="파란 원 = Entities (가장 안쪽 · 순수 규칙)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="730" y="610" width="250" height="20" as="geometry" />
</mxCell>
<mxCell id="footer" value="v1 (minimalist) · 2026-07-04" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontStyle=2;fontFamily=Pretendard,Helvetica;fontColor=#9CA3AF;" vertex="1" parent="1">
<mxGeometry x="760" y="720" width="220" height="20" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,48 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="760" viewBox="0 0 1000 760" font-family="Pretendard, Helvetica, Arial, sans-serif">
<defs>
<marker id="arrowBlue" markerWidth="12" markerHeight="12" refX="8" refY="5" orient="auto" markerUnits="userSpaceOnUse">
<path d="M0,0 L9,5 L0,10 z" fill="#1F6FEB"/>
</marker>
</defs>
<rect x="0" y="0" width="1000" height="760" fill="#FFFFFF"/>
<text x="40" y="42" font-size="20" font-weight="bold" fill="#1F2937">Clean Architecture — 4개 동심원과 The Dependency Rule</text>
<text x="40" y="66" font-size="12" fill="#6B7280">의존성은 바깥 → 안으로만 향한다. 안쪽 원은 바깥 원의 이름·타입·함수를 전혀 모른다.</text>
<!-- Concentric rings -->
<ellipse cx="600" cy="345" rx="270" ry="235" fill="none" stroke="#57606A" stroke-width="1.5"/>
<ellipse cx="600" cy="345" rx="200" ry="180" fill="none" stroke="#57606A" stroke-width="1.5"/>
<ellipse cx="600" cy="345" rx="135" ry="125" fill="none" stroke="#57606A" stroke-width="1.5"/>
<ellipse cx="600" cy="345" rx="70" ry="55" fill="#EFF6FF" stroke="#1F6FEB" stroke-width="2.5"/>
<!-- Ring labels (top of each ring) -->
<text x="600" y="132" text-anchor="middle" font-size="12" font-weight="bold" fill="#57606A">Frameworks &amp; Drivers</text>
<text x="600" y="149" text-anchor="middle" font-size="11" fill="#57606A">DB · Web · UI · 외부 기기</text>
<text x="600" y="187" text-anchor="middle" font-size="12" font-weight="bold" fill="#57606A">Interface Adapters</text>
<text x="600" y="204" text-anchor="middle" font-size="11" fill="#57606A">Controller · Gateway · Presenter</text>
<text x="600" y="242" text-anchor="middle" font-size="12" font-weight="bold" fill="#57606A">Use Cases</text>
<text x="600" y="259" text-anchor="middle" font-size="11" fill="#57606A">application 규칙</text>
<text x="600" y="341" text-anchor="middle" font-size="13" font-weight="bold" fill="#1F6FEB">Entities</text>
<text x="600" y="359" text-anchor="middle" font-size="11" fill="#1F6FEB">핵심 규칙</text>
<!-- Dependency Rule arrow -->
<line x1="150" y1="345" x2="322" y2="345" stroke="#1F6FEB" stroke-width="3" marker-end="url(#arrowBlue)"/>
<text x="180" y="303" text-anchor="middle" font-size="11" font-weight="bold" fill="#1F6FEB">The Dependency Rule</text>
<text x="180" y="321" text-anchor="middle" font-size="11" fill="#1F6FEB">바깥 → 안으로만</text>
<!-- Callout (key insight) -->
<rect x="120" y="600" width="580" height="130" rx="8" fill="#F6F8FA" stroke="#57606A" stroke-width="1.5"/>
<text x="136" y="626" font-size="12" font-weight="bold" fill="#374151">안쪽일수록 순수, 바깥일수록 기술</text>
<text x="136" y="652" font-size="11" fill="#374151">• 제어 흐름(호출)은 바깥→안, 소스 의존성도 바깥→안 (일치)</text>
<text x="136" y="674" font-size="11" fill="#374151">• 흐름과 반대인 곳은 인터페이스(DIP)로 방향을 뒤집는다</text>
<text x="136" y="696" font-size="11" fill="#374151">• 경계를 넘는 데이터는 단순 구조(DTO 등)로 전달</text>
<text x="136" y="718" font-size="11" fill="#374151">• Hexagonal 과 규칙은 같고, 링을 4개로 더 세분화한 표현</text>
<!-- Legend -->
<text x="730" y="614" font-size="11" fill="#1F6FEB">● 파란 원 = Entities (가장 안쪽 · 순수 규칙)</text>
<text x="960" y="732" text-anchor="end" font-size="10" font-style="italic" fill="#9CA3AF">v1 · 2026-07-04</text>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,62 @@
<mxfile host="Claude Code" agent="wiki-superpowers + diagram-standards v2 minimalist" version="24.0.0" type="device">
<diagram name="hexagonal-architecture" id="hexagonal">
<mxGraphModel dx="1100" dy="700" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1040" pageHeight="720" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" value="Hexagonal (Ports &amp; Adapters) — 도메인을 바깥에서 격리한다" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#1F2937;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="960" height="32" as="geometry" />
</mxCell>
<mxCell id="subtitle" value="모든 adapter가 core에 의존(안쪽). core는 port(interface)만 정의하고 외부(web·DB)를 모른다." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" vertex="1" parent="1">
<mxGeometry x="40" y="52" width="960" height="20" as="geometry" />
</mxCell>
<mxCell id="core" value="&lt;b&gt;Application Core&lt;/b&gt;&#10;domain + use case" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#EFF6FF;strokeColor=#1F6FEB;strokeWidth=2.5;fontSize=13;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="410" y="270" width="240" height="150" as="geometry" />
</mxCell>
<mxCell id="web" value="&lt;b&gt;Web Adapter&lt;/b&gt;&#10;REST · inbound" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="80" y="230" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="test" value="&lt;b&gt;Test / Batch&lt;/b&gt;&#10;inbound" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="80" y="390" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="persist" value="&lt;b&gt;Persistence Adapter&lt;/b&gt;&#10;JPA · outbound" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="780" y="230" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="db" value="&lt;b&gt;DB&lt;/b&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=14;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="820" y="400" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="e-web" value="inbound port" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.4;entryDx=0;entryDy=0;strokeColor=#1F6FEB;strokeWidth=2.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" edge="1" parent="1" source="web" target="core">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-test" value="inbound port" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.6;entryDx=0;entryDy=0;strokeColor=#1F6FEB;strokeWidth=2.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" edge="1" parent="1" source="test" target="core">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-persist" value="outbound port 구현" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#1F6FEB;strokeWidth=2.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" edge="1" parent="1" source="persist" target="core">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-db" value="JDBC" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" edge="1" parent="1" source="persist" target="db">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="callout" value="&lt;b&gt;핵심 — 의존성 역전(DIP)&lt;/b&gt;&#10;&#10;• core 는 port(interface)만 정의, 구현은 바깥 adapter 가 담당&#10;• 그래서 core(도메인)는 web·DB 의 존재를 모른다&#10;• DB·web 교체 자유 + 실제 장비 없이 격리 테스트 가능&#10;• 대가: port/adapter 보일러플레이트, 모델 매핑 비용" style="rounded=8;whiteSpace=wrap;html=1;fillColor=#F6F8FA;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#374151;align=left;verticalAlign=top;spacingLeft=12;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="340" y="500" width="560" height="120" as="geometry" />
</mxCell>
<mxCell id="leg1" value="파란 육각형 = Application Core (격리 대상)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="60" y="510" width="260" height="20" as="geometry" />
</mxCell>
<mxCell id="leg2" value="파란 화살 = adapter → core 의존(안쪽)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="60" y="532" width="260" height="20" as="geometry" />
</mxCell>
<mxCell id="footer" value="v1 (minimalist) · 2026-07-04" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontStyle=2;fontFamily=Pretendard,Helvetica;fontColor=#9CA3AF;" vertex="1" parent="1">
<mxGeometry x="780" y="670" width="220" height="20" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,65 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1040" height="720" viewBox="0 0 1040 720" font-family="Pretendard, Helvetica, Arial, sans-serif">
<defs>
<marker id="arrowBlue" markerWidth="10" markerHeight="10" refX="7" refY="5" orient="auto" markerUnits="userSpaceOnUse">
<path d="M0,0 L8,5 L0,10 z" fill="#1F6FEB"/>
</marker>
<marker id="arrowGray" markerWidth="10" markerHeight="10" refX="7" refY="5" orient="auto" markerUnits="userSpaceOnUse">
<path d="M0,0 L8,5 L0,10 z" fill="#57606A"/>
</marker>
</defs>
<rect x="0" y="0" width="1040" height="720" fill="#FFFFFF"/>
<text x="40" y="42" font-size="20" font-weight="bold" fill="#1F2937">Hexagonal (Ports &amp; Adapters) — 도메인을 바깥에서 격리한다</text>
<text x="40" y="66" font-size="12" fill="#6B7280">모든 adapter가 core에 의존(안쪽). core는 port(interface)만 정의하고 외부(web·DB)를 모른다.</text>
<!-- Application Core (hexagon) -->
<polygon points="410,345 450,270 610,270 650,345 610,420 450,420" fill="#EFF6FF" stroke="#1F6FEB" stroke-width="2.5"/>
<text x="530" y="340" text-anchor="middle" font-size="13" font-weight="bold" fill="#1F6FEB">Application Core</text>
<text x="530" y="360" text-anchor="middle" font-size="12" fill="#1F6FEB">domain + use case</text>
<!-- Web Adapter (inbound) -->
<rect x="80" y="230" width="200" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="180" y="260" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Web Adapter</text>
<text x="180" y="280" text-anchor="middle" font-size="12" fill="#24292F">REST · inbound</text>
<!-- Test / Batch (inbound) -->
<rect x="80" y="390" width="200" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="180" y="420" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Test / Batch</text>
<text x="180" y="440" text-anchor="middle" font-size="12" fill="#24292F">inbound</text>
<!-- Persistence Adapter (outbound) -->
<rect x="780" y="230" width="200" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="880" y="260" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Persistence Adapter</text>
<text x="880" y="280" text-anchor="middle" font-size="12" fill="#24292F">JPA · outbound</text>
<!-- DB cylinder -->
<path d="M820,412 L820,470 A60,10 0 0 0 940,470 L940,412" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<ellipse cx="880" cy="412" rx="60" ry="10" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="880" y="448" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">DB</text>
<!-- Edges: adapters -> core (inward, blue) -->
<line x1="280" y1="265" x2="444" y2="306" stroke="#1F6FEB" stroke-width="2.5" marker-end="url(#arrowBlue)"/>
<text x="352" y="276" font-size="11" fill="#1F6FEB">inbound port</text>
<line x1="280" y1="425" x2="446" y2="386" stroke="#1F6FEB" stroke-width="2.5" marker-end="url(#arrowBlue)"/>
<text x="352" y="420" font-size="11" fill="#1F6FEB">inbound port</text>
<line x1="780" y1="265" x2="616" y2="306" stroke="#1F6FEB" stroke-width="2.5" marker-end="url(#arrowBlue)"/>
<text x="648" y="276" font-size="11" fill="#1F6FEB">outbound port 구현</text>
<!-- Edge: persistence -> DB (gray) -->
<line x1="880" y1="300" x2="880" y2="410" stroke="#57606A" stroke-width="1.5" marker-end="url(#arrowGray)"/>
<text x="890" y="360" font-size="11" fill="#6B7280">JDBC</text>
<!-- Callout (key insight) -->
<rect x="340" y="500" width="560" height="120" rx="8" fill="#F6F8FA" stroke="#57606A" stroke-width="1.5"/>
<text x="356" y="526" font-size="12" font-weight="bold" fill="#374151">핵심 — 의존성 역전(DIP)</text>
<text x="356" y="552" font-size="11" fill="#374151">• core 는 port(interface)만 정의, 구현은 바깥 adapter 가 담당</text>
<text x="356" y="574" font-size="11" fill="#374151">• 그래서 core(도메인)는 web·DB 의 존재를 모른다</text>
<text x="356" y="596" font-size="11" fill="#374151">• DB·web 교체 자유 + 실제 장비 없이 격리 테스트 가능</text>
<text x="356" y="618" font-size="11" fill="#374151">• 대가: port/adapter 보일러플레이트, 모델 매핑 비용</text>
<!-- Legend -->
<text x="60" y="516" font-size="11" fill="#1F6FEB">⬡ 파란 육각형 = Application Core (격리 대상)</text>
<text x="60" y="538" font-size="11" fill="#1F6FEB">→ 파란 화살 = adapter → core 의존(안쪽)</text>
<text x="1000" y="690" text-anchor="end" font-size="10" font-style="italic" fill="#9CA3AF">v1 · 2026-07-04</text>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

@@ -0,0 +1,48 @@
<mxfile host="Claude Code" agent="wiki-superpowers + diagram-standards v2 minimalist" version="24.0.0" type="device">
<diagram name="layered-architecture" id="layered">
<mxGraphModel dx="1000" dy="700" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="780" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" value="전통적 Layered 아키텍처 — 의존성이 DB로 향한다" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#1F2937;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="820" height="32" as="geometry" />
</mxCell>
<mxCell id="subtitle" value="Presentation → Business → Data Access → DB. 위에서 아래로만 의존한다 (질문: 무엇이 문제인가?)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=12;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" vertex="1" parent="1">
<mxGeometry x="40" y="52" width="820" height="20" as="geometry" />
</mxCell>
<mxCell id="pres" value="&lt;b&gt;Presentation&lt;/b&gt;&#10;Controller · View" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="320" y="100" width="280" height="70" as="geometry" />
</mxCell>
<mxCell id="biz" value="&lt;b&gt;Business Logic&lt;/b&gt;&#10;Service · 도메인 규칙" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="320" y="215" width="280" height="70" as="geometry" />
</mxCell>
<mxCell id="dao" value="&lt;b&gt;Data Access&lt;/b&gt;&#10;Repository · DAO" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="320" y="330" width="280" height="70" as="geometry" />
</mxCell>
<mxCell id="db" value="&lt;b&gt;Database&lt;/b&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=14;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1.5;fontSize=12;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="360" y="445" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="e1" value="depends on" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" edge="1" parent="1" source="pres" target="biz">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e2" value="depends on" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" edge="1" parent="1" source="biz" target="dao">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e3" value="depends on" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#6B7280;" edge="1" parent="1" source="dao" target="db">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="callout" value="⚠️ &lt;b&gt;문제 — 도메인이 기술에 묶인다&lt;/b&gt;&#10;&#10;• 비즈니스 규칙이 아래(DB·기술)에 의존 → DB·프레임워크를 바꾸면 도메인까지 영향&#10;• 도메인 테스트에 DB가 필요 → 느리고 깨지기 쉬움&#10;• (package-by-layer) 한 도메인이 controller/service/repository로 흩어져 저응집" style="rounded=8;whiteSpace=wrap;html=1;fillColor=#FEF2F2;strokeColor=#DC2626;strokeWidth=1.5;fontSize=11;fontFamily=Pretendard,Helvetica;fontColor=#7F1D1D;align=left;verticalAlign=top;spacingLeft=12;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="180" y="575" width="560" height="120" as="geometry" />
</mxCell>
<mxCell id="footer" value="v1 (minimalist) · 2026-07-04" style="text;html=1;strokeColor=none;fillColor=none;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontStyle=2;fontFamily=Pretendard,Helvetica;fontColor=#9CA3AF;" vertex="1" parent="1">
<mxGeometry x="640" y="730" width="220" height="20" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -0,0 +1,48 @@
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="780" viewBox="0 0 900 780" font-family="Pretendard, Helvetica, Arial, sans-serif">
<defs>
<marker id="arrowGray" markerWidth="10" markerHeight="10" refX="7" refY="5" orient="auto" markerUnits="userSpaceOnUse">
<path d="M0,0 L8,5 L0,10 z" fill="#57606A"/>
</marker>
</defs>
<rect x="0" y="0" width="900" height="780" fill="#FFFFFF"/>
<text x="40" y="42" font-size="20" font-weight="bold" fill="#1F2937">전통적 Layered 아키텍처 — 의존성이 DB로 향한다</text>
<text x="40" y="66" font-size="12" fill="#6B7280">Presentation → Business → Data Access → DB. 위에서 아래로만 의존한다 (질문: 무엇이 문제인가?)</text>
<!-- Presentation -->
<rect x="320" y="100" width="280" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="460" y="130" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Presentation</text>
<text x="460" y="150" text-anchor="middle" font-size="12" fill="#24292F">Controller · View</text>
<!-- Business -->
<rect x="320" y="215" width="280" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="460" y="245" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Business Logic</text>
<text x="460" y="265" text-anchor="middle" font-size="12" fill="#24292F">Service · 도메인 규칙</text>
<!-- Data Access -->
<rect x="320" y="330" width="280" height="70" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="460" y="360" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Data Access</text>
<text x="460" y="380" text-anchor="middle" font-size="12" fill="#24292F">Repository · DAO</text>
<!-- DB cylinder -->
<path d="M360,457 L360,523 A100,12 0 0 0 560,523 L560,457" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<ellipse cx="460" cy="457" rx="100" ry="12" fill="#FFFFFF" stroke="#57606A" stroke-width="1.5"/>
<text x="460" y="497" text-anchor="middle" font-size="12" font-weight="bold" fill="#24292F">Database</text>
<!-- Edges -->
<line x1="460" y1="170" x2="460" y2="213" stroke="#57606A" stroke-width="1.5" marker-end="url(#arrowGray)"/>
<text x="470" y="196" font-size="11" fill="#6B7280">depends on</text>
<line x1="460" y1="285" x2="460" y2="328" stroke="#57606A" stroke-width="1.5" marker-end="url(#arrowGray)"/>
<text x="470" y="311" font-size="11" fill="#6B7280">depends on</text>
<line x1="460" y1="400" x2="460" y2="443" stroke="#57606A" stroke-width="1.5" marker-end="url(#arrowGray)"/>
<text x="470" y="426" font-size="11" fill="#6B7280">depends on</text>
<!-- Callout (problem) -->
<rect x="180" y="575" width="560" height="120" rx="8" fill="#FEF2F2" stroke="#DC2626" stroke-width="1.5"/>
<text x="196" y="601" font-size="12" font-weight="bold" fill="#7F1D1D">⚠️ 문제 — 도메인이 기술에 묶인다</text>
<text x="196" y="629" font-size="11" fill="#7F1D1D">• 비즈니스 규칙이 아래(DB·기술)에 의존 → DB·프레임워크를 바꾸면 도메인까지 영향</text>
<text x="196" y="653" font-size="11" fill="#7F1D1D">• 도메인 테스트에 DB가 필요 → 느리고 깨지기 쉬움</text>
<text x="196" y="677" font-size="11" fill="#7F1D1D">• (package-by-layer) 한 도메인이 controller/service/repository로 흩어져 저응집</text>
<text x="860" y="745" text-anchor="end" font-size="10" font-style="italic" fill="#9CA3AF">v1 · 2026-07-04</text>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB