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:
@@ -17,13 +17,15 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.agents.memoir.narrative_agent import NarrativeAgent
|
||||
from app.core.config import settings
|
||||
from app.core.db import get_sync_db
|
||||
from app.core.db import get_sync_db, transactional_sync
|
||||
from app.core.llm_gateway import LlmGateway, LlmUseCase
|
||||
from app.core.logging import get_logger
|
||||
from app.core.memoir_pipeline_progress import merge_pipeline_run
|
||||
from app.features.memoir.models import Chapter
|
||||
from app.features.memoir.repo import mark_chapter_dirty_sync
|
||||
from app.features.story.models import Story
|
||||
from app.features.memoir.constants import memoir
|
||||
from app.features.story.constants import story
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -54,7 +56,7 @@ def _polish_story_title(
|
||||
return False
|
||||
|
||||
body = (story.canonical_markdown or "").strip()
|
||||
if len(body) < settings.story_title_min_body_chars:
|
||||
if len(body) < story.title_min_body_chars:
|
||||
return False
|
||||
|
||||
narrative_agent = NarrativeAgent()
|
||||
@@ -76,7 +78,7 @@ def _polish_story_title(
|
||||
return True
|
||||
|
||||
|
||||
@shared_task(bind=True, max_retries=2, default_retry_delay=30)
|
||||
@shared_task(bind=True, max_retries=2, default_retry_delay=30, ignore_result=True)
|
||||
def memoir_quality_pass(
|
||||
self,
|
||||
user_id: str,
|
||||
@@ -89,7 +91,7 @@ def memoir_quality_pass(
|
||||
Runs asynchronously after the fast draft is committed and visible.
|
||||
"""
|
||||
qptid = str(self.request.id)
|
||||
if not settings.memoir_quality_pass_enabled:
|
||||
if not memoir.quality_pass_enabled:
|
||||
if memoir_correlation_id:
|
||||
merge_pipeline_run(
|
||||
memoir_correlation_id,
|
||||
@@ -152,34 +154,32 @@ def memoir_quality_pass(
|
||||
== "en"
|
||||
else "zh"
|
||||
)
|
||||
for sid in story_ids:
|
||||
story = db.get(Story, sid)
|
||||
if not story or story.user_id != user_id:
|
||||
continue
|
||||
with transactional_sync(db):
|
||||
for sid in story_ids:
|
||||
story = db.get(Story, sid)
|
||||
if not story or story.user_id != user_id:
|
||||
continue
|
||||
|
||||
chapter_category = story.stage or "summary"
|
||||
if _polish_story_title(
|
||||
db,
|
||||
story,
|
||||
llm,
|
||||
chapter_category=chapter_category,
|
||||
language=user_language,
|
||||
):
|
||||
titles_polished += 1
|
||||
stmt = select(Chapter.id).where(
|
||||
Chapter.user_id == user_id,
|
||||
Chapter.category == chapter_category,
|
||||
Chapter.is_active == True, # noqa: E712
|
||||
)
|
||||
ch_id = db.execute(stmt).scalar_one_or_none()
|
||||
if ch_id:
|
||||
chapters_dirtied.add(str(ch_id))
|
||||
chapter_category = story.stage or "summary"
|
||||
if _polish_story_title(
|
||||
db,
|
||||
story,
|
||||
llm,
|
||||
chapter_category=chapter_category,
|
||||
language=user_language,
|
||||
):
|
||||
titles_polished += 1
|
||||
stmt = select(Chapter.id).where(
|
||||
Chapter.user_id == user_id,
|
||||
Chapter.category == chapter_category,
|
||||
Chapter.is_active == True, # noqa: E712
|
||||
)
|
||||
ch_id = db.execute(stmt).scalar_one_or_none()
|
||||
if ch_id:
|
||||
chapters_dirtied.add(str(ch_id))
|
||||
|
||||
for ch_id in chapters_dirtied:
|
||||
mark_chapter_dirty_sync(db, ch_id)
|
||||
|
||||
if titles_polished > 0:
|
||||
db.commit()
|
||||
for ch_id in chapters_dirtied:
|
||||
mark_chapter_dirty_sync(db, ch_id)
|
||||
|
||||
elapsed = time.perf_counter() - t0
|
||||
duration_ms = elapsed * 1000
|
||||
|
||||
Reference in New Issue
Block a user