From 876b38bd1b3a9671137d4394efd2d33ef921f419 Mon Sep 17 00:00:00 2001 From: hyungi Date: Wed, 24 Jun 2026 12:06:57 +0900 Subject: [PATCH] =?UTF-8?q?fix(publish):=20=EB=A7=88=EC=9D=B4=EA=B7=B8=203?= =?UTF-8?q?65~370=20=E2=86=92=20367~372=20renumber=20(=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20scan=20365/366=20=EC=B6=A9=EB=8F=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 라이브 pkm DB 가 scan-feature-build 의 365(scan_jobs)·366(pending_command) 을 이미 apply + schema_migrations 스탬프함. 발행 마이그가 365 부터면 러너가 365/366 을 적용필로 보고 스킵 → published 테이블 미생성 → 367 깨짐. 다음 free=367 로 +2 시프트해 회피. 파일 rename + 헤더 주석 + published.py 모델 주석(mig 번호) 동기화. 내용 무변경(멱등 CREATE ... IF NOT EXISTS). Co-Authored-By: Claude Opus 4.8 (1M context) --- app/models/published.py | 6 +++--- migrations/{365_published.sql => 367_published.sql} | 2 +- ...ed_kind_pubid_uq.sql => 368_published_kind_pubid_uq.sql} | 2 +- ..._kind_source_uq.sql => 369_published_kind_source_uq.sql} | 2 +- ...{368_published_rev_idx.sql => 370_published_rev_idx.sql} | 2 +- .../{369_publish_outbox.sql => 371_publish_outbox.sql} | 2 +- ...essed_idx.sql => 372_publish_outbox_unprocessed_idx.sql} | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename migrations/{365_published.sql => 367_published.sql} (98%) rename migrations/{366_published_kind_pubid_uq.sql => 368_published_kind_pubid_uq.sql} (85%) rename migrations/{367_published_kind_source_uq.sql => 369_published_kind_source_uq.sql} (85%) rename migrations/{368_published_rev_idx.sql => 370_published_rev_idx.sql} (84%) rename migrations/{369_publish_outbox.sql => 371_publish_outbox.sql} (96%) rename migrations/{370_publish_outbox_unprocessed_idx.sql => 372_publish_outbox_unprocessed_idx.sql} (84%) diff --git a/app/models/published.py b/app/models/published.py index a6f3f7b..8fbe278 100644 --- a/app/models/published.py +++ b/app/models/published.py @@ -1,6 +1,6 @@ """발행 레이어 ORM (docsrv-viewer-publish) — published projection + publish_outbox. -관계(relationship) 없음 = 독립 테이블, configure_mappers 무영향. 마이그 365~370. +관계(relationship) 없음 = 독립 테이블, configure_mappers 무영향. 마이그 367~372. published = 뷰어가 read API(P0-2)로 당기는 render-ready projection(kind-discriminated). publish_outbox = 저작/4-A 트랜잭션이 같은 tx에서 INSERT, 발행 워커가 drain 하며 rev 부여. @@ -39,7 +39,7 @@ class Published(Base): DateTime(timezone=True), default=datetime.now, nullable=False ) - # UNIQUE(kind, pub_id)=mig366, UNIQUE(kind, source_id)=mig367, idx(rev)=mig368. + # UNIQUE(kind, pub_id)=mig368, UNIQUE(kind, source_id)=mig369, idx(rev)=mig370. class PublishOutbox(Base): @@ -57,4 +57,4 @@ class PublishOutbox(Base): ) processed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - # 미처리 부분 인덱스 idx(id) WHERE processed_at IS NULL = mig370. + # 미처리 부분 인덱스 idx(id) WHERE processed_at IS NULL = mig372. diff --git a/migrations/365_published.sql b/migrations/367_published.sql similarity index 98% rename from migrations/365_published.sql rename to migrations/367_published.sql index a9b5c18..82cb4ad 100644 --- a/migrations/365_published.sql +++ b/migrations/367_published.sql @@ -1,4 +1,4 @@ --- 365_published.sql +-- 367_published.sql -- 발행 레이어(docsrv-viewer-publish) projection 테이블. 뷰어가 read API로 당겨 자기 SQLite로 복제. -- kind-discriminated 단일 테이블(study_question | study_explanation | ... 후속 news/document). -- pub_id = opaque+stable(워커가 (kind,source_id)당 1회 부여, republish=rev bump에도 불변) = 뷰어 dedup키=progress키. diff --git a/migrations/366_published_kind_pubid_uq.sql b/migrations/368_published_kind_pubid_uq.sql similarity index 85% rename from migrations/366_published_kind_pubid_uq.sql rename to migrations/368_published_kind_pubid_uq.sql index cb01db0..9d41263 100644 --- a/migrations/366_published_kind_pubid_uq.sql +++ b/migrations/368_published_kind_pubid_uq.sql @@ -1,3 +1,3 @@ --- 366_published_kind_pubid_uq.sql +-- 368_published_kind_pubid_uq.sql -- pub_id 는 kind 내 유일(뷰어 dedup/progress 키 무결성, pub_id→내부 역해소 유일성 보장). CREATE UNIQUE INDEX IF NOT EXISTS published_kind_pubid_uq ON published (kind, pub_id); diff --git a/migrations/367_published_kind_source_uq.sql b/migrations/369_published_kind_source_uq.sql similarity index 85% rename from migrations/367_published_kind_source_uq.sql rename to migrations/369_published_kind_source_uq.sql index f98b1cc..fe7d3ea 100644 --- a/migrations/367_published_kind_source_uq.sql +++ b/migrations/369_published_kind_source_uq.sql @@ -1,3 +1,3 @@ --- 367_published_kind_source_uq.sql +-- 369_published_kind_source_uq.sql -- (kind, source_id) 당 발행 행 1개 — 발행 워커 upsert 타깃 + pub_id 재사용(같은 source=같은 pub_id) 키. CREATE UNIQUE INDEX IF NOT EXISTS published_kind_source_uq ON published (kind, source_id); diff --git a/migrations/368_published_rev_idx.sql b/migrations/370_published_rev_idx.sql similarity index 84% rename from migrations/368_published_rev_idx.sql rename to migrations/370_published_rev_idx.sql index 9141c7f..7ae96a1 100644 --- a/migrations/368_published_rev_idx.sql +++ b/migrations/370_published_rev_idx.sql @@ -1,3 +1,3 @@ --- 368_published_rev_idx.sql +-- 370_published_rev_idx.sql -- 뷰어 pull-sync feed: SELECT ... WHERE rev > :since ORDER BY rev LIMIT :page (P0-2). CREATE INDEX IF NOT EXISTS published_rev_idx ON published (rev); diff --git a/migrations/369_publish_outbox.sql b/migrations/371_publish_outbox.sql similarity index 96% rename from migrations/369_publish_outbox.sql rename to migrations/371_publish_outbox.sql index 02aebe1..a53fdc2 100644 --- a/migrations/369_publish_outbox.sql +++ b/migrations/371_publish_outbox.sql @@ -1,4 +1,4 @@ --- 369_publish_outbox.sql +-- 371_publish_outbox.sql -- transactional outbox — 저작/4-A 트랜잭션이 같은 tx에서 여기 INSERT(P0-1 규율), -- 단일 발행 워커가 id(커밋순) 순으로 drain 하며 published 에 rev 부여(소스 updated_at 폴링 금지=갭 재발). -- processed_at = 워커 drain 시 스탬프(NULL=미처리). payload/hash 는 enqueue 시점 스냅샷. diff --git a/migrations/370_publish_outbox_unprocessed_idx.sql b/migrations/372_publish_outbox_unprocessed_idx.sql similarity index 84% rename from migrations/370_publish_outbox_unprocessed_idx.sql rename to migrations/372_publish_outbox_unprocessed_idx.sql index 9a9b127..b3c9cd2 100644 --- a/migrations/370_publish_outbox_unprocessed_idx.sql +++ b/migrations/372_publish_outbox_unprocessed_idx.sql @@ -1,3 +1,3 @@ --- 370_publish_outbox_unprocessed_idx.sql +-- 372_publish_outbox_unprocessed_idx.sql -- 워커 drain 쿼리: WHERE processed_at IS NULL ORDER BY id (커밋순). 부분 인덱스로 미처리분만. CREATE INDEX IF NOT EXISTS publish_outbox_unprocessed_idx ON publish_outbox (id) WHERE processed_at IS NULL;