{ "version": "1.1", "id": "topic-variant-model", "title": "주제 안의 축과 기록을 잇는 자리", "question": "하나의 질문에 대한 네 답을 무엇으로 담고, 기록은 어떻게 축에 걸리는가?", "type": "architecture", "direction": "LR", "audience": [ "백엔드 개발자", "아키텍처 검토자" ], "summary": "주제가 축의 이름을 정하고, 축의 값들이 그 아래 있고, record_variant 가 종류와 아이디 쌍으로 세 기록 테이블을 가리킨다.", "alt": "왼쪽부터 topic, topic_variant, record_variant 로 이어지고 record_variant 가 document·open_question·project_decision 세 테이블을 가리키는 구조도.", "long_description": "왼쪽에 topic 이 있고 variant_label 로 축의 이름을 스스로 정한다. 그 오른쪽에 topic_variant 가 있고 SPA, Mediator, BFF, Forward-Auth 같은 축의 값들을 담는다. 그 오른쪽에 record_variant 가 있고 어느 기록이 어느 축에 걸리는지를 종류와 아이디의 쌍으로 적는다. record_variant 는 오른쪽의 document, open_question, project_decision 세 테이블을 가리키는데, 기록이 종류마다 다른 테이블에 살기 때문에 외래키를 걸지 못하고 쌍으로만 가리킨다.", "source_context": { "document": "document.md", "document_sha256": "93b9fec4884efa0e6231de07dc27e2b0ac36c9052d3720e28d102d9747ac4f8f", "anchor": { "kind": "marker", "value": "topic-variant-model", "line": 1064 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "본문은 topic 에서 topic_variant 로, 다시 record_variant 로 내려가고 그것이 세 기록 테이블을 가리키는 참조 방향을 적는다. 방향이 있는 참조 사슬이므로 component-flow 다. 자동 선택이 고른 후보(two-zone-pipeline, sequence, comparison)는 이 절에 시간 순서도 두 구역도 비교 대상도 없어서 맞지 않는다.", "focus_node": "record-variant" }, "groups": [ { "id": "record-tables", "label": "기록은 종류마다 다른 테이블에 산다", "kind": "system", "role": "zone", "evidence": [ { "start_line": 1071, "end_line": 1073 } ], "assumption": false } ], "nodes": [ { "id": "topic", "label": "topic", "kind": "database", "shape": "box", "role": "source", "details": [ "variant_label 로 축 이름을 정한다" ], "description": "주제. 축의 이름을 주제가 정한다.", "evidence": [ { "start_line": 1057, "end_line": 1059 }, { "start_line": 1067, "end_line": 1068 } ], "assumption": false }, { "id": "topic-variant", "label": "topic_variant", "kind": "database", "shape": "box", "role": "store", "details": [ "SPA · Mediator · BFF · Forward-Auth" ], "description": "축의 값들.", "evidence": [ { "start_line": 1060, "end_line": 1060 }, { "start_line": 1047, "end_line": 1048 } ], "assumption": false }, { "id": "record-variant", "label": "record_variant", "kind": "database", "shape": "box", "role": "store", "details": [ "(kind, id) 쌍 · 외래키 없음" ], "emphasis": "primary", "description": "어느 기록이 어느 축에 걸리는지 적는 자리. 외래키를 걸지 못한다.", "evidence": [ { "start_line": 1061, "end_line": 1061 }, { "start_line": 1071, "end_line": 1073 } ], "assumption": false }, { "id": "document", "label": "document", "kind": "database", "shape": "box", "role": "store", "group": "record-tables", "description": "기록 테이블 하나.", "evidence": [ { "start_line": 1071, "end_line": 1072 } ], "assumption": false }, { "id": "open-question", "label": "open_question", "kind": "database", "shape": "box", "role": "store", "group": "record-tables", "description": "기록 테이블 하나.", "evidence": [ { "start_line": 1071, "end_line": 1072 } ], "assumption": false }, { "id": "project-decision", "label": "project_decision", "kind": "database", "shape": "box", "role": "store", "group": "record-tables", "description": "기록 테이블 하나.", "evidence": [ { "start_line": 1071, "end_line": 1072 } ], "assumption": false } ], "edges": [ { "id": "t1", "from": "topic", "to": "topic-variant", "label": "1 : N", "kind": "data", "style": "solid", "evidence": [ { "start_line": 1057, "end_line": 1060 } ], "assumption": false }, { "id": "t2", "from": "topic-variant", "to": "record-variant", "label": "축에 건다", "kind": "data", "style": "solid", "evidence": [ { "start_line": 1060, "end_line": 1061 } ], "assumption": false }, { "id": "t3", "from": "record-variant", "to": "document", "label": "(kind, id)", "kind": "data", "style": "dashed", "evidence": [ { "start_line": 1061, "end_line": 1073 } ], "assumption": false }, { "id": "t4", "from": "record-variant", "to": "open-question", "label": "(kind, id)", "kind": "data", "style": "dashed", "evidence": [ { "start_line": 1061, "end_line": 1073 } ], "assumption": false }, { "id": "t5", "from": "record-variant", "to": "project-decision", "label": "(kind, id)", "kind": "data", "style": "dashed", "evidence": [ { "start_line": 1061, "end_line": 1073 } ], "assumption": false } ], "legend": [ { "symbol": "점선", "meaning": "외래키 없이 (kind, id) 쌍으로만 가리킨다" } ], "metadata": { "rationale": "축에 걸리지 않은 기록이 공통 기록이 된다는 규칙과 editorial 칸(thesis·summary·conclusion) 이야기는 같은 절의 문장으로 남긴다. 그림은 자리와 참조 방향만 담는다.", "profile_deviation": "techviz references 가 고른 후보(two-zone-pipeline, sequence, comparison) 밖의 프로필이다. 이 절에는 시간 순서도 두 구역도 비교 대상도 없어 후보로는 그릴 수 없었다." } }