Files
diary-news/docs/architecture.md
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

2.3 KiB
Raw Blame History

架构设计

对应方案 v0.1 的实现版本。

模块边界

模块 路径 职责
API backend/app/api/ HTTP 路由,处理鉴权 / 入参 / 出参
业务 backend/app/services/ 抓取、翻译、领域逻辑
Worker backend/app/workers/ 后台调度、pipeline
数据 backend/app/models/ SQLAlchemy ORM
迁移 backend/alembic/ 数据库 schema 版本
前端 frontend/src/ Vue 3 + Naive UI

数据流

Source (DB)
   │
   ▼
Scheduler (cron / interval)
   │
   ▼
RSSFetcher.fetch() ── HTTP GET ──► upstream RSS
   │
   ▼
FetchedItem list
   │
   ▼ (url_hash UNIQUE 去重)
Article INSERT
   │
   ▼ (translation_status='pending')
TranslationService.translate()
   ├─ Redis cache hit → return
   ├─ quota check
   ├─ Tencent TMT (主) ──► 30 天 Redis 月度计数
   └─ Local NLLB (降级,需启用)
   │
   ▼
Article UPDATE (title_zh / body_zh_* / status)

关键设计决策

  • PostgreSQL:UNIQUE 约束 + ON CONFLICT DO NOTHING 做去重,O(1) 写
  • Redis 三用:翻译缓存(30 天 TTL)+ 月度配额(INCRBY)+ 后续限流
  • AScheduler 重构 jobs:每天 00:30 从 DB 重新读,运行时新增源自动生效
  • 翻译分块:按段落切,单段 > 1500 字符按句号再切,单请求 ≤ 4500 字符(腾讯 TMT 上限)
  • 失败退避:某源连续失败 3 次,fetch_interval × 2(封顶 720 分钟),成功一次恢复
  • API Token 双轨:网页用短期 JWT(15min)+ refresh(14d);Android 用长期 API Token(可独立撤销)

字段保留

articles 表里这些字段已建,MVP 全部 null,后续 enrichment 阶段直接写值不动表:

  • category / commentary / entities / sentiment / topic_id / bias

安全

  • 密码 bcrypt(cost=12)
  • JWT 走 HTTPS-only cookie(网页) / Bearer header(APP)
  • 数据库/Redis 不暴露到宿主机
  • Caddy 做 TLS 终止
  • API 限流(MVP 暂未实现,后续加)

不在 MVP

  • 全文搜索(可用 PG to_tsvector,MVP 先简单 ILIKE)
  • PWA 离线缓存
  • Android 客户端
  • 自动分类/点评/实体识别
  • 主题聚类
  • 跨源立场
  • Telegram 推送
  • i18n(只 zh)

DEPLOY.md 跑起来,见 ../README.md 看全貌。