Skip to content

fix(settings): auto-map legacy description field names to the new contract - #541

Open
Anionex wants to merge 7 commits into
mainfrom
fix/legacy-description-field-map
Open

fix(settings): auto-map legacy description field names to the new contract#541
Anionex wants to merge 7 commits into
mainfrom
fix/legacy-description-field-map

Conversation

@Anionex

@Anionex Anionex commented Jul 31, 2026

Copy link
Copy Markdown
Owner

背景

描述字段契约早已从老四字段(视觉元素 / 视觉焦点 / 排版布局 / 演讲者备注)升级为新三字段(配图与素材 / 版式与重点 / 演讲者备注),但字段改名之前保存的数据仍然生效

  1. 设置(settings):数据库里非空的 description_extra_fields / image_prompt_extra_fields 优先于代码默认值,导致设置页展示、描述生成 prompt 与文生图 prompt 继续使用老字段名。
  2. 存量页面数据:字段改名之前生成页面的 extra_fields 键名仍是老名字,详情卡片/编辑弹窗/属性抽屉直接展示原始键名,与设置面板的新契约名不一致。

代码此前只对存量页面数据在生图 prompt 拼接时做了旧字段名兼容(LEGACY_FIELD_EQUIV),没有对设置本身做等价处理,也没有在展示层把存量页面旧键名映射为新契约名。

改动

后端(backend/models/settings.py)

  • get_description_extra_fields():读取时把旧字段名自动等价到新契约字段(视觉元素→配图与素材视觉焦点/排版布局/排版建议→版式与重点),映射到同一新字段时去重、顺序保留;自定义字段原样保留;非字符串条目丢弃;非法/空值回退默认。只读映射不落库——用户下次在设置页保存时自然持久化为新字段名。
  • get_image_prompt_extra_fields():与描述字段走同一套读时映射。此前存量旧名 image_prompt 设置会匹配不到新 key 页面内容(如 配图与素材/版式与重点),导致文生图 prompt 静默丢弃配图与版式信息(已实测复现)。

前端(展示层对齐新契约,数据不迁移)

  • frontend/src/utils/projectUtils.ts:新增 EXTRA_FIELD_LEGACY_EQUIV / resolveExtraFieldName()(与后端 LEGACY_FIELD_EQUIV 保持一致)、isInImagePrompt()(与后端 _append_extra_fields 同语义双匹配,且对设置列表内的旧名也对称命中)、buildExtraFieldEntries()(存量旧键等价显示为新名;同义旧键合并为一个条目、内容换行拼接、优先有内容的主键)。
  • DescriptionCard.tsx / PagePropertiesDrawer.tsx:详情卡片、编辑弹窗、属性抽屉的字段名统一按映射后的新契约名展示;「不影响图片生成」标记与后端同语义;编辑仍绑定原始键,保存不改写数据键名(避免 视觉焦点+排版布局 并存页合并丢内容);同义旧键在编辑会话内收敛为单一主键。
  • DetailEditor.tsx:设置字段池加载时把旧版本 localStorage 残留的旧名胶囊归一化为新名并去重、过滤非字符串;添加字段入口对旧名做等价归一化;image-prompt 胶囊显示与开关统一基于等价新名。

测试

  • 后端 test_description_field_contract.py 新增 9 个用例(映射去重保序、自定义字段、不落库、image_prompt 映射/演讲者备注保持、to_dict 契约、新/旧 key 页面 × 新/旧设置 双组合进 prompt、边界值)。
  • 前端新增 14 个用例:resolveExtraFieldNameisInImagePrompt 六种组合、buildExtraFieldEntries(映射/合并/主键偏好/非字符串强转/自定义字段)、卡片展示映射、同义键合并、编辑弹窗新名标签。
  • E2E 更新并新增:存量旧键页面以新契约名展示(无旧名残留、内容不丢);存量旧名设置 → 新名胶囊;真实后端旧 key 页面不误标「不影响图片生成」;顺带修复 streaming-descriptions 两个存量失效断言(contentEditable 选择器、已移除的详细程度按钮、tooltip 文案 strict 冲突)。

影响面

生成 prompt、描述解析、GET /api/settings、前端设置页、详情卡片、编辑弹窗、属性抽屉全部统一到新契约名;存量页面数据键名保持原样(只读映射展示),生图链路双向兼容。

⚠️ 语义收敛提示:老字段 视觉焦点排版布局 均收敛到新字段 版式与重点(且 排版建议 也等价),因此一个老设置/老页面最多收敛为三个新字段;并存的两个旧键内容以换行合并展示,编辑保存后收敛为单一键。这是设计内行为,不是数据丢失。

