Commit Graph

8 Commits

Author SHA1 Message Date
xiaji
55e20e923a perf(translate): translation_loop 跳过中文源头,省 TMT 配额
中文 RSS 长新闻(原文就是中文)走 TMT 中翻中,纯粹浪费
月配额(500 万字符)且产生无意义译文。前端 commit 6
已经隐藏"译文"板块;本 commit 在后端拦截,从源头不跑翻译。

改动:
- translation_loop SQL 加 WHERE lang_src IS NULL OR NOT LIKE 'zh%'
  - lang_src 为 NULL 时仍走翻译(英文 RSS 没设 language_src 的合法场景)
  - LIKE 'zh%' 覆盖 zh / zh-CN / zh-Hans / zh-TW 等区域码
- translate_article() 函数内加防御性 guard:中文源直接返
  并把 translation_status 改 'n/a',避免反复入队
  (主路径 SQL 过滤已足够,这里是兜底,应对手动 reset status 的情况)

不影响:
- 短新闻(commit 1 已是 translation_status='n/a',根本不进队列)
- 外文 RSS(走翻译)
- 历史已被错误翻译的中文长新闻:保留 translation_status='ok'
  + body_zh_text 中文(空跑产生的) — commit 6 前端已隐藏,
  不影响用户感知;回滚存量不在本 commit 范围(独立 SQL 即可,
  风险与收益需要单独评估)
- enrichment_loop(commit 1 已经能扫到中文源头的 is_short_news,
  长新闻 lang_src=zh 仍能被 enrichment 处理,排版+插图+评论都跑)

范围:仅 backend/app/workers/pipeline.py,+20/-2 行。
2026-06-14 20:57:11 +08:00
xiaji
e274246056 feat(ingest): API Push 前端层 + 文档 + 端到端联通
后端(支持 api_push source 创建/调度):
- schemas/source.py:SourceIn.url 改成 str(允许 api_push 的 api-push:// 占位)
- admin.py create_source 简化 url 传递
- workers/__main__.py:_rebuild_jobs 跳过 api_push 源(它是被动接收,不抓取)
- workers/pipeline.py:run_once 也加同条件,api_push 不进抓取循环

前端:
- api/articles.ts:ArticleListItem 加 is_short_news(required)/source_ref;
  ArticleDetail 加 external_id;导出 IngestTokenOut;adminApi 加
  list/create/revoke ingest token 三个方法
- views/Feed.vue:卡片根 class 短新闻加 short-card(淡蓝底 #f6f9fc +
  左侧 3px 蓝色色条 #4f9eff);元信息栏加 📰 短讯 角标;长新闻摘要
  body_zh_text 截前 200 字,短新闻不截取保留换行(white-space: pre-wrap);
  短新闻不显示 AI 插图
- views/ArticleDetail.vue:tag 行加 📰 短讯 + source_ref 角标;短新闻
  路径下隐藏翻译状态/重译/原文链接按钮;正文区短新闻直接渲染
  body_zh_text,跳过译文/原文/AI 配图卡片;Angel + 美团双评论卡片
  都保留
- views/AdminSources.vue:kind 加 api_push 选项;api_push 源 URL 字段
  变只读占位、隐藏抓取间隔;列表操作列加 🔑 Token 按钮;
  弹窗支持生成(raw_token 一次性显示 + 复制)/列表/撤销

文档:
- docs/api-push.md:调用方契约 + 三层去重 + 限速 + lifecycle +
  owner 操作手册 + curl/Python 示例 + 重试策略 + 故障排查
- README.md:关键特性加 API Push;API 概览加 /api/v1/ingest 和
  3 个 /admin/.../ingest-tokens 端点
2026-06-14 16:15:21 +08:00
Mavis
fd7817b881 fix(translate): 拦截引擎错误 marker + pipeline 严格 status 判定,避免 TMT AuthFailure 伪装 ok 2026-06-11 10:01:19 +08:00
Mavis
a8e93cf7c7 fix(translate): pipeline 写库用 service 返回的 engine(之前写死 tencent)
pipeline.translate_article 调 translation_service.translate() 后,
自己写 engine_label='tencent',忽略 service 实际返回的 engine。
效果:即使 service 内部按 spark 优先链路跑成功了,
DB 里 translation_engine 也只显示 tencent。

修法: 改用 tr_title.engine(or 默认 tencent 兜底)。

附带: deploy_pull.py 加 sys.stdout.reconfigure(encoding='utf-8'),
Windows GBK 终端下 Unicode 字符不会再 UnicodeEncodeError。
2026-06-10 23:31:03 +08:00
Mavis
523c82f7a5 fix: NHK 源配置改 ja(seed 写错了); translate_article 加强 lang_src 兜底 2026-06-08 00:54:02 +08:00
Mavis
9862a92423 perf: 翻译独立后台循环(1 篇/秒)+ Semaphore 1
之前 fetch_one_source 入库后立即调翻译(可能并发触发腾讯 TMT 限速)
改为独立 translation_loop 后台循环:
- 完全不和 RSS 抓取并行
- 1 篇/秒节拍(Semaphore 1 + sleep 1.0)
- 没活时空闲 5 秒再轮询
- pending/failed 都重试
2026-06-08 00:27:09 +08:00
Mavis
3ebf280278 fix: pipeline INSERT 去掉不存在的 translate_to 字段 2026-06-07 23:32:13 +08:00
Mavis
60b062daf2 feat: initial MVP - FastAPI backend + Vue3 frontend + docker-compose
- backend: FastAPI + SQLAlchemy 2.0(async) + asyncpg + Alembic
- 7 API routes: auth/me/articles/sources/bookmarks/subscriptions/admin
- models: User/Source/Article/Bookmark/Subscription/ApiToken
- services: RSS fetcher (feedparser) + Tencent TMT translator with quota + cache + local NLLB fallback
- workers: APScheduler + asyncio pipeline (fetch -> dedupe -> insert -> translate)
- seed scripts: create_user, seed_sources (5 RSS: Reuters/BBC/Al Jazeera/NHK/DW)
- frontend: Vue 3 + Vite + Naive UI + Pinia + vue-router
- pages: Login, Feed (24h), ArticleDetail, Sources, Bookmarks, AdminSources
- deploy: docker-compose (postgres/redis/api/worker/frontend/caddy)
- docs: README, DEPLOY, architecture, acceptance
2026-06-07 21:51:01 +08:00