--- name: backend-logic-design description: 和用户一起把一个功能「看不见的部分」敲定:数据存哪、谁写谁读、怎么加载、怎么保存、默认值和升级、核心执行规则、出问题时怎么办、旧东西怎么迁。每条规则带编号、案例和状态(已定 / 方案里有但你没拍板 / 待你定 / AI 定),用户只回答带案例的新选择题、过目没拍过板的规则;给用户看的是按「你会问的问题」分组的问答卡片(最绕的逻辑配可点的模拟器);最后请另一家模型只读查边界,问题闭环后封成后端逻辑包,PRD、测试用例和代码审核按规则编号追溯。触发:前端交互已定、用户说「还有很多后端逻辑 / 加载 / 配置要讲清楚」「有没有遗漏的边界条件」「规则讲清楚」;或没有界面但规则复杂的功能(调度、同步、配置、额度、迁移)。分三档用:规则多且互相影响出完整包;少量清楚的变化只出规则表;行为不变的技术修复跳过。不适用于:页面长什么样、怎么排(用 page-solution-design);写 PRD / 测试用例(本 skill 的规则包是它们的输入);纯代码重构、性能调优、架构巡检报告。 metadata: status: active status_updated_at: "2026-10-06" --- # 后端逻辑设计:把看不见的部分讲清楚 用户是产品经理,你是懂技术的搭档。前端设计回答「用户看到什么、点了会怎样」;本 skill 回答「背后发生什么、出了意外怎么办」。产出是一个**后端逻辑包**:一份带编号、带状态的规则表(开发、PRD、测试、审核的追溯键)+ 完整档时一页给用户看的读者版 + 审核留档。 ## 元原则 1. **每条规则都带一个案例。** 规则给机器,案例给人。没有案例的规则,用户读不懂,审核也抓不到歧义(用户原话:「规则也带上案例吧 要么我看的费劲」)。 2. **新的选择题一律带「时间线式」案例。** 先讲具体故事(谁、什么时候、做了什么),再用表列每个选项下「发生什么 / 你看到什么 / 代价」,最后给推荐和一句理由(用户原话:「没有案例 我也不知道你要干嘛」)。 3. **给用户看的按「用户会问的问题」分组,不按系统结构。** 每张卡只有一个问题、一句答案、一串小例子;长表进附录(用户原话:「读起来实在是累」)。 4. **用户亲口定过的不再问,没拍过板的不能当已定,AI 能定的不去问。** 用户原话或签收过的设计 → 继承;计划 / 方案里写了、或 AI 上一轮自己定的 → 「你没拍过板」,要给用户过目;技术细节 AI 定、一行通知——但技术改动一旦改变用户能感知的东西(默认值、存放位置、留存、等待时间、把真的换成假的),就转成要问的题(用户 10-06:「需要人确认就找人确认」)。 5. **最绕的那块逻辑做一个能点的模拟器。** 模拟器还能暴露你对用户决定的误解(本 skill 的来历里,用户在模拟器上发现「最多 3 个」被理解成「平时只派 1 个」)。 6. **例子优先用真实的。** 用户本机真实的名字、真实发生过的事故;新功能没有真实事件时可以构造,但要标「构造」。 7. **不推翻用户已定的事。** 审核者的建议和已定决定冲突时,摆出来、说清代价,默认保留,问一句要不要改。 8. **编号稳定、双向对照。** 规则用 `后-NN`,给用户看过就不重排,作废的标作废不复用。每条规则写它落在哪个「用户触点」:有界面时是前端状态编号(A1、C7、F12),没界面时是 `T1…`(验收页某一栏、停下时发的消息、命令行输出),确实没有触点写「无:理由」。前端每个状态也都要能找到背后的规则。 9. **先读代码事实,再写规则。** 写到现有实现的地方,在附录标出文件和行号;新建功能写明「无现存代码」,不伪造依据。事实分三种标:现状 / 目标 / 待验证。 ## 先判断:用不用、用多深 | 档 | 什么时候 | 做哪几步 | 产出 | |---|---|---|---| | **完整包** | 还有没定的、用户能感知的规则,**并且**涉及以下任一:跨模块的数据归属、规则互相影响、同步 / 调度、升级迁移、出错降级、多步写文件 | 第 0–6 步全做 | 规则 md + 读者版 HTML(卡片、模拟器)+ 业务题页 + 边界审查留档 | | **只出规则表** | 规则清楚、只有少量互相独立的变化(如「什么时候改写某个文件」) | 第 0、1 步;有新选择题、或有要过目的规则(`proposed`、新增的用户可感知规则)就做第 2 步;边界审查并进开发流程的开工前检查 | 规则 md(`build.py` 不放 cards.json 即可) | | **跳过** | 用户能感知的行为不变的技术修复(拆代码、提速但结果不变) | — | 无;高风险技术问题照常走开发流程的审核 | 判断看「有没有待定的业务规则、规则之间会不会互相影响、出错后果」,**不看代码量**,而且**只看本次改动新增或改变的部分**——功能里早就有的迁移、降级分支不算。拿不准时先按「只出规则表」做,写的过程中发现规则互相牵扯再升档并告诉用户。项目约定「设计相关要先问用户走哪条流程」的,照项目约定。 - **业务都定了、但有高风险的多步写 / 崩溃恢复**:按「只出规则表」,但步骤表和边界审查必做,需要时可以加一个模拟器给自己和审核者用。 - **只出规则表时,题和审查放哪**:新选择题——单独用写一份 `业务题.md`;dev 简版里并进 `1-plan.md` 的「规则」一节(测试清单直接引用 `后-NN`,不把同一件事写两遍);dev 正式版里并进业务确认。边界审查——单独用自己请另一家;dev 流程里随开工前检查一起送审。 ## 确认分工 | 产出 | 用户确认 | 另一家模型校核 | AI 自己定 | |---|---|---|---| | 新的选择题 | **要**:用户选 | 题多、互相影响时查漏问 | 写案例、选项、推荐 | | 已定过且没变的决定(status `inherited`:用户原话或签收过的设计) | 不再问 | 查转述有没有走样 | 整理、写出处 | | 方案里写了、你没拍过板的(status `proposed`) | **要过目**:随读者版或业务确认一起看 | 查有没有藏着改变你能感知的东西 | 标出来源,不当已定 | | 新增的、用户能感知的规则 | **要**:随读者版或业务确认一起看 | 整包一起查 | 起草 | | 技术规则(status `ai`):落实已定语义的保护(原子写、锁、校验、幂等) | 不用 | 高风险、跨模块的查 | **是**,一行通知 | | 技术改动改变了你能感知的东西(默认值、存放位置、留存、花钱、授权、数据删留、多等待、把真的换成假的) | **要**:转成选择题 | 查 | 写案例和推荐 | | 模拟器 | 只看演示结果 | 逻辑复杂时查 | 实现,并用列出的输入 / 预期验证 | | 排版、生成文件、编号格式 | 不用 | 不用(浪费) | **程序检查**(build.py) | | 审核后的实质修改 | 改了行为或范围时要 | **原审核者复核受影响的规则** | 技术修复;错别字不复审 | 不值得花的多模型校核:同一份规则的不同格式各审一遍、让第三家逐条审第二家的意见、每个例子单独审、查编号和空字段。 ## 两种用法 - **单独用**:本 skill 自己出业务题页、自己请另一家模型审,产出放 `<主题>-后端逻辑/` 文件夹。 - **在 dev-workflow 正式版里用**(编排已开任务时):本 skill **只交**规则 md、待问的选择题和要过目的规则、规则 ↔ 前端状态的对照;**不另开**确认和审核——这些并进正式版的「业务确认」由根编排统一问用户,边界审查走正式版已有的审核路线。产出**不放进前端设计定稿包**(插件登记定稿包只认前端那几种文件),单独一个文件夹,由根编排作为需求来源登记。 ## 工作流程 ### 第 0 步:输入齐了再动手 - 有界面的功能:前端定稿先定(没定就先用 page-solution-design)。 - 列出**已定决定**,继承前先看出处:用户原话、或用户签收过的设计包(含其中「AI 补」的条目)→ `inherited`,写出处,不再问;只是计划 / 方案 / 讨论稿里写的、或 AI 上一轮自己定的 → `proposed`,写材料位置,要给用户过目。 - 读代码事实。读不到的标「待查」,并分两种:**影响方案的**(可行性、授权、数据去留、失败时的行为)必须在封装前查清;**只影响实现落点的**可以留给开发,写进交接。 ### 第 1 步:起草规则表(AI 自己做,先不给用户看) - 按七块逐条写(见下表),每条:`后-NN` + 一句规则 + 一个案例(用 → 串到结果)+ 用户触点 + 状态(新选择、新的用户可感知规则 → `pending`;方案里有没拍板 → `proposed`;落实已定语义的技术规则 → `ai`;继承 → `inherited`)。没有规则的块写「不适用」理由。写法见 `references/规则写法.md`。 - **用户触点**:有界面时用前端状态编号,并把前端状态全集写进 `frontStates`;每个状态都要挂到规则上——已有的行为挂到继承的规则,**只有真正纯显示 / 纯布局 / 纯交互的**才写进 `frontOnly`,并写具体理由(不能用「沿用上一版」一句话打发);没界面时先列 3–5 个候选触点(终端输出、验收页某一栏、停下时发的消息、某个文件),**随第一次给用户的材料一起让他认一认**。 - **多步写操作**(搬文件、先写 A 再写 B、先备份再删)必须在规则的 `steps` 里写步骤表:每一步「来自哪一版 / 做之前 / 做之后 / 怎么验 / 断在这里怎么认出来 / 怎么倒回去或接着做」;还要把**恢复路径和每一条例外交叉过一遍**(例如删库时只放回原件的例外,恢复时有没有被继承)。 - **时间类规则**(缓存、刷新、超时、日界)在 `timeline` 里写时间轴;有几个计时器就各写一根,写清谁先到点、到点后怎么办(模板见规则写法)。 - `rules.json` 是编辑源(改规则只改它);规则 md 和读者版都由它生成,md 是冻结后追溯用的,不手改。 | 块 | 回答什么 | 常见要定的事 | |---|---|---| | ① 数据和负责人 | 有几份数据,谁写谁读 | 一份数据一个负责人;对外的是不是「算出来的结果」;能不能手改;凭证和私人路径不外流 | | ② 加载 | 打开时读什么 | 各读各的还是串行;哪份坏了只影响哪一块;一个坏文件 / 慢查询会不会拖垮整体;打开时写不写 | | ③ 保存 | 每个操作写到哪 | 两步写怎么保证一致;失败退回;重复点击、多窗口、多进程;多步写的步骤表 | | ④ 默认值和升级 | 没设过用什么,升级后怎么变 | 默认值一份正本;改过和没改过怎么区分;恢复默认的范围 | | ⑤ 执行 | 核心规则怎么算 | 挑选、排序、计数、上限、不够时、中途变更、计数会不会被换人或升级清零 | | ⑥ 出问题时 | 每种意外下用户看到什么、系统做什么 | 继续还是停下;停下时告诉用户什么;超时后真的停了没有;事后在哪留痕 | | ⑦ 迁移 | 现在的东西怎么过渡 | 哪些删、哪些留;正在跑的旧任务;回退;协议 / 配置 / 文档跟着改哪些 | ### 第 2 步:要用户看的先给他看 - 三样一起给(模板见 `references/业务题模板.md`):**新选择题**(`pending` 里两个结果都合理的,写法照元原则 2)、**过目清单**(`proposed` 和新增的用户可感知规则,每条一句话 + 一个例子,用户回「对 / 不对,改成……」)、无界面时的**候选触点表**。用户答「没听懂」:换一个更贴近他日常的故事,不加长解释。 - 写回:用户认可的规则 status 改 `confirmed`,`source` 写原话和日期,`confirmedText` 抄下他认可的那一版正文;之后正文再改一个字,`build.py` 会要求重新确认。用户说「不对」的,按他的话改完再过目一次。 - 放哪:完整档并进读者版;只出规则表时单独用写 `业务题.md`、dev 简版并进 `1-plan.md`;dev 正式版交根编排并进业务确认页,不另出页面。 ### 第 3 步:读者版(完整档) - `cards.json` 按 4–5 个用户问题分组,每张卡挂它对应的规则编号(`rules`);小例子用 `ok:` / `stop:` / `todo:` 标结果;`python3 scripts/build.py <目录>` 生成 HTML 和 md。还有 `pending` / `proposed` 时加 `--draft`,这些卡片会标红(「待你定」「你没拍过板」)。 - 挑选 / 分配 / 计数 / 时间类逻辑配模拟器,一页可以有多个(每组一个 `sim` 文件),写法见 `references/模拟器写法.md`。 - 生成的 md 里有「卡片对账表」:逐行核对卡片的一句话和它挂的规则说的是不是一回事——**卡片不许比规则说得更满**(例如规则允许断电后短暂不一致,卡片就不能写「永远一致」)。 - 浏览器截图自查;手机宽度不横向滚动。 ### 第 4 步:边界审查(另一家模型,只读) - Claude 写的请 Codex,反之亦然(同一家开多个 subagent 只算多场景,不算多模型)。发给它:已定决定清单(写明不许推翻)、规则 JSON、前端状态清单、代码路径;让它按 `references/边界清单.md` 逐类过一遍,输出 P0 / P1 / P2 + 「要用户拍板的业务题」。 - AI 先对照源码核实,再分三类:**要你定的**(按第 2 步写法问用户)、**AI 补的**(一句话清单,写进规则)、**留给开发时的**(写进交接)。 - **闭环条件**:P0、P1 每条都有处理结论(改了哪条规则 / 为什么不改)和证据;改了规则行为的,**原审核者复核受影响的规则和相邻边界**——相邻边界 = 它 `related` 里的规则、同一个用户触点上的规则、同一条链上前后一步的规则;错别字、排版不复审。技术问题不推给用户裁决。 - `build.py` 通过只说明结构完整(编号、引用、状态、触点、七块),不代表语义对、边界全。 ### 第 5 步:发现前端要改(回流) 后端讨论中发现新状态、新交互或新文案:按 `references/回流模板.md` 列出影响(哪些规则、哪些前端状态 / 流程 / 文案、前后差异、候选文案)→ 交回前端设计修订 → 用户**只需重点看改动的部分**,但插件的签收绑定整份定稿包,所以由前端设计 / 根编排把**整份新版包**重新登记、签收 → 再更新规则(相关规则在签收前保持 `pending`,触点写「候选:W16」这类,只允许出草稿;签收后换成正式状态编号)。dev 正式版里,新版签收之后还要按插件的设计衔接规则重做受影响的需求对齐和业务确认,由根编排推进。**不直接改已签收的前端定稿包。**没有界面变化时不动前端包。 ### 第 6 步:封装 - 封装条件:没有 `pending` / `proposed`(`build.py` 不加 `--draft` 能过);第 4 步闭环;第 5 步的回流已签收;影响方案的「待查」已查清;完整档的卡片对账已核。 - 产出放 `<主题>-后端逻辑/`:`后端规则-<主题>.md`(正本)+ 完整档的 `后端逻辑-<主题>.html` + README。和前端定稿包并列,不放进去。 - 过程件(业务题页、审核原文、旧版本)放 `_review/`。 - 交接说明写清:用户定了哪些(带出处)、审核指出的坑、留给开发的「待查」。 ## 样板与工具 - 样板:`examples/审核配置/`(CodePal 审核调度解耦,2026-10-05/06)——`rules.json` 52 条、`cards.json` 23 张卡、`sim-挑模型.html`;`python3 scripts/build.py examples/审核配置` 生成。样例目录包含规则、卡片、模拟器和生成结果,可在副本中运行生成脚本。 - `scripts/build.py`:结构检查(编号与类型、七块有规则或不适用理由、空字段、案例有结果、状态与出处、正文「要你定」与状态一致、所有引用、触点双向、前端状态反向覆盖、卡片挂规则、模拟器是数据目录里的文件且元素 id 不撞、定稿不许留待定 / 没拍板),全部在内存生成后再一起写盘;出规则 md(含步骤表、时间轴、卡片对账、技术细节)和读者版。没有 cards.json 就只出规则表。 - `references/`:规则写法、边界清单、模拟器写法、回流模板、业务题模板。 ## 用户信号 → 动作 | 用户说 | 含义 | 动作 | |---|---|---| | 没听懂 / 不知道你要干嘛 | 案例不够具体或没有案例 | 换一个他日常会遇到的故事重讲,选项改成「发生什么 / 你看到什么 / 代价」表 | | 读起来累 / 看得费劲 | 按系统结构铺了长表 | 改成按用户问题分组的卡片,技术规则进附录,最绕的做模拟器 | | 这个不对吧(指着模拟器或案例) | 你对他某个决定的理解偏了 | 不辩解,把两种理解做成带例子的选择题让他选,改完同步规则、卡片、模拟器(涉及界面的按第 5 步回流) | | 有没有遗漏的边界 | 要另一家查 | 第 4 步 | | 都没问题 / 确认完了 | 可以封 | 核对第 6 步的封装条件,再封 | ## 交付前自查 - [ ] 档位判断写明了理由;只出规则表时没有多做卡片和模拟器 - [ ] 七块都过了一遍,不适用的写了「不适用」 - [ ] 每条规则有编号、案例、触点、状态;用户定 / 继承 / 没拍板的有出处;构造的例子标了「构造」 - [ ] 继承的每一条都核过出处是用户原话或签收过的设计;只在方案里写的标了 `proposed` - [ ] 技术改动里改变了用户能感知的东西的,都转成了题 - [ ] 多步写操作有步骤表;时间类规则写成了时间轴 - [ ] 新选择题都带时间线案例和推荐;回答已写回并改为 `confirmed` - [ ] 每个前端状态(或触点)都能找到规则;每条规则写了触点 - [ ] `build.py` 不加 `--draft` 能通过;完整档的卡片对账表逐行核过 - [ ] 模拟器按列出的输入 / 预期跑过,结果和规则一致 - [ ] 另一家模型审过;P0 / P1 有结论和证据;实质修改已由原审核者复核 - [ ] 影响方案的「待查」已查清,其余写进交接 - [ ] 不含凭证;本机路径不进对外材料