Files

82 lines
7.6 KiB
Markdown
Raw Permalink Normal View History

---
id: T-583
title: 标题提示词模板数据层:泛化 prompts 模板 CRUD + 新增 prompts/title 目录(加法,不换单文件)
phase: 7
deps: []
2026-07-10 11:43:35 +08:00
status: DONE
created: 2026-07-10
---
## 问题 / 背景
②标题提示词现为**单文件** `title_prompt.txt`(一条,`prompts.load/save_title_prompt`),无模板管理;封面提示词已是**目录多模板**(`cover_prompts_dir` + 一套 CRUD)。运营希望标题也能像封面一样存/取多个命名模板。
已核关键事实(决定改动范围):
- 生成时 `generate_batch(tasks, prompts, ...)` 的 `prompts["title"]/["cover"]` **取编辑框当前文本**(`generate.py:1219`/`1281`),**不读文件/模板**。模板只是"把某段文本载入编辑框"的持久化层——**本任务不碰 `generate_batch`、不碰生成读取路径**。
- `prompts.py` 现有 `list/load/save/rename/delete_cover_template` 五个写死 cover 的函数 + `render_prompt`(共享)+ `ensure_default_prompts`(播种默认封面模板)。
定案(已评审):
1. **加法、不换单文件**:`title_prompt.txt` **保留为"当前工作文本"**(语义不变、不迁移、编辑框仍从它载入),**另加** `data/prompts/title/` 目录放命名模板。纯新增能力,零迁移、零丢失风险。
2. **泛化 CRUD**:把 cover 那五个函数泛化成按目录参数化的通用模板 CRUD,标题/封面共用一套,不复制第二份(防两套分叉)。
3. **标题默认模板**:拿现有默认标题提示词播一条进 `data/prompts/title/`(不新建 `default_prompts/title` 包)。
本任务只做数据层,无 UI(UI reorg 见 T-584)。
## 方案(改哪个文件、改成什么)
### `app/prompts.py` — 泛化模板 CRUD
- 抽出目录参数化的通用函数(命名实现定,如):`list_templates(directory)`、`load_template(name, directory)`、`save_template(name, text, directory)`、`rename_template(old, new, directory)`、`delete_template(name, directory)`,含现有 `_normalize_name`/`_template_path`/重名保护。
- 现有 `*_cover_template` 保留为**薄封装**(转调通用函数,传 `COVER_PROMPTS_DIR`),保证封面既有调用点零改动、零回归。
- 新增标题模板薄封装或直接让 GUI 传 `title_templates` 目录调用通用函数(择一,UI 任务据此对接)。
- 通用函数的错误文案使用中性中文,例如「提示词模板名不能为空 / 提示词模板不存在 / 提示词模板已存在」,不要在标题模板路径上暴露“封面提示词模板”。
### `app/appconfig.py` — 目录路径
- 新增 `title_templates_dir(config=None)` → `data_path("prompts", "title", config=config)`,与现有 `cover_prompts_dir(config=None)` 的 `data/prompts/cover/` 形成同层目录。
- 不把标题模板放到 `data/title_templates/`,避免提示词存储分散。
### `app/prompts.py` `ensure_default_prompts` — 播种标题默认模板
- 现有逻辑保留(`title_prompt.txt` 缺失时写默认、封面模板缺失时播默认)。
- 新增第三参数 `title_templates_dir=None`:若为空时播入一条默认标题模板(内容 = `_read_default_prompt_text("title_prompt.txt")`,模板名如「默认」)。不新建 `app/default_prompts/title` 包。
- 调用方显式传入 `title_templates_dir` 时按该目录播种;未传时必须从 `title_prompt_path` 推导同一个用户数据根下的 `prompts/title/`,避免测试或临时配置只传 `title_prompt_path` / `cover_prompts_dir` 时误写真实默认 `data/`。
- 已有标题模板时不覆盖;`title_prompt.txt` 为空时仍按旧逻辑写默认工作文本。
### 数据/边界
- `title_prompt.txt` 语义**不变**:仍是编辑框当前工作文本的持久化,`load/save_title_prompt` 不动。
- 标题模板与封面模板是**两个独立目录**:`data/prompts/title/*.txt` 与 `data/prompts/cover/*.txt`,占位符(标题 `{旧标题}` 等 vs 封面 `{新标题}` 等)各自语义不变;`render_prompt` 共享不改。
### 文档同步
- 更新 `docs/04-architecture.md` 提示词存储说明:`data/title_prompt.txt` 是当前工作标题提示词;`data/prompts/title/*.txt` 是标题模板;`data/prompts/cover/*.txt` 是封面模板。
- 若 `docs/routes.md` / 设置或打包文档已有提示词目录描述,同步保持 `prompts/title` / `prompts/cover` 口径。
## 验收要点
- 通用模板 CRUD 存在且被 cover 薄封装复用;`list/load/save/rename/delete_cover_template` 行为不回归(既有封面模板测试全绿)。
- 新增 `title_templates_dir` 指向 `data/prompts/title`;`list_templates` 能对该目录增删查、重名保护生效。
- `ensure_default_prompts`:`prompts/title/` 为空时播入一条默认标题模板(内容 = 现有默认标题提示词);已有模板时不覆盖;传临时 `title_prompt_path` 时不会误写真实默认 `data/`。
- `title_prompt.txt` 及 `load/save_title_prompt` 行为不变(编辑框工作文本不受影响,无迁移、无丢失)。
- 标题/封面模板互不干扰(各自目录)。
- `docs/04-architecture.md` 已同步提示词存储结构。
- 不改 `generate_batch`/生成读取路径/`render_prompt`。
- 验证命令(unittest,不引入 pytest):
- `py -3.10 -m unittest tests.test_prompts tests.test_appconfig`(若无 test_prompts 则新建)
- `python -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `py -3.10 -m unittest discover -s tests`
- `git diff --check`
## 边界(不改什么)
- 不动 `generate_batch`、生成时的 prompt 读取(仍取编辑框文本)。
- 不改 `title_prompt.txt` 语义、不迁移/删除该文件。
- 不复制第二份模板 CRUD;封面走薄封装复用通用实现。
- 不做 GUI(T-584);不新建 `default_prompts/title` 包。
- 不把标题模板放到 `data/title_templates/`;统一使用 `data/prompts/title/`。
- 不改 CDP/DB/AI 请求/cmhub/Excel。
## 执行记录
2026-07-10 11:43:35 +08:00
- 2026-07-10:已完成数据层实现。`app/appconfig.py` 新增 `title_templates_dir(config=None)`,指向 `data/prompts/title`;`app/prompts.py` 新增通用 `list/load/save/rename/delete_templates` 能力,标题/封面模板复用同一套 CRUD,保留封面旧 API 薄封装,并新增标题模板薄封装。
- 2026-07-10:`ensure_default_prompts()` 增加 `title_templates_dir=None`,为空时从 `title_prompt_path` 推导同一数据根的 `prompts/title/`,为空目录时播入「默认」标题模板;不改 `title_prompt.txt` 工作文本语义,不改生成读取路径。
- 2026-07-10:同步 `docs/04-architecture.md` 提示词存储结构;补 `tests/test_prompts.py` 和 `tests/test_appconfig.py` 覆盖标题模板目录、通用 CRUD、默认播种、互不干扰与封面旧 API 回归。
- 当前工作区验证:`python -m ruff check app tests main.py` 通过;`py -3.10 -m compileall app main.py` 通过;`git diff --check` 通过。
- 当前工作区运行 `py -3.10 -m unittest tests.test_prompts tests.test_appconfig` 失败 1 项,原因是本任务开始前已有未提交改动把默认封面模板从 `papa1` 改成「默认」,导致旧断言仍期望 `papa1`;该封面默认模板改名不属于 T-583,本次未处理、未提交。提交后需用干净 worktree 验证本次提交本身。
2026-07-10 11:44:52 +08:00
- 提交后在干净 worktree `D:\chengma\cmshopee_verify_t583` 验证本次 T-583 提交:`py -3.10 -m unittest tests.test_prompts tests.test_appconfig` 通过 24 项,`python -m ruff check app tests main.py` 通过,`py -3.10 -m compileall app main.py` 通过,`git diff --check` 通过,`py -3.10 -m unittest discover -s tests` 通过 327 项。