docs(integration): direct Learning README images

This commit is contained in:
2026-08-20 14:09:50 +08:00
parent 9956739693
commit 2168e291b2
11 changed files with 95 additions and 33 deletions

View File

@@ -26,20 +26,20 @@ Renderer 的固定链路为 `Renderer -> Host API -> Electron Main -> Works Squa
| 排序 `sort_order` | 有界整数;列表默认按运营排序,再按发布时间稳定排序 |
| 状态 `status` | `draft``published``archived` |
上传中的对象不能直接进入公开目录。发布必须在一个事务/发布代际中冻结元数据、README、封面、镜像图片和 ZIP 摘要;任一校验失败则整个发布失败,旧的已发布版本继续可读。下架后列表和详情立即不可见,但已有审计记录不能物理删除。
上传中的对象不能直接进入公开目录。发布必须在一个事务/发布代际中冻结元数据、经过净化和 URL 校验的 README、封面 ZIP 摘要;任一校验失败则整个发布失败,旧的已发布版本继续可读。下架后列表和详情立即不可见,但已有审计记录不能物理删除。
后台必须记录操作人、时间、发布代际、变更摘要、归档 SHA-256/字节数和远程图片抓取结果。客户端不提供任何运营上传或发布入口。
后台必须记录操作人、时间、发布代际、变更摘要、归档 SHA-256/字节数、README 警告和远程图片 URL 数量。客户端不提供任何运营上传或发布入口。
## 3. README 远程图片发布规则
README 中的远程图片在“发布”时由服务端解析 Markdown AST 并镜像,客户端不直接使用原始远程图片 URL。处理要求:
README 中的远程图片在“发布”时由服务端解析 Markdown,并保留通过校验的原始 HTTPS URL服务端不下载或处理图片字节。处理要求:
1. 只接受无用户名/密码的 HTTPS URL拒绝 `http:``data:``file:`、本地路径和协议相对地址。
2. 每一跳重新解析 DNS并拒绝 loopback、私网、链路本地、保留地址、云元数据地址和非公网目标;最多 5 次重定向
3. 单图最大 10 MiB同时限制超时、并发数和 README 图片总量;响应必须是实际可解码的 PNG/JPEG/WebP/GIF/AVIF拒绝 SVG、HTML、XML 和 MIME 欺骗
4. 将通过校验的字节写入受控对象存储,以内容摘要去重;发布记录引用不可变对象
5. Markdown 图片地址改写为 `/api/learning/projects/:projectId/media/:mediaId`。详情接口只返回改写后的 Markdown不返回原始远程 URL 或对象 key
6. Markdown 原始 HTML在客户端被禁用服务端也应在预览与发布时提示被忽略的 HTML避免运营误判展示效果
2. 只允许默认 HTTPS 端口且不允许 fragment解析当前 DNS任一结果属于 loopback、私网、链路本地、保留地址、云元数据或其他非公网地址时拒绝发布
3. 限制 README 图片总量不请求远端响应因此不校验重定向、响应大小、MIME、像素、实际格式或内容。SVG 及其他 Electron 可渲染格式可直接显示
4. 发布后的 Markdown 保留通过校验的 URL不创建 README 图片 blob 或新 release-media 行;现有媒体路由继续用于封面和历史已镜像发布
5. Markdown 原始 HTML 在客户端被禁用;服务端也从发布内容中移除 HTML 并返回 warning避免运营误判展示效果
6. 客户端请求会直接到第三方图片 origin图片可用性、后续 DNS/重定向和格式支持由 origin 与 Electron 决定origin 也会看到请求方网络信息。单图加载失败不得阻断 README 其余内容
封面同样优先返回固定媒体路径。若返回 HTTPS CDN 地址,该地址必须无凭据、由 Works Square 控制且不包含用户隐私。
@@ -106,7 +106,7 @@ README 中的远程图片在“发布”时由服务端解析 Markdown AST 并
"archiveBytes": 12582912,
"publishedAt": "2026-08-01T00:00:00Z",
"updatedAt": "2026-08-18T00:00:00Z",
"readmeMarkdown": "# 桌面机械臂\n\n![接线图](/api/learning/projects/robot-arm/media/wiring)",
"readmeMarkdown": "# 桌面机械臂\n\n![接线图](https://docs.example.com/wiring.svg)",
"archiveFileName": "makelore-robot-arm-1.2.0.zip",
"archiveSha256": "64位小写十六进制SHA-256"
}
@@ -117,7 +117,7 @@ TypeScript 权威字段定义位于 [`shared/learning.ts`](../shared/learning.ts
### 媒体与归档响应
- 媒体接口只返回受控 raster 内容,必须设置准确 `Content-Type``Content-Length`Main 限制 10 MiB并转换为 data URL给 Renderer。
- 媒体接口只用于封面和历史已镜像内容,返回受控 raster 内容设置准确 `Content-Type``Content-Length`Main 限制 10 MiB并转换为 data URL 给 Renderer。新发布 README 的 HTTPS 图片不经过该接口。
- 归档接口返回 `application/zip``application/x-zip-compressed``application/octet-stream`,设置准确 `Content-Length`。如需重定向,只能跳转到与 Works API 相同 origin 的 HTTP(S) 地址,最多 5 跳Main 不向重定向目标转发 Bearer。
- 归档字节必须与详情中的 `archiveBytes``archiveSha256` 精确一致。客户端验证失败时删除临时文件,不留下部分下载。
@@ -131,6 +131,6 @@ TypeScript 权威字段定义位于 [`shared/learning.ts`](../shared/learning.ts
- `LEARNING_CONFLICT`409发布代际变化
- `LEARNING_UNAVAILABLE`429/502/503
列表/详情可对发布代际生成 ETag媒体和归档按内容摘要设置不可变缓存但不得缓存带用户私有授权的响应到公共共享缓存。日志不得记录 Bearer、签名 URL、README 原始私有 URL或对象存储 key。
列表/详情可对发布代际生成 ETag媒体和归档按内容摘要设置不可变缓存但不得缓存带用户私有授权的响应到公共共享缓存。日志不得记录 Bearer、签名 URL、完整 README 图片 URL 或对象存储 key可记录规范化主机、URL 摘要和图片数量
上线顺序:先部署数据库/对象存储、运营后台、远程图片镜像和四个公开接口,并用真实账号完成发布/下架/图片/ZIP 联调;再发布新客户端。旧 `/api/learning/courses`、generation/progress/runtime 接口不在新客户端兼容范围内,可按服务端消费者盘点结果独立退役。
上线顺序:先部署数据库/对象存储、运营后台、README HTTPS URL 校验和四个公开接口,再发布包含直连图片支持的新客户端;随后用真实账号完成发布/下架/远程图片(含 SVG、失效 origin 和隐私提示)/ZIP 联调。旧 `/api/learning/courses`、generation/progress/runtime 接口不在新客户端兼容范围内,可按服务端消费者盘点结果独立退役。