# 2026-06-06 — 凭据轮询登录与连接失败列表

## 摘要

密码/SSH 密钥预设增加用户名；快速添加服务器仅需 IP，自动轮询全部凭据尝试 SSH 登录；失败进入 `pending_servers` 列表并可重试。

## 动机

批量添加 2000+ 子机时，每台需尝试多组账号密码；手动填用户名密码效率低，需凭据预设驱动自动探测。

## 涉及文件

- `server/domain/models/__init__.py` — `username` 字段、`PendingServer` 模型
- `server/infrastructure/database/migrations.py` — 幂等 schema 迁移
- `server/infrastructure/ssh/asyncssh_pool.py` — `try_ssh_login`
- `server/application/services/credential_poller.py` — 轮询服务（新）
- `server/infrastructure/database/pending_server_repo.py` — 失败队列 repo（新）
- `server/api/servers.py` — `add-by-ip`、`/pending`、retry、delete
- `server/api/schemas.py`、`server/api/settings.py` — 预设 username
- `frontend/src/pages/CredentialsPage.vue` — 凭据 UI
- `frontend/src/pages/ServersPage.vue` — 快速添加 + 失败列表
- `tests/test_credential_poller.py`

## 迁移 / 重启

- 启动时 `run_schema_migrations()` 自动 ALTER/CREATE
- 需重启 API；前端需 `vite build` 部署

## 验证

```bash
.venv/bin/pytest tests/test_credential_poller.py -q
cd frontend && npx vite build
```

## API

| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/servers/add-by-ip` | 仅 IP，轮询凭据 |
| GET | `/api/servers/pending` | 失败列表 |
| POST | `/api/servers/pending/{id}/retry` | 重试轮询 |
| DELETE | `/api/servers/pending/{id}` | 删除 pending |
