fix(documents): accept-suggestion 항상 409 버그 + compose 127.0.0.1 바인딩

- accept-suggestion: documents.updated_at != expected stale 검사 제거.
  classify_worker 가 source_updated_at 을 pre-commit 값으로 저장하는데
  SQLAlchemy onupdate 가 commit 에서 updated_at 을 bump → 항상 불일치 →
  승인 영구 불가. payload 교체 검사 하나만으로 core race 는 막힘.
  사용자 직접 편집 감지는 별도 user_updated_at 컬럼 도입 시 재논의.
- docker-compose.yml: postgres/kordoc/fastapi/frontend 포트 127.0.0.1
  바인딩. GPU 서버 로컬에만 있던 drift 를 main 으로 승격. UFW-Docker
  우회 컨텍스트에서 불필요한 LAN 노출 축소.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-24 07:20:38 +09:00
parent 31d76edba0
commit a8e24ab114
2 changed files with 13 additions and 15 deletions
+9 -11
View File
@@ -770,9 +770,14 @@ async def accept_suggestion(
- 200 (no-op): ai_suggestion 이 이미 NULL — 이전 승인/반려 후 중복 호출로 간주
- 200 (applied): payload 적용 + ai_suggestion 을 NULL 로 clear
- 409 Conflict: 두 가지 벡터로 stale 감지
· ai_suggestion.source_updated_at != expected → 새 classify 가 payload 덮어씀
· documents.updated_at != expected → 사용자가 doc 을 다른 경로로 수정함
- 409 Conflict: ai_suggestion.source_updated_at != expected
→ 새 classify 결과가 payload 를 덮어쓴 race 감지 (payload 교체)
Note: 원 plan 은 documents.updated_at != expected 로 "문서 전체 수정" 도 감지하려
했으나, SQLAlchemy onupdate 가 모든 워커 commit(classify/embed/...)에서 updated_at
을 bump 하므로 이 검사는 항상 fail → accept 영구 불가. payload 교체 검사 하나만으로
core race 는 막히고, 사용자 직접 편집 감지는 별도 user_updated_at 컬럼이 들어와야
의미 있다. 일단 payload key 검사만 유지.
"""
from sqlalchemy import select as sa_select
@@ -792,7 +797,7 @@ async def accept_suggestion(
expected = body.expected_source_updated_at
# Stale 검사 1: payload 교체 감지 (새 classify 결과가 덮어쓴 경우)
# Stale 검사: payload 교체 감지 (새 classify 결과가 덮어쓴 경우)
raw_src = doc.ai_suggestion.get("source_updated_at")
suggestion_src = None
if isinstance(raw_src, str):
@@ -806,13 +811,6 @@ async def accept_suggestion(
detail="제안 payload 가 교체되었습니다. 목록을 새로고침하세요.",
)
# Stale 검사 2: 문서 전체 수정 감지 (사용자가 title/태그를 다른 경로로 편집)
if doc.updated_at != expected:
raise HTTPException(
status_code=409,
detail="문서가 다른 곳에서 수정되었습니다. 목록을 새로고침하세요.",
)
# payload 적용
proposed_category = doc.ai_suggestion.get("proposed_category")
proposed_path = doc.ai_suggestion.get("proposed_path")
+4 -4
View File
@@ -9,7 +9,7 @@ services:
POSTGRES_USER: pkm
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "15432:5432"
- "127.0.0.1:15432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U pkm"]
interval: 5s
@@ -20,7 +20,7 @@ services:
kordoc-service:
build: ./services/kordoc
ports:
- "3100:3100"
- "127.0.0.1:3100:3100"
volumes:
- ${NAS_NFS_PATH:-/mnt/nas/Document_Server}:/documents:ro
mem_limit: 4g
@@ -135,7 +135,7 @@ services:
fastapi:
build: ./app
ports:
- "8000:8000"
- "127.0.0.1:8000:8000"
volumes:
- ${NAS_NFS_PATH:-/mnt/nas/Document_Server}:/documents
- ./config.yaml:/app/config.yaml:ro
@@ -159,7 +159,7 @@ services:
frontend:
build: ./frontend
ports:
- "3000:3000"
- "127.0.0.1:3000:3000"
depends_on:
- fastapi
restart: unless-stopped