feat(权限): 收敛普通账号写权限至本人凭证

将调度时刻、采集参数等实例级配置收归管理员,普通账号仅可维护本人 Cookie 与 User-Agent。
新增 config.writable_by 作为唯一写权限入口,set_setting 强制全局键落到 user_id=0,
消除「管理员改了只有自己生效」的静默缺陷。新增 tools/check_docs.py 文档自检,
smoke 断言扩至 215 项、check_live 扩至 122 项并支持普通账号越权验收,
忽略 backups/、data/*.bak* 与 legacy-v1/,版本升至 v1.3.0。
这个提交包含在:
2026-09-18 08:46:00 +08:00
父节点 df7db3582e
当前提交 1bf961f6b3
共修改 42 个文件,包含 2615 行新增和 854 行删除
+8 -3
查看文件
@@ -29,7 +29,11 @@
<a href="{{ url_for('views.records') }}" class="{{ 'on' if nav=='records' }}">数据明细</a>
<a href="{{ url_for('views.tasks') }}" class="{{ 'on' if nav=='tasks' }}">任务管理</a>
<a href="{{ url_for('views.config_page') }}" class="{{ 'on' if nav=='config' }}">配置管理</a>
{# 日志管理里是实例运行信息(数据库路径 / 账号名 / 来源 IP),仅管理员可见;
服务端另有 @admin_required 兜底,这里隐藏只是不给出会 403 的死链。 #}
{% if cur.is_admin %}
<a href="{{ url_for('views.logs') }}" class="{{ 'on' if nav=='logs' }}">日志管理</a>
{% endif %}
{% if cur.is_admin %}
<a href="{{ url_for('views.users_page') }}" class="{{ 'on' if nav=='users' }}">用户管理</a>
{% endif %}
@@ -37,7 +41,8 @@
<div class="me">
<a class="who" href="{{ url_for('views.profile_page') }}" title="个人中心">
<b>{{ cur.display_name }}</b>
{% if cur.is_admin %}<span class="tag accent">管理员</span>{% endif %}
{% if cur.is_admin %}<span class="tag accent">管理员</span>
{% else %}<span class="tag mute">普通账号</span>{% endif %}
</a>
{# 退出用 POST + CSRF:GET 型退出会被 <img src="/logout"> 这类请求静默触发 #}
<form method="post" action="{{ url_for('views.logout_post') }}" style="margin:0">
@@ -60,8 +65,8 @@
</main>
<footer class="foot">
<b>{{ project_title }}</b> · {{ project_name }} · 多用户 · 采集在 Web 进程内按各账号配置的时刻执行<br>
每个账号只使用并只见得到自己的 Cookie 与用量数据;数据正本 <code>data/usage.sqlite</code>
<b>{{ project_title }}</b> · {{ project_name }} · 多用户 · 调度与采集参数由管理员统一设定<br>
每个账号只使用并只见得到<b>自己的</b> Cookie 与用量数据;数据正本 <code>data/usage.sqlite</code>
</footer>
<script>