docs(S15P11A705-125): Collection published_at NOT NULL 불변식을 정본에 반영 - #22
Merged
Conversation
back#75가 V4 마이그레이션으로 `collection.published_at`을 백필 후 `DEFAULT now()` · `NOT NULL`로 고정했다. 정본 문서는 여전히 `TIMESTAMPTZ NULL`이라 구현과 어긋난 상태였다. - 06 §2.6 스키마 표: `published_at TIMESTAMPTZ NOT NULL DEFAULT now()` - 06 §2.6 규칙: 생성 즉시 발행이므로 NULL 불허, 기존 NULL은 created_at 백필 - 06 §4.1 DB 보장 표: "Collection 발행 시각 누락 금지" 행 추가 - 07 ERD: COLLECTION.published_at 제약 표기 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 28, 2026
back#75 리뷰를 수용해 구현이 `NOT NULL DEFAULT now()`에서 `CHECK (NOT is_published OR published_at IS NOT NULL)`로 바뀌었습니다. 앞선 커밋이 정본에 반영한 NOT NULL 표기를 그에 맞게 정정합니다. - 06 §2.6 스키마 표: `TIMESTAMPTZ NULL`로 되돌립니다. 컬럼 자체는 nullable입니다 - 06 §2.6 규칙: 발행된 행만 값을 반드시 갖는다는 것과, 컬럼을 NOT NULL로 만들지 않는 이유(`is_published`가 false일 수 있다는 전제 위의 컬럼이라는 점)를 적습니다 - 06 §4.1 DB 보장 표: "Collection 발행 시각 누락 금지 / NOT NULL DEFAULT now()"를 "발행된 Collection의 발행 시각 누락 금지 / CHECK"로 바꿉니다 - 07 ERD: COLLECTION.published_at 표기를 "발행 시 필수 (CHECK)"로 맞춥니다 08 API 명세의 `publishedAt` 응답 필드는 제약 형태와 무관해 손대지 않았습니다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
Collection.published_at의 DB 불변식을 정본 문서(06·07)에 반영한다. 구현은 back#75의V5__collection_published_at_invariant.sql이 담당하고, 이 PR은 그 제약을 정본 규칙·무결성 표·ERD에 옮기는 문서 변경이다. 정본 문서 2개 외 변경 없음(코드·API 명세·AI 설계 무변경).S15P11A705-125의 3번째이자 마지막 PR이다(사유는 아래 "왜 한 티켓에 세 번째 PR인가").
Jira
병합 순서 — back#75 이후
이 PR은 back#75가 병합된 뒤에 병합한다.
정본 문서는 "현재 시스템이 보장하는 것"을 기술한다. 제약이 적용되지 않은 상태에서 이 PR만 병합하면 문서가 구현보다 앞서간다.
변경 사항
초안은
NOT NULL DEFAULT now()였으나 back#75 리뷰에서CHECK함의형으로 바뀌었고, 이 PR도 그에 맞춰 다시 썼다. 아래가 최종 형태다.06_데이터모델_및_무결성.md§2.6 규칙published_at은 컬럼 자체로는 NULL을 허용하지만 발행된 행은 반드시 값을 가진다는 규칙 한 줄 추가. 백필 소스(created_at)와NOT NULL로 만들지 않은 이유를 함께 기술TIMESTAMPTZ(nullable) 그대로다. 제약이 컬럼이 아니라CHECK에 있으므로 표가 아니라 규칙에 적어야 실제와 일치한다06_데이터모델_및_무결성.md§4.1 DB 보장 표발행된 Collection의 발행 시각 누락 금지 → CHECK (NOT is_published OR published_at IS NOT NULL)행 추가07_ERD.mdCOLLECTION 블록timestamptz published_at→timestamptz published_at "발행 시 필수 (CHECK)"05_AI_설계.md는 의도적으로 건드리지 않았다 — 아래 참조.왜
NOT NULL이 아니라CHECK인가back#75 리뷰에서 나온 판단을 그대로 따른다.
is_published가 false일 수 있다는 전제 위에published_at이 존재하므로, 컬럼을NOT NULL로 만들면 미발행 상태를 표현할 수 없게 되어 스키마가 자기모순이 된다. 함의 한 방향(NOT is_published OR published_at IS NOT NULL)만 걸면 오늘 얻는 보호는 같으면서(Feed 후보 쿼리가 전부is_published = true를 건다) 비공개 전환이나 발행 취소가 들어와도 제약을 풀 필요가 없다.상세 근거는 BD-33에 있다.
배경
이 변경은 back 레포 미커밋 변경을 back#74·back#75로 외부화하던 시점에
docs레포 로컬에도 생겼는데, 당시 외부화 범위에docs가 포함되지 않아 커밋되지 못했다. 로컬 정리 중 발견해 stash·patch로 보존한 뒤 이 PR로 살렸다.보존물에는
05_AI_설계.md의 Feed category/region 제외 변경도 있었으나 제외했다 — docs#21이 같은 내용을 더 자세히 담고 있어 중복·충돌이 된다. 반면06·07의published_at변경은 docs#21에도 없는 유일본이라 이 PR이 유일한 반영 경로다.왜 한 Jira 티켓에 세 번째 PR인가
S15P11A705-125는 "로컬 미커밋 변경의 외부화"라는 한 작업이고, 그 산출물이 성격이 다른 세 덩어리로 나왔다. 리뷰 축이 각각 달라 하나로 묶으면 리뷰가 흐려진다.
V5마이그레이션·마이그레이션 테스트 (동작·배포 호환성)레포도 갈린다(1·2는
back, 3은docs). 티켓을 쪼개는 대신 PR을 쪼갠 이유는 세 산출물이 "같은 로컬 변경 하나에서 나왔다"는 추적성을 티켓 한 개로 유지하기 위해서다.테스트 / 검증
문서 전용 변경이라 실행 가능한 테스트가 없다. 대신 아래를 확인했다.
06·07두 파일에 한정됨 — 의도 외 변경 없음05_AI_설계.md변경 0 (docs#21 범위 침범 없음)CHECK (NOT is_published OR published_at IS NOT NULL), 백필 소스created_at(BD-33 · BI-19 ·V5__collection_published_at_invariant.sql)CHECK에 있다"주석"형태만 추가했고(예:int record_count "활성 연결 수 비정규화"), 배포 시 GitHub Pages 빌드에서 검증된다리뷰 포인트
created_at으로 백필합니다"는 마이그레이션 시점의 일회성 처리인데 이를 정본 스키마 문서에 남길지 판단이 필요하다. 남긴 이유는 백필 소스를 지우면 나중에 "기존 행의 발행 시각은 어디서 왔나"를 back 레포 BD-33까지 가야 알 수 있기 때문이다. 정본을 순수 현재 스키마로만 유지하는 편이 낫다면 이 한 줄만 빼면 된다."발행 시 필수 (CHECK)"로 적었다. 이 ERD는 지금까지 NULL 여부를 표기하지 않아 와서 이 컬럼만 표기가 붙는다. 전체 컬럼 표기는 이 PR 범위를 넘어서므로 하지 않았다.미결 / 후속
published_at만 제약이 표기된다. 전체 컬럼 표기 정책은 별도로 다룰 것.is_publishedMVP 활용 여부 —06§8 미확정 항목에 그대로 남아 있다. 비공개 전환이나 예약 발행을 도입하면 "발행 전published_at이 NULL"이 실제 상태가 되며,CHECK는 그때도 제약을 풀 필요 없이 유효하다.published_at컬럼 존치 검토 — back#75에서 백엔드가 제기했다. AI 파트는 유지 의견(recency가 "최근 공개"를 재는 값이라created_at으로 대체 불가)이며, 근거를 back#75에 회신했다. 결정은 스키마 소유자인 백엔드 몫이다.🤖 Generated with Claude Code