# two-cooks **Repository Path**: knight7z/two-cooks ## Basic Information - **Project Name**: two-cooks - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-08 - **Last Updated**: 2026-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 双人食记(TwoCooks) 为自己与伴侣记录食谱、互动点菜、辅助下厨和保存共同留念的全栈应用,也兼顾少量情侣试运营。 使用各项功能请看[用户使用指南](doc/用户使用指南.md),包含功能树和操作步骤。 主要页面、API、数据库和说明文档已按双人使用整理:绑定前管理账号与邀请,绑定后共同使用厨房。本机 `two_cooks` 已完成重建及后续增量更新。实际验证范围和剩余部署工作见[交付计划 §0](doc/开发计划/分阶段交付与验收计划.md#0-当前工程进展2026-10-08),尚未获准上线。 | 地址 | 用途 | | --- | --- | | `/` | 正式入口,未登录进入登录页,待绑定进入 `/space/invite`,已绑定进入 `/kitchen` | | `/intro` | 公开产品介绍 | | `/preview` | 使用虚构数据的交互原型,刷新重置,不写业务数据库 | ## 本地运行 ### 先看演示 使用 [.nvmrc](.nvmrc) 指定的 Node 版本;既有验证环境为 Node 24.13.1、npm 11.8.0。兼容范围以 [package.json](package.json) 的 `engines` 为准。 ```powershell npm ci # 首次安装;已有依赖时可跳过 npm run dev -- --host 127.0.0.1 # 启动开发服务 ``` 在实际端口打开 `http://localhost:3000/preview` 或 `/intro`,这两个页面不需要先启动 MySQL。端口占用时可追加 `--port 3001`。`npm ci` 按锁文件重装依赖,安装后的 `nuxt prepare` 会生成 Nuxt 类型。 ### 开发真实业务 1. 已有 `.env` 时保留原配置;首次将 [.env.example](.env.example) 复制为 `.env`,填写已有开发库的 `DATABASE_URL`、强随机 `SESSION_SECRET` 和实际访问来源 `APP_BASE_URL`。 2. 确认 MySQL 结构与当前 schema 一致。本机 `two_cooks` 已按新版迁移重建;其他环境先看[数据库与 Prisma](#数据库与-prisma),不要直接向旧表应用空库迁移。 3. 运行 `npm run prisma:generate` 生成数据库客户端,再启动开发服务。该命令不改表;Windows 若报 Prisma DLL 被占用,先确认占用进程,不强行覆盖。 4. 访问 `/`,检查登录及业务页面。账号操作需要 localhost/127.0.0.1 或 HTTPS,以及支持 Web Locks、允许 localStorage 的浏览器;普通局域网 HTTP 会阻断账号操作。`APP_BASE_URL` 必须与浏览器实际来源一致,包括端口。 开发未配 SMTP 时,验证码和邀请使用明确标识的模拟投递,凭据可在终端查看,勿分享相关输出。密码重置另需邮件队列任务;真实邮件配置见[配置与部署](#配置与部署)。 ### 验证与生产预览 | 命令 | 用途与结果判定 | | --- | --- | | `npm run test` | Vitest 隔离回归,检查失败用例;通过不代表真实 MySQL 和邮件已验收 | | `npm run typecheck` | 检查前后端、测试及脚本的 TypeScript 类型 | | `npm run build` | 生成 `.output/`,检查退出码、错误和告警 | | `npm run start` | 运行最近一次构建;须先确认当前源码构建成功,再检查实际端口 HTTP 与静态资源 | | `npm audit` | 查看当前依赖告警;不要直接运行 `npm audit fix --force` | 代码、配置或依赖修改后至少做类型检查和构建;页面、路由、样式及静态资源修改还需本地 HTTP 检查。安装、启动和数据库操作按当前任务授权执行,以下运维命令须另行确认目标与范围;文档本身不构成运行授权。 ## 工程基线与目录 Nuxt 4 在同一工程中组织 Vue 页面与 Node 服务端,由 Nitro 处理服务端运行。当前使用 Vue 3、TypeScript、Tailwind 3、Pinia、Prisma 5 和 MySQL 8;准确依赖与锁定版本分别见 [package.json](package.json)、[package-lock.json](package-lock.json)。 ### 与 Vue、Spring 项目的对应关系 | 熟悉的职责 | 本项目位置 | 主要差异 | | --- | --- | --- | | Vue 页面与路由 | `app/pages/` | 按文件生成路由;`recipes/[id]/index.vue` 对应 `/recipes/:id` | | 公共页面外框、组件 | `app/layouts/`、`app/components/` | 正式业务使用 `business.vue` 布局,介绍与原型独立 | | 前端业务逻辑、状态 | `app/composables/`、`app/stores/` | `useRecipe` 等组合式函数负责页面业务,Pinia 保存认证与容量状态 | | 前端初始化、导航拦截 | `app/plugins/`、`app/middleware/` | 包含认证初始化和路由守卫,接口权限仍由服务端检查 | | Controller | `server/api/` | 文件路径决定 URL,`.get.ts`、`.post.ts` 等决定 HTTP 方法 | | Service | `server/utils/*-service.ts` | 用普通 TypeScript 函数组织业务和显式传入依赖 | | 数据访问与事务 | Prisma Client、`server/utils/db-transaction.ts` | 用生成的客户端查询,通过事务函数显式划定范围 | | DTO、共用规则 | `shared/types/`、`shared/utils/` | TypeScript 类型在运行时被擦除,接口仍需实际校验输入 | 以读取食谱列表为例,依次看这些文件即可理解一次请求: ```text app/pages/recipes/index.vue → app/composables/useRecipe.ts → app/composables/useApiClient.ts → GET /api/recipes → server/api/recipes/index.get.ts → server/utils/recipe-service.ts → Prisma Client → MySQL ``` 页面可能先在服务端渲染,再由浏览器接管。`window`、localStorage 等浏览器能力放在客户端生命周期或 `import.meta.client` 分支;用户私密状态不能放进跨请求共用的模块变量。请求统一走 `useApiClient`,复用 Cookie 透传、错误处理和写请求安全标头。API 返回 `{ code, msg, data }`,错误同时使用对应 HTTP 状态;服务端逐次检查资源权限。机制见[技术设计 §3](doc/设计文档/技术架构与可靠性设计.md#3-鉴权权限与-api-边界)。 ### 其余目录与文件 设计实验源码保留在 [design-reference](doc/设计文档/design-reference/),仅作开发参考;不参与页面路由、生产构建和公开白名单。用途及兼容字段保留决定见[技术设计 §1.3](doc/设计文档/技术架构与可靠性设计.md#13-目录与类型边界已迁移)。 | 路径 | 用途 | | --- | --- | | `prisma/` | 数据模型、数据库迁移和测试数据初始化程序 | | `public/` | 任何人可访问的图标、静态资源及样式演示 HTML | | `scripts/`、`tests/` | 独立后台脚本、Vitest 测试及隔离夹具 | | `doc/` | 产品、技术、开发计划与数据库说明;按 [PROJECT_INDEX](PROJECT_INDEX.md) 定位 | | `storage/private/`、`backups/` | 默认私密附件根及本地备份,实际数据不提交 Git,不能按缓存删除 | | `node_modules/`、`.nuxt/`、`.output/` | 依赖、Nuxt 生成文件、生产构建产物,可重新生成;`start` 依赖 `.output/` | | `.cache/`、`output/` | 本地缓存与验证产物;历史 `output/` 已清理,隔离测试可能重新生成 | | `.git/`、`.idea/` | 版本库元数据、本地 IDE 设置 | | `nuxt.config.ts`、`tailwind.config.ts`、`tsconfig.json` | Nuxt 运行配置、主题、类型检查范围 | | `docker-compose.yml` | 可选的本地 MySQL 配置,启动前确认端口、卷和已有数据库 | ## 数据库与 Prisma 三个对象分别维护不同事实:`prisma/schema.prisma` 定义模型;Prisma Client 是从模型生成的查询代码;MySQL 保存实际表和数据。改 schema、生成客户端、更新数据库结构是三个不同操作。 2026-10-26 已保留原库名重建本机开发库,并应用[空库初始化迁移](prisma/migrations/20261026000000_couple_business_baseline/migration.sql)。随后确认旧记账表为空,应用[媒体记账清理迁移](prisma/migrations/20261026010000_remove_unused_media_quota_charge/migration.sql),原初始化迁移保持不变。实际结构与 schema 一致,两份迁移校验和正确;增量更新前后逐表核对,原有业务数据保留。 初始化迁移只用于空库,没有旧单人内容转换功能。其他环境应用增量迁移前同样须确认旧表为空,非空则停止核查。`npm run prisma:migrate` 和 `db push` 会改库;`generate` 只生成客户端。重建范围和回退资料见[交付计划](doc/开发计划/分阶段交付与验收计划.md#11-双人使用改造2026-10-26-确认)。 改库前确认目标与授权,备份并暂停网站及后台写入,再核对实际结构和 SQL 前置条件;完成后重查结构、生成客户端并验证业务。MySQL DDL 会隐式提交,部分成功时先停止核对,不忽略错误或整份重跑。其他环境和空库须按当前模型单独制定准备方案。 ### 当前数据表 下表说明当前 28 张业务表,字段定义见 [prisma/schema.prisma](prisma/schema.prisma)。2026-10-26 已与本机 MySQL 核对;另有 Prisma 自动维护的 `_prisma_migrations` 表,共 29 张表。 | 表名 | 作用 | | --- | --- | | `tc_account_action_token` | 保存密码重置凭据的摘要、有效期和使用状态。 | | `tc_active_space_slot` | 保证一个用户同时只能绑定一个双人空间。 | | `tc_auth_email_delivery` | 记录密码重置邮件的发送状态和重试次数。 | | `tc_auth_rate_window` | 记录一段时间内的认证请求次数,限制频繁登录、发码等操作。 | | `tc_background_job` | 记录后台任务的执行状态、进度和重试信息。 | | `tc_cooking_moment` | 保存当前双人空间的一次做饭留念,双方可见。 | | `tc_cooking_record` | 记录当前双人空间中谁掌勺完成了一次做饭,用于厨房统计,不要求先写留念。 | | `tc_couple_member` | 记录双人空间里有哪些成员,以及各自的加入时间和角色。 | | `tc_couple_space` | 保存两个人共同使用的空间信息和状态。 | | `tc_email_challenge` | 保存注册或补验邮箱时所用验证码的摘要、有效期和验证状态。 | | `tc_idempotency_record` | 记录一次提交的处理结果,防止重复点击或网络重试造成重复操作。 | | `tc_ingredient` | 保存每份食谱需要的食材和用量。 | | `tc_media_asset` | 记录上传图片的文件位置、大小、归属和状态。 | | `tc_media_cleanup_task` | 记录待清理的图片文件,方便删除失败或进程中断后继续处理。 | | `tc_media_reference` | 记录图片被哪些食谱、步骤、留念或头像使用。 | | `tc_moment_contribution` | 分别保存双方对一次留念填写的评分、文字和照片。 | | `tc_notification` | 保存用户收到的站内通知及已读状态。 | | `tc_order_dish` | 保存谁向谁点了什么菜、计划时间,以及接单到上桌的处理状态。 | | `tc_quota_reservation` | 上传前暂时预留图片容量,防止同时上传时超过上限。 | | `tc_recipe` | 保存食谱内容、所属双人空间、创建者与版本,双方可见,创建者维护。 | | `tc_recipe_step` | 按顺序保存食谱的制作说明、配图和计时时长。 | | `tc_resource_mutex` | 让同时修改同一资源的操作依次处理,避免互相干扰。 | | `tc_safety_ledger` | 记录食谱删除和图片撤回,防止恢复备份时把这些内容重新恢复出来。 | | `tc_sensitive_audit` | 记录谁做了哪些敏感操作,以及操作结果。 | | `tc_session` | 保存用户的登录会话,供服务端识别身份和撤销登录状态。 | | `tc_space_invite` | 保存伴侣邀请码或邮件邀请,以及接受、过期和撤销状态。 | | `tc_upload_rate_window` | 记录一段时间内的图片上传次数,限制过于频繁的上传。 | | `tc_user` | 保存账号、昵称、密码哈希和账号状态等用户信息。 | ## 配置与部署 当前方向是单台常驻服务器运行网站、MySQL 及独立后台任务,附件持久保存并做异机备份。域名、服务器规格和调度仍待确定,部署结果见交付计划。 与 Tomcat 部署相比,这里使用 Node 运行 `.output/server/index.mjs`,同一构建提供页面、API 和静态资源。需要服务端鉴权与数据库的业务应使用该服务,`npm run generate` 的静态输出不能承载完整业务。 开发时 Nuxt 读取 `.env`;构建后的服务不会自动读取项目 `.env`,生产配置通过进程环境传入。独立脚本读取 `process.env`,也不会自动加载 `.env`,运行前由受控环境或 Node 的 `--env-file` 显式提供。变量示例见 [.env.example](.env.example),网站运行时通过 `runtimeConfig` 读取: | 配置 | 网站运行时 | 独立脚本 | | --- | --- | --- | | MySQL 连接 | `DATABASE_URL` | `DATABASE_URL` | | 强随机密钥 | `NUXT_SESSION_SECRET` | `SESSION_SECRET` | | 会话期限(天) | `NUXT_SESSION_MAX_AGE_DAYS` | `SESSION_MAX_AGE_DAYS` | | 可信访问来源 | `NUXT_AUTH_APP_BASE_URL` | `APP_BASE_URL` | | 邮件 | `NUXT_SMTP_HOST/PORT/USER/PASS/FROM` | `SMTP_HOST/PORT/USER/PASS/FROM` | | 私密附件根 | `NUXT_UPLOAD_DIR` | `UPLOAD_DIR` | | 容量阈值及管理员邮箱 | `NUXT_STORAGE_*` | `STORAGE_*` | | 本地/异机备份根 | `NUXT_STORAGE_BACKUP_DIR`/`NUXT_STORAGE_OFFSITE_DIR` | `BACKUP_DIR`/`BACKUP_OFFSITE_DIR` | `NUXT_APP_BASE_URL` 是路由前缀;公网访问来源使用上表的认证配置,生产必须为 HTTPS。会话采用 HttpOnly Cookie,生产密钥缺失或为示例值时操作失败;SMTP 缺配置也明确失败。只信任登记的代理 IP,避免盲信转发头。 会话期限允许1—365整数天,未配置默认30天;显式无效值使注册/登录返回503。期限由服务端统一解析,并用于数据库会话与Cookie;调整仅影响新签发会话,既有会话仍按已保存的过期时间校验。开发/构建时可用 `SESSION_MAX_AGE_DAYS`,运行已构建网站时用上表的 Nuxt 变量覆盖。 私密根默认 `./storage/private`,网站与脚本必须解析到同一稳定目录,部署建议用绝对路径;不能放入 `public/`。换路径前要迁移实际附件及补偿记录。数据库、附件、备份均使用持久存储;MySQL 凭据、备份密钥及明文临时快照需限权保管。 ## 后台任务 以下脚本均为单次运行,网站启动不会自动调度。真实执行前单独确认数据库、文件备份、配置及运行范围,外部定时调度尚未部署验收。 | 命令 | 前置条件与行为 | | --- | --- | | `npm run email:worker` | `ACCOUNT_EMAIL_WORKER_ENABLED=true`;只处理密码重置队列,失败或延后非零退出;验证码与邀请在请求中投递 | | `npm run media:maintenance` | 先核对结构、历史引用和容量账目;有界处理到期预留、未绑定新图及已登记补偿,保护合法历史引用,不递归清空目录 | | `npm run storage:monitor` | 检查私密根、备份目的地及已登记积压;需真实 SMTP 与管理员邮箱,检查/告警失败非零退出 | | `npm run backup:run -- --dry-run` | `BACKUP_DIR` 与 `BACKUP_ALLOWED_ROOT` 为一致的显式绝对目录,保留期 14—365 天;仅检查,不连接数据库或创建、删除文件 | | `npm run backup:run` | 需显式启用、操作者标识、受控 MySQL 凭据文件、32 字节随机备份密钥及确认的异机目的地;上传根与备份根不得重叠 | | `npm run safety:export` | 显式启用,向独立持久目的地新建加密账本文件,不覆盖旧文件 | | `npm run backup:restore` | 禁止生产;空的 `twocooks_restore_*` 库与同名环境标记、网站离线、空私密根、受控凭据、操作者标识及 5 分钟内的独立最新账本,均须明确确认 | 生产必须显式设置 [.env.example](.env.example) 中的磁盘剩余量、积压数量/时长、备份最长耗时、监控有效期与告警间隔;调度间隔小于监控有效期。正式存储根及备份目的地须已存在可访问;监控过期或容量异常会暂停新增图片并返回 503。监控/维护/备份告警只接受真实 SMTP,成功接收才记发送状态。 完整备份校验附件、清单和异机副本后才生成 `COMPLETE`;轮转至少保留两个完整备份,损坏或不完整目录保留并告警。新版清单包含 `schemaVersion: couple-space-v1`,恢复与轮转拒绝缺少该标记的旧备份;本机旧备份已在第 7 步隔离,不能作为新版业务恢复来源。备份失败须后续完整备份成功且健康检查通过才解除;中断重试前人工确认旧进程已停止,仅单次开启 `BACKUP_RETRY_INTERRUPTED_CONFIRMED`。 恢复先认证解密,撤销旧凭据并重放删除/敏感撤回账本,不能使用陈旧账本或直接恢复到业务库,也不会自动开放网站。参数和实现见 [.env.example](.env.example)、[恢复设计](doc/设计文档/技术架构与可靠性设计.md#91-可证明的恢复)。 ## 测试数据 常规 Vitest 回归使用内存替身、临时文件和回环 HTTP;关键表单与通知补充 Happy DOM 完整模板测试,真实组件脚本、模板事件及 Headless UI 对话框共同执行。桌面和手机浏览器的视觉、布局及触摸操作仍需另验。 真实 MySQL 专项使用独立端口、独立目录和专用空库;不加载 `.env`,不连接现有 `two_cooks`。确认范围后运行: ```powershell ./scripts/run-isolated-mysql.ps1 -MySqlBin '/bin' -ConfirmIsolatedRun ISOLATED_SYNTHETIC_ONLY -Workload Couple ``` 运行器应用项目现有两份迁移 SQL,再调用 [verify-couple-database.ts](scripts/verify-couple-database.ts)。入口要求 `NODE_ENV=test`、本次目录标记、非默认端口、专用库名,并核对服务器实际端口与数据目录及空用户表;任一不符即停止。结束后关闭临时实例并清理数据库、凭据和附件,结果保存在 `doc/history/couple-verify-*/`。不再提供针对默认开发库的执行入口。 ### 隔离容量与备份测量 在确认隔离运行范围及规模后,可使用 [measure-capacity.ps1](scripts/measure-capacity.ps1) 启动独立 MySQL 实例,再由 [measure-capacity.ts](scripts/measure-capacity.ts) 调用实际业务服务。需要可用的 MySQL 8 二进制及至少20 GiB临时空间;不安装或重启现有服务,不加载 `.env`,不复用3306端口或现有数据目录。 ```powershell # 将路径替换为已安装的 MySQL bin 目录;此命令会创建临时实例并写入合成数据。 .\scripts\measure-capacity.ps1 -MySqlBin '\bin' -ConfirmIsolatedRun ISOLATED_SYNTHETIC_ONLY ``` 脚本仅接受本机独立端口、匹配本次运行标记及数据目录的新建空库。两档规模、并发与目标在 TypeScript 脚本中声明;实际备份会导出、加密并校验文件,但副本仍在同机目录,不代表异机网络验证。完成后关闭本次实例,删除其数据库、凭据、附件和备份;只保留 `doc/history/capacity-*/results.json` 中的合成测量记录。结果判定与适用范围见[容量与备份测量报告](doc/history/2026-10-28-容量与备份测量报告.html)。 ### 测试数据初始化与保护 “初始化”是指自动准备一组用于开发体验的账号、食谱、点餐和图片,命令名称仍为 `seed`。这些账号和内容是测试样例,不会给邮箱发送真实邮件。 `npm run seed` 的常规重置会处理六个预置账号:Alice/Bob 和 Charlie/Frank 为两对伴侣,Dana 与 Eve 待绑定。仅允许 `NODE_ENV` 为 `development` 或 `test`,库名匹配 `twocooks_test_` 加小写字母、数字或下划线,且 `SEED_TEST_DATABASE` 同名、`SEED_CONFIRM_RESET=RESET_TEST_SEED_USERS`。发现越界关系、共享资产或无法证明归属的下厨事实时整次拒绝;测试订单及其留念对应的完成事实可在相同范围内重置,检查与清理使用同一事务。常规重置仍禁止在 `two_cooks` 或生产环境执行,不清空全库审计/限流,不删除磁盘图片。 保留原名的本地开发库有单独的空库初始化分支:必须同时设置 `NODE_ENV=development`、`SEED_TEST_DATABASE=two_cooks`、`SEED_LOCAL_DEVELOPMENT_DATABASE=two_cooks`、`SEED_CONFIRM_RESET=INITIALIZE_EMPTY_TWO_COOKS`,连接仅限本机 3306 端口;还会在事务中核对实际库名、已完成的双人初始化迁移和媒体记账清理迁移,并逐表确认所有业务表为空。任何一项不满足都会拒绝,整个分支不执行删除。显式加载环境后运行 `node --env-file=.env --import tsx prisma/seed.ts`;不要把这些一次性标记长期写入 `.env`。当前库已初始化,重复运行会被空库检查阻止。 初始化程序会生成一张可读取的合成食谱封面,按实际文件写入大小、尺寸和 SHA-256,并创建示例已上桌订单对应的下厨完成记录。图片写入 `UPLOAD_DIR` 指定的私密根,默认 `storage/private`;重复初始化时复用相同图片,发现内容不符则拒绝覆盖。所有数据库写入使用同一事务;若事务失败,已生成的合成图片保留供下次复用,不删除磁盘历史文件。 测试账号邮箱以 [prisma/seed.ts](prisma/seed.ts) 的 `SEED_EMAILS` 为准,格式为 `twocooks.seed.<用户名>@qq.com`;用户名和开发密码不变。Dana 已验证邮箱,Eve 保留未验证状态,可先通过验证码补验再接受邀请。使用这些虚构账号时保持本地模拟邮件配置(`SMTP_HOST` 留空,同时不设置 `NUXT_SMTP_HOST`);初始化程序本身不发邮件。自动化测试使用模拟邮件驱动,检查补验、邀请和业务资格。 本机 `two_cooks` 的六个测试邮箱已定点更新,账号 ID、密码、关系和业务内容保留;图片读取、两人统计和空间隔离已重新核对。另在独立临时库验证了空库初始化与重复运行,真实图片和统计正确,环境保护生效。当前 `two_cooks` 非空,不要重新初始化。 `scripts/kitchen-demo.ts` 则只向已绑定的 Vibes/Knight 追加虚构数据,不重置账号。仅限已确认可追加演示数据的本地测试库,要求 `NODE_ENV` 为 `development` 或 `test`、`KITCHEN_DEMO_TEST_DATABASE` 与实际库同名、`KITCHEN_DEMO_CONFIRM=APPEND_VIBES_KNIGHT_ONLY`;显式加载环境后运行 `node --env-file=.env --import tsx scripts/kitchen-demo.ts`。两账号及 ACTIVE 双人关系必须已存在,批次可重复检查,不能代替首次建库。既有追加结果见[交付计划 §0.2](doc/开发计划/分阶段交付与验收计划.md#02-已有验证记录与适用范围)。 ## 验证状态与风险 - **安全审计待整改**:2026-10-28 的 `npm audit` 返回 18 项依赖告警(2 严重、3 高、6 中、7 低,含依赖传播条目),[本轮原始审计](doc/history/quality-step3-20261028/audit.json)已保留。新加入的 Happy DOM 未被报告有漏洞;其余告警尚未逐项完成受影响入口核对和修复。当前 DevTools 关闭不代表依赖问题已解决,本轮未做依赖升级修复,不能据此认定可安全上线。 - **实际环境待验**:本地独立 MySQL 专项已验证,桌面双账号流程记录对应2026-10-26;三步代码改动后的真实浏览器回归、真实邮件、手机/软键盘/读屏器、生产负载、后台自动调度和异机恢复仍待验。恢复时限是待实测目标;PWA 安装和网页锁屏均不保证通知准时送达。 - **记录按范围使用**:最近测试、类型检查和构建结果,以及真实业务的验证范围见[交付计划 §0.2](doc/开发计划/分阶段交付与验收计划.md#02-已有验证记录与适用范围),上线条件见其 [§2](doc/开发计划/分阶段交付与验收计划.md#33-生产准入标准)。 按任务找代码和业务规则用 [PROJECT_INDEX](PROJECT_INDEX.md),追溯变更用[历史索引](doc/history/README.md);协作规则统一见 [AGENTS](AGENTS.md)。