§1.4 로 세운 도메인·비즈니스 규칙을 그것이 실제로 설명하는 기록에 넣었다. 프로젝트가 문서 게시 파이프라인을 안 타는 이유 → 화면 다섯이 비어 있던 Case 홈 focus 설정이 FK 없이 사는 설계 → 「열린 질문이 없습니다」 Case 결정이 자기 화면을 안 갖는 이유 → 목록이 문서 전체를 실어야 했던 Case 게시가 단계마다 다른 코드로 거절하는 설계 → 화면이 추측 셋을 출력한 Case (반대 사례) 종류마다 애그리거트와 테이블이 다르다 → 매퍼가 종류를 판정해야 하는 Case 축을 지우면 연결만 끊고 주제를 지우면 거절하는 이유 → 축 Concept 개념이 문서 테이블에 얹힌다 → 열세 곳 Case 화면 상태와 도메인 상태가 원래 갈려 있었다 → 이름을 두 번 바꾼 Case Case 본문 중앙값 675 → 1,342 자. 검사 넷 전부 통과한다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.1 KiB
kind, slug, title, topic, topicName, project, status, basisVersion, assets, evidence, sourceRevision, source
| kind | slug | title | topic | topicName | project | status | basisVersion | assets | evidence | sourceRevision | source | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CONCEPT | topic-variant-and-record-variant | 축은 주제가 이름을 정하고, 기록은 종류와 아이디의 쌍으로 축에 걸린다 | an-axis-inside-a-topic | 주제 안의 축 | TechLog | 게시 전 | tech-log-backend 2026-09-01 의 축 스키마 · record_variant 에 외래키 없음 · studio_validation 과 publication 이 쓰는 방식을 따름 |
|
|
tech-log@2026-09-02 |
|
축은 주제가 이름을 정하고, 기록은 종류와 아이디의 쌍으로 축에 걸린다
주제 안의 축은 세 테이블로 표현된다. 주제가 축의 이름을 스스로 정하고, 축의 값들이 따로 있고, 어느 기록이 어느 축에 걸리는지를 종류와 아이디의 쌍으로 적는다. 기록이 종류마다 다른 테이블에 살기 때문에 그 쌍에 외래키를 걸지 못한다.
관계
- 주제를 넷으로 쪼개지 않고 주제 안에 축을 하나 뒀다 이 구조를 만든 결정이다.
- 축 링크가 자기 자신을 가리켰고, 고친 뒤에는 백엔드를 먼저 배포했다 이 구조 위에 축 화면을 만든 사건이다.
- 홈의 비교 구역이 세 번 바뀌었다 이 구조가 화면에서 어떻게 쓰이는지가 그 기록에 있다.
본문
세 테이블
topic (주제)
├─ variant_label 축의 이름 — 주제마다 다르다
│ 인증 경계 → 「구조」 / 조회 성능 → 「조회 전략」
└─ topic_variant 축의 값들 (SPA, Mediator, BFF, Forward-Auth)
└─ record_variant 어느 기록이 어느 축에 걸리는지 (kind, id) 쌍
:::evidence key="topic-variant-model" alt="topic·topic_variant·record_variant 가 이어지고 record_variant 가 세 테이블을 가리키는 구조도" caption=" " zoom="true" :::
축 이름은 주제가 정한다
내부 이름은 축으로 고정하고, 화면에 보이는 이름은 주제가 자기 칸에 적는다.
주제마다 비교하는 것이 다르기 때문이다. 인증 경계 주제는 credential 을 어디에 두느냐로 갈리므로 「구조」이고, 조회 성능 주제는 같은 데이터를 어떻게 읽느냐로 갈리므로 「조회 전략」이다. 이름을 한 값으로 고정하면 둘 중 하나에서 어긋난다.
기록은 여러 축에 걸린다
한 기록이 여러 축에 걸릴 수 있다. PKCE 는 SPA 와 BFF 양쪽에 관계된다.
아무 축에도 걸리지 않은 기록은 그 주제의 공통 기록으로 읽는다. 「공통」이라는 축을 따로 만들지 않는 이유는, 만들면 그 축이 비교 화면에 한 줄로 서서 다른 축들과 견주는 것처럼 보이기 때문이다.
외래키가 없다
기록이 어느 축에 걸리는지를 담는 표는 외래키를 갖지 않는다. 기록이 종류마다 다른 테이블에 살기 때문이다 — 문서·열린 질문·프로젝트 결정이 각각 다른 테이블이고, 하나의 외래키로 셋을 함께 가리킬 수 없다.
그래서 종류와 아이디의 쌍으로만 가리킨다. 이 방식은 이 저장소에서 처음 쓰는 것이 아니고, 검증 상태와 게시 기록이 이미 같은 방식으로 기록을 가리키고 있었다.
대가는 데이터베이스가 참조 무결성을 지켜 주지 않는다는 것이다. 기록을 지울 때 그 쌍을 함께 지우는 것은 코드가 한다.
축을 지우면 기록은 남는다
축을 지울 때 걸려 있던 기록은 지우지 않는다. 연결만 끊고 그 기록은 주제의 공통 기록이 된다.
주제를 지울 때와 반대다. 주제는 그것을 쓰는 기록이 있으면 아예 거절한다.
주제를 지웠다는 이유로 그 주제를 쓰던 문서의 분류가 조용히 사라지면 안 되기 때문이다 — 지우려면 먼저 그 문서들을 옮기라는 뜻이다.
주제는 그 기록이 무엇에 관한 것인지를 말하는 분류이고, 축은 같은 주제 안에서 무엇과 견주는지를 말하는 비교 축이다. 분류가 사라지면 기록의 뜻이 바뀌고, 비교 축이 사라지면 비교만 없어진다.
slug 제약이 주제 안에서만 걸린다
축 slug 의 유일성 제약은 주제와 slug 의 쌍이다. 그래서 다른 주제에서 같은 이름을 쓸 수 있고, 여러 주제가 「공통」 같은 같은 이름을 각자 갖는 것이 정상이다.
축 화면을 조회할 때 주제까지 함께 맞춰야 하는 이유가 이것이다. 주제를 빼면 다른 주제의 같은 이름 축이 함께 걸린다.
사람이 쓰는 칸
주제의 논지, 축의 요약과 결론은 기록을 합쳐 자동으로 나오는 글이 아니다.
특히 결론은 비교표가 읽는 칸이라 기록의 요약 첫 줄을 잘라 쓰면 안 된다. 요약은 그 축이 무엇인지 말하고 결론은 그 축에서 무엇을 알게 됐는지 말하므로, 둘을 같은 문장으로 채우면 비교표가 아무것도 비교하지 않는다.
같은 구조가 다르게 보일 때
두 주제가 같은 구조를 쓰는데 축에 걸린 기록 수가 달라 다르게 보인다.
oauth-oidc-auth-boundary 축 이름 「구조」 축 4개
spa ← CASE 1 + REFERENCE 3 (기록 4)
mediator ← CASE 1 + QUESTION 2 + REFERENCE 2 (기록 5)
bff ← CASE 1 + QUESTION 3 + REFERENCE 1 (기록 5)
forward-auth ← CASE 1 + QUESTION 1 + REFERENCE 1 (기록 3)
공통 기록: CONCEPT 1 + 결정 2 + REFERENCE 2
jpa-feed-query-performance 축 이름 「조회 전략」 축 3개
derived-query ← CASE 1
fetch-join ← CASE 1
fetch-join-paging ← CASE 1
축마다 기록이 하나씩이고 축 제목을 그 기록 제목과 비슷하게 적으면 「문서가 그대로 나온다」로 보인다. 구조 차이가 아니라 내용 양의 차이다.