--- id: T-583 title: 标题提示词模板数据层:泛化 prompts 模板 CRUD + 新增 title_templates 目录(加法,不换单文件) phase: 7 deps: [] status: TODO 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` **保留为"当前工作文本"**(语义不变、不迁移、编辑框仍从它载入),**另加** `title_templates/` 目录放命名模板。纯新增能力,零迁移、零丢失风险。 2. **泛化 CRUD**:把 cover 那五个函数泛化成按目录参数化的通用模板 CRUD,标题/封面共用一套,不复制第二份(防两套分叉)。 3. **标题默认模板**:拿现有默认标题提示词播一条进 `title_templates/`(不新建 `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("title_templates", ...)`(与 `cover_prompts_dir` 同款)。 ### `app/prompts.py` `ensure_default_prompts` — 播种标题默认模板 - 现有逻辑保留(`title_prompt.txt` 缺失时写默认、封面模板缺失时播默认)。 - 新增:若 `title_templates/` 为空,把**现有默认标题提示词**(`_read_default_prompt_text("title_prompt.txt")` 同源)作为一条模板播入(模板名如「默认」)。不新建 `app/default_prompts/title` 包。 ### 数据/边界 - `title_prompt.txt` 语义**不变**:仍是编辑框当前工作文本的持久化,`load/save_title_prompt` 不动。 - 标题模板与封面模板是**两个独立目录**,占位符(标题 `{旧标题}` 等 vs 封面 `{新标题}` 等)各自语义不变;`render_prompt` 共享不改。 ## 验收要点 - 通用模板 CRUD 存在且被 cover 薄封装复用;`list/load/save/rename/delete_cover_template` 行为不回归(既有封面模板测试全绿)。 - 新增 `title_templates_dir` 指向 `data/title_templates`;`list_templates` 能对该目录增删查、重名保护生效。 - `ensure_default_prompts`:`title_templates/` 为空时播入一条默认标题模板(内容 = 现有默认标题提示词);已有模板时不覆盖。 - `title_prompt.txt` 及 `load/save_title_prompt` 行为不变(编辑框工作文本不受影响,无迁移、无丢失)。 - 标题/封面模板互不干扰(各自目录)。 - 不改 `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` 包。 - 不改 CDP/DB/AI 请求/cmhub/Excel。 ## 执行记录 (做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)