验证

  • 后端单测:SKIP_SERVICE_TESTS=true uv run pytest backend/tests/unit -q600 passed
  • 前端单测:vitest run218 passed(27 个文件);lint 0 errors;tsc 错误数与基座一致(47 个存量,无新增)。
  • E2E(真实前后端,排除真实 AI 用例):description-field-contract / streaming-descriptions / page-properties-drawer 三个 spec 35 passed
  • 真实 API 验证:worktree 数据库写入老四字段与老名 image_prompt 设置 → GET /api/settings 返回 ['配图与素材','版式与重点','演讲者备注'] / ['配图与素材','版式与重点']
  • Browser 验证:存量旧 key 页面(视觉元素/视觉焦点/演讲者备注)详情页展示新契约名(配图与素材/版式与重点/演讲者备注)、无旧名残留、内容全部保留、「不影响图片生成」仅标记演讲者备注。

…tract

Settings saved before the description field rename (视觉元素/视觉焦点/
排版布局/演讲者备注) still drive generation prompts and the settings
page, because a non-null DB value wins over the new defaults. Map legacy
field names to the current contract (配图与素材/版式与重点/演讲者备注)
at read time, deduplicating where two legacy names map to the same field,
while keeping custom fields and their order untouched. No data migration:
the mapping is read-only, and saving settings later persists the new names.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1bebadf956

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# 存量设置里的旧字段名自动等价到新契约字段(视觉元素→配图与素材、
# 视觉焦点/排版布局→版式与重点),去重保序;自定义字段原样保留。
# 只做读时映射不落库,用户下次保存设置时自然持久化为新字段名。
return self._normalize_extra_fields(fields)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize the legacy image-prompt allowlist too

When a pre-upgrade database contains both legacy description_extra_fields and a legacy image_prompt_extra_fields allowlist, this line makes newly generated descriptions use names such as 配图与素材, while get_image_prompt_extra_fields() still returns names such as 视觉元素. _append_extra_fields() only translates a legacy content key toward a new allowlist key, not the reverse, so the new description fields no longer match the old allowlist and their image instructions are silently omitted from generated image prompts. Normalize the image-prompt allowlist alongside the description fields.

Useful? React with 👍 / 👎.

Anionex added 6 commits July 31, 2026 22:50
GET /api/settings 与文生图 prompt 构建都统一走读时映射,
避免存量旧名 image_prompt_extra_fields 匹配不到新 key 页面
内容时被静默丢弃。补边界用例:空列表保持为空、非法 JSON
回退默认、非字符串丢弃、新旧名混合去重。
设置读取映射为新字段名后,存量页面旧 key(视觉元素等)在
DescriptionCard 会被误标为「不影响图片生成」,与后端实际进
prompt 行为矛盾。按后端 _append_extra_fields 同语义改为原名或
等价新名任一命中即视为进生图;设置字段池加载时把旧名胶囊统一
归一化为新名并去重。补前端单测覆盖三种组合。
…rawer

属性抽屉的「不进生图」标记与 DescriptionCard 同一误标问题
(存量页面旧 key + 映射后新名设置),按后端同语义改为原名或
等价新名任一命中即视为进生图。
- 抽取 isInImagePrompt 公共谓词(与后端 _append_extra_fields 同语义),
  DescriptionCard / PagePropertiesDrawer / DetailEditor 统一使用
- add 字段入口对旧名做等价归一化,避免旧名/新名语义重复胶囊导致
  生图开关卡死;image-prompt 开关统一操作等价新名
- 字段池加载同时归一化服务端 activeFields、过滤非字符串条目
- 后端补 image_prompt 含演讲者备注映射保持、to_dict 输出契约测试
- e2e 新增真实后端用例:存量旧名设置 → 新名胶囊、旧 key 页面不误标
胶囊文案带 tooltip 后缀,锚定正则 ^旧名$ 无法命中实际按钮文本,
改为前缀匹配,确保旧名胶囊真的不存在时用例才通过;恢复设置时
空数组回退默认,避免控制器 400。
存量页面 extra_fields 的旧键名(视觉元素/视觉焦点/排版布局/排版建议)
在详情卡片、编辑弹窗与属性抽屉中统一等价显示为新契约字段名
(配图与素材/版式与重点/演讲者备注),数据仍绑定原始键不迁移;
同义旧键(视觉焦点+排版布局)合并为一个条目、内容换行拼接,
编辑保存时收敛到主键,避免重复展示与内容丢失。isInImagePrompt
补对称匹配(设置列表含旧名时同样命中)。顺带修复 streaming-
descriptions 两个存量失效断言(textarea 选择器/contentEditable、
已移除的详细程度按钮、tooltip 文案 strict 冲突)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant