Ctrl K
ComunidadGuías…

docs/RELEASE_NOTES_v0.1.8.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# BailingHub v0.1.8:首次管理员只创建一次

`v0.1.8` 修复无人值守安装与 demo 启动路径中的管理员生命周期问题:首次管理员现在只会在管理员表为空时创建。后续针对同一持久化数据库的服务重启、版本升级、容器重建或重新安装,都不会再次协调或覆盖已有账号。

## 为什么要修

部署系统可以提供“首次安装时创建管理员”的能力,但不能把启动配置永久当成管理员账号的权威来源。

如果每次启动都根据环境变量重写账号,管理员主动改密后,服务重启可能把旧的 bootstrap 密码重新写回数据库。这既破坏运维预期,也会让旧部署配置持续拥有不应保留的密码重置能力。

`v0.1.8` 将这两种动作明确分开:

- **bootstrap**:只负责空数据库的首次管理员创建;
- **显式管理**:后续创建账号或重置密码继续使用 `npm run admin:create`。

## 主要变化

### Create-once bootstrap

使用成对环境变量:

```text
BAILING_BOOTSTRAP_ADMIN_USERNAME
BAILING_BOOTSTRAP_ADMIN_PASSWORD
```

语义如下:

- 两个变量都未配置:跳过自动创建;
- 只配置其中一个:拒绝启动,避免半配置状态;
- 管理员表为空:创建首个启用的 `admin` 账号;
- 管理员表已有任何账号:不修改任何账号、密码、角色或启用状态。

### 并发冷启动安全

MySQL 模式使用命名锁和事务串行化首次创建。多副本同时冷启动时,只有一个副本能够创建首个管理员;无法取得初始化锁时,服务会失败退出,而不是在不确定状态继续运行。

### demo 与安装器采用同一契约

- 一键安装器生成随机首次管理员密码,并通过 bootstrap 环境变量传入;
- demo seed 使用同一 create-once 逻辑;
- 重启不会重置管理员密码;
- 服务日志不再打印管理员密码。

### 管理员仓储兼容修复

显式修改密码时,如果调用方没有提供角色:

- 新账号使用 `admin` 作为插入缺省角色;
- 已有账号保留原角色。

这避免了 MySQL 在执行重复键更新前,先因非空角色列缺值而拒绝请求。

## 升级与兼容性

- 不需要数据库迁移;
- 不改变 Client API、执行器协议、工具签名或 ACC 语义;
- 既有 `npm run admin:create` 保持可用;
- 保留数据库的升级、重装和容器重建不会重置账号;
- 只有删除持久化数据库后的真正全新安装,才会重新创建首个管理员。

升级前仍应按常规流程备份数据库与部署配置。若历史部署继续保留 `BAILING_DEMO_ADMIN_PASSWORD`,它只服务于兼容的 demo 配置,不再构成每次启动重置管理员的依据。

## 验证

发布前执行:

```bash
npm run typecheck
npm test
npm run security:scan
npm run release:check
```

同时在真实 MySQL 上验证:

1. 空管理员表能够首次创建;
2. 管理员改密后重启,旧 bootstrap 密码不会恢复;
3. 多副本冷启动只创建一个首个管理员;
4. 日志不包含首次管理员密码;
5. Docker demo CI 在改密并重启后仍能使用新密码登录。

## 相关文档

- [快速开始](QUICKSTART.md)
- [生产运维](OPERATIONS.md)
- [兼容性与升级](兼容性与升级.md)
- [发布记录](CHANGELOG.md)