> For the complete documentation index, see [llms.txt](https://summerain-1.gitbook.io/summerain/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.8.md).

# V2.0.8

> 开发预发布版本。此版本从 `dev` 分支发布，可能会快速接收后续更改，不会被默认的 `latest` 镜像标签选择。

## 概述

v2.0.8 把固定图片策略从 Go 常量与环境变量中移出，改由服务端配方文件定义； 同时新增生成器，把 MySQL 结构渲染成用于生产部署的显式 SQL。

配方文件现在负责变体尺寸、像素与体积上限、可接受的源格式，以及浏览器上传必须发送的 `recipe_version`。容器会把默认配方写入 `/app/config/image-recipe.json`，二进制文件 内置同一份默认配方，`IMAGE_RECIPE_FILE` 与 `IMAGE_RECIPE_REQUIRED` 控制查找行为。 文件缺失时会回退到内置默认配方，除非显式要求必须存在；文件不可读、格式错误或取值越界 都会在连接 MySQL 之前中止启动。

`V2_RECIPE_VERSION`、`V2_MAX_PART_BYTES` 和 `V2_MAX_PIXELS` 不再被读取； 请把这些取值迁移到配方文件。默认值保持不变，因此未修改的部署与 v2.0.7 行为完全一致。

## 变更内容

### 图片配方文件

* 新增默认配方 `backend/internal/config/image-recipe.json`，通过 `go:embed` 内嵌到二进制文件，并复制到镜像内的 `/app/config/image-recipe.json`。
* 新增 `IMAGE_RECIPE_FILE`（默认 `/app/config/image-recipe.json`）与 `IMAGE_RECIPE_REQUIRED`（默认 `false`）。
* 配方声明 `pipeline_version`、`recipe_version`、`max_pixels`、`max_part_bytes`、 `supported_source_mime_types`，以及四个固定变体 （`master`、`gallery`、`admin`、`publish_source`）。
* 代码级边界仍保留在代码中：`pipeline_version` 必须为 2；源格式列表必须是五种受支持格式的 非空子集；`max_pixels` 需在 1 MP 到 100 MP 之间；`max_part_bytes` 需在 1 MiB 到 64 MiB 之间；变体尺寸需在 1 到 4096 像素之间；质量需在 1 到 100 之间。配方只能收紧 这些取值，绝不能突破。
* 变体校验、源格式接受、部件体积与像素上限，以及 `/api/v1/uploads/recipe` 响应均改为读取 配方，而不再使用代码常量。响应结构保持不变。
* 启动日志输出一行 `image_recipe_*` 摘要，包含来源、版本、上限与变体信息，绝不包含凭据。
* 配方不进入管理员 API：配方相关键会被现有配置白名单拒绝。

### 生成的数据库结构 SQL

* 新增 `backend/cmd/schema-migration-gen` 与 `scripts/generate-sql-migration.sh`。
* 执行 `bash scripts/generate-sql-migration.sh baseline_schema` 会写入 `backend/migrations/<UTC 时间戳>_baseline_schema.up.sql` 并立即校验。
* 生成过程只在 `SUMMERAIN_SCHEMA_DSN` 上创建并删除一次性数据库，绝不接触已有数据库。
* 校验会把文件应用到一个空数据库，并要求随后运行的引导过程不改变该结构，从而证明快照与 GORM 模型及所有带校验和的迁移一致。设置 `SUMMERAIN_SCHEMA_DSN` 后， `go test ./cmd/schema-migration-gen/...` 会执行同样的检查。
* 已提交 `backend/migrations/20261003_122900_baseline_schema.up.sql`，包含全部 17 张表。

### 部署示例

* `backend/.env.example` 记录了新增的两个变量，并移除被配方取代的三个变量； 依赖锁校验脚本会断言新增行存在。

## 验证

* 后端 `go build ./...`：通过。
* 后端 `go vet ./...`：通过。
* 后端 `go test ./...`：通过。
* 前端 ESLint 与 Vite 生产构建：通过。
* 前端 Vitest：17 个测试文件、131 个测试全部通过。
* 配方测试覆盖内置默认值、外部文件覆盖、文件缺失行为、格式错误文件、全部校验错误， 以及上传校验确实遵循配方取值。
* 结构校验：针对 MySQL 8.4.10 执行 `scripts/generate-sql-migration.sh --verify` 与 `go test ./cmd/schema-migration-gen/...`：通过。
* Python requirements lock 验证：通过。
* GitBook 文档与翻译验证：通过。

## 安装

必须显式拉取开发镜像：

```bash
docker pull jaykserks/summerain:dev-v2.0.8
```

等效的精确开发标签：

```
jaykserks/summerain:dev-2.0.8
```

移动的 `dev` 标签也指向最新的成功开发构建。`latest`、`main` 和稳定的语义版本别名 不受此版本影响。

从 v2.0.7 升级不需要数据库迁移或 API 迁移。部署前请把自定义的 `V2_RECIPE_VERSION`、`V2_MAX_PART_BYTES` 或 `V2_MAX_PIXELS` 取值迁移到配方文件。

## 已知限制

* 生成的 SQL 是面向空数据库的完整结构快照。本版本不包含针对已有数据库的增量 `ALTER TABLE` 生成；已有数据库继续通过追加型带校验和运行器升级。
* 配方只在启动时读取一次；修改配方需要重启并提升 `recipe_version`。
* 在后续客户端配置阶段完成之前，前端仍发送固定的 `recipe_version`；默认配方让两者保持同步。
* 动画图像支持仍计划在后续版本中实现。

## 相关工作

此版本实现了 `PHASES-2-8-PLAN-v2.md` 的**阶段 3**：配方外部化与显式 SQL 迁移生成。

**下一阶段**：阶段 4（v2.0.9）将在保持现有字段不变的前提下，为 `/api/v1/uploads/recipe` 增加可选的客户端提示字段。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://summerain-1.gitbook.io/summerain/zh-cn/fa-bu-shuo-ming/v2.0.8.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
