docs(TechLog): 얇은 Case 열 편과 Question 셋을 저장소 실물로 채운다

SSOT 를 저장소에서 확인해 더 보강하고 그것으로 다시 썼다.

  §7.2   참조 검사 SQL 을 문자열로 조립하는 실제 코드 — 컴파일러가 표 이름도
         컬럼 이름도 보지 않는다는 것이 그 모양에서 드러난다
  §11.2  section-heading-rank 가 미디어 쿼리 값을 먼저 걷어내는 이유(테스트 주석)
  §16.1  질문 삭제는 참조가 둘뿐이라 같은 문제가 덜하다는 대조

Case 열 편과 Question 셋을 다시 썼다. Question 은 사실·가정·미지수·제약을 갈라
채우고 선택지마다 무엇을 감수하는지 적었다 — 오류 코드를 나누면 계약과 반입한 두
저장소가 함께 움직인다는 것처럼.

SSOT 62,643 → 68,319 자. 검사 넷 전부 통과한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-07 19:18:37 +09:00
co-authored by Claude Opus 5
parent 6917ce2420
commit fd221353a3
15 changed files with 162 additions and 50 deletions
@@ -66,6 +66,8 @@ DB : 실제 PostgreSQL (Testcontainers)
> 그 쿼리의 여섯 컬럼 중 다섯은 마이그레이션과 대조했다. 이 하나만 가정했고, 그것이 틀렸다.
같은 어댑터의 다른 참조 검사들은 문서 식별자 컬럼을 가진 표를 조회하므로 그 이름이 맞는다. 한 함수 안에서 표마다 컬럼 이름이 다른데, 다섯 개가 맞으니 여섯 번째도 맞을 것으로 읽었다.
## 그 SQL 은 한 번도 실행되지 않았다
컬럼 이름보다 더 드러난 것은 검사 구조였다.
@@ -79,6 +81,22 @@ DB : 실제 PostgreSQL (Testcontainers)
표준 검사가 컨테이너를 띄우지 않으므로 어댑터의 SQL 은 한 줄도 실행되지 않은 채 빌드가 통과한다. 컬럼 이름이 맞는지 묻는 검사가 어디에도 없었다.
## 문자열로 조립한 SQL 은 컴파일러가 보지 않는다
이 어댑터는 SQL 을 문자열로 이어 붙여 만든다.
```java
"SELECT EXISTS ("
+ " SELECT 1 FROM document_relation WHERE target_document_id = :id"
+ " UNION ALL SELECT 1 FROM question_document_link WHERE document_id = :id"
+ " UNION ALL SELECT 1 FROM project_document_link WHERE document_id = :id"
+ " UNION ALL SELECT 1 FROM topic_featured_document WHERE document_id = :id"
+ " UNION ALL SELECT 1 FROM project_decision WHERE source_case_id = :id"
+ ")"
```
컴파일러가 확인하는 것은 이 식이 문자열이라는 것까지다. 표 이름도 컬럼 이름도 실행해야 검증된다.
## 전용 태스크로 여덟 시나리오를 돌린다
삭제 경로 전용 통합 테스트 태스크를 만들고, 실패했던 그 쿼리를 포함해 여덟 시나리오를 실제 PostgreSQL 에서 돌린다.
@@ -89,6 +107,6 @@ DB : 실제 PostgreSQL (Testcontainers)
이 태스크가 덮는 것은 삭제 경로다. 표준 검사는 여전히 컨테이너를 띄우지 않고, 새 어댑터 SQL 이 이 태스크에 등록되는지 보는 검사도 없다.
같은 참조 검사가 지금도 다섯 테이블을 하나로 묶어 확인하므로, 무엇이 막았는지를 응답이 말하지 못한다.
같은 참조 검사가 지금도 다섯 표를 하나로 묶어 확인하므로, 무엇이 막았는지를 응답이 말하지 못한다.
<!-- body:end -->