From ae7513a093e0e8b4ae2dfddcd9af3db9cafa9e65 Mon Sep 17 00:00:00 2001 From: colosair Date: Tue, 28 Jul 2026 20:31:26 +0900 Subject: [PATCH 1/2] =?UTF-8?q?docs(S15P11A705-125):=20Collection=20publis?= =?UTF-8?q?hed=5Fat=20NOT=20NULL=20=EB=B6=88=EB=B3=80=EC=8B=9D=EC=9D=84=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B8=EC=97=90=20=EB=B0=98=EC=98=81=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ...270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" | 5 ++++- static/07_ERD.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" index fd36606..850a63c 100644 --- "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" +++ "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" @@ -196,7 +196,7 @@ id BIGINT PK member_id BIGINT FK -> member title VARCHAR(20) NOT NULL is_published BOOLEAN NOT NULL DEFAULT TRUE -published_at TIMESTAMPTZ NULL +published_at TIMESTAMPTZ NOT NULL DEFAULT now() record_count INT NOT NULL DEFAULT 0 created_at TIMESTAMPTZ NOT NULL updated_at TIMESTAMPTZ NOT NULL @@ -205,6 +205,8 @@ deleted_at TIMESTAMPTZ NULL - 소유자는 `member_id` 하나입니다. `shelf_id`를 두지 않습니다. - 활성 Collection에는 활성 CollectionRecord가 최소 한 개 있어야 합니다. +- MVP Collection은 생성 즉시 발행되므로 `published_at`은 DB에서도 NULL을 허용하지 않습니다. + 기존 NULL 데이터는 `created_at`으로 백필합니다. - `is_published`는 MVP에서 항상 `true`로 생성되지만, 향후 공개·비공개 전환을 위해 데이터로 관리합니다(정책 7.2). - `record_count`는 활성 연결 수의 비정규화 값입니다. 목록·피드에서 장소 개수(정책 8.1)를 N+1 없이 제공하기 위해 두며, 연결 추가·제거와 **동일 트랜잭션**에서 갱신합니다. @@ -353,6 +355,7 @@ ALTER TABLE place ADD CONSTRAINT ck_place_lng CHECK (lng BETWEEN -180 AND 180); | 동일 Shelf 중복 Follow 금지 | 활성행 부분 유니크 | | 자기 Shelf Follow 금지 | `CHECK` | | Collection 제목 20자 이하·공백만 금지 | 컬럼 길이 + `CHECK` | +| Collection 발행 시각 누락 금지 | `published_at NOT NULL DEFAULT now()` | | Context 본문 공백만 금지 | `CHECK` | | 좌표 범위 | `CHECK` | diff --git a/static/07_ERD.md b/static/07_ERD.md index 266df81..debd4cc 100644 --- a/static/07_ERD.md +++ b/static/07_ERD.md @@ -72,7 +72,7 @@ erDiagram bigint member_id FK varchar title "20자" boolean is_published - timestamptz published_at + timestamptz published_at "NOT NULL, DEFAULT now()" int record_count "활성 연결 수 비정규화" timestamptz created_at timestamptz updated_at From ebf9a181d3afd97e4e97d2a8e243fc1dbf5d2944 Mon Sep 17 00:00:00 2001 From: colosair Date: Wed, 29 Jul 2026 10:28:24 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs(S15P11A705-125):=20published=5Fat=20?= =?UTF-8?q?=EB=B6=88=EB=B3=80=EC=8B=9D=EC=9D=84=20CHECK=20=ED=95=A8?= =?UTF-8?q?=EC=9D=98=ED=98=95=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EC=A0=95?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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` 응답 필드는 제약 형태와 무관해 손대지 않았습니다. --- ...0_\353\260\217_\353\254\264\352\262\260\354\204\261.md" | 7 +++---- static/07_ERD.md | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" index 850a63c..c1f93b9 100644 --- "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" +++ "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" @@ -196,7 +196,7 @@ id BIGINT PK member_id BIGINT FK -> member title VARCHAR(20) NOT NULL is_published BOOLEAN NOT NULL DEFAULT TRUE -published_at TIMESTAMPTZ NOT NULL DEFAULT now() +published_at TIMESTAMPTZ NULL record_count INT NOT NULL DEFAULT 0 created_at TIMESTAMPTZ NOT NULL updated_at TIMESTAMPTZ NOT NULL @@ -205,8 +205,7 @@ deleted_at TIMESTAMPTZ NULL - 소유자는 `member_id` 하나입니다. `shelf_id`를 두지 않습니다. - 활성 Collection에는 활성 CollectionRecord가 최소 한 개 있어야 합니다. -- MVP Collection은 생성 즉시 발행되므로 `published_at`은 DB에서도 NULL을 허용하지 않습니다. - 기존 NULL 데이터는 `created_at`으로 백필합니다. +- `published_at`은 컬럼 자체로는 NULL을 허용하지만, **발행된 행(`is_published = true`)은 반드시 값을 가집니다**(§4.1 `CHECK`). MVP Collection은 생성 즉시 발행되므로 실질적으로 모든 행에 값이 있고, 기존 NULL 데이터는 `created_at`으로 백필합니다. 컬럼을 `NOT NULL`로 만들지 않는 이유는 `is_published`가 false일 수 있다는 전제 위에 이 컬럼이 존재하기 때문입니다. - `is_published`는 MVP에서 항상 `true`로 생성되지만, 향후 공개·비공개 전환을 위해 데이터로 관리합니다(정책 7.2). - `record_count`는 활성 연결 수의 비정규화 값입니다. 목록·피드에서 장소 개수(정책 8.1)를 N+1 없이 제공하기 위해 두며, 연결 추가·제거와 **동일 트랜잭션**에서 갱신합니다. @@ -355,7 +354,7 @@ ALTER TABLE place ADD CONSTRAINT ck_place_lng CHECK (lng BETWEEN -180 AND 180); | 동일 Shelf 중복 Follow 금지 | 활성행 부분 유니크 | | 자기 Shelf Follow 금지 | `CHECK` | | Collection 제목 20자 이하·공백만 금지 | 컬럼 길이 + `CHECK` | -| Collection 발행 시각 누락 금지 | `published_at NOT NULL DEFAULT now()` | +| 발행된 Collection의 발행 시각 누락 금지 | `CHECK (NOT is_published OR published_at IS NOT NULL)` | | Context 본문 공백만 금지 | `CHECK` | | 좌표 범위 | `CHECK` | diff --git a/static/07_ERD.md b/static/07_ERD.md index debd4cc..b4c94ca 100644 --- a/static/07_ERD.md +++ b/static/07_ERD.md @@ -72,7 +72,7 @@ erDiagram bigint member_id FK varchar title "20자" boolean is_published - timestamptz published_at "NOT NULL, DEFAULT now()" + timestamptz published_at "발행 시 필수 (CHECK)" int record_count "활성 연결 수 비정규화" timestamptz created_at timestamptz updated_at