writing-as-the-person-who-did-it 을 서브에이전트 셋으로 나눠 56편에 적용했다. 56편 중 20편만 고쳤다 — 나머지 36편은 SSOT 를 절 단위로 대조했을 때 옮길 흔적이 이미 옮겨져 있었거나 없었다. 없는 목소리를 채우지 않는다. 옮긴 것은 전부 SSOT 의 어느 절에서 왔는지 댈 수 있다. §3.4 「눈으로 찾을 일이 아니었다」— 세 계약을 파싱해 뽑은 이유 §4.3 구현하지 않기로 한 것과 빠뜨린 것은 다르다 §8.5 표의 마지막 줄을 더할 때 이 목록을 또 빠뜨렸다 §9.4 「왜 주제 링크가 탐색으로 가지?」— 우회를 남겨 두면 계속 나온 질문 §11.3 「세 버튼」을 실제 이름으로 되돌리고 두 언어가 섞인 것을 그 자리에 §12.2 막지 않은 대신 메모리에 남긴 것 §13.1 여섯 벌 인용이 어느 커밋이 짚은 말인지 §13.3 고쳐 쓴 첫 안이 거절당한 것과 사용자가 고른 말 두 쌍 §14.3 「문서가 그대로 나온다」는 구조 차이가 아니라 내용 양의 차이라는 정정 §16.1 삭제가 막힌 실제 기록 이름과 그것을 막은 프로젝트 링크 §16.9 주제 논지와 축 결론이 AI 가 써서 DB 에 직접 넣은 미검토 초안이라는 것 §17.5 바운딩 박스로 잘못 지목한 대상이 「판단 기준」이었다는 것 검증 환경의 커밋 해시 하나가 틀려 있었다(ca1cfa2 → ca1fc92). SSOT §13.1 과 부록 A 가 적은 값이고 저장소에 그 커밋이 있다. 검사 넷 전부 통과한다 — check_prose 56편 error 0 · check_body PASS · check_evidence --repo 문제 없음 · verify-tech-log-tree 프로젝트 5 error 0 warn 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
82 lines
3.9 KiB
Markdown
82 lines
3.9 KiB
Markdown
---
|
|
kind: CONCEPT
|
|
slug: eleven-boundaries-a-value-crosses
|
|
title: 공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개
|
|
topic: values-lost-between-boundaries
|
|
topicName: 값이 경계에서 사라진다
|
|
project: TechLog
|
|
status: 게시 전
|
|
basisVersion: tech-log-backend · tech-log-frontend 2026-09-02 · OpenAPI 3.1 계약 3종을 반입해 쓰는 구조
|
|
assets:
|
|
- key: value-boundaries
|
|
file: ../../../final/assets/diagrams/value-boundaries/value-boundaries.svg
|
|
sourceRevision: tech-log@2026-09-02
|
|
source:
|
|
- final/document.md#§1.2
|
|
- final/document.md#§17.1
|
|
---
|
|
|
|
# 공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개
|
|
|
|
공개 화면의 한 줄은 PostgreSQL 의 투영 테이블에서 출발해 열한 번 모양을 바꾼 뒤에 그려진다. 그 사이 어느 한 곳이 값을 담지 않아도 오류가 나지 않는다. `undefined` 는 빈 문자열로 그려지고 빈 배열은 「항목이 없습니다」로 그려진다.
|
|
|
|
## 관계
|
|
|
|
- **공개 Reference 가 통째로 비어 있었다 — 이름이 어긋났고 본문은 다른 테이블에 있었다**
|
|
이 경계 중 두 곳에서 값이 사라진 사건이다.
|
|
- **관계의 요약이 경계 세 곳을 지나며 사라졌다**
|
|
한 값이 연달아 세 경계에서 버려진 사건이다.
|
|
- **한 경계를 고쳤으면 값의 여정 끝에서 확인한다**
|
|
이 경계 수가 그 규칙의 근거다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
## 열한 번 모양이 바뀐다
|
|
|
|
```text
|
|
PostgreSQL 테이블
|
|
└─ public_resource_projection (게시 시점에 굳어진 투영)
|
|
└─ JDBC 어댑터의 SQL (컬럼 이름을 컴파일러가 검사하지 않는다)
|
|
└─ *View 레코드 (application-core)
|
|
└─ *ResponseMapper (adapter/inbound/web)
|
|
└─ 생성된 DTO (계약이 만든 모양)
|
|
└─ HTTP envelope
|
|
└─ openapi-typescript 타입
|
|
└─ http-public-content-gateway 의 매퍼
|
|
└─ 포트 타입 (application/ports)
|
|
└─ 화면 컴포넌트
|
|
```
|
|
|
|
:::evidence key="value-boundaries" alt="저장·백엔드 조립·HTTP envelope·프론트엔드 조립·화면 다섯 묶음을 세 저장소 구역으로 나눠 이은 흐름도" caption=" " zoom="true"
|
|
:::
|
|
|
|
저장 쪽에 둘, 백엔드 조립에 넷, 전선에 하나, 프론트엔드 조립에 셋, 화면에 하나다.
|
|
|
|
이 기간에 적은 결함의 절반 이상이 「이 중 한 경계가 값을 버렸다」는 같은 모양이었다.
|
|
|
|
## 어디서 검사가 끊기는가
|
|
|
|
경계마다 무엇이 값을 지키는지가 다르다.
|
|
|
|
JDBC 어댑터의 SQL 은 컬럼 이름을 문자열로 적는다. 컬럼이 없거나 이름이 다르면 실행할 때 알게 된다.
|
|
|
|
계약이 만든 DTO 와 생성된 타입 사이는 생성기가 지킨다. 다만 생성기가 보는 것은 스키마의 모양이고, 그 칸에 값이 담기는지는 보지 않는다.
|
|
|
|
게이트웨이의 매퍼는 계약의 타입을 읽는다. `as` 단언을 쓰면 그 확인이 사라진다.
|
|
|
|
포트 타입과 화면 컴포넌트 사이는 TypeScript 가 지킨다. 포트와 어댑터가 타입을 따로 들고 있으면 그 확인도 사라진다.
|
|
|
|
## 값을 버려도 오류가 나지 않는다
|
|
|
|
이 경계들은 값을 담지 않아도 그렇다고 말하지 않고 다음으로 넘긴다.
|
|
|
|
`undefined` 는 화면에서 빈 문자열이 된다. 빈 배열은 「항목이 없습니다」가 된다. 그래서 화면만 보면 값이 없는 것과 값을 잃은 것이 같아 보인다.
|
|
|
|
## 두 화면이 같은 데이터를 볼 때
|
|
|
|
Studio 와 공개 화면은 같은 DB 를 보지만 계약이 다르다. Studio 는 작성 계약을, 공개 화면은 조회 계약을 지난다. 한쪽에만 값이 보이면 그 사이의 계약에 칸이 없다.
|
|
|
|
<!-- body:end -->
|