角色:Controller(管理端,无数据库)

端口 8015 · 面向管理端 · 聚合 user_manager 与控制器
manager_server 就是 arch.png 里的 Admin ServerData Collection + Management)。它是管理控制台与 rakull_manager 客户端唯一对接的后端。 和控制器一样,它不拥有任何数据库:解码共享 HS256 JWT、要求 role == root,再把管理员的 token 转发给真正拥有数据的服务。

接口 /api/manager/*

方法 / 路径用途上游
POST /login登录并校验管理员角色(非 root 返回 403)user_manager
GET /me当前管理员身份
GET /overview数据采集概览(用户/邀请码/申请/用量/文章总数)user_manager + 控制器
GET/PUT/DELETE /users*用户列表 / 改角色 / 删除user_manager
GET/POST/PUT/DELETE /invite-codes*邀请码增删改查 / 启停user_manager
GET/POST /registration-requests*注册申请 / 批准 / 拒绝user_manager
GET/PATCH/PUT/DELETE /articles*全站文章筛选、元信息编辑、公开状态与安全删除控制器
GET/POST/PUT/DELETE /cos*COS 配置、读写探测、对象浏览/下载/删除data_server(经控制器)
GET/POST/PATCH/DELETE /model-routing*Endpoint / ModelBinding CRUD、连接探测、自动默认与可选 CallPlanagent_server(经控制器)
GET/PUT/POST /speech-settings*Whisper / Azure TTS 配置与真实测试agent_server(经控制器)
GET/PUT /runtime-settings文章自动 TTS 开关控制器
内置静态管理控制台在 /app/console/)。

访问管理后台

浏览器直接打开,用写入数据库的管理员账号登录即可:
open http://localhost:8015   # 默认 admin / admin123
控制台包含「概览 / 用户 / 邀请码 / 注册申请 / 文章 / COS storage / AI APIs」标签页;AI APIs 内分为 ModelsSpeech & automation
  • 「用户」保留角色调整与删除;「文章」支持服务端筛选/排序、标题/作者/简介/类型编辑、公开/私有切换,并显示每篇文章实际成功执行翻译与语法讲解的解析模型;没有调用历史时显示 。永久删除要求输入完整标题或文章 ID,处理中的文章会拒绝删除;删除响应会显示未引用媒体与 COS 清理结果。
  • COS storage 是一个直接覆盖的简单表单。测试会用当前表单执行 Bucket、PUT、HEAD、GET、LIST、DELETE 探测但不保存;保存才会覆盖配置并热应用到新请求,空凭证按清空处理。对象浏览与安全删除规则见对象存储(COS)
  • AI APIs → Models 用于维护 OpenAI-compatible Endpoint、API Key 与 Endpoint 下的模型 Binding。只要存在一个有效 Binding,首个模型就会显示为“自动默认模型”并可立即使用;CallPlan 仅用于指定不同模型之间的默认/Fallback,同名 Endpoint 路由由后台按历史估价自动选择更便宜者。Endpoint 表单直接表示候选配置:API Key 留空即无 Key,填写即覆盖,不另设清除选项;连接测试使用当前未保存表单且不落盘,结果紧邻操作按钮显示,创建/保存会先实测同一候选,只有通过才写入。已配置模型默认折叠为“模型名 + enabled/disabled”摘要,点击后才展开完整设置与 Model Test。Model Test 仍由管理员显式触发,不会因保存自动运行。
  • AI APIs → Speech & automation 管理 Whisper Key / Base URL / Model、Azure TTS Key / Region / Voice 与自动文章 TTS 开关。Whisper 可上传不超过 5 MB 的常见音频进行真实转写;Azure 用固定日文短句真实合成并返回可播放音频,可能产生少量费用。测试使用未保存候选值,错误会移除密钥。
所有外部服务字段都遵循 后台运行时设置 > 环境变量 > config.local.yaml > config.yaml > 默认值 也可单独验证 API:
TOKEN=$(curl -s -X POST http://localhost:8015/api/manager/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin123"}' \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')

curl -s http://localhost:8015/api/manager/overview \
  -H "Authorization: Bearer $TOKEN"

curl -s http://localhost:8015/api/manager/model-routing \
  -H "Authorization: Bearer $TOKEN"

管理员账号(写入数据库)

管理员直接写入 user_manager 的数据库app/db/seed.py,初始化时幂等执行),不再是“第一个注册用户自动成为 root”。由 ROOT_ADMIN_USERNAME / ROOT_ADMIN_PASSWORD 控制(默认 admin / admin123,置空则跳过)。普通用户注册后进入待审批队列,由管理员在此控制台批准。

扇入拓扑

环境变量

下表变量同样是该服务根目录下的 YAML 配置键(键名一致):config.yaml 存非敏感默认值(已提交),config.local.yaml 存密钥与本机覆盖(已 gitignore,可从 config.example.yaml 复制)。优先级(高 → 低):环境变量 > config.local.yaml > config.yaml > 代码默认值。JWT_SECRET 等密钥放进 config.local.yaml
变量说明默认
JWT_SECRET校验 Bearer 的共享密钥(须与服务栈一致change-me-in-config-local
USER_MANAGER_URLuser_manager 地址(用户 / 用量)http://localhost:8010
STUDY_SERVER_URL控制器地址(文章)http://localhost:8012
ALLOW_ORIGINSCORS 允许来源(逗号分隔),用于独立部署的控制台*

运行

cd rakull_server/manager_server
JWT_SECRET=dev-secret USER_MANAGER_URL=http://localhost:8010 STUDY_SERVER_URL=http://localhost:8012 \
uv run uvicorn app.main:app --port 8015
scripts/run_all_servers.sh 会自动在 :8015 拉起本服务。

管理端客户端:rakull_manager

rakull_manager 是一个只做 WebView 的 Flutter 壳,指向本服务的控制台 URL —— 所有管理 UI 只维护一份,在每个平台复用。
cd rakull_manager
flutter create --project-name rakull_manager --platforms=android,ios,macos,windows,linux,web .
flutter pub get
flutter run --dart-define=MANAGER_CONSOLE_URL=http://localhost:8015
Web / 桌面也可以直接用浏览器打开控制台 URL —— 它本就是个普通 Web 应用。