# Auth Capability - Delta Spec

## ADDED Requirements

### Requirement: 启动时自动初始化默认管理员

系统在 API 服务启动时 SHALL 检查数据库是否存在超级管理员账号，如果不存在则自动创建默认管理员账号。

**业务规则**：
- 检查条件：`user_type = 1`（超级管理员）且未被软删除的账号
- 仅在不存在时创建，存在管理员时跳过
- 默认账号信息读取优先级：
  1. **配置文件优先**：读取 `config.yaml` 的 `default_admin` 配置节
  2. **代码默认值**：如果配置文件未提供，使用代码内置常量
- 代码内置默认值：
  - 用户名：`admin`
  - 密码：`Admin@123456`（bcrypt 哈希存储）
  - 手机号：`13800000000`
  - 用户类型：`1`（超级管理员）
  - 状态：`1`（启用）
- 初始化失败不中断服务启动（记录错误日志，降级处理）

#### Scenario: 空数据库首次启动（使用代码默认值）

- **WHEN** API 服务启动且数据库中不存在任何超级管理员账号
- **AND** 配置文件未提供 `default_admin` 配置
- **THEN** 系统使用代码内置默认值创建管理员账号
- **AND** 用户名为 `admin`，密码为 `Admin@123456`，手机号为 `13800000000`
- **AND** 记录日志："已创建默认管理员账号: admin（使用代码默认值）"
- **AND** 创建的账号可以正常使用（密码验证通过）

#### Scenario: 空数据库首次启动（使用配置文件）

- **WHEN** API 服务启动且数据库中不存在任何超级管理员账号
- **AND** 配置文件提供了 `default_admin` 配置
- **THEN** 系统使用配置文件中的值创建管理员账号
- **AND** 用户名、密码、手机号均从配置文件读取
- **AND** 记录日志："已创建默认管理员账号: {username}（使用配置文件）"
- **AND** 创建的账号可以正常使用（配置的密码验证通过）

#### Scenario: 已有管理员时启动

- **WHEN** API 服务启动且数据库中已存在至少一个超级管理员账号
- **THEN** 系统跳过创建默认管理员
- **AND** 记录日志："检测到已有管理员账号，跳过初始化"
- **AND** 不创建任何新账号

#### Scenario: 用户名或手机号冲突

- **WHEN** API 服务启动且尝试创建默认管理员
- **AND** 数据库中已存在用户名为 `admin` 或手机号为 `13800000000` 的账号（非超级管理员）
- **THEN** 系统创建失败
- **AND** 记录错误日志："创建默认管理员失败: 用户名或手机号已存在"
- **AND** 不中断服务启动（降级处理）

#### Scenario: 初始化执行时机

- **WHEN** API 服务执行启动流程
- **THEN** 管理员初始化在以下时机执行：
  1. 所有组件（Store、Service、Handler）初始化完成后
  2. 注册路由前
  3. 服务器开始监听前
- **AND** 确保 AccountStore 可用时才执行初始化

### Requirement: 默认管理员配置支持

系统 SHALL 支持通过配置文件自定义默认管理员账号信息，配置文件优先级高于代码默认值。

**配置格式**：
```yaml
default_admin:
  username: "admin"         # 可选，默认 "admin"
  password: "Admin@123456"  # 可选，默认 "Admin@123456"
  phone: "13800000000"      # 可选，默认 "13800000000"
```

#### Scenario: 配置文件完整提供

- **WHEN** `config.yaml` 中配置了 `default_admin` 节
- **AND** 提供了 `username`、`password`、`phone` 三个字段
- **THEN** 系统读取配置文件的值
- **AND** 不使用代码默认值
- **AND** 创建管理员账号时使用配置的值

#### Scenario: 配置文件部分提供

- **WHEN** `config.yaml` 中配置了 `default_admin` 节
- **AND** 只提供了部分字段（如只配置了 `password`）
- **THEN** 系统对已提供的字段使用配置值
- **AND** 对未提供的字段使用代码默认值
- **AND** 例如：配置了 `password: "MySecret123"`，但未配置 `username` 和 `phone`
  - 使用 `password = "MySecret123"`
  - 使用 `username = "admin"`（代码默认值）
  - 使用 `phone = "13800000000"`（代码默认值）

#### Scenario: 配置文件未提供

- **WHEN** `config.yaml` 中未配置 `default_admin` 节
- **THEN** 系统使用代码内置默认值
- **AND** 用户名为 `admin`
- **AND** 密码为 `Admin@123456`
- **AND** 手机号为 `13800000000`

#### Scenario: 配置验证

- **WHEN** 读取 `default_admin` 配置
- **THEN** 配置项为可选，不参与 `Validate()` 验证
- **AND** 允许配置为空或不存在
- **AND** 不阻止服务启动

### Requirement: 默认管理员安全配置

系统 SHALL 使用足够复杂的默认密码，并记录管理员创建日志用于安全审计。

#### Scenario: 默认密码复杂度

- **WHEN** 创建默认管理员账号
- **THEN** 代码内置默认密码 SHALL 满足以下复杂度要求：
  - 长度 ≥ 12 位
  - 包含大写字母、小写字母、数字、特殊字符
  - 示例：`Admin@123456`

#### Scenario: 审计日志记录

- **WHEN** 创建或跳过默认管理员账号
- **THEN** 系统记录审计日志到 `app.log`
- **AND** 日志包含以下信息：
  - 操作时间
  - 操作结果（创建成功/跳过/失败）
  - 创建的用户名（成功时）
  - 配置来源（配置文件/代码默认值）
  - 失败原因（失败时）
- **AND** 不在日志中记录明文密码

### Requirement: 系统账号创建内部接口

Account Service SHALL 提供内部方法用于系统初始化场景创建账号，绕过常规的用户上下文检查。

#### Scenario: 系统初始化创建账号

- **WHEN** 系统初始化需要创建内部账号（如默认管理员）
- **THEN** 调用 `createSystemAccount(ctx, account)` 方法
- **AND** 该方法不检查当前用户 ID（允许 context 中无用户信息）
- **AND** 保留用户名和手机号唯一性检查
- **AND** 密码使用 bcrypt 哈希存储
- **AND** 自动设置 creator 和 updater 为 0（系统创建）

#### Scenario: 常规 API 请求不使用系统接口

- **WHEN** 通过 HTTP API 创建账号
- **THEN** 使用常规 `Create()` 方法
- **AND** 必须有当前用户上下文（user_id > 0）
- **AND** 不允许调用 `createSystemAccount()` 方法（内部使用）
