fix(km): backfill symptoms hash read column
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m7s
CD Pipeline / build-and-deploy (push) Successful in 4m50s
CD Pipeline / post-deploy-checks (push) Successful in 3m37s

This commit is contained in:
ogt
2026-07-09 17:27:08 +08:00
parent 4f87ad97f3
commit 4018548552
3 changed files with 25 additions and 3 deletions

View File

@@ -19,7 +19,8 @@ from contextlib import asynccontextmanager
from fastapi import HTTPException
from sqlalchemy import text
from sqlalchemy.exc import DBAPIError, TimeoutError as SQLAlchemyTimeoutError
from sqlalchemy.exc import DBAPIError
from sqlalchemy.exc import TimeoutError as SQLAlchemyTimeoutError
from sqlalchemy.ext.asyncio import (
AsyncConnection,
AsyncEngine,
@@ -450,12 +451,15 @@ async def _run_init_db_ddl(conn: AsyncConnection) -> None:
# 2026-04-29 ogt + Claude Opus 4.7: M4 KMWriter 反查鏈 + 冪等補欄
# CD #1115-1117 全 failure 根因commit c22e5f33 加 ORM 欄位但無對應 ALTER
# 錯誤column "related_approval_id" of relation "knowledge_entries" does not exist
# 2026-07-09 Codex: 舊 prod schema 也可能缺 symptoms_hash會讓 KM list/search
# 只剩 source-backed fallback同一段補齊避免正式 KM 看似歸零。
# 補防禦性 ALTER同 timeline_events 模式)+ 對應 index
await conn.execute(
text("""
ALTER TABLE knowledge_entries
ADD COLUMN IF NOT EXISTS related_approval_id VARCHAR(64),
ADD COLUMN IF NOT EXISTS path_type VARCHAR(50);
ADD COLUMN IF NOT EXISTS path_type VARCHAR(50),
ADD COLUMN IF NOT EXISTS symptoms_hash VARCHAR;
""")
)
# M3 冪等 unique index (incident_id + path_type)
@@ -470,6 +474,11 @@ async def _run_init_db_ddl(conn: AsyncConnection) -> None:
"ON knowledge_entries(related_approval_id) "
"WHERE related_approval_id IS NOT NULL;"
))
await conn.execute(text(
"CREATE INDEX IF NOT EXISTS ix_knowledge_symptoms_hash "
"ON knowledge_entries(symptoms_hash) "
"WHERE symptoms_hash IS NOT NULL;"
))
# W2 PR-L1 2026-04-28 ogt + Claude Sonnet 4.6: KM→Playbook 互饋回路(飛輪 C3 修復)
# PlaybookRecord 新增 review_required 欄位

View File

@@ -9,8 +9,8 @@ from sqlalchemy.dialects import postgresql
from src.db.models import KnowledgeEntryRecord
from src.models.knowledge import EntrySource, EntryStatus, EntryType
from src.repositories.knowledge_repository import (
KnowledgeDBRepository,
_ASSET_TAXONOMY_KEYS,
KnowledgeDBRepository,
_enum_text,
)

View File

@@ -255,3 +255,16 @@ def test_api_lifespan_closes_worker_redis_pool_after_signal_worker() -> None:
assert "close_worker_redis_pool" in source
assert source.index("close_signal_worker") < source.index("close_worker_redis_pool")
assert source.index("close_worker_redis_pool") < source.index("close_redis_pool")
def test_init_db_backfills_all_optional_knowledge_read_columns() -> None:
import inspect
from src.db import base as db_base
source = inspect.getsource(db_base._run_init_db_ddl)
assert "ALTER TABLE knowledge_entries" in source
assert "ADD COLUMN IF NOT EXISTS related_approval_id" in source
assert "ADD COLUMN IF NOT EXISTS path_type" in source
assert "ADD COLUMN IF NOT EXISTS symptoms_hash" in source
assert "CREATE INDEX IF NOT EXISTS ix_knowledge_symptoms_hash" in source