refactor(api): TOML 配置 SSOT、统一错误契约、Auth/事务加固与可观测性 (#33)

配置 SSOT(TOML + .env)
统一错误契约
Auth 与事务边界
Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client
可观测性(OpenTelemetry + LGTM)
This commit is contained in:
Sully
2026-05-22 13:44:50 +08:00
committed by GitHub
parent f09ae248f9
commit 53e0065e3e
298 changed files with 15247 additions and 4344 deletions

View File

@@ -2,7 +2,8 @@
from __future__ import annotations
from unittest.mock import AsyncMock, MagicMock
from contextlib import asynccontextmanager
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from sqlalchemy.ext.asyncio import AsyncSession
@@ -10,8 +11,14 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.features.conversation.history_store import HumanAiTurnIds
@asynccontextmanager
async def _capture_transactional(db):
yield db
await db.commit()
@pytest.mark.asyncio
async def test_record_human_ai_turn_returns_both_message_ids(monkeypatch) -> None:
async def test_record_human_ai_turn_returns_both_message_ids() -> None:
conv_id = "conv-1"
captured: list[object] = []
@@ -25,20 +32,19 @@ async def test_record_human_ai_turn_returns_both_message_ids(monkeypatch) -> Non
def add_conversation_message(msg: object, db) -> None:
captured.append(msg)
monkeypatch.setattr(
"app.features.conversation.history_store.ConversationMessage",
FakeMsg,
)
db = MagicMock(spec=AsyncSession)
db.commit = AsyncMock()
db.refresh = AsyncMock()
import app.features.conversation.history_store as hs_mod
orig_repo = hs_mod.repo
hs_mod.repo = _FakeRepo # type: ignore[misc]
try:
with patch(
"app.features.conversation.history_store.transactional",
_capture_transactional,
), patch(
"app.features.conversation.history_store.ConversationMessage",
FakeMsg,
), patch(
"app.features.conversation.history_store.repo",
_FakeRepo,
):
from app.features.conversation import history_store as hs
store = hs.ConversationHistoryStore(db)
@@ -57,8 +63,6 @@ async def test_record_human_ai_turn_returns_both_message_ids(monkeypatch) -> Non
segment_id="seg-1",
memory_retrieval_trace=None,
)
finally:
hs_mod.repo = orig_repo # type: ignore[misc]
assert isinstance(out, HumanAiTurnIds)
assert len(captured) == 2
@@ -67,3 +71,4 @@ async def test_record_human_ai_turn_returns_both_message_ids(monkeypatch) -> Non
assert captured[0].segment_id == "seg-1"
assert out.human_message_id == captured[0].id
assert out.assistant_message_id == captured[1].id
db.commit.assert_awaited_once()