一套开箱即用的开源基座——投稿 → 审稿 → 录用 → 发表 → 阅读 → 订阅,一个代码库跑通全流程。
大多数团队都在反复从头搭同一套期刊脚手架——投稿表单、审稿人分配、一个装已发表文章的 CMS。 ScholarHUB 把它打包成一个真正的多角色产品,而不是又一次定制 CMS 的重复劳动。
作者投稿、编辑分配并裁决、审稿人出意见、读者浏览关注——它们在同一个系统里,不再需要胶水代码互相缝。
稿件元数据、单盲/双盲审稿、带版本的修改稿、DOI 注册、卷期目录、浏览器内阅读且进度跨设备同步、订阅、推荐——全部打通并落到测试里。
Passkey(WebAuthn)+ TOTP 双因素、带服务端 denylist 且可在线轮换的 JWT、注册验证码、逐操作审计日志。安全是默认值,不是 checklist。
一条 docker compose up 单节点起全栈。生产用 PostgreSQL 17,开发/CI 用 SQLite——不需要为本地开发准备重型环境。
从作者点"提交"到读者点"收藏",中间每一环都是真实可用的界面,不是流程图上的箭头。
全部是真实运行截图,桌面 1440×900、移动端 390×844,没有设计稿占位。








每个领域能力都是独立模块,可以单独启用、替换或扩展,不需要碰 core。
| 能力 | 亮点 |
|---|---|
| 投稿与审稿 | 完整元数据录入、单盲/双盲工作流、审稿人分配、带版本管理的修改稿、编辑裁决、终态守卫 |
| 发表与目录 | 卷期管理、可检索的已发表目录、通过 DataCite 注册 DOI |
| 元数据抓取 | 从 Crossref、arXiv、PubMed、OpenAlex、Semantic Scholar 拉取权威记录,外加 BibTeX / RIS / CSV 导入 |
| 阅读体验 | 浏览器内 PDF 阅读、跨设备阅读进度同步、个人阅读列表、关注作者与学科 |
| 鉴权与安全 | WebAuthn Passkey、TOTP 双因素、JWT denylist + 密钥轮换、验证码、RBAC(作者/编辑/审稿人/读者/admin) |
| 多租户 | 一个部署托管多个期刊,基于 host 解析租户并带路由缓存 |
| 发现 | 关注关系图、个性化推荐、邮件 + 站内通知、引用导出(BibTeX / RIS / CSL) |
启动时 core 自动创建,之后可在 admin 后台再分配。
| 角色 | 范围 |
|---|---|
admin | 全部权限——admin 后台、用户管理、审计日志 |
editor | 分配审稿人、组织卷期、录用/拒稿、推到「已发表」 |
reviewer | 查看分配给自己的稿件、提交审稿意见 |
author | 投递稿件、查看自己稿件状态、上传修改稿 |
member | 阅读、收藏、订阅、查看推荐 |
FastAPI async 后端 + React 19 前端,全程严格类型,模块化到 core 几乎不动。
每个领域表都带 tenant_id:应用层在每条查询上追加过滤,PostgreSQL 行级安全(RLS)即使应用层漏写也会拒掉跨租户行。是纵深防御,不是靠祈祷。
app.core.modules.load_all() 按依赖顺序加载模块、注册 ORM 表、挂载路由、加入健康检查。新能力 = 一处注册,core 零改动。
三种方式,按你的场景挑一种。推荐第一条——一条命令起全栈。
Postgres + 后端 + 前端全部拉起来,包含自动 TLS 的 Caddy。
# 生成强密钥 echo "SCHOLARHUB_SECRET_KEY=$(openssl rand -hex 32)" > .env echo "SCHOLARHUB_ADMIN_PASSWORD=$(openssl rand -base64 18)" >> .env # 启动 dev 栈 docker compose -f infra/docker-compose.yml up --build
需要 Python 3.12+、Node 20+,以及一个 PostgreSQL 17 实例。
# 后端 cd apps/backend && uv sync uv run alembic upgrade head uv run uvicorn app.main:app --reload # 前端(另开一个终端) cd apps/frontend && npm install && npm run dev
四个远端保持同步(分支、标签、HEAD 均一致)。
由 CI 兜底,不是嘴上说说。
后端 —— 644 个 pytest 用例,行覆盖率 84%,硬性门槛 --cov-fail-under=80;mypy --strict 与 ruff 全绿。
前端 —— vitest 单元 + 组件测试,严格 tsc 下 100 个用例。
E2E —— 66 个 Playwright 用例跑完整业务旅程。
迁移 —— 独立 job 在真实 PostgreSQL 17 上跑迁移并用 alembic check 比对元数据,专门抓单元测试(内存 SQLite)永远抓不到的模型/迁移漂移。
认证 —— bcrypt 哈希;短有效期 JWT access + httpOnly 刷新 Cookie + 每用户 token_version。
双因素 —— RFC 6238 TOTP,每用户密钥 Fernet 加密存储,10 个一次性备份码。
Passkey —— WebAuthn 注册/认证状态机,挑战一次性且带 TTL。
密钥轮换 —— 有序密钥链,POST /api/admin/reload-secret-keys 零停机轮换。
扫描门禁 —— bandit 以 LOW+ 为门槛(历史 9 处 LOW 已清零),依赖漏洞走 pip-audit 审计锁定的依赖集。
VERSION / pyproject /
package.json / __version__,任何一处漂移都会直接失败 —— 避免"文档说 0.2.0、实际装的是 0.1.0"这种事。