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

+8 -5
View File
@@ -8,7 +8,7 @@
用法::
uv run python tools/seed_preview_db.py --days 7 --seed 20261031
uv run python app.py serve --preview --config data/preview/config.json
uv run python app.py serve --preview --config data/preview/config.jsonc
"""
from __future__ import annotations
@@ -31,7 +31,9 @@ from reaction_board.timeutil import SHANGHAI_TZ, shanghai_datetime # noqa: E402
DEFAULT_SOURCE = ROOT / "data" / "app.db"
DEFAULT_TARGET = ROOT / "data" / "preview" / "app.db"
DEFAULT_CONFIG_SOURCE = ROOT / "config.json"
from reaction_board.config import default_config_path # noqa: E402
DEFAULT_CONFIG_SOURCE = default_config_path(ROOT)
BASE_DAILY_RATES: dict[str, float] = {
"view": 0.0040,
@@ -187,8 +189,9 @@ def _read_source_config(path: Path | None) -> dict[str, Any] | None:
if path is None or not path.exists():
return None
try:
data = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
from reaction_board import jsonc
data = jsonc.load(path)
except (OSError, ValueError):
return None
return data if isinstance(data, dict) else None
@@ -617,7 +620,7 @@ def seed_preview(
config_target = (
Path(config_out).resolve()
if config_out is not None
else target_path.parent / "config.json"
else target_path.parent / "config.jsonc"
)
config_target.parent.mkdir(parents=True, exist_ok=True)