Files
document-haness/docs/n+1liner/final/.techviz/query-port-boundary/spec.json
T

161 lines
5.0 KiB
JSON
Executable File

{
"version": "1.1",
"id": "query-port-boundary",
"title": "조회 전략은 FeedQueryPort 뒤의 퍼시스턴스 어댑터에 격리된다",
"question": "GET /feed 조회는 어떤 상위 계층을 거쳐 포트에 도달하며, 실제 조회 전략은 어디에 격리되는가?",
"type": "architecture",
"direction": "LR",
"audience": [
"백엔드 개발자",
"아키텍처 검토자"
],
"summary": "FeedController는 조회 유스케이스를 호출하고, 유스케이스는 FeedQueryPort에 의존하며, FeedQueryAdapter가 포트를 구현해 PostgreSQL 조회 전략을 맡는다.",
"alt": "GET /feed를 받는 FeedController에서 GetFeedUseCase와 FeedQueryPort로 이어지고 FeedQueryAdapter가 포트를 구현하는 포트·어댑터 구조.",
"long_description": "왼쪽의 FeedController가 GET /feed 요청을 받아 중앙의 GetFeedUseCase에 조회를 위임한다. 유스케이스는 오른쪽의 FeedQueryPort에 조회를 의존한다. FeedQueryAdapter는 FeedQueryPort를 구현하는 아웃바운드 어댑터이며 PostgreSQL 조회를 수행한다. Fetch Join, Batch Fetch, DTO Projection, 윈도우 함수 같은 구체 전략은 이 어댑터의 책임이므로 상위 계층은 전략 교체의 영향을 받지 않는다.",
"source_context": {
"document": "/home/donghyeon/workspace/ai-tool/topic-arrange/n+1liner/n+1liner.md",
"document_sha256": "1bb38964ca2a849690f5355646c1aa988111b4cd4e1055c6cb05cf7e5fc35cde",
"anchor": {
"kind": "marker",
"value": "query-port-boundary",
"line": 297
}
},
"composition": {
"profile": "ports-adapters",
"diagram_only": true,
"reference_ids": [
"order-ports-adapters"
],
"rationale": "문서의 핵심은 상위 웹·애플리케이션 계층과 교체 가능한 조회 전략 사이의 포트 의존 및 어댑터 구현 방향이므로 ports-adapters 구성이 직접 답한다.",
"focus_node": "get-feed-use-case"
},
"groups": [],
"nodes": [
{
"id": "feed-controller",
"label": "FeedController",
"kind": "adapter",
"role": "inbound-adapter",
"details": [
"GET /feed"
],
"description": "조회 입력과 FeedSummary 반환 형태만 아는 웹 계층.",
"evidence": [
{
"start_line": 295,
"end_line": 295
}
],
"assumption": false
},
{
"id": "get-feed-use-case",
"label": "GetFeedUseCase",
"kind": "application",
"role": "core",
"shape": "hexagon",
"emphasis": "primary",
"description": "조회 사용자, 페이지 크기, FeedSummary 계약만 아는 애플리케이션 계층.",
"evidence": [
{
"start_line": 295,
"end_line": 295
}
],
"assumption": false
},
{
"id": "feed-query-port",
"label": "FeedQueryPort",
"kind": "interface",
"role": "port",
"shape": "port",
"description": "상위 계층과 구체 조회 전략을 분리하는 조회 포트.",
"evidence": [
{
"start_line": 295,
"end_line": 295
},
{
"start_line": 299,
"end_line": 299
}
],
"assumption": false
},
{
"id": "feed-query-adapter",
"label": "FeedQueryAdapter",
"kind": "adapter",
"role": "outbound-adapter",
"description": "FeedQueryPort를 구현하며 구체 조회 전략을 책임지는 퍼시스턴스 어댑터.",
"details": [
"PostgreSQL 조회",
"Fetch Join · Batch Fetch",
"DTO Projection · 윈도우 함수"
],
"evidence": [
{
"start_line": 295,
"end_line": 295
},
{
"start_line": 299,
"end_line": 299
}
],
"assumption": false
}
],
"edges": [
{
"id": "controller-to-use-case",
"from": "feed-controller",
"to": "get-feed-use-case",
"label": "GET /feed 조회 위임",
"kind": "request",
"emphasis": "primary",
"evidence": [
{
"start_line": 295,
"end_line": 295
}
],
"assumption": false
},
{
"id": "use-case-to-port",
"from": "get-feed-use-case",
"to": "feed-query-port",
"label": "조회 의존",
"kind": "dependency",
"evidence": [
{
"start_line": 295,
"end_line": 295
}
],
"assumption": false
},
{
"id": "adapter-implements-port",
"from": "feed-query-adapter",
"to": "feed-query-port",
"label": "implements",
"kind": "dependency",
"evidence": [
{
"start_line": 295,
"end_line": 295
}
],
"assumption": false
}
],
"legend": [],
"metadata": {
"rationale": "구체 조회 기법보다 웹·애플리케이션 계층, FeedQueryPort, 퍼시스턴스 어댑터 사이의 의존 경계를 한 수준에서 보여준다."
}
}