Files

85 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 实例自定义图标技术设计
## 数据流
```text
本地 PNG/JPEG/WebP
→ 浏览器解码并居中裁剪为 512×512 PNG
→ POST /api/instance-iconBearer二进制≤4 MiB
→ 服务端验证 Content-Type、PNG 签名、IHDR 尺寸
→ CONFIG_DIR/.instance-icon.png.tmp 原子 rename
→ 返回 { custom, version, updatedAt, url }
→ 前端更新 favicon、Apple Touch、登录 Logo、通知图标与设置预览
```
## 持久化与升级
- 正式文件:`CONFIG_DIR/instance-icon.png`
- 临时文件:`CONFIG_DIR/.instance-icon.png.tmp`,失败时清理。
- 默认 `CONFIG_DIR``APP_DIR/config``.gitignore` 精确忽略这两个文件。
- 如果部署设置 `CC_WEB_CONFIG_DIR` 到仓库外,图标自动跟随外置配置目录。
- 不覆盖任何 `public/*.png`,源码升级只更新默认兜底图。
## HTTP 契约
### GET /api/instance-icon/config
公开返回:
```json
{
"custom": true,
"version": "sha256-short-hash",
"updatedAt": "ISO-8601",
"url": "/api/instance-icon?v=sha256-short-hash"
}
```
未配置时 `custom=false``version=default`URL 仍指向统一读取接口。
### GET /api/instance-icon
- 自定义存在且有效:返回该 PNG。
- 未配置或运行文件失效:返回 `public/icon-192.png`
- `Content-Type: image/png``X-Content-Type-Options: nosniff`
- 使用 ETag/no-cache版本化 URL 负责同页缓存刷新。
### POST /api/instance-icon
- 必须通过现有 Bearer token 鉴权。
-`Content-Type: image/png`body 非空且不超过 4 MiB。
- 必须是标准 PNG 签名IHDR 宽高均为 512。
- 固定路径原子写入;返回最新配置对象。
### DELETE /api/instance-icon
- 必须通过现有 Bearer token 鉴权。
- 删除实例运行文件,幂等返回默认配置对象。
### GET /api/site.webmanifest
- 未自定义:保留现有 192/512 默认图标声明。
- 已自定义:使用版本化 `/api/instance-icon`,声明 512×512。
## 前端契约
- head 中 favicon、Apple Touch 与 Manifest 从首屏即指向动态 API默认服务端兜底避免闪烁。
- 需要动态更新的图片用 `data-instance-icon` 标识;图标 link 用 `data-instance-icon-link` 标识。
- `instanceIconUrl(config)` 是唯一 URL 生成入口;浏览器通知和 Service Worker 默认也用 `/api/instance-icon`
- 外观设置中新增“实例图标”区:预览、选择图标、恢复默认、状态文字。
- 客户端拒绝非 PNG/JPEG/WebP使用 canvas 居中裁剪,不拉伸;上传失败保留旧图标。
## 错误语义
- 401未鉴权写操作。
- 400空内容、错误 MIME、非法 PNG、非 512×512。
- 413超过 4 MiB。
- 500原子保存/读取不可恢复错误;前端显示服务端中文消息。
## 测试顺序
1. 增加聚焦服务集成测试并确认在实现前失败。
2. 覆盖默认读取、鉴权、非法输入、上传、覆盖版本、恢复默认与 Git 外置路径。
3. 增加前端静态/DOM 契约测试,覆盖设置 UI 和所有图标消费点。
4. 实现最小代码使测试通过,再运行总回归。