feat: 문서 구조 변경 및 tech-visual 스킬 추가

This commit is contained in:
DongHyeonka
2026-09-04 18:20:00 +09:00
parent 43901f0abf
commit 2efb7ee1f2
683 changed files with 61180 additions and 10479 deletions
@@ -0,0 +1,195 @@
{
"version": "1.1",
"id": "eager-lazy-query-sequence",
"title": "EAGER 2차 조회는 반환 전에, LAZY highlights 조회는 매핑 접근 뒤에 실행된다",
"question": "루트 피드 조회부터 EAGER ToOne과 LAZY highlights 조회까지 SQL은 어떤 순서로 발생하는가?",
"type": "sequence",
"direction": "LR",
"audience": [
"JPA·Hibernate를 사용하는 백엔드 개발자",
"쿼리 성능 분석자"
],
"summary": "Hibernate는 feed_items를 먼저 조회하고 EAGER user·page를 2차 SELECT로 채운 뒤 반환하며, 매핑 중 getHighlights() 접근이 생긴 다음 LAZY highlights SELECT를 실행한다.",
"alt": "loadFeed 매핑, Hibernate, PostgreSQL 사이에서 루트 SELECT, EAGER user·page 2차 SELECT, getHighlights 접근, LAZY highlights SELECT가 차례로 일어나는 시퀀스.",
"long_description": "세 참가자를 왼쪽부터 loadFeed DTO 매핑, Hibernate, PostgreSQL 순으로 읽는다. loadFeed가 findAllBy 파생 쿼리를 호출하면 Hibernate가 PostgreSQL에서 feed_items를 먼저 조회한다. 이어 fetch join되지 않은 EAGER user와 page를 별도의 2차 SELECT로 채우고, 반환 시점까지 로딩된 FeedItem을 loadFeed에 돌려준다. 이후 DTO 매핑이 getHighlights()에 접근하면 Hibernate가 해당 아이템의 highlights 컬렉션 SELECT를 실행한다.",
"source_context": {
"document": "/home/donghyeon/workspace/ai-tool/topic-arrange/n+1liner/n+1liner.md",
"document_sha256": "1bb38964ca2a849690f5355646c1aa988111b4cd4e1055c6cb05cf7e5fc35cde",
"anchor": {
"kind": "marker",
"value": "eager-lazy-query-sequence",
"line": 324
}
},
"composition": {
"profile": "sequence",
"diagram_only": true,
"reference_ids": [
"payment-approval-sequence"
],
"rationale": "문서가 루트 조회, EAGER 2차 SELECT, 반환, 매핑 접근, LAZY SELECT의 시간 순서를 명시하므로 참가자별 메시지를 위에서 아래로 배열하는 sequence 구성이 적합하다.",
"focus_node": "hibernate"
},
"groups": [],
"nodes": [
{
"id": "load-feed-mapping",
"label": "loadFeed DTO 매핑",
"kind": "participant",
"role": "participant",
"description": "FeedItem을 순회하며 응답 DTO를 조립하고 highlights 게터에 접근하는 호출자.",
"evidence": [
{
"start_line": 322,
"end_line": 322
},
{
"start_line": 449,
"end_line": 451
}
],
"assumption": false
},
{
"id": "hibernate",
"label": "Hibernate",
"kind": "participant",
"role": "participant",
"emphasis": "primary",
"description": "파생 쿼리의 루트 조회와 EAGER 2차 SELECT, LAZY 컬렉션 초기화를 수행하는 JPA provider.",
"evidence": [
{
"start_line": 320,
"end_line": 322
}
],
"assumption": false
},
{
"id": "postgresql",
"label": "PostgreSQL",
"kind": "participant",
"role": "participant",
"shape": "database",
"description": "Hibernate가 루트 및 연관 SELECT를 실행하는 데이터베이스.",
"evidence": [
{
"start_line": 417,
"end_line": 422
},
{
"start_line": 447,
"end_line": 447
}
],
"assumption": false
}
],
"edges": [
{
"id": "m1-find-all",
"from": "load-feed-mapping",
"to": "hibernate",
"label": "findAllBy(...)",
"kind": "request",
"order": 1,
"evidence": [
{
"start_line": 320,
"end_line": 320
}
],
"assumption": false
},
{
"id": "m2-root-select",
"from": "hibernate",
"to": "postgresql",
"label": "SELECT feed_items",
"kind": "data",
"order": 2,
"emphasis": "primary",
"evidence": [
{
"start_line": 320,
"end_line": 320
}
],
"assumption": false
},
{
"id": "m3-eager-secondary-selects",
"from": "hibernate",
"to": "postgresql",
"label": "SELECT user / page · EAGER 2차",
"kind": "data",
"order": 3,
"evidence": [
{
"start_line": 318,
"end_line": 321
}
],
"assumption": false
},
{
"id": "m4-return-eager-loaded-items",
"from": "hibernate",
"to": "load-feed-mapping",
"label": "EAGER 연관이 채워진 FeedItem 반환",
"kind": "response",
"style": "dashed",
"order": 4,
"evidence": [
{
"start_line": 318,
"end_line": 320
}
],
"assumption": false
},
{
"id": "m5-access-highlights",
"from": "load-feed-mapping",
"to": "hibernate",
"label": "매핑 중 getHighlights() 접근",
"kind": "request",
"order": 5,
"evidence": [
{
"start_line": 322,
"end_line": 322
},
{
"start_line": 449,
"end_line": 451
}
],
"assumption": false
},
{
"id": "m6-lazy-highlights-select",
"from": "hibernate",
"to": "postgresql",
"label": "SELECT highlights WHERE feed_item_id = ?",
"kind": "data",
"order": 6,
"emphasis": "primary",
"evidence": [
{
"start_line": 322,
"end_line": 322
},
{
"start_line": 429,
"end_line": 430
}
],
"assumption": false
}
],
"legend": [],
"metadata": {
"rationale": "EAGER와 LAZY의 차이를 정적 관계가 아니라 실제 SQL 발생 순서와 접근 시점으로 보여준다."
}
}