feat: switch config to JSONC + split secrets.json

Load business config as JSONC (comments + trailing commas) via an
in-repo stripper then stdlib json — no new deps. Default path prefers
config.jsonc, falls back to legacy config.json. Auth write-back targets
only sibling secrets.json so JSONC comments are never wiped; secrets
overlay merges on load. Examples, compose, Docker, docs, favsort and
tools all share the same loader. Phase A only — no DB settings migration.
This commit was merged in pull request #4.
This commit is contained in:
bot-ci committed 2026-11-02 12:58:20 +08:00
1 parent b4f0f45c4e
commit 8e7ead1669
21 files changed
+652 -182

No files matched your search

+24 -20
View File
@@ -113,14 +113,14 @@ uv run python app.py status
# P2 起启动本地看板服务
uv run python app.py serve
uv run python app.py serve --config .\config.json
uv run python app.py serve --config .\config.jsonc
# 无子命令启动完整服务:只读 Web + 调度 + Telegram
uv run python app.py
# 生成 7 天预览库并启动预览
uv run python tools/seed_preview_db.py --days 7
uv run python app.py serve --preview --config data/preview/config.json
uv run python app.py serve --preview --config data/preview/config.jsonc
# 从 B 站粉丝历史 CSV 回填(先 dry-run;首次完整导入可用 --replace)
uv run python tools/import_fans_csv.py --csv E:\Downloads\history.csv --dry-run
@@ -152,8 +152,8 @@ uv sync --all-groups
不得提交:
- `.venv/`
- `config.json`
- `config.json.bak`
- `config.jsonc` / `config.json`
- `secrets.json` / `secrets.json.bak`
- `data/` 中的运行期数据库、日志、计划和备份。
---
@@ -205,8 +205,11 @@ PRAGMA synchronous = NORMAL;
├── pyproject.toml # uv / Python 项目元数据
├── uv.lock # uv 生成并提交的锁文件
├── .python-version # 固定 Python 3.14
├── config.json # 运行期私密配置,不提交
├── config.example.json # 脱敏配置样例
├── config.jsonc # 运行期业务配置(JSONC,不提交)
├── secrets.json # 运行期凭据(auth 回写目标,不提交)
├── config.example.jsonc # 脱敏业务配置样例(含注释)
├── secrets.example.json # 脱敏凭据样例
├── config.docker.example.jsonc # 服务器业务配置样例
├── DEVELOPMENT.md
│
├── reaction_board/
@@ -261,24 +264,22 @@ PRAGMA synchronous = NORMAL;
### 5.1 运行期配置
所有凭据和可变业务参数放在 `config.json` 中。文件必须被 Git 忽略,日志中不得输出其敏感值。
业务参数放在 `config.jsonc`(JSONC:`//` / `/* */` 注释与尾逗号;实现为自研轻量剥离后再 `json.loads`,无额外依赖)。
敏感凭据放同目录 `secrets.json`(纯 JSON,供 `auth` 原子回写)。二者都必须被 Git 忽略,日志中不得输出敏感值。
默认路径优先 `config.jsonc`,否则回落 `config.json`;旧单体 `config.json`(凭据内嵌)仍可加载,若存在 `secrets.json` 则凭据以它为准。
`config.jsonc` 示例:
```jsonc
{
"bilibili": {
"mid": 28802351,
"csrf": "<bili_jct>",
"cookie": "SESSDATA=...; bili_jct=...; buvid3=..."
},
// bilibili / bot_token / auth_token → secrets.json
"telegram": {
"enabled": true,
"bot_token": "123456:ABC",
"chat_id": 123456789
},
"web": {
"host": "127.0.0.1",
"port": 8080,
"auth_token": "replace-with-a-long-random-token",
// auth_token → secrets.json
"public_base_url": ""
},
"storage": {
@@ -303,11 +304,14 @@ PRAGMA synchronous = NORMAL;
```
- `folders` 仅作为历史来源与 `favsort.py` 重排序目标,系统不再自动同步或建夹;
- 配置必须为 `bilibili.read` / `bilibili.write` 双账号结构;不兼容顶层扁平 `mid` / `csrf` / `cookie`;
- `bilibili.read` / `bilibili.write` 写在 `secrets.json`(或旧单体主配置内);不兼容顶层扁平 `mid` / `csrf` / `cookie`;
- `python app.py auth` 只原子回写 `secrets.json`(并保留 `.bak`),不改主 JSONC;
- P0/P3 已实现的命令行:`python app.py init`、`python app.py ingest`、`python app.py status`、`python app.py run`。
### 5.2 安全规则- Windows 本地开发时应限制 `config.json` 的文件访问权限;部署到 Linux 时权限必须为 `600`;
- 配置文件每 60 秒检查一次 mtime,凭据、分类规则和权重变更后无需重启;
### 5.2 安全规则
- Windows 本地开发时应限制 `config.jsonc` / `secrets.json` 的文件访问权限;部署到 Linux 时权限必须为 `600`;
- 主配置与凭据文件每 60 秒检查一次 mtime,凭据、分类规则和权重变更后无需重启;
- Cookie / CSRF 变化时由 `ClientProvider` 重建 B 站请求客户端,并保留该角色的限速与重试策略;
- `schedule.discover_minutes`、`schedule.snapshot_at` 与 `schedule.seed_at` 在启动时固化,修改后需重启 `run`;
- Telegram 操作必须同时验证 `from.id` 和 `chat.id` 是否为配置的私聊用户;
@@ -788,7 +792,7 @@ uv run python tests/test_moves.py
- `reaction_board/client_ip.py`:来源 IP 提取、路由归一化与机器人判定纯函数(三种来源 + 伪造防护);
- `reaction_board/web/visits.py`:访问上报先落内存缓冲,后台每分钟批量 upsert,支持单键上限与保留期清理,关闭时最后一次 flush;
- 前端 `navigator.sendBeacon("/api/visit")` 埋点;Web 只读边界放宽为显式 POST 白名单(`/api/visit` + `/login`);
- `config.json` 新增 `web.track`(`enabled`/`header_order`/`trusted_proxies`/`count_bots`/`flush_seconds`/`keep_days`/`max_hits_per_ip_path_per_day`);
- `config` 新增 `web.track`(`enabled`/`header_order`/`trusted_proxies`/`count_bots`/`flush_seconds`/`keep_days`/`max_hits_per_ip_path_per_day`);
- 系统状态页展示近 30 天 PV/UV 与 Top 页面(`GET /api/stats`,需登录,合并未落库缓冲);
- `deploy/nginx/` 提供直连 EIP / Cloudflare / EdgeOne 的 realip 与站点配置、网段刷新脚本和说明;
- 自动化测试新增 `tests/test_client_ip.py`、`tests/test_visits.py`,并扩展 `test_config.py`、`test_web_queries.py`、`test_web_server.py`、`test_migrations.py` 等。
@@ -796,7 +800,7 @@ uv run python tests/test_moves.py
### P4:可选部署
- 反向代理、TLS、远程访问鉴权;
- 仓库已提供 `Dockerfile` / `compose.example.yml` / `config.docker.example.json`;容器内执行 `python app.py --config /config/config.json`,挂载 `/config` 与 `/data`;
- 仓库已提供 `Dockerfile` / `compose.example.yml` / `config.docker.example.jsonc` / `secrets.example.json`;容器内执行 `python app.py --config /config/config.jsonc`,挂载 `/config` 与 `/data`;
- Docker 不作为本机开发、联调或日常运行的前置条件。
---