196 KiB
NestJS 后端迁移
2026-10-03 架构整理补记:已补齐 AppConfigService、Nest SQL/资源读取的 Drizzle 注入、领域实现归位、shared 包边界、显式 apiFetch 和 PR 质量检查。此前材料堆叠与九劫内容哈希的两项测试失败已按既有规则提交核对并修正断言,完整 237 文件/2403 测试通过。下文历史阶段结果保持原样;特殊数据、自然续期和生产灰度/回滚验收不因本次构建验证而视为完成。现行结构见 架构审查与规范。
目标与边界
最终由 NestJS 承载全部 HTTP、SSE、原生 WebSocket、调度与消息生命周期,移除 Hono 运行依赖和构建插件。保留 React、共享战斗规则、Zod 契约、Better Auth 会话、Drizzle、Redis CAS、NATS JetStream 及资源/奖励提交语义。
采用按功能划分的模块、构造器注入、单例无请求状态的服务、显式导出与导入。共享引擎与仓储不依赖 Nest。遵循项目测试规范,不引入服务器、数据库或第三方服务 mock 单元测试。
可行性与方案取舍
可行。主要迁移对象是传输层和进程生命周期:原有应用服务、共享战斗引擎、Drizzle仓储与资源提交机制已有独立边界,可以继续复用。Nest的收益在功能模块、依赖注入、统一鉴权与生命周期管理;没有基准数据支持吞吐或延迟会因此改善,也不需要同时拆微服务、替换ORM或重做数据库模型。
- HTTP采用Nest+Express;Controller负责契约、身份和响应,功能Service编排已有应用服务。保留Zod,避免同时维护class-validator DTO及前后端共享Schema。
- Better Auth继续拥有认证原始请求;业务Guard、Pipe、Filter分别处理授权、输入和异常。API方法、路径、JSON结构、Cookie及错误顺序都属于兼容范围,不能只按Controller数量验收。
- POST SSE保留现有事件格式、AbortSignal和业务幂等;原生WebSocket保留既有协议,不改Socket.IO。重点验证掉线、重连、权限撤销、终局及结算,不重写战斗核心。
- Nest生命周期统一拥有调度和消息设施。迁移双入口并存阶段要避免重复启动Cron或消费者;上线仍按已有锁、消息去重、outbox与事务规则运行,不另加一条奖励发放路径。
- 工具链使用pnpm workspace与Turborepo,运行Nest编译产物采用Node 24。开发watch、镜像生产依赖、健康检查和停机信号一起验证。
- 实施顺序为基础设施适配→按功能迁入HTTP→SSE/WS/调度→协议及真实玩法验收→默认入口与构建切换→生产灰度和回滚演练。当前代码已完成入口切换,生产发布仍应以剩余验收收口为前置条件。数据库结构未随框架迁移改变,回滚以固定旧镜像及其匹配的Compose健康检查配置为基础。
当前阶段(2026-10-02)
框架代码迁移与monorepo工具链切换已完成:apps/api(Nest)、apps/web(React/Vite)、packages/shared由pnpm workspace管理,Turborepo编排构建、类型检查与开发任务。API、Docker和watch均运行Nest,旧Hono入口、路由、构建插件和运行依赖已移除,无Hono兼容转发层。44个Module复核无循环模块导入或重复类provider;配置校验、单一Drizzle连接池和退出排空沿用已验收实现。
第五十八批在最终pnpm依赖树下通过lint、类型检查、Nest/Vite构建、冻结安装、Docker构建与production模式本地健康检查,浏览器验证已有登录会话和背包读取。完整共享测试为2401通过/2项迁移前已存在的失败。本次完成的是代码及本地交付,未发布真实生产;下表的特殊数据、自然续期和生产验收仍未完成,不将其记为通过。以下分批记录保留当时命令和状态,现行命令见本地开发。
第五十三批交付审计:当时42个Module、77个Controller共362条展开后的HTTP路由声明,无重复method/path;旧348条路由清单中仅Better Auth通配入口由Nest外层原始请求处理器承载,其余已覆盖。当前lint与完整构建通过,服务端产物与已验收amd64镜像的文件SHA-256一致;两项共享测试失败已在迁移前原提交/原锁文件独立复现。路由覆盖和构建通过不等于全部业务分支或生产发布验收通过。
以下为第五十六批起保留的发布/业务分支验收条件。代码与工具链交付完成不表示这些外部条件已满足。
| 剩余验收 | 当前限制及证据 | 继续所需条件 |
|---|---|---|
| 自然会话续期与响应Cookie | 现有可操作浏览器会话尚未达到updateAge;第五十四批正常访问没有续期。数据库有较老会话,但未读取其令牌来构造登录 | 既有浏览器会话自然达到一天阈值;已知local2最早为2026-10-02 09:41:47 UTC,以实际updatedAt为准 |
| 私有寄售成功与可见性 | local1—local8活跃角色的统一库存均无贵宾符;物品库唯一对应条目已归档,声望/宗门货架均无对应来源 | 已合法持有贵宾符的本地测试角色或正常可用来源 |
| 旧消耗品/灵种取出及旧功法/法宝兑换 | 八个测试账号的活跃角色均无数量大于0的旧消耗品或旧灵种,也无creation_products记录 | 含相应历史存量的本地测试数据 |
| 多人讨伐胜利奖励、蜃楼等境界受限玩法 | 八个现有角色最高筑基中期;当前最低讨伐目标金丹50级,第四十六批实战落败。境界差距不证明所有策略必败,但现有证据不足以验证胜利发奖 | 具备正常完成相应玩法条件的测试角色/队伍;不为覆盖而提高属性或伪造胜利 |
| 目标生产配置、灰度及回滚 | 本地amd64 production模式与双实例检查不等于真实目标环境;第五十三批已询问本轮是否包括生产交付,尚无答复或目标环境信息 | 明确生产交付范围及目标环境;此前不擅自部署 |
其余历史批次未穷举的业务分支仍按各自记录保留,不能因框架迁移而声称整个游戏全部业务测试通过。两项共享测试原有失败也继续单独列明,不修改断言制造全绿。
已实现:
- Express adapter、原生 WsAdapter 与 ESM 服务端构建,显式
@Inject不依赖编译器隐式生成设计类型元数据。 - Better Auth 原始请求处理器独立于框架,保留 ALTCHA 和原认证管理路径屏蔽。注册不再收集昵称;账号
name在创建时按邮箱前缀补齐。 - 默认要求登录的 AccessGuard,可声明 public、active、admin、account-admin;透传会话续期 Cookie。
- Zod Pipe、异常 Filter、请求日志、CORS、Origin 校验、BYOK 校验及现有 Redis IP 限流。
- AsyncLocalStorage保存框架无关的身份和LLM配置,由Nest请求层填充;后台任务无请求上下文时维持服务端路由选择。
- 角色引用与缓存失效从 Hono middleware 抽离;服务层不再反向依赖该 middleware。
- 认证、验证码、账号密码、健康检查、玩家资源快照/事件窗口、每日占卜 Controller。
- POST SSE 传输及取消信号适配;占卜服务继续复用原有发奖和事务逻辑。
/api/realtimeGateway,保留频道、身份作用域、心跳、连接配额、Origin、Cookie 和背压处理。- 现有消息基础设施由Nest生命周期管理;Nest Schedule使用迁出的十项UTC调度定义,保留发布去重键。
- 社交、剧情、任务、邮件、角色名号/属性/状态、修仙日志、反馈,以及游戏壳的战斗活动和宗门身份查询已接入
AppModule。 - 背包、灵兽、功法、宗门战斗养成、训练、野外战斗、突破试炼、宗门任务战斗、自动策略、回放、狩猎队伍、秘境、蜃楼幻境、竞技场、炼器、铭文、悟道、炼丹、丹方、市场、拍卖、灵田、声望商店、黑市、排行榜、社区配置、敌人查询、宗门组织/社交、角色生成/保存/删除、命格生成/重塑、身份重塑、公开天机、赞助、internal cron、闭关/历练、旧产物与功法/法宝迁移已接入。全量静态清单核对及后续socket普通HTTP补齐见第十七、十九批;Better Auth通配入口与原生WebSocket单独处理。代码接入不表示全部方法和异常路径均已运行验收。
- 竞技场房间服务和开战编排通过 Nest factory provider 注入;竞技场 Gateway 接入参战者及观战者两类动态 URL。升级请求由同一个 WsAdapter listener 分派,保留通用实时频道的固定路径,两类 Gateway 共用 BYOK 和 IP 限流检查。竞技场连接在销毁阶段先关闭订阅、等待异步连接与 presence 清理,再进入消息设施/数据库/Redis 的退出流程。
- 业务请求体由
JsonBody的首个Pipe在Guard之后按原始字节读取、解析,之后才执行Zod等校验Pipe。参数工厂保持同步,避免Nest 12将未解析的Promise直接交给校验器(修复见第二十四批)。不按Content-Encoding自动解压,保留原Bun的128MiB读取上限;Webhook独立限制256KiB。每个Controller显式保留原JSON解析失败回退(undefined、null或空对象);Zod仍是输入契约,不引入第二套DTO校验。方法级Filter保留各接口的领域错误、锁冲突及状态码。
第二批接入范围(38 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Social | world-chat/messages、friends 列表/查询/邀请/添加/移除 | 7 |
| Story | 剧情读取、演出完成、教学完成 | 3 |
| Tasks | 列表、详情、挑战、领奖 | 4 |
| 列表、未读数、发送、单封/批量领取、单封/批量已读 | 7 | |
| Cultivator Profile | 转世、旧装配 410、灵气日志、名号、属性预览/分配/重置、兑换码 | 8 |
| Cultivator Condition | 使用消耗品、灵泉恢复、肉身突破预览/执行、洗髓破限 | 5 |
| Player Journal / Feedback | 修仙日志、反馈提交 | 2 |
| Combat / Sects | combat-v6/activity、sects/current/context | 2 |
第三批接入范围(52 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Inventory / Beasts | 背包读取与操作、灵兽列表/融合/领取/阵容/休息/加点/改名/放生 | 11 |
| Training / Wild | 训练、野外探索和战斗会话、指令、结算、自动与放弃 | 18 |
| Replays / Auto Strategy | 历史、私有回放、分享创建与公共回放、自动策略 | 7 |
| Breakthrough / Sect Tasks | 突破试炼和宗门任务战斗 | 10 |
| Manuals / Sect Combat | 个人功法、宗门构筑/流派/养成 | 6 |
第四批接入范围(37 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Hunts | 活动列表、大厅、奖励读取、建队、入队、队伍指令 | 6 |
| Dungeon | 开始/状态/推进/恢复/退出、历史/次数、搜刮、战斗会话及旧接口 410 | 19 |
| Tower | 状态/开始/推进/排行榜、战斗会话及旧接口 410 | 12 |
第四批继续调用既有领域服务,保留秘境资源事务、狩猎队伍 Redis CAS 和蜃楼结算路径。各入口分别保留原有错误响应,不统一改写秘境恢复、战斗指令与旧接口状态码。狩猎保留 private, no-store;蜃楼旧战斗通配入口排在现有会话入口之后。
第五批接入范围(13 个 HTTP 方法及 2 类 WebSocket 路径):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Arena Rooms | 当前房间、房间详情、建房、入房、准备、保活、换队、开战、离房 | 9 |
| Arena Battles | 参战视图、观战视图、指令提交、战局回放 | 4 |
| Arena Gateway | /api/combat-v6/arena/:battleId/socket、/:battleId/watch/socket |
单独统计 |
第六批接入范围(18 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Forging | 炼器读取/铸造、宝库分页/单项取出/本页取出 | 5 |
| Enlightenment / Inscriptions | 悟道与阵纹读取/提交 | 4 |
| Alchemy Formulas | 材料、丹方分页、删除、推演、发现确认 | 5 |
| Craft | 炼丹预览/执行,以及 pending/confirm 旧接口 410 | 4 |
本批仍复用既有领域服务和应用命令,不改炼制规则或数据库模型。Controller 保留各自错误结构;炼器、悟道、铭文保留 no-store。炼丹旧制作类型在参数校验前返回 410,丹方推演在领域分析前核对材料版本,正式制作继续走角色锁、灵气预留、事务与资源提交。
第七批接入范围(20 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Market | 货架、购买、回收 | 3 |
| Auction | 货单、物品/灵兽上架、购买、下架 | 5 |
| Reputation Shop | 货架、兑换 | 2 |
| Spirit Field | 读取、初始种子、播种、培育、收获 | 5 |
| Black Market | 读取、入场、流式交互、成交、离开 | 5 |
本批保留原有资源事务、灵气预留、拍卖锁及黑市入场/成交幂等路径。流式交互在准备完成后发送 SSE 头,准备阶段和流式阶段均监听连接关闭。灵田培育/收获继续向原应用服务传递取消信号。
第八批接入范围(11 个 Controller 方法,对应 13 个 HTTP 方法/路径):
| 模块 | 对应入口 | HTTP 路径数 |
|---|---|---|
| Rankings | 三类公开榜单、个人排名、查探、待恢复挑战、V6挑战、三个旧挑战410入口 | 10 |
| Community | QQ群配置、登录页公告 | 2 |
| Enemies | 登录用户所属活跃角色查询 | 1 |
公开榜单和社区配置不要求登录;个人排名、查探和挑战要求活跃角色,敌人查询保留账号及活跃状态谓词。排行榜继续使用既有 Redis 排名和 V6 幂等挑战服务;丹药、财富和敌人查询的 SQL 与展示映射从旧路由原样迁入功能服务。具名查询参数保留重复参数首值语义;不更换 Zod 契约、共享战斗规则或结算路径。
第九批接入范围(新增21个 Controller 方法,对应33组 HTTP 方法/路径):
| 模块 | 对应入口 | 新增方法/路径数 |
|---|---|---|
| Sect Organization | 设施、俸禄、晋升、任务、候选提交物、商店、建设、成员、转宗与入宗 | 16 |
| Sect Social | 聊天读取/发送、累积贡献榜 | 3 |
| Retired Sect Progression | 七条旧养成路径,各自保留POST和PUT的410响应 | 14 |
包含已有身份查询在内,两个旧宗门router的34组方法/路径全部接入。组织命令保留 Idempotency-Key 与 source:method:path:canonicalPayload 的SHA-256指纹、角色锁、事务和资源提交。查询继续按角色或宗门读取资源作用域。宗门聊天保留冷却、成员查询和独立错误契约;旧战报分享拦截Pipe抽至HTTP公共目录供世界聊天与宗门聊天复用。新增 FirstQuery 参数装饰器在本批查询对象校验前保留重复参数首值;其他已迁入口的查询兼容仍需收口。
第十批接入范围(18 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Genesis | 角色生成配额/生成、命格生成、角色保存 | 4 |
| Cultivator Lifecycle | 删除、转世上下文 | 2 |
| Fate Reshape | 会话读取/开启、重抽、确认、放弃 | 5 |
| Identity Reshape | 会话读取/开启/草稿、生成、确认、放弃 | 6 |
| Divine Fortune | 公开天机读取/生成缓存 | 1 |
保持原有JSON接口;这些角色生成和重塑服务原本未接入请求取消,本批不引入新的SSE或取消语义。角色生成保留规范化字符计数、邮箱/IP额度和Redis临时数据;保存/删除保留已有角色应用命令和缓存失效。重塑保留符箓消耗、会话恢复及资源提交。命格确认在路由局部处理JSON解码错误,身份草稿/生成则保留原有全局错误处理边界。公开天机保留24小时缓存和降级内容。
第十一批接入范围(18 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Sponsorship | Webhook、公开配置/名录、个人功德/公开设置、下单意图创建/查询、认领 | 8 |
| Internal Cron | 过期拍卖、排名奖励、市场刷新、两类清理、材料生成、赞助普通/深度对账、赞助清理/摘要 | 10 |
赞助复用原有签名验证、订单事务、资源履约和脱敏读模型。Webhook在读取请求体阶段限制256 KiB;实际旧应用将超限异常映射成500,本批保留该响应。赞助的中间件输入校验也按旧应用实测的500处理,通过ZodPipe的显式legacy-unhandled契约与领域错误区分。Cron使用独立Guard,保留生产缺少密钥500、配置密钥时不匹配401、非生产缺省放行;入口仍调用原有带锁作业,不新增调度或重复消费者。
第十二批接入范围(2 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Cultivator | POST retreat、yield | 2 |
闭关与历练继续调用原应用命令,保留锁、事务、请求编号幂等及资源事件。命令结算后才发送SSE结果、状态与叙事;连接在准备阶段断开不会取消已经执行的结算,之后不再开始叙事。流式阶段将断开信号传给LLM,闭关叙事仍在finally中执行原历史持久化回调。闭关保留独立路由错误处理,历练保留旧全局错误契约;非法JSON均按旧validateJson回退为undefined后校验。
第十三批接入范围(11 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Legacy Products | 类型分页、单件读取、旧装配/删除退役入口 | 4 |
| Artifact Migration | 可用性、列表、兑换 | 3 |
| Manual Migration | 可用性、列表、兑换、管理员统计 | 4 |
旧路由目录内的两份兑换服务迁至apps/api/src/lib/services/legacy,仅替换身份类型import,两套入口复用同一业务实现。保留来源归属、只读事务隔离级别、兑换行锁与资源提交;旧装配/删除继续410。LegacyItemsModule的迁移路径middleware在Guard之前设置no-store,参数解析继续复用共享Zod契约及undefined回退;迁移路由保留独立错误处理。
第十四批接入范围(14 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Account Administration | 列表、改邮箱、封禁、解封、撤销会话 | 5 |
| Admin Settings / Monitoring | 管理员会话、公告与QQ群读写、LLM指标、在线人数 | 7 |
| Admin Feedback | 反馈列表与状态更新 | 2 |
账号管理继续要求ADMIN_USER_IDS,普通管理入口允许原有ID/邮箱管理员。Better Auth响应分别追加每条Set-Cookie,保留邮箱前置条件、审计、撤销会话及部分成功错误。反馈仍按原有状态更新、奖励与邮件顺序执行;本批不改变该业务流程。设置继续使用safeParse及flatten错误,账号输入校验保留旧全局500契约。
第十五批接入范围(11 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Admin Reputation / Sect Shop | 两类商店列表、创建、更新、归档 | 8 |
| Admin Reward Items | 奖励物品生成 | 1 |
| Admin Tower | 周配置查询、带指纹重生成 | 2 |
四类Controller与服务注册到AdminModule,继续使用admin Guard。商店调用原有服务并保留局部400、领域状态码及缺失商品404,查询保留重复参数首值。奖励生成复用原有共享生成器与RewardItemSchema,保持随机种子/UUID生成方式;返回草稿不发放物品。蜃楼查询仍从同一快照生成指纹和展示,只有成功读取设置no-store;重生成继续走原仓储的事务行锁与expectedFingerprint比较,不改战斗配置生成规则。
第十六批接入范围(29 个 HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Admin System Mails | 列表、详情、草稿创建/更新、发布、停止 | 6 |
| Admin Item Library | 列表/详情、材料与灵种生成、每日设置、创建/更新/归档、旧预览退役 | 10 |
| Admin Redeem Codes | 列表、创建、启停 | 3 |
| Admin Sponsorship | 配置读写、连接检查、订单读写、快照查看、手动发放 | 10 |
继续使用admin Guard,JSON局部null回退与safeParse错误保持原样。系统邮件复用共享契约并保留创建指纹、草稿revision条件、发布事务行锁和停止投递锁语义;不额外引入邮件发送路径。材料库仅开放material,旧产物创建/预览保持410。兑换码保留奖励快照、自动码重试和手动码格式检查;赞助继续委托原应用服务并保留领域error/code/status,手动发放成功仍201。路由里的局部catch迁成HttpException时,保留原直接返回的404/400边界。
第十七批接入范围(8 个 Controller HTTP 方法):
| 模块 | 对应入口 | 方法数 |
|---|---|---|
| Dev Tools | 物资发放、角色调整、背包清空、占卜重置 | 4 |
| Legacy Inventory | 旧背包分页、丢弃、鉴定退役 | 3 |
| Legacy Battle Records | 旧战绩根路径和子路径统一410 | 1 |
DevToolsModule仅在allowsLocalDevTools(APP_ENV, NODE_ENV)为true时导入,并保留请求期环境检查与no-store。角色调整先校验ID再解码JSON,避免非法ID加畸形JSON从原400变成500。旧背包保持原仓储/丢弃应用服务及资源元数据;不把仍有运行逻辑的入口误改成退役。旧战绩入口公开返回原410及LEGACY_BATTLE_HISTORY_RETIRED,不恢复历史战斗实现。
开发启动:bun run dev:api(或组合命令bun run dev)。该命令先类型检查并构建,再由Vite监听源码重建、Node.js监听产物并用SIGTERM停止旧进程后重启,加载本地环境。编译产物apps/api/dist/main.js需要node_modules;原临时build:nest/dev:api:nest命令已合并到默认入口。旧框架对照记录保留在下文,源码历史可从Git读取。
验收清单
- 迁入后台管理、开发工具及全量清单发现的旧背包/战绩遗漏入口;仅表示代码接入,成功写入和异常/并发路径仍按下述记录逐项验收。
- 修正已复现的请求体大小/自动解压/读取顺序、查询1,000项截断以及WS失败握手JSON/响应头偏差,见第二十二批。
- 对齐异常查询编码、具名参数的编码别名优先级和查询对象首值语义,见第二十七批。
- 恢复旧整段路由鉴权覆盖的未知子路径,并核对兜底优先级和相关缓存头,见第二十八批。
- 完成会话续期Cookie及其余响应头核对;不把已测样本等同于所有HTTP输入完全兼容。
- 对齐已识别的旧Hono全局异常行为:未被局部处理器捕获的Zod/JSON错误保留500,局部400/409继续保留,真实协议对照见第十八批。
- 四类SSE入口均完成代表性断开/恢复及重试检查:占卜、历练、闭关(普通修炼与成功突破)、黑市,见第二十四、二十六、二十八、三十四、三十五批;寿元耗尽等特殊业务分支未运行,不代表穷举所有时序。
- 核对原41个模块、构造器注入、Provider归属及四项模块导出;第二十八批增加第42个末位兜底模块,仅含两个Controller,没有新增Provider或导出。共享纯函数与应用服务不导入Nest。
- 验证密码认证POST、ALTCHA开关/校验/并发防重放、账号权限隔离与撤销会话Cookie透传,见第二十四、二十五批。
- 当前55个后台Controller方法完成普通已登录非管理员403检查,包括旧功法迁移管理入口和account-admin,见第四十九批;不替代管理员成功写入或任意未知路径覆盖。
- 系统邮件后台草稿完成管理员创建/更新/读取、创建指纹冲突、旧版本及并发更新冲突验证,见第五十一批;未发布或投递邮件,其他后台写入仍未全部验收。
- 宗门清扫任务完成页面承接、开局、正常清扫、领奖及刷新恢复;四阶段请求重放、缺少幂等键与指纹冲突未重复发奖,见第五十批。不替代其他任务及并发/过期分支。
- 自动战斗策略完成合法保存/读回/重置,错误流派、技能、资源、状态及客户端角色ID拒绝,见第五十四批;不替代实际战斗中策略执行验证。
- 经本地Mailpit完成OTP邮件、错误验证码拒绝、首次注册登录及重放拒绝,见第二十九批。
- 两账号并发调用实际LLM,确认BYOK模型/凭据选择及成功/兜底结果分别归属原请求,见第二十九批。
- 完成密码注册、未验证邮箱登录拒绝、Mailpit验证链接与验证后的密码登录,见第三十三批。
- 补齐会话到期续期;不把OTP注册或新会话登录当作续期分支通过。
- 通用WebSocket完成拒绝连接、同账号配额释放/重连及断线期间资源事件补读,见第十九、二十二、二十五批。
- 两个本地Nest实例并存时,资源事件跨进程送达且按账号隔离;旧实例退出后,新实例继续处理读写并接受重连,见第五十二批。不替代实际OpenResty切流、活跃战斗或生产灰度验证。
- 两个本地Nest实例并发移动同一版本物品时,仅一次提交成功;锁竞争429保留Retry-After,旧版本重试409且无额外变更,见第五十五批。
- 完成实际擂台参战/观战连接、观战重连、权限撤销、终局资源与回放权限检查,见第二十六批。
- 完成待完成握手停机验证及通用实时频道慢消费者背压运行验收,见第三十批;不推广为所有频道和负载组合均已覆盖。
- 完成活跃HTTP排空、30秒连接关闭、启动信号串行清理及开发watch验收,见第二十批。
- 完成占卜实际生成中SSE的停机排空与重启后奖励幂等,见第二十六批。
- 完成占卜客户端先断开再停机的结算、重启读取及重试幂等,见第二十八批。
- 完成本地NATS重启后持久消费者处理已结算事件及原有WebSocket实时订阅恢复,见第三十二批;仅证明所验消费者/频道与同一Nest进程的恢复。
- 完成历练生成中SSE断开、事务relay发布中停机、重启后新奖励消息结算及同编号重试,见第三十四批。
- 完成正常成功突破生成中SSE断开/停机、部分叙事持久化及重试幂等,见第三十四批。
- 完成黑市流式回复与准备阶段断开/停机恢复,见第三十五批;事务relay活跃发布排空及新历练奖励恢复见第三十四批。
- 新历练奖励消息在消费者数据库事务中断后完成重投、结算与同请求重试核对,见第三十七批;不推广为所有消费者及中断时序均已覆盖。
- 完成默认入口切换、Docker生产依赖、本地容器运行与停机验证、版本/提交镜像标签和回滚操作文档;未部署生产或运行CI推送,见第二十一批。
- 重建包含第二十七、二十八批兼容性修复的本地arm64镜像,并在该镜像执行协议及停机检查,见第三十一批;生产模式、amd64与实际灰度仍不在此次运行范围。
- 移除旧入口、路由、中间件、Hono依赖和构建插件,更新当前项目技能与启动文档;历史验证记录保留原始阶段描述。
- 炼器完成真实页面成功提交、已提交响应丢失后的页面重试、刷新持久化、版本冲突及幂等指纹冲突,见第三十八批。
- 随心炼丹与丹方炼丹完成真实页面成功提交、资源/材料/产物持久化及同请求重试;随心炼丹另验证旧材料版本与幂等指纹冲突,见第三十九批。丹方发现确认尚未覆盖。
- 随心炼丹自然发现新丹方后,完成本人页面保存、刷新持久化、跨账号拒绝及重复确认不新增,见第四十八批;不推广为并发保存或过期时序均已覆盖。
- 公开拍卖完成页面上架、跨账号API部分/全部购买、购买与买方邮件领取重试、越权领取拒绝、卖方页面领取成交款,见第四十批;私有货单与灵兽交易未覆盖,也不记为双账号浏览器全流程通过。
- 灵兽拍卖完成双账号独立浏览器上架/购买/邮件领取、个体归属转移和重试验证;私有寄售缺符返回400且持久状态不变,见第四十三批。私有货单成功上架及可见性仍未覆盖。
- 旧宝库材料完成单项/批量取出、背包满后的储藏室溢出、数量冲突/重复项的整批回滚及越权拒绝,见第四十四批;旧消耗品/灵种成功取出尚无本批运行证据。
- 黑市完成页面按价成交、库存交付、持久journal防重复扣款/发货及刷新恢复;重试仍递增Redis会话版本并追加提示的既有行为单独记录,见第四十五批。
- 灵田完成真实页面播种、三阶段自然生长/培育、跨进程恢复及收获入包;五个原请求重试和版本/指纹/阶段冲突未产生重复变更,见第四十一批。
- 当前源码构建linux/amd64镜像,并完成本地production模式鉴权、开发接口关闭、Cron密钥分支与正常停机检查,见第四十二批;不替代目标服务器及真实生产配置验收。
- 双人讨伐完成页面组队/准备/开战、落败终局、持久气血法力结算、无奖励及回放权限核对,见第四十六批;多人胜利奖励发放仍未覆盖。
- 全量浏览器玩法回归,包括多人战终局、奖励幂等和回放权限。
第一阶段验证记录
bun run lint:通过。bun run build:旧前后端入口构建通过,保留现有前端分包警告。bun run build:nest:类型检查与 ESM 构建通过;prompt 的?raw导入可正常构建。- 本地 Nest 启动:NATS topology、消费者与 Redis 正常;
/api/health-check返回 200 和 up 状态。 - HTTP 检查:未登录占卜返回 401,非法验证码场景返回 400,认证管理路径返回 404,非法写入 Origin 返回 403,不完整 BYOK 返回 400。
- 本地浏览器现有 local2 会话:会话读取、玩家资源快照和占卜记录读取正常;捕获到游戏 WebSocket 的 ready 与 ping 事件。
- Node.js 24.18.0 编译产物 SIGTERM:消息基础设施、数据库、Redis 完成清理,进程退出。Bun 1.3.14 直接运行 Nest 源码时 SIGTERM 后进程未退出,尚未定位根因,因此 Nest 启动命令采用 Node。
bun run test:237 个文件中 235 通过;2403 项中 2401 通过。失败为材料堆叠测试预期[99, 2]、实际[101],以及宗门技能内容哈希基线不匹配。两个文件定向复跑同样失败。packages/shared/src与 Vitest 配置未改,lockfile 中原有依赖版本未变;未为框架迁移修改领域断言。
占卜页面已显示记录,但本轮页面点击未产生可验证的 POST SSE 请求,不能将流式发奖记作通过。生产环境、外部 LLM/OAuth/赞助和完整游戏流程尚未验证。没有执行数据迁移或部署。
第二批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src、git diff --check均通过。前端构建保留既有分包警告。- 本地运行 Node Nest 编译产物,原 Hono API 未同时启动;使用现有 local2 浏览器会话,数据仅来自本地环境。
- 邮件页载入 20 封邮件、11 封未读;好友名录显示已有的本地道友1。观察到邮件分页、好友列表、剧情、宗门身份、战斗活动接口均返回 200。
- 角色名号从空值改为「迁移验收」,POST
/api/cultivator/title返回 200,响应包含success/data/state,HUD 与角色页更新。随后通过相同页面恢复为空名号,返回 200,页面重新显示「暂无名号」。 - 属性分配界面暂选体魄 +1,POST
/api/cultivator/attributes/preview返回 200;随后取消,保留原有 75 点待分配属性与六维各 65。未执行实际加点、重置、转世、消耗或发奖。 - 任务页与修仙日志页显示已有本地记录;肉身修炼页显示铁骨与五轨数据。部分页面复用资源快照,因此不能据此将所有独立 Controller 方法都记为运行验证通过。
- 未登录邮件 GET 返回 401;未登录名号 POST 即使携带畸形 JSON 也先返回 401,确认鉴权先于参数解析。
- 浏览器与 API 日志仍观察到未迁移的赞助、背包、宗门聊天和战绩入口 404。这些属于剩余迁移范围,不代表游戏已可完整运行。
- 邮件发送/领奖、任务挑战/领奖、剧情完成、消耗品/突破、兑换码、反馈写入,以及已登录状态下各种 JSON 回退尚未逐项运行验收。
- 未新增前端/后端单元测试;共享领域逻辑没有改动,本批不重复运行全量共享测试,第一阶段的两个已知失败仍待独立处理。
- 本轮启动的 Nest 与 Vite 进程已停止,临时浏览器页已关闭。Nest 收到 SIGTERM 后记录消息设施、数据库和 Redis 清理完成并退出;未将这次空闲退出当作活跃 HTTP/SSE 排空验收。
第三批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src、git diff --check通过。静态 AST 对照七个原路由文件的 53 个入口(含已有 activity),未发现缺失。- 本地 local2 背包显示 21/40 格;主动刷新背包接口返回 200。灵兽页读取返回 200,展示已有三只灵兽,未执行灵兽写入。
- 实际创建训练会话,为人物和灵兽提交防御指令,结算后进入第 2 回合;创建、提交与结算均返回 200。刷新恢复相同回合和战报,随后通过页面确认放弃,DELETE 返回 200,页面恢复为「开始训练」。该临时训练已经结束。
- 返回游戏后气血为 955/955、法力 850/850,训练中的 1 点伤害没有持久化;灵石 35977、天地灵气 240/240。
- 未登录训练查询返回 401;非法公开分享链接返回 404 和「分享链接无效」。尚未逐项验证回放归属与分享、融合/放生、野外结算、突破及宗门任务战斗。
第四批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src、git diff --check通过;旧前端构建仍有既有分包警告。静态 AST 比较狩猎、秘境、蜃楼三个原 router 的 37 个方法/路径,全部在 Nest 中有对应入口。通配符按两个框架的语法归一后比较。- 新 Nest 产物成功启动,NATS 消费者、Redis 正常;未并行启动 Hono API。
- 本地 local2 页面:秘境状态返回 200;历史分页返回 200,展示 8 条历史,能打开黄枫谷藏经阁地窖的已有详情。此操作未新建秘境、消耗资源或结算奖励。
- 蜃楼页面正确显示金丹境界门槛,金丹排行榜查询返回 200。只读查询确认现有 local1—local8 角色均低于金丹;本批未修改角色境界,未将排行榜读取记作蜃楼战斗通过。
- 地图狩猎活动列表与金身尸王大厅返回 200。通过页面创建临时单人队伍,POST
/api/hunts/teams返回 200;点击准备后显示「已准备」,刷新仍恢复该队伍和准备状态。 - 随后通过「离开队伍」发送队伍指令,POST 返回 200;大厅恢复「还没有队伍」,临时队伍已退出。未开始讨伐、未执行奖励领取。该队伍 ID 为
43109ee1-5f9e-47be-8257-a1a4b62e1212。 - 未登录请求
/api/hunts、/api/dungeon/state、/api/tower/battle/legacy均返回 401,旧接口退役入口也保留鉴权。 - 秘境完整推进/恢复/战斗结算、蜃楼挑战、多人狩猎与奖励幂等、所有错误分支及已登录旧接口 410 尚待后续验收;竞技场 HTTP/动态 WebSocket 仍未迁入。
- 本批未修改共享领域逻辑,不重复运行全量共享测试,保留第一阶段两个已知失败记录。未新增服务器/前端单元测试或一次性验收脚本,未执行数据库迁移或部署。
- 临时浏览器页、Nest 和 Vite 已关闭。Nest 在 SIGTERM 后记录消息设施、数据库和 Redis 清理完成并退出;本次同样没有验证活跃 HTTP/SSE 请求排空。本地 Docker 基础设施保持运行。
第五批验证记录(2026-10-01)
- 修正新增参数的 lint 未使用提示和握手 IP 返回类型后,
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src、git diff --check通过。完整前端构建保留既有分包警告。 - 静态 AST 对照两个旧竞技场 router 的 13 个普通 HTTP 方法/路径,全部找到 Nest 对应入口。动态 WebSocket 另外运行验收。
- 使用
127.0.0.1:5174的既有 local2 会话和localhost:5174的既有 local1 会话,两者均为已配置的本地 Origin;未重新注册、修改认证配置或角色数据。 - local2 建房返回 201,local1 凭邀请码加入;双方准备后,页面实时显示两人已准备。开战返回 200,双方进入同一战斗
40a66919-396e-4616-8724-a120e6975641;房间为arena-ebde7315-eeaf-4591-91d7-e5e0412aff20。 - 参战者动态 socket 握手返回 101,并收到
ready、state、ping、resync;同时通用/api/realtime?channels=player-state握手为 101,两个 Gateway 可共用同一 HTTP 服务。 - 第一回合 local2 人物逃跑、灵兽防御,local1 防御;指令提交返回 200,逃跑失败,双方进入第 2 回合。第二回合 local1 逃跑成功,战斗正常结束,local2 显示胜利。
- 刷新 local2 战斗页恢复相同第 2 回合终局与战报;归档接口
/api/combat-v6/replays/:id返回 200,页面可跳转第二回合并推进到 6/6 行动及最终胜利。真实本地战绩保留,未删除归档。 - 双方返回擂台后均显示建房/入房入口,没有遗留候场房间。local2 气血 955/955、法力 850/850、灵石 35977、灵气 240/240;local1 气血 1241/1241、法力 830/830、修为 620/2500、感悟 49/200,页面显示与战前一致。
- local2 未加入观战席时,观战 HTTP 返回 403,页面显示「请先凭邀请码进入房间观战席」。无 Cookie 的参战者和观战者 WebSocket 升级请求均返回 401。
- 停机前重新确认已结束战局的 socket 仍握手 101 并收取心跳;SIGTERM 后观察到战斗 socket 与通用 realtime socket 关闭,消息设施、数据库和 Redis 清理完成,进程退出。该项只覆盖已连接且战局已终结的场景,不代表活跃结算、HTTP/SSE 请求排空已完成验收。
- 尚待验证:有权限观战者的广播/权限撤销、四连接配额及释放、慢消费者、握手中断、活跃回合断线恢复、重复指令、待开战 202 和失败重试。此次没有修改共享引擎,不重跑全量共享单元测试,第一阶段的两个已知失败继续单独记录。
- 临时浏览器页及 Nest/Vite 测试进程已关闭,Docker 基础设施保持运行。默认 Hono 入口与生产镜像未切换,未部署。
第六批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、本批文件的bunx prettier --check、git diff --check通过。全量构建后再次构建 Nest,恢复被默认构建清理的 Nest 产物;保留既有前端分包警告。- 通过 TypeScript AST 对照五个旧 router 的注册方法与新 Controller:5 + 2 + 2 + 5 + 4 = 18,方法/路径没有遗漏或新增。该核对不等于所有请求分支完成验收。
- 本地 Node Nest 与 Vite 使用现有 local2 会话。丹方列表 GET 200,账号暂无丹方;炼器读取 GET 200,现有背包没有图纸;悟道页面读取并选择聚灵书,显示 25% 成功率、1 灵气及1感悟的前端预览,未执行参悟。
- 炼丹预览 GET 200。先投入青纹藤叶1份,再以青纹藤叶和紫蕴灵参各1份尝试,两次 POST 均调用了现有 LLM 和应用命令,最终返回领域错误400「本炉药蕴不足,无法凝成丹药。」。代码定位到
alchemyServiceV2.ts原有产量检查,在材料和灵石扣除前抛错,事务中灵气预留一并回滚;没有修改该规则以获得成功验收。刷新后灵石35977、灵气240/240、青纹藤叶3份、紫蕴灵参1份均保持原值。成功炼丹和丹方发现仍未验证。 - 铭文实际绘制成功:青溪磨石、青溪铁砂、青溪兽骨、青溪灵玉各投入1份,产出「定神阵纹」1件;灵石35977→35970,灵气240→239,四种材料数量分别3→2、2→1、4→3、5→4。刷新后资源保持一致,合成物品栏可见新阵纹,读取接口200。保留本次真实本地玩法产物和消耗;没有通过数据库修改恢复它们。截图:
/tmp/daoyou-nest-verification/inscriptions-created.png。 - 未登录炼器GET返回401;未登录炼丹POST携带畸形JSON也返回401,确认这些请求在JSON解码前经过鉴权。
- 尚待验证:炼器成功/版本冲突、宝库取出、悟道提交、铭文合成与烙印、炼丹成功/重复提交/材料版本冲突、丹方推演与发现确认。没有为验证删除已有丹方,也未准备或修改测试账号数据。
- 本批未修改共享引擎,不重跑全量共享单元测试,第一阶段的两项失败仍作为已知基线记录。默认入口和生产镜像未切换,未部署。
- 本轮临时浏览器页、Nest 和 Vite 进程已关闭。Nest 收到 SIGTERM 后完成消息设施、数据库和 Redis 清理并退出;Docker 基础设施保持运行。
第七批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、本批文件bunx prettier --check、git diff --check通过。静态 AST 核对五个 router 的 20 个方法/路径,无遗漏或新增。- 本地 local2 在市场购买露凝草1份,POST 与刷新 GET 均200;灵石35970→35916,背包增加该药材。截图:
/tmp/daoyou-nest-verification/market-purchased.png。 - 灵田初始种子领取 POST200,刷新可见青木藤籽3份、赤炎火核2份;初始领取按钮消失,六块田仍为空。没有播种、培育或收获。
- 将上批产出的定神阵纹1件以100灵石公开上架,POST200;随后下架 DELETE200,货单消失。仅领取对应「拍卖行物品返还」邮件,刷新背包确认阵纹返还,背包25/40,灵石35916。货单 ID 为
1bf77a38-aa7a-44da-ba36-40a7572725fc,没有遗留活跃测试货单。截图:/tmp/daoyou-nest-verification/auction-returned.png。 - local2 黑市读取按境界门槛403。local1筑基角色首次免费入场,两次尝试均遇到原有 black-market-observations LLM 输出 Zod 校验失败;接口200返回 retryable,第二次
entry.replayed和state.replayed为true、费用0,验证凭证重放不重复扣费。未生成可交互会话,未验证 SSE 成功、成交及离开。保留凭证,不改提示词或领域校验来获得通过结果。 - local1声望商店页面读取正常,声望65、商品0件;没有兑换。未登录拍卖读取401;未登录黑市入场携带畸形JSON仍401。
- 尚待验证:市场回收/库存冲突、拍卖购买/私有可见性/部分成交/灵兽交易、声望兑换、灵田播种/培育/收获、黑市成功交互/断开取消/成交幂等。真实本地购买、种子、阵纹与费用均保留,没有数据库回写恢复。
- 未修改共享引擎,不重复运行全量共享测试,第一阶段两项已知失败保留。没有执行数据迁移或部署。临时浏览器页及 Nest/Vite 进程已关闭;Nest SIGTERM 完成消息设施、数据库和Redis清理并退出。Docker基础设施保持运行;本次不代表活跃请求排空验收。
第八批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、本批文件bunx prettier --check、git diff --check通过。AST 对照三个旧 router 与新 Controller,排行榜10、社区2、敌人1个方法/路径均匹配。当前全部 Controller 共198个方法;数组路径展开后201条注册,不含 Better Auth middleware 与原生 WebSocket。- 本地匿名 HTTP:健康检查200;公告和QQ群配置200;炼气榜200;财富榜200共10人;丹药榜200共1件。重复
realm及type参数按首值处理;旧装备榜410,非法类型400。未登录个人排名和敌人读取401;未登录查探、V6挑战、旧挑战入口即使携带畸形JSON仍401。 - 现有 local2 浏览器会话:炼气榜初始3人,个人未留名、次数30/30;查探本地道友5返回200并显示V6面板;财富榜和丹药榜切换正常,各自请求200。待恢复挑战与个人排名读取200。
- 实际挑战林归尘成功,POST
/api/rankings/challenge-battle/v6200,回放读取200。请求与战局 ID 均为c09a02c9-2482-4cfb-806f-d49ccbef435d,结果 victory,local2排名3、对手排名4,剩余挑战29次。 - 刷新相同挑战页面后恢复回放;返回榜单排名3、次数29/30。再次通过浏览器返回相同挑战链接,捕获POST200及响应体:同一战局、同一结果和29次,未重复扣次数。保留真实本地排名和战绩,不回写数据库撤销。返回榜单气血955/955、法力850/850、灵石35916、灵气240/240、声望65。截图:
/tmp/daoyou-nest-verification/rankings-challenge.png。 - 敌人查询已静态核对
id + userId + active查询条件和原有灵根映射,并验证匿名401。浏览器直接导航本地API地址被客户端阻止,未完成已登录成功/跨账号404运行验证;未尝试绕过该限制。 - 尚待验证:排行榜已登录非法JSON/参数、查探不存在角色、旧挑战410、越境切磋、空榜直接入榜、并发挑战/失败恢复/次数耗尽、社区配置读取失败503和敌人归属边界。已验证的单请求重放不代表所有并发故障路径均通过。
- 本批没有修改共享引擎,不重复全量共享测试;第一阶段两项已知失败保留。没有新增服务端/前端测试或验收脚本,没有数据库迁移或部署;默认Hono入口和生产镜像尚未切换。
- 临时浏览器页及本轮 Nest/Vite 进程已关闭。Nest SIGTERM 记录消息设施、数据库和Redis清理完成并退出;Docker基础设施保持运行。空闲退出不代表活跃请求排空验收。
第九批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、本批文件bunx prettier --check、git diff --check通过;保留现有前端分包警告。首次静态核对命令误用了Bun stdin选项,只显示帮助;改用Node后实际执行AST核对:组织31组、社交3组方法/路径均匹配,没有缺失或额外入口。- 本地Node Nest与Vite复用local2会话。宗门大殿周俸读取200,显示可领1,575灵石;领取POST200,灵石35,916→37,491,刷新后显示「本周周俸已经入账」,余额保持37,491。保留本次真实本地领取与状态。截图:
/tmp/daoyou-nest-verification/sect-stipend.png。 - 领取后HUD余额立即更新,但对话仍暂留领取按钮;刷新后才消失。本批没有改变前端或原有资源提交响应,记录此界面现象,尚未对照旧服务运行来归因;不能将其当作重复领取或幂等冲突验收。
- 同门名录GET200,显示本地道友2与本地道友7两名幽都弟子;贡献榜GET200,local2累积贡献5、排名1,另一成员贡献0;日常任务GET200,显示清扫山门、巡视矿场和灵矿采掘,未接受新任务。
- 宗门总览设施GET200,舆图正常加载;宝库页面显示「须晋升外门弟子后开放」,未触发购买。角色仍为记名弟子,贡献5、灵石37,491;没有改动成员境界或身份准备验收数据。
- 匿名任务/成员/聊天查询401,非法分页也先鉴权;匿名周俸领取、任务动作和退役POST/PUT携带畸形JSON均401。
- 尚待运行验证:组织命令同键重放/异载荷冲突、缺失幂等头、重复周俸、晋升、入宗/转宗、捐献、商店购买、任务接受/提交/领奖、候选材料、分页边界、已登录退役410,以及聊天发送冷却/跨宗门隔离。没有发送测试聊天消息。静态对齐和一次周俸成功不代表上述分支均通过。
- 本批没有修改共享引擎,不重复全量共享测试;第一阶段两项已知失败保留。未新增服务端/前端单元测试或验收脚本,未执行数据库迁移或部署。默认Hono入口与生产镜像尚未切换。
- 临时浏览器页及本轮Nest/Vite进程已关闭。Nest SIGTERM记录消息设施、数据库和Redis清理完成并退出;Docker基础设施保持运行。此次不覆盖活跃HTTP/SSE排空。
第十批验证记录(2026-10-01)
bun run lint通过;首次全量构建暴露新增Genesis服务的IP类型写为string | null,已按现有getRequestIp修正为string | undefined。重跑bun run build及随后bun run build:nest通过,保留现有前端分包警告。本批文件bunx prettier --check与git diff --check通过。- TypeScript AST对照七个旧router与新Controller:2+1+1+2+5+6+1=18,方法/路径均匹配。全体Controller实际计数237;此计数不表示所有分支完成运行验收。
- 只读查询本地数据库确认local1—local8均邮箱已验证、各有一个活跃角色;测试域内没有无活跃角色的账号。现有本地账号背包没有天机逆命符/改天换地符。首次查询误写Better Auth邮箱验证列名,查阅schema后用
emailVerified正确重查;未执行任何数据库写入或准备临时角色。 - local2的命格重塑页面正常展示未开启、天机逆命符0张;身份重塑页面正常展示改天换地符0张,开启按钮均禁用。未消耗符箓、修改命格/身份或删除现有角色;此检查只证明状态页面可用。
- 匿名配额、角色生成、命格生成、角色保存、角色删除、转世上下文及重塑请求均401;POST/PATCH携带畸形JSON也先返回401。
- 公开
/api/divine-fortune首次GET200,返回生成内容;再次GET200且cached:true,验证生成和缓存读取。未验证上游失败降级与缓存损坏恢复。 - 尚待验证:已登录生成输入边界/限额、角色生成→命格生成→保存完整流程、命格重抽限额、临时数据过期、已有角色保存冲突、删除成功/跨账号权限、转世上下文,以及两种重塑的开启/草稿/生成/确认/放弃与并发恢复。没有通过删除既有角色、修改账号或造符箓来消除验收前置条件。
- 本批未改共享引擎,不重复全量共享测试;第一阶段两项已知失败保留。没有新增服务端/前端测试或验收脚本,未迁移数据库或部署;默认Hono入口及生产镜像尚未切换。
- 本轮临时浏览器页及Nest/Vite进程已关闭。Nest SIGTERM记录消息设施、数据库和Redis清理完成并退出;Docker基础设施保持运行。本次不覆盖活跃生成请求或SSE排空。
第十一批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest通过;增加显式旧校验契约后再次运行lint及Nest构建通过。本批bunx prettier --check和git diff --check通过。AST核对赞助8、Cron10个方法/路径,无遗漏或额外入口。- 按Hono技能尝试
bun --env-file=env/local.env x hono request --help,当前hono包没有可运行CLI。改用一次性终端调用现有app.request()核对真实本地路由,未创建测试文件或mock。Webhook超限实际返回500及{success:false,error:'服务器内部错误'};公开名录page=0的Zod错误同样返回500。该证据推翻了仅按中间件源码推断400的假设,早先迁移入口的同类错误仍需全面核对,不能宣称协议已全部等价。 - 本轮Nest进程临时设置本地测试CRON_SECRET,未更改env文件。10个Cron入口无密钥均401,错误密钥401;正确测试密钥调用赞助对账200,
processed:0, skipped:true, reason:sponsorship_provider_disabled。日志只显示本次对账作业执行;没有触发清理、排行榜发奖、材料生成或摘要邮件。 - 公开赞助配置200、
provider:null, enabled:false;公开名录200且为空,重复page参数按首值处理。非法page=0返回与Hono一致的500。匿名个人功德、意图查询、公开设置、下单及认领均401,写请求即使携带畸形JSON也先鉴权。 - 无效Webhook JSON与空对象均400、
{ec:400,em:'invalid webhook'};262144字节请求仍进入原处理器并返回无效Webhook400,262145字节请求由大小限制拒绝并返回旧契约500。使用Content-Length与Transfer-Encoding:chunked分别验证边界,结果一致,没有写入有效订单。 - local2浏览器功德簿可查看我的功德、天下功德及续添功德页签;个人尚未留名、公开榜为空,赞助未开放且购买按钮禁用。没有改变公开设置、创建下单意图、认领订单或打开外部支付页。
- 尚待验证:真实签名Webhook及重放/履约幂等、意图归属与支付跳转、认领/公开设置写入、生产缺失密钥与非生产无密钥的运行分支、Cron锁竞争/作业失败/各清理和通知任务。上述生产与外部服务行为不能由禁用提供方的跳过响应证明。
- 未改共享引擎,不重复全量共享测试;第一阶段两个已知失败保留。没有新增后端/前端单元测试或验收脚本,未迁移数据库或部署,默认Hono入口与生产镜像未切换。
- 第十一批临时浏览器页及Nest/Vite进程已关闭;随后核对赞助验收日志,确认Nest记录消息设施、数据库和Redis清理完成。Docker基础设施保持运行。
第十二批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src/cultivator及git diff --check通过。前端构建仍有既有分包警告。核对旧路由挂载与新Controller路径,均为POST/api/cultivator/retreat、/api/cultivator/yield;当前Controller HTTP方法总数257。- 本地Node Nest使用既有local2会话。一年闭关POST返回200、text/event-stream,结果及资源状态各一个事件;修为2426→2428,天地灵气240→236,剩余寿元2081→2080年,灵石保持37491。闭关编号
d2f42d6f-7713-4c6b-9e32-9e202e90dcb2。截图:/tmp/daoyou-nest-verification/retreat-success.png。 - 洞府领取约18.37小时历练收益,POST返回200、text/event-stream,收到result、state及26个chunk,无error事件,LLM叙事成功完成。灵石37491→41141,修为2428→2566,感悟70→88;提示另有6件奖励经邮件投递,未在本轮领取或核验全部邮件附件。历练编号
678a537d-382a-4a38-9778-100296563342。截图:/tmp/daoyou-nest-verification/yield-success.png。 - 通过浏览器临时CDP Fetch拦截,将页面发起的POST替换为上述已完成请求的编号,向真实本地服务重放;历练重放同时将目标改为已观察到的yield路径。两者均200、state.replayed=true;历练重放只含result/state,不再次生成叙事。刷新确认灵石41141、修为2566、感悟88、天地灵气236、剩余寿元2080年,无重复扣费或发奖。这是协议重放验收,不能等同于两个页面的自然重试流程或并发竞争验收。
- 匿名两入口携带非法JSON均401。已登录用相同临时拦截提交畸形JSON:Nest闭关400、
{error:'闭关突破参数无效'};历练500、{success:false,error:'服务器内部错误'}。停止Nest后顺序启动原Hono,在同一浏览器会话对照相同输入,两种状态码和响应体完全一致。未修改鉴权、数据库或响应来获得通过;所有请求拦截已清除。 - 本地真实闭关成本、历练奖励及历史记录保留。尚待验证:突破/寿元耗尽叙事及历史回调、流式中途断开、准备阶段断开、灵气不足、请求编号冲突、锁竞争与活跃请求停机。本轮不覆盖这些边界。
- 本批未改共享领域逻辑,不重复全量共享测试;第一阶段两项已知失败保留。未新增服务器/前端测试或一次性验收脚本,未迁移数据库或部署,默认入口与生产镜像尚未切换。
- 临时浏览器页、Nest、对照Hono及Vite进程已停止;Nest记录shutdown complete,Hono正常退出。Docker基础设施保持运行,空闲退出不代表活跃请求排空验收。
第十三批验证记录(2026-10-01)
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src/legacy-items apps/api/src/app.module.ts及git diff --check通过,前端既有分包警告保留。使用实际Hono路由清单与TypeScript AST抽取Nest Controller,11个method/path完全一致;当前HTTP方法总数268。- 对两份迁出的服务与HEAD原文件作逐字比较,除
ActiveCultivatorRef从hono/types改为auth/types之外,业务实现相同。没有修改兑换规则、SQL、锁、事务及资源提交逻辑,旧路由仅更新import。 - 只读查询本地测试域活跃角色,现有角色均无creation_products来源。local2的旧功法、旧法宝页面正常显示空列表,读取200且Cache-Control为no-store;两类availability均200、available=false。本轮没有创建历史物品或执行成功兑换。
- 11个入口匿名访问均401;包括畸形JSON的兑换请求,以及已经退役的装配/删除入口。local2已配置管理员,管理员功法统计读取200、stats与owners为空;已通过本地身份配置函数核实其权限,没有调整管理员配置。本轮未覆盖普通已登录用户403。
- 使用临时浏览器CDP Fetch拦截,将刷新请求定向到真实本地接口,验证两类兑换畸形JSON均400、兑换参数无效;有效结构但不存在来源的兑换均409,携带对应来源已兑换/不存在/不属于你的提示。所有拦截在请求后清除,未伪造服务器响应。旧产物非法type返回400,缺失UUID详情404,旧装配/删除410。
- 重复type、page与pageSize按首值处理:
type=gongfa&type=invalid&page=2&page=bad&pageSize=5&pageSize=bad得到200、items为空、page=2、pageSize=5。没有为分页迁移引入更严格的新校验。 - 停止Nest后顺序启动旧Hono,使用同一浏览器会话对照上述8项错误/退役分支及重复参数查询,状态码、错误文案及分页结果一致;响应均no-store。两套API未同时运行。鉴权前的body限制、未知子路径、大小写/尾斜杠仍属于整体协议收口范围。
- 待验证:有来源时的完整兑换、自选奖励、背包转仓库、跨角色来源、重复/并发兑换、战斗占用、事务失败回滚及非管理员403。本轮资源与历史物品未发生兑换变更,天地灵气自然恢复至237;不将缺失来源409当作成功兑换或全部归属边界通过。
- 本批未改共享领域逻辑,不重复全量共享单元测试,第一阶段两项已知失败仍单独记录。未新增服务器/前端测试或一次性验收脚本,未迁移数据库或部署,默认入口与生产镜像未切换。
- 临时浏览器页、Nest、对照Hono和Vite均已关闭;Nest记录shutdown complete,Hono正常退出。Docker基础设施保持运行。本次仍不覆盖活跃HTTP/SSE排空。
第十四批验证记录(2026-10-01)
- 本批14个入口已并入AdminModule;与第十五批合计25组method/path通过TypeScript AST对照旧路由声明,无缺失或额外入口。当前总计293个Controller HTTP方法;数量不代表全部验收通过。
- 本地local2会话可进入后台;公告、QQ群、反馈列表、LLM指标和在线人数请求返回200。公告为空,QQ群使用内建默认值,反馈列表为空。账号管理全部5个入口返回403,即使提交畸形JSON仍先拒绝权限;没有变更管理员配置来获取账号管理权限。
- 25个管理入口均完成真实本地匿名请求检查,全部401,写入口携带畸形JSON仍401。此项证明这些输入下的鉴权顺序,不涵盖超限请求体或所有未知路径。
- 浏览器临时CDP Fetch拦截将刷新请求改为真实本地协议检查:公告/QQ群畸形JSON400,反馈缺失状态400,有效状态但不存在反馈404。随后停止Nest,顺序启动Hono,QQ群错误、两类反馈错误及账号管理5项403,共8项状态码与响应体一致。所有拦截清除并重载页面恢复正常请求。
- 未执行账号改绑、封禁、解封、撤销会话;现有测试会话无account-admin权限。未保存公告/QQ群、改变反馈状态、发放反馈奖励或发送通知。普通已登录非管理员403、授权账号管理成功路径和会话Cookie变更仍待验证。
第十五批验证记录(2026-10-01)
bun run lint、bun run build、随后bun run build:nest通过;bunx prettier --check apps/api/src/admin与git diff --check通过。保留原有前端分包警告。构建日志为/tmp/daoyou-nest-admin-catalog-build.log与/tmp/daoyou-nest-admin-catalog-nest-build.log。- 本地Node Nest配合现有local2会话,声望商店展示3件已下架商品,宗门宝库展示2件已下架商品;蜃楼展示2026-W40、本周第一层金丹阵容。读取成功,未改变现有商品与周配置。
- 通过真实页面“新增商品→选择道具→符箓→生成并预览”调用奖励生成,POST200,得到归元洗髓符箓的consumable.v1草稿,详情正常展示。随后关闭预览、取消新增商品;未保存或发放。截图:
/tmp/daoyou-nest-verification/admin-reward-preview.png。 - 两类商店非法status与无效创建/更新体400;不存在UUID的归档404,有效商品结构但不存在UUID的更新404。重复status按首值archived返回200;蜃楼重复floor按首值1返回200。
- 奖励生成空对象、蜃楼floor=0与空重生成体均500,保留旧Hono实际全局异常契约。历史周重生成400;当前周以确认不匹配的指纹请求重生成409。仓储在指纹比较失败后直接返回,未生成或写入新配置。
- 停止Nest后顺序启动Hono,用同一浏览器会话比较12项错误/重复参数/缺失更新/指纹冲突响应及符箓生成成功响应,状态码和响应体一致;两套消费者未并行。临时拦截仅修改请求,不伪造响应;协议探测造成承载页面的临时错误提示已通过清除拦截和重载恢复,不作为自然UI流程覆盖。
- 尚未运行:商店创建/修改/归档成功路径、蜃楼实际重生成及并发竞争、道装/丹药/灵果生成成功与领域错误分支、普通用户403。没有改共享引擎,不重复全量共享测试;第一阶段两项已知失败保留。
- 未新增服务端/前端测试或验收脚本,未迁移数据库或部署。默认Hono入口、镜像、剩余后台与开发工具入口以及全局协议/生命周期收口仍待完成。
- 本轮临时浏览器页、Nest/Hono/Vite进程均已关闭,3001与5174无监听;Docker基础设施保持运行。Nest日志确认消息设施、数据库及Redis清理完成,本次为空闲退出,不替代活跃请求排空验收。
第十六批验证记录(2026-10-01)
- TypeScript AST逐文件核对系统邮件6、材料库10、兑换码3、赞助10组method/path,无缺失或额外入口。首次完整构建发现系统邮件参数input与解构字段重名,修正为request后
bun run build通过;bun run lint、bun run build:nest通过。源码复查修正赞助领域错误的动态status转译,确保抛出HttpException,未把错误body作为200/201返回。 - 29个入口匿名真实请求均401,写入口携带畸形JSON仍401。沿用本地local2会话,系统邮件列表显示4条已停用记录,首条详情200;材料库和每日生成设置读取正常(enabled=true、count=20),兑换码显示2条已停用记录,赞助订单为空。
- 实际页面创建并更新归档材料
nest-migration-20261001-material,数据库行ID为05051677-6ab0-4d58-839c-5bcd9a205927,两次请求均200。材料名称“Nest迁移验收草”,更新后描述标注本地验收;从创建起即archived,未上架、发放或进入角色背包。重新打开编辑器确认最终状态与描述,截图/tmp/daoyou-nest-verification/admin-material-archived.png。归档样本保留供后续迁移验收。 - 临时浏览器请求拦截向实际本地服务检查36项错误/缺失记录/重复查询分支:系统邮件非法query/ID/body500,缺失详情与发布404、缺失更新/停止409;材料非法输入400、旧接口410、缺失详情/更新/归档404;非法兑换码400与缺失启停404;赞助无效配置400、非法查询400、缺失订单/快照/手动发放角色404,并保留领域code。四类列表重复参数按首值读取200。
- 停止Nest后顺序运行旧Hono,同会话重放上述36项,状态码及响应体36/36一致。该验证为协议检查,不等于自然UI中的全部异常或并发流程。旧helper曾捕获已关闭标签页,未发起请求;重建为显式传递当前tab/CDP后完成全部检查。拦截已清除并重载页面。
- 未发布/停止实际邮件,未创建兑换码或改变既有启停状态,未保存赞助设置、调用外部连接检查、处理真实订单、查看真实敏感快照或发放赞助。材料批量生成、定时设置写入、归档专用端点成功路径以及普通用户403待验证。没有新增单元测试或验收脚本,没有运行数据库迁移或部署。
第十七批与全量路由清单核对(2026-10-01)
- 从实际本地Hono app.routes提取HTTP入口,过滤中间件并保留认证与退役ALL路由,得到348组method/path。首次AST展开遇到宗门retiredPaths常量,补充常量数组解析后重跑成功;未将失败提取当成通过。
- 全量对照发现旧背包3个入口及旧战绩退役入口遗漏,已补入LegacyItemsModule。最终Nest有330个Controller方法,展开数组与根路径后346组method/path;与Hono清单相差的4组是由configureHttp处理的认证通配入口和3条原生WS路径,已核对对应处理器/Gateway/动态路径分派。Nest显式多出的旧战绩根路径和蜃楼battle根路径对应旧通配语义。这是静态覆盖证据,不证明全部行为或WebSocket普通HTTP访问响应等价。
- 开发工具4个入口保留纯本地环境限制。使用同一env/local.env与127.0.0.1数据库/Redis/NATS,在本地进程临时将APP_ENV设为staging、NODE_ENV仍development以验证禁用分支;没有加载env/staging.env或访问真实预发布环境。四个入口全部404且不附开发工具no-store,启动日志没有DevTools注册;未以production启动避免开启本地定时作业,production限制本轮仅源码核对。
- 原Hono与Nest顺序运行,对照16项匿名/开发工具协议(JSON错误顺序、非法ID、缺失角色、未知dev路径、旧战绩410、旧背包401),状态码、body与Cache-Control全部一致。所有开发工具修改/删除请求使用非法或不存在的角色ID,没有改变角色、清空背包或重置占卜。
- 同一local2会话另外对照11项旧背包协议:三类分页200、重复type首值、无效类型/材料筛选/排序400、畸形或空丢弃请求500、历史法宝丢弃410、鉴定410,响应体与状态码全部一致。未实际丢弃材料/消耗品。
- 最终
bun run lint、bun run build、随后bun run build:nest通过;本批相关目录Prettier与git diff --check通过。日志/tmp/daoyou-nest-route-closure-build.log、/tmp/daoyou-nest-route-closure-nest-build.log;路由清单产物/tmp/daoyou-hono-route-inventory.json、/tmp/daoyou-nest-route-inventory.json。 - 共享规则未改,不重复全量共享测试;第一阶段两项已知失败保留。静态入口补齐后,剩余工作转为早期接口协议偏差、认证/权限/请求隔离、SSE与WS故障恢复、活跃请求排空、开发watch、部署产物和默认入口切换;Hono仍未移除,不能标记迁移完成。
- 本轮临时浏览器页及Nest/Hono/Vite进程已关闭,3001、5174无监听;最后一个Nest进程日志确认消息设施、数据库与Redis完成清理,Docker基础设施保持运行。
第十八批:输入与路由匹配协议收口(2026-10-01)
- 扩展
FirstQuery支持命名参数,将24个早期Controller中的Express@Query替换为首值读取。覆盖分页、筛选、资源查询、战斗事件游标等;没有修改Better Auth的请求解析。Express简单查询解析器的参数数量上限及异常编码尚未对照。 - 以实际旧服务响应纠正早期错误映射:未被局部处理器捕获的Zod/JSON/未知异常统一保留500、
{success:false,error:'服务器内部错误'},不向客户端暴露异常message或开发详情。野外探索、灵兽融合/改名、宗门中间件校验、自动指令等在局部catch之外的校验改用显式legacy-unhandled;移除无调用方的default校验契约。局部业务catch中的400/409和领域code继续由对应Filter保留。 - 修复Express默认忽略路径大小写及尾斜杠的问题。首次在
configureHttp设置未生效,真实对照仍返回200;源码确认ExpressAdapter构造时已经安装中间件并创建Router,遂改为在构造适配器之前配置Express实例。最终公开正常路径、大小写变体、尾斜杠、未知路径和API根路径等9项状态码、Location及响应体与旧Hono一致。非API重定向继续302、空响应体。 - 使用同一local2浏览器会话、顺序启动Hono与Nest,完成60项参数/异常协议对照:59项状态码与JSON完全一致;任务列表剩余一项仅3个目标的
updatedAt随真实读取刷新,状态码、业务数据和资源信息一致。覆盖非法与畸形输入、重复参数、领域400及通用500。最终适配器修复后的构建又抽查10项,全部与旧基线一致。匿名5项受保护接口返回401,畸形JSON仍先拒绝未登录身份。 - 协议请求由页面刷新按钮触发,临时CDP Fetch只改请求目标、方法和输入,不伪造响应;每次清除拦截,最后重载恢复正常页面。这不替代自然游戏流程、并发竞争或成功写入验收。本轮未发送聊天/邮件/反馈,未执行领取、购买、开战或角色配置修改。
- 11项路径探测中有2项已确认未解决:普通HTTP GET访问
/api/realtime和擂台socket路径,Nest当前404,旧Hono匿名401;第三条观战socket的普通HTTP语义也需一并处理。不要将原生Gateway存在视为普通HTTP访问协议已兼容。未知受保护子路径的中间件顺序、请求体大小/编码、响应头、认证续期、请求隔离及长连接故障恢复仍需继续收口。 bun run lint、bun run build、随后bun run build:nest均通过;bunx prettier --check apps/api/src与git diff --check通过,保留前端既有分包警告。日志为/tmp/daoyou-nest-input-{lint,build,nest-build}.log;对照产物为/tmp/daoyou-nest-input-audit-comparison.json和/tmp/daoyou-nest-path-audit-results.json。未修改共享规则,不重复全量共享测试,第一阶段两个既有失败保留。- 默认入口、Docker、开发watch和Hono移除尚未完成。本批没有部署或数据库迁移,不能标记全面迁移完成。
- 本轮临时标签页和自启动Hono/Nest/Vite进程已关闭,3001与5174无监听;Nest日志确认shutdown complete。Docker基础设施保留,仍未以空闲退出代替活跃请求排空验收。
第十九批:WebSocket地址的HTTP访问与连接名额(2026-10-01)
- 增加通用实时HTTP Controller/Guard,以及擂台参与者、观战socket的HTTP回退,共补齐3条已有地址的普通HTTP行为。通用连接保留Origin→登录→配额顺序;擂台保留活跃角色→Origin→UUID→参与/观战资格顺序。真正的升级仍由原生Gateway处理,不经HTTP Controller。
- 通用实时服务提取可共用的身份/配额预留,升级入口继续执行独立的API admission;HTTP入口已通过Express的BYOK/限流,不重复执行。Guard逐条透传Set-Cookie及其他认证响应头,并在finally释放普通HTTP请求的临时名额,不创建订阅、在线记录或WS pending项。
- Hono与Nest顺序运行,同一local2会话完成5项已登录路径对照及3项非法Origin对照,状态码与响应体8/8一致:通用已登录普通GET404,擂台非法UUID400、缺失战斗404;非法Origin保留通用
{success:false,error}与擂台{error}两种403结构。另12项匿名/Origin/非法BYOK组合全部一致,证明已验证输入下的校验顺序。 - 实际复现旧Hono的失败升级名额泄漏:一次普通GET404之后追加4次请求,结果404、429、429、429。源码中事件工厂在确认升级成功前删除pending reservation,失败升级无法释放名额。Nest回退连续6次均404;这是明确修复的旧缺陷,不宣称其泄漏行为也已等价迁移。旧Hono源文件未修改,重启后进程内残留名额清除。
- 使用独立本地探测IP发起两次匿名普通HTTP请求,均401,限流remaining从9999到9998,每请求只计一次。只验证正常请求计数,不覆盖全局限流上限、失败Redis和所有握手响应头。
- 真实游戏页面确认通用WS握手101并收到ready,包含local2角色、player-state/world-chat频道及account/cultivator/sect资源scope。增加同账号页面触发连接限制429;关闭一条已连接的测试页面后,失败页面自动重连101并再次收到ready。该实验验证限额触发与名额释放/自动重连,不证明IP40条边界、心跳超时、背压、资源事件漏读恢复或擂台实战/观战恢复。
bun run lint、bun run build、bun run build:nest、bunx prettier --check apps/api/src/realtime apps/api/src/arena及git diff --check通过;前端既有分包警告保留。构建日志为/tmp/daoyou-nest-socket-{lint,build,nest-build}.log,协议记录为/tmp/daoyou-nest-socket-http-{anonymous,authenticated}.json,脱敏连接事件为/tmp/daoyou-nest-socket-live-results.json。- 未发送消息、创建擂台、开战、扣费、领奖或修改角色配置;临时请求拦截均清除。共享引擎未改,不重复全量共享测试,原两个已知失败保留;没有新增测试/验收脚本。后续仍需处理未知受保护路径、原生握手失败响应头/body、认证续期与隔离、长连接恢复及活跃请求停机,再切换默认启动/部署并移除Hono。
- 本轮3个临时标签页及Hono/Nest/Vite进程均已关闭,3001与5174无监听,Nest记录shutdown complete;Docker基础设施保持运行。这次清理仍不替代活跃HTTP/SSE排空验收。
第二十批:生命周期与开发 watch(2026-10-01)
- 调整退出顺序:先停止并等待定时发布,排空HTTP与处理器,再停止消息设施、关闭数据库/Redis。控制器与Better Auth的异步处理均登记在请求工作集合,客户端断开后仍等待处理器结束;30秒关闭剩余HTTP连接,60秒全局退出期限避免无限挂起。消息设施启动等待各消费者启动结果后统一处理失败;停机等待事务relay的恢复/发布以及战斗outbox发布。没有修改战斗规则、事务提交或奖励幂等语义。
- Nest 12 HTTP应用的
init()未设置基础应用上下文停机所等待的initializationPromise。启动期间先记录SIGTERM/SIGINT及退出期限,显式等待初始化,收到信号时跳过监听并清理;正常监听成功后切换至Nest停机钩子。真实本地进程在路由注册期间分别收到两种信号,均在初始化完成后才清理,最终退出143/130。普通启动健康检查Redis/NATS/messaging均up,随后SIGTERM正常清理。 - 本地故意连接不存在的NATS端口,启动失败并清理、退出1;另以非法PORT=-1令全部消费者启动后监听失败,同样清理并退出1。最初构建发现
app.close()公共类型不接受signal参数,已修正并重新构建;失败构建后对旧产物的检查不计入新实现验收。最终新产物重跑上述两种失败路径均通过。消费者部分并行启动失败只作代码检查,未人为破坏本地消息拓扑。 - 真实HTTP请求使用Expect:100-continue和分段JSON上传。SIGTERM后新连接拒绝,既有请求在约1028ms收到剩余请求体并返回401,之后才停止消息设施。另一次始终不结束上传,约30008ms被关闭,随后正常清理。它们验证传输排空和期限,不代表真实业务SSE取消、结算或断线重试已通过。
dev:api:nest由首次类型检查/构建、Vite build watch与Node 24 watch组成,Node以SIGTERM停止旧进程。实际触碰源码触发重建,日志确认旧进程完成清理后新进程才启动;重建时持有慢请求,该请求约2033ms返回401后才完成重启。新进程健康检查全部up。首次构建含类型检查,增量只转译,不替代提交前lint/build。- 组合命令的非TTY外层Bun单进程SIGINT未向全部子进程传播;随后向本次专属进程组发送SIGINT,等价于终端Ctrl-C,全部已记录子进程退出且端口释放。未新增自制进程管理器或一次性验收脚本;不能把单PID退出等同于整组已关闭。
bun run lint、bun run build、随后bun run build:nest、相关文件Prettier与git diff --check通过。启动竞态修正后再次运行bun run build:nest与bun run lint通过。原前端分包警告和共享测试两个既有失败保留;本批未修改共享逻辑,未重复共享单元测试。- 日志:
/tmp/daoyou-nest-lifecycle-{lint,full-build,build,runtime,timeout}.log、/tmp/daoyou-nest-watch.log、/tmp/daoyou-nest-bootstrap-{build,lint,SIGTERM,SIGINT,normal,nats-failure,listen-failure}.log。未验证60秒强退分支、处理中结算的SSE、活跃奖励发布的停机,以及清理钩子失败时的最终退出状态;不将正常退出日志推广为这些分支通过。 - 本批实际进程均已退出,Docker基础设施保留。未部署或执行数据库迁移,默认入口与生产产物切换继续在下一阶段处理。
第二十一批:默认入口与生产构建切换(2026-10-01)
dev:api和prd:api改为类型检查/构建后运行Vite watch与Node watch,分别加载local/staging环境;移除临时Nest命令。build:server改用Nest的ESM构建,配置合并到apps/api/nest-cli.json,删除临时vite.nest.config.ts。服务端仅清理apps/api/dist,实际完整构建确认dist/index.html与apps/api/dist/main.js同时保留。build:client/build:server稳定入口不变。- Docker使用Node 24.18.0,构建阶段使用Bun 1.3.14和冻结bun.lock;生产依赖阶段通过package-lock执行
npm ci --omit=dev。运行阶段仅复制生产依赖、package.json和Nest产物,以node用户运行,明确SIGTERM。实际本地arm64镜像检查UID1000、Node版本正确,/app/env、/app/src和Bun可执行文件均不存在。依赖清单与npm lock根节点相符,两套锁安装均成功;本批仅改变脚本,未新增依赖或重生成锁文件。 - 使用专用本地Docker网络与既有PostgreSQL/Redis/NATS运行镜像,显式覆盖NODE_ENV=development,未启用生产Cron。健康检查200且Redis/NATS/messaging均up;验证码配置200、匿名Better Auth会话查询200/null,背包及实时入口匿名401。容器中发送慢上传请求后执行docker stop,原请求约1050ms返回401,随后消息设施、数据库和Redis按序关闭,容器正常退出。最终默认构建命令生成的镜像又完成健康检查及停机检查。未以此宣称生产模式或amd64平台已经运行验收。
- 生产Compose健康检查由Bun改为Node,停机宽限期75秒。使用local环境文件只解析Compose配置,blue/green两服务均解析为Node健康检查与1m15s宽限期;没有启动生产Compose。
bash -n scripts/blue-green-app.sh通过,脚本本身未改。GitHub工作流增加版本标签、完整提交SHA标签及OCI标签,继续写latest;未推送标签、触发工作流或发布镜像。 - 部署文档补充指定版本/SHA/digest与上一镜像回滚方式;若回滚至旧Bun镜像,需要同步恢复旧Compose健康检查。该操作方案仅源码与配置核对,未在真实OpenResty环境演练蓝绿切换/回滚。
- 实际执行默认
bun run dev,现有local2会话在浏览器正常进入洞府。认证、资源、宗门、功德、战斗活动、剧情、任务、战绩、占卜读取均200;WS升级101并收到ready。未执行领取、战斗、聊天、账号变更等业务写入。浏览器页已关闭,向本次专属进程组发送SIGINT后API/Vite/watch父子进程全部退出。 bun run lint、bun run build、两次docker build -f docker/Dockerfile.app -t daoyou-nest:local .、相关文件Prettier和git diff --check通过,前端既有分包警告保留。日志:/tmp/daoyou-nest-cutover-{lint,build,docker-build,docker-runtime}.log、/tmp/daoyou-nest-docker-{build,runtime}.log、/tmp/daoyou-nest-default-dev.log。共享引擎未改,未重复共享单元测试;原两项已知失败保持单独记录。预发布prd:api仅检查命令与环境选择,未连接远程服务执行。- GitHub工作流YAML与技能frontmatter已由Bun YAML解析检查。技能Python验证器因本机缺少PyYAML未能执行,未将其记为通过;未为此安装额外依赖。
- 更新README、AGENTS、开发/测试文档和后端安全技能,使新工作使用Nest入口。旧Hono源码与依赖仍保留,长连接异常与认证边界仍有待验证项;不能标记全面迁移完成。两个临时验收容器均已停止并移除,本地镜像保留,基础设施容器继续运行。
第二十二批:升级拒绝响应与请求读取(2026-10-01)
- 真实旧Hono升级请求证实:拒绝握手返回JSON,携带CORS、限流及会话响应头。Nest适配器统一执行升级API admission,随后调用各功能服务的身份/配额检查,成功与失败均透传响应头;不再在服务里重复限流。握手工作登记到请求工作集合,停机等待其结束后才关闭基础设施。
- 保留通用实时Origin→session与擂台session→active→Origin顺序,擂台Origin错误继续使用
{error},其余错误保留{success:false,error}。原ws拒绝回调会拼接数组头为逗号字符串,且小写content-type无法覆盖内建的同名大写头;首次检查暴露JSON仍标记为text/html,遂使用经过Headers校验的字段序列化失败响应,独立输出各条Set-Cookie。没有读取或记录用户Cookie值。多Cookie续期的真实运行分支尚未触发,当前此项为源码证据。 - 顺序运行Hono与Nest,对照6项匿名升级(允许/拒绝Origin、非法BYOK、参与者/观战路径)。最终状态码和JSON均一致,CORS/Vary/限流头保留;Content-Type统一为
application/json; charset=utf-8,不声称与旧服务的有无charset/空格逐字一致。另在仅本地进程临时将IP限额设为1,两次升级分别401、429,限额/remaining均正确,第二次包含Retry-After:60。未修改环境文件或全局Redis限流配置。 - 真实对照发现原Express raw解析的三类迁移偏差:查询超过1,000项被截断、1MiB新限制先于鉴权返回413、Content-Encoding自动解压或拒绝编码先于业务处理。现使用显式raw-body依赖按原始字节读取,业务读取和JSON解析都放到Guard之后;大小上限按Bun公开类型中记录的默认128MiB保留,Webhook独立保持256KiB。Node querystring设置maxKeys=0,保留既有FirstQuery首值行为。方法级领域Filter把读取超限交给全局413响应。
- 8项请求体/查询对照全部与旧服务状态码和body一致:超过1,000项的末尾page、编码参数、畸形参数、匿名1.1MB请求、匿名伪gzip头、实际gzip字节、公开接口伪gzip头、Webhook伪gzip头。另验证1.1MB合法JSON但无业务必需字段的开发请求返回400;声明Content-Length为128MiB+1但不发送大体积内容时返回413。未传输128MiB实际数据,不将此项当作完整分块上限验证;413的JSON结构也没有与Bun原生超限body做逐字对照。
- Webhook262144字节仍进处理器并返回无效Webhook400,262145字节返回旧契约500。匿名受保护请求仅发请求头、不发正文,也立即401,确认不再等待未授权请求体。没有以这些无效输入触发资源发放、创建角色或有效支付订单。
- 复用local2浏览器会话,临时修改刷新请求检查闭关畸形JSON400、历练畸形JSON500、公告畸形JSON400以及1.1MB缺失公告字段的JSON400,保留既有文案/校验结构;未保存公告。拦截清除后进入洞府,通用WS升级101并收到ready,随后关闭临时页面。
- 新请求读取方式下重新验证停机:公开开发入口收到分段
{}无效输入,SIGTERM后约1104ms补齐正文并返回400,再关闭消息设施与数据库;始终不结束正文时约30117ms连接重置,处理器结束后依赖清理完成。此前匿名401慢上传用例不再代表当前实现,因为Guard现在会立即拒绝。此轮仍不代表真实SSE结算取消已通过。 - 新增raw-body直接依赖并同步bun.lock/package-lock.json。npm锁更新意外移除了5项既有WASM可选依赖记录,已依据HEAD恢复这些无关记录;保留必要依赖标记变化。最终Docker构建中的冻结Bun安装和npm生产安装均成功。
bun run lint、bun run build通过;补充握手工作登记后再次运行bun run build:server和lint通过。Prettier/git diff --check通过。最终arm64 Docker镜像又完整执行上述8项HTTP与6项升级对照,全部保持预期,并正常停机。未改共享引擎,不重复共享单元测试,原两项既有失败继续保留;未新增测试/验收脚本或执行数据库迁移。- 记录:
/tmp/daoyou-{hono,nest}-upgrade-protocol.json、/tmp/daoyou-nest-upgrade-after.json、/tmp/daoyou-hono-body-query-protocol.json、/tmp/daoyou-nest-body-query-{before,after}.json;最终日志为/tmp/daoyou-nest-protocol-{lint,build,runtime,boundary,docker-final,docker-runtime}.log和/tmp/daoyou-nest-upgrade-final-{build,lint}.log。只记录脱敏握手信息,不保存完整网络头。 - 自启动Hono/Nest/Vite进程及验收容器均已关闭/移除,Docker基础设施与本地镜像保留。下一阶段仍需完成旧Hono源码/依赖清理及认证、SSE和长连接恢复的剩余验证,目标尚未完成。
第二十三批:移除Hono实现与依赖(2026-10-01)
- 删除旧
src/index.ts、apps/api/src/app.ts、apps/api/src/routes、apps/api/src/lib/hono、旧Origin适配及内部Cron调度器,共87个本批退役文件。仍被调用的历史物品应用服务保留在lib/services/legacy。移除旧入口的TypeScript包含项及无调用的updateRequestContext;当前源码、构建入口和项目技能不再导入Hono实现。 - 删除
hono与@hono/vite-build直接依赖,同步两套锁。ALTCHA包元数据仍声明Hono为可选peer,但最终镜像中两者均无法require.resolve,没有重新安装旧运行依赖。Bun冻结安装及Docker中的npm生产依赖安装通过;保留npm锁中五项无关WASM可选依赖记录。 - 清单包含332个Controller方法、349条展开路由。旧清单348条中Better Auth的
ALL /api/auth/*由原始Node处理器承接;Nest增加两个退役通配接口的根路径。清单证据为/tmp/daoyou-nest-retired-route-inventory.json,静态计数不代表全部方法运行通过。 bun run lint、bun run build及清理孤立函数后的bun run build:server通过。全量共享测试为237个文件中235通过、2失败,2403个用例中2401通过、2失败;仍为炼器数量预期和技能内容哈希两个原有基线问题,packages/shared/src没有改动。日志为/tmp/daoyou-nest-retire-tests.log,不记录成全绿。- 最终本地arm64 Docker镜像启动成功,健康检查Redis/NATS/messaging均up。浏览器通过正常退出/密码登录切换至local3,真实
/api/admin/session返回403;该次登录POST状态未完整捕获,仅以页面身份和会话读取确认成功,后续认证POST证据见下一批。没有修改密码、权限或部署生产。
第二十四批:异步JSON解析修复与认证/SSE验收(2026-10-01)
- 在移除Hono后的真实浏览器流程中,local2使用合法UUID领取历练仍返回500。定位到Nest 12的
router-execution-context不等待自定义参数工厂,PipesConsumer直接将Promise交给首个ZodPipe。第二十二批改成异步参数工厂时引入了这个回归;此前错误输入得到预期错误码不能证明合法请求可用,也不再将更早的成功写入记录视为第二十二批版本的成功证据。 JsonBody现使用同步工厂提供Request,再由首个异步Pipe读取、解析正文,后续校验获得真实JSON。保留137处装饰器调用的接口、解析回退、鉴权顺序和大小限制,不修改领域服务或共享Schema。其他自定义参数工厂经检查均为同步。后端技能补充此Nest 12约束。- 浏览器正常退出local3后,local2错误密码POST返回401、正确密码POST返回200,恢复本地道友2会话。另用两个独立临时API会话运行16个并发资源读取,全部匹配各自账号/角色;两次跨角色事件窗口读取均403。两个登录响应各含独立的
better-auth.session_token,HttpOnly、SameSite=Lax、Path=/;仅记录属性,未输出Cookie值。请求携带不同合法BYOK头,但未观察下游模型调用,不据此宣称BYOK并发隔离已经验证。临时会话最终均正常退出200,浏览器会话保留。 - 修复前的合法历练请求未生成执行凭据。修复后同一请求
2360b23f-9cf6-4c55-9052-84e46e3949b8返回200,随后在浏览器响应拦截处制造丢失响应。此时服务端叙事已完成,不能称作生成中取消。以相同编号重试返回200、result和state.replayed=true;最终镜像再次重放仍相同。数据库对应player_journal只有一条,灵石41141→41479、修为2566→2580、感悟88→90,重放不再增加。该业务当前凭据位于journal,不误用旧player_mutation_requests的零行数判定未提交;奖励物品数为0。 - 通过真实本地API为此前无签的local3正常求签(drawId=
06445505-f6bd-4128-b125-bfad0a9cbbd9),在解签SSE第一个真实模型text事件到达时立即AbortController断开。服务端日志记录上游AbortError并使用预设签文;后续读取确认fallback及rewardGranted均true。只读数据库检查消耗品数量0→1,再以原drawId解签只返回complete、空changes,数量仍为1。保留正常玩法生成的签与奖励,没有重置占卜、造物资或直接改数据库。 - 合法属性预览200且含preview;闭关畸形JSON400,历练畸形JSON及非法UUID均保持旧500;退役战报请求经解析后在Zod之前返回410,没有发送消息。临时浏览器请求拦截已清除,并重载正常页面。洞府在已提交历练的响应丢失后隐藏重试入口是现有前端行为,本批未改前端;API幂等通过不等于该UI恢复问题已修复。
bun run lint、bun run build:server、bun run build及JSON解析文件Prettier通过;重新构建Docker镜像,在新建容器上验证健康检查、合法属性预览和幂等SSE均通过,另8项请求体/查询对照与旧基线相符。共享引擎未改,本批未重复共享测试,沿用第二十三批两项失败的明确记录;未新增服务端单元测试或一次性验收脚本。- 构建与运行日志:
/tmp/daoyou-nest-json-pipe-{build,lint,full-build,docker-build,runtime}.log;协议结果/tmp/daoyou-nest-json-pipe-body-query.json;最终页面截图/tmp/daoyou-nest-json-pipe-browser.png。会话续期、ALTCHA开启、防重放、其他SSE场景准备阶段取消/结算停机及实时恢复仍未全部完成;不将本批两个场景推广为全部长连接通过。 - 本轮临时浏览器页已关闭,正常登录的local2会话保留;临时API会话均退出。验收容器已停止并移除,最终日志
/tmp/daoyou-nest-json-pipe-docker-runtime.log确认消息设施、数据库和Redis完成清理。专属Vite进程组已退出,3001/5174没有监听;本地PostgreSQL/Redis/NATS/Mailpit容器保持运行。没有部署、推送或数据库迁移。
第二十五批:ALTCHA、会话撤销与实时补读(2026-10-01)
- 使用第二十四批的最终Nest产物和纯本地基础设施,单独启动绑定127.0.0.1的开发进程。仅该进程临时设置随机ALTCHA密钥,未修改环境文件、认证配置或数据库会话日期。
/api/captcha/config返回enabled=true,config与challenge都带no-store;未启用生产Cron。 - 通过真实挑战接口和ALTCHA库求解:缺失载荷、畸形载荷、超长载荷、错误action、篡改签名均400;有效载荷登录200,重放同一载荷400。header和body的captchaPayload两种入口均成功。另一次新挑战由8个并发登录请求使用,恰好1个200、7个400,验证Redis NX防重放在实际并发下生效。所有成功登录的临时会话最终正常退出200,没有输出或保存Cookie值、挑战解答及密钥。
- 正常退出local3临时会话后,使用该已撤销的原会话请求玩家资源与管理员会话均401,Better Auth会话读取200/null,原生WS升级401。HTTP及WS拒绝均返回session_token、session_data、dont_remember三条独立Set-Cookie,每条Max-Age=0、HttpOnly;WS原始头字段数也为3,确认未逗号拼接。这是实际多Cookie清理路径,不是会话到期续期路径;后者仍未触发。
- OTP缺少邮箱返回400「缺少邮箱地址」,不存在的邮箱缺少昵称返回400「首次注册请填写昵称」;Better Auth admin根路径和list-users均404。密码重置与发送OTP缺少ALTCHA时均400,没有发送邮件、创建账号或修改凭据。邮件验证码完整成功流程尚未验收。
- local2通用WS先收到player-state ready,读取角色资源版本492后正常断开。断线期间通过正式解签接口完成既有待领签礼(drawId=
15022f00-6b9e-4c77-b657-8837661dc1a4,此前已有完整签文,未触发LLM);重连ready身份及scope一致,事件窗口从492补到493,恰好包含一条divination.reward.granted且requiresReload=false。原drawId再请求只回放完成态,窗口仍仅一条奖励事件。保留正常签礼和奖励,不重置数据;此项验证真实API协议恢复,未声称浏览器断网界面或所有擂台恢复已覆盖。 - local3通用WS收到ready后分别发送二进制帧及513字符文本,均以1003关闭。另一个连接持续不发送应用层心跳回复,约75005ms以4000关闭;实现每25秒检查是否超过50秒,因此不声称恰在50秒截止。关闭后同一会话可以再次收到ready,随后主动正常关闭并退出临时会话。慢消费者背压和所有IP配额边界没有在本批运行验证。
- 静态审查41个模块、156个带Nest装饰器的类:无静态模块导入环、无重复类Provider声明,无ModuleRef/forwardRef或请求作用域服务。运行启动可解析全部当前依赖;构造器唯一不带@Inject的是显式new并传Schema/错误契约的ZodPipe,不由容器推断依赖。模块只导出SessionService、RequestWorkService、RealtimeService、ArenaRealtimeService,分别用于跨模块鉴权、请求排空和启动时Adapter装配;既有纯函数与应用服务保持框架无关,未为形式统一重写仓储或领域逻辑。
- 本批未改运行代码,未重跑lint/构建/共享单元测试,沿用第二十四批构建产物;原两项共享测试失败仍单独保留。没有新增测试脚本、执行迁移或部署。
git diff --check通过。独立本地进程收到SIGTERM后完整清理并退出143,日志/tmp/daoyou-nest-altcha-runtime.log含shutdown complete;3001/5174均无监听,基础设施保持运行。临时ALTCHA密钥仅存在于已结束的进程内,正常配置文件和浏览器既有会话未改动。
第二十六批:擂台恢复与生成中SSE停机(2026-10-01)
- 对既有已结束战斗发起8次升级后立即断开TCP,随后4条擂台连接均ready,第5条关闭1008;释放一条后替补连接ready,战斗revision仍为9。仅证明这些中止尝试没有耗尽连接名额,无法据此确定每次中止所处的异步握手阶段,也不算待完成握手停机验收。
- local2与local1通过正常API建房、加入并开始切磋,local3观战;战斗
13094a0b-34fd-443b-9cfb-e11c50b9b926。参战和观战连接均ready,观战视图不含操控指令。观战断开期间参战者提交AUTO,同requestId及内容重放响应相同且不再推进revision;观战重连后读取revision由0到1。 - local3正常离开观战后,下一次实际战局广播使其socket关闭1008,后续观战HTTP返回403;参战者持续收到状态广播。两人通过正常AUTO指令完成18回合切磋,local2落败。双方灵石与修行进度(含感悟)和战前一致;只读Redis确认双方占用key为空、战斗presence为0,三个账号房间查询均为空。
- 回放权限实际复查为参战者local1/local2均200,非参战者local3为404。首轮验证误以为无权限应403,因而客户端检查退出1;查阅既有
arenaReplayV6确认有意以404隐藏不可访问回放,再按真实契约复查通过。没有把这一验证预期错误改成产品行为变更。 - local4正常抽取锻造方向签
fd0f2fe6-39db-4814-bd95-0ed5d95286d5,解签收到首个实际模型text帧时向本轮Nest进程发送SIGTERM。SSE继续返回26个text帧及interpretation、complete,未使用fallback,奖励成功。日志先记录开始HTTP排空,随后解签POST200(2044ms),最后才记录处理器排空、停止消息设施及关闭数据库/Redis,进程退出143。 - 重启后读到同一签的奖励已提交,再解签只返回complete及空changes;只读核对消耗品数量由0到1且重试后仍为1。该检查验证了客户端仍连接时生成中SSE的停机排空,尚不覆盖客户端先断开再停机、其他SSE业务结算和活跃后台发布故障恢复。
- 所有临时API会话均已退出,浏览器原有会话保留;没有发送聊天/邮件、变更密码或权限、改写测试夹具。保留正常本地切磋历史与占卜奖励。日志
/tmp/daoyou-nest-arena-recovery-runtime.log与/tmp/daoyou-nest-sse-restart-runtime.log。 - 本批未改运行源码,复用第二十四批构建产物,不重复lint/构建/共享测试;两个既有共享测试失败仍保留。没有新增测试脚本、数据库迁移或部署。重启后的本地Nest暂留供后续验收,不能把第一进程退出记为所有进程均已清理。
第二十七批:查询编码兼容(2026-10-01)
- 直接读取原依赖Hono 4.13.7的查询解析器,与Node querystring对照确认差异:
%E0%A4%A原样保留而非�%A;%FF%41整体保留而非�A。具名读取name时,%6Eame=first&name=second返回second;读取整个查询对象时则取first。此前的Express解析加数组首值无法保留这些区别。 FirstQuery改为解析原URL,保留合法字符解码、加号空格、异常百分号分段回退、对象首值、具名参数的字面键优先级、空键忽略与无参数数量截断。以无原型对象存放参数,避免特殊键影响原型。关闭已无业务调用方的Express查询解析,Better Auth仍直接接收原始请求;同步更新后端技能说明。- 新构建运行实际本地HTTP:13项公开具名查询检查通过,覆盖编码别名、重复键、有效与异常编码、空键以及1,100个前置参数;5项已登录旧产物查询确认对象首值和分页。另10组资源查询以真实400响应里的未知资源值对照Hono 4.13.7解码结果,逐项一致,包含不完整UTF-8、合法中文、混合有效/无效编码、空字节及编码重复键。
- 资源快照检查首次遗漏必填keys,按原契约得到500,导致该次客户端检查退出1;此前13+5项查询已执行通过。补齐
keys=session,profile,currency后真实读取200,合法attributes/previewPOST也返回200。没有修改产品来迎合错误检查输入,没有分配属性或改变背包物资;两次临时登录均在finally中退出。 bun run lint、bun run build、两个改动TS文件的bunx prettier --check通过;保留现有前端分包警告。共享引擎没有变更,不重复共享单元测试,沿用最近2401通过/2失败的已知状态。本次未重复Docker构建或浏览器全流程,不能将第二十四批镜像称为包含本批修改的新镜像。- 构建与运行日志:
/tmp/daoyou-nest-query-final-{lint,build,runtime}.log。前一遗留验收进程及本批新进程均已SIGTERM退出143,日志确认shutdown complete,3001/5174无监听;Docker基础设施保留。未执行数据库迁移、部署或Git提交。 - 迁移主体与默认入口已经落地,但上方剩余验收项尚未全部完成,不能将此次局部查询验证宣称为全面迁移验收完成。
第二十八批:未知路径鉴权与断开后的SSE排空(2026-10-01)
- 对照Git中旧router的全部
.use('*', …)范围,确认部分未知路径曾先验证活跃角色/管理员,迁移后直接404。实际修改前请求/api/combat-v6及其尾斜杠/深层未知路径、/api/divination/missing、迁移工具与四类管理深层路径,均复现缺失兜底鉴权;普通/api/admin/accounts/no/such/path原本没有整段鉴权,不纳入修正范围。 - 新增最后导入的
NotFoundModule,两个Controller分别声明active与admin,复用全局AccessGuard;仅覆盖旧整段鉴权的9类活跃角色路径(含全部combat-v6子路径)和4类管理路径。已知Controller仍优先,兜底不读JSON、不调用业务服务。狩猎及指定战斗养成路径在鉴权后保留原缓存头;旧迁移入口仍由既有middleware在鉴权前设置no-store。 - 首轮新产物检查发现
{/*path}未覆盖只有尾斜杠的路径,检查因此退出1,尚未创建登录会话。调整为{/{*path}}并重新构建后完成92项真实HTTP检查:匿名未知/尾斜杠路径401、畸形POST先401、非法Origin先403;活跃角色未知路径404并保留缓存头;local2管理员未知管理路径404,local3普通账号为403。相似前缀、大小写变体、未整体保护的命名空间与未知cron路径继续404。 - 两个账号读取健康检查、角色资源、战斗活动、占卜、狩猎和两类迁移可用性均200,确认这些已知路由没有被兜底遮挡。没有发送消息、改权限、执行物品迁移或进行这些业务的写操作;临时会话正常退出。新模块没有Provider/构造器/导出,不引入模块依赖环或请求状态,当前共42个模块。
- local5正常抽取锻造方向签
a0b2084d-2b08-4110-831c-65b1cf4d59e8。解签收到200及SSE响应头后,客户端未读取任何body帧即Abort,并立即向自启动Nest发SIGTERM;不能据此断言服务器尚未开始生成或socket内没有已缓冲帧。日志顺序为开始排空→占卜AbortError降级→处理器排空→停止消息设施→关闭数据库/Redis,进程退出143。 - 重启后该签
fallback:true、rewardGranted:true,只读数据库核对消耗品数量0→1;同drawId重试只产生complete,changes为空,数量仍为1。证明本次客户端已断开时,处理器仍完成结算且依赖保持存活;不能推广成其他SSE场景或任意故障时序的验收。保留真实本地签礼,临时local5会话已正常退出。 bun run lint与完整bun run build通过;尾斜杠修正后bun run build:server、最终lint、两个改动文件Prettier及git diff --check通过。共享领域未改,不重复共享单元测试,既有2401通过/2失败状态保留。本批未重复Docker构建、浏览器全流程或部署,没有新增服务器/前端测试文件或验收脚本。- 日志:
/tmp/daoyou-nest-protected-path-{before,after,final-runtime,lint,build,final-build,final-lint}.log及/tmp/daoyou-nest-aborted-sse-restart.log。停机/端口清理结果见本批后续记录;不以被信号终止的前一个进程代替重启进程的清理状态。 - 重启进程最后也已SIGTERM退出143,日志确认shutdown complete,3001/5174无监听;Docker基础设施保留。最终
git diff --check通过。本轮完成了两项明确验收缺口,其他未勾选项仍待继续,不标记全面迁移完成。
第二十九批:Mailpit验证码与真实BYOK并发(2026-10-01)
- 启动前核对SMTP为
127.0.0.1:11025、Mailpit API为127.0.0.1:18025,数据库为本地daoyou_local,没有连接预发布/生产。现有local1—local8均已验证邮箱;本轮经正常邮箱验证码页面新增local-nest-otp@daoyou.local,昵称「本地认证验收」,未设置密码或创建角色。 - 浏览器
localhost:5174原本已有local1会话,先经正常账号设置退出;127.0.0.1的local2会话未动。通过真实表单发送验证码,Mailpit收到仅供本地验收的邮件;错误验证码返回400并显示「验证码错误」,正确验证码返回200,页面进入「尚未凝聚真身」。只读数据库确认新账号emailVerified:true且角色数0,资源读取200。没有直接修改邮箱验证状态或认证表。 - 新账号缺少活跃角色时没有可用的设置退出入口,因此在该本地页面通过实际sign-out API退出200;同一OTP重放返回400。随后经正常密码登录页恢复localhost的local1账号,页面重新显示原角色。保留新OTP账号与Mailpit测试邮件,不删除已有账号或其他邮件。截图
/tmp/daoyou-nest-email-otp-success.png;验证码、会话Cookie与凭据未输出或保存到验收文件。 - 两个独立临时会话local6/local7正常抽签,并并发请求解签。local6通过BYOK头使用本地已有阿里云凭据及
qwen3.7-flash;local7使用明确无效的测试凭据及deepseek-v4-flash。真实下游日志分别出现阿里云200、DeepSeek401,没有使用模拟Provider或修改服务器路由表。有效凭据只在进程内读取并发送到本地API,再由既有Provider发送至配置的上游,没有记录请求头。 - 两次HTTP生成分别在相对0ms/1ms开始,2077ms/186ms结束,时间区间重叠。local6收到24个text帧、
fallback:false;local7没有text帧、fallback:true。结果与各自BYOK选择对应,未串用凭据/模型,也未将无效BYOK默默换成服务器有效凭据。此项验证一次真实并发及两种Provider的隔离,不等同于穷尽所有调度和模型组合。 - local6签
69ca6a81-8051-4b7d-a2c9-3d7b25e2a72b、local7签518ee16b-f199-47a4-99e4-e4e01ffcfe70均正常结算;只读核对消耗品各从0到1,同drawId重试仅complete且changes为空,数量仍为1。保留正常签礼,两份临时API会话最终均退出。 - Better Auth当前默认会话有效期7天、续期间隔1天。数据库只读统计存在达到续期时间的历史本地会话,但没有读取其令牌。当前可用的127.0.0.1浏览器会话通过
get-session?disableRefresh=true读取的创建时间为2026-10-01T09:41:47.441Z,到期时间2026-10-08T09:41:47.440Z,尚未达到续期时间;不能将历史会话计数当作续期成功证据。没有改动会话日期、过期策略或配置来制造通过,续期与密码注册验证链接仍待验收。 - 本轮没有运行源码变更,复用第二十八批构建,不重复lint/build/共享单元测试或Docker构建。数据库访问均只读,所有业务写入经正式本地API;没有新增测试脚本、数据库迁移或部署。服务器日志
/tmp/daoyou-nest-auth-completion-runtime.log、前端日志/tmp/daoyou-nest-auth-completion-web.log。 - 临时页面均已关闭,API完成SIGTERM清理并退出143,Vite及其启动进程退出;3001/5174无监听,基础设施保留。localhost恢复local1登录,127.0.0.1继续保留local2登录。整体目标仍待上方剩余验收收口。
第三十批:待完成握手停机与慢消费者(2026-10-01)
- 使用现有local2账号及已结束战斗
13094a0b-34fd-443b-9cfb-e11c50b9b926。核对本地PostgreSQL容器及127.0.0.1:15432映射后,短暂暂停数据库,分别发送通用实时与擂台参战原生升级请求。600ms后两条TCP连接均无响应字节且未关闭;向自启动Nest发送SIGTERM,再等待600ms,进程仍在且未报告清理完成。恢复数据库后两次握手均503并关闭,Nest在10秒内退出143。finally保证数据库恢复;重启后同一战斗读取200,临时会话正常退出。此项使用真实依赖延迟,没有模拟认证或改写战斗数据。 - 使用local7临时会话建立三条player-state连接,一条Node原生ws客户端调用pause,另两条正常读取。通过正式API读取当前scopeVersion为5的最后一条兼容资源事件,再经现有
publishResourceEvents及本地NATS Core重新发布100批、每批367份同一已提交事件,约128KB/批。独立Bun内联进程负责调用现有发布服务;未新增资源版本、journal或聊天消息。这是传输行为验收,不代表正常玩法自然产生此批量,也不是性能基准。 - 暂停客户端恢复读取后收到1013及
backpressure limit;在它读取关闭帧前,替补连接已ready,确认服务端名额释放。两个正常客户端均保持连接并各收到100条事件消息,API事件窗口与scopeVersion仍为5。全部四条客户端最终关闭,临时会话退出,发布进程flush后关闭NATS连接。 - 前期探测先因使用不存在的NATS_URL变量退出;随后发现Bun的ws实现不提供所需pause行为,且after=0窗口因旧事件兼容性为空。这两次均未进入发布阶段,已清理连接/会话。最终改用NATS_SERVERS、Node原生ws与当前版本减一的事件窗口后通过,没有为探测错误修改产品代码。
- 本批没有运行源码修改,复用第二十八批产物,不重复lint、build或共享测试;最近共享测试仍为2401通过/2失败。最终Docker镜像仍需重建以纳入第二十七、二十八批修改。握手日志为
/tmp/daoyou-nest-pending-handshake-runtime.log,重启日志为/tmp/daoyou-nest-pending-handshake-restart.log。未保存一次性验收脚本、执行数据库迁移或部署。 - 收尾核对重启进程的PID、命令和工作目录后发送SIGTERM;日志确认shutdown complete,进程已退出,3001/5174均无监听。PostgreSQL运行且未暂停,其余本地基础设施保留。Markdown结构检查及
git diff --check通过。
第三十一批:最新Docker产物验收(2026-10-01)
- 执行
docker build -f docker/Dockerfile.app -t daoyou-nest:local .成功,实际重新执行服务端类型检查与构建,产物包含第二十七批查询解析及第二十八批未知路径鉴权修复。当前本地镜像ID为sha256:8a38e440a9da05d29bbff6e5aa4a8729840091893f2fc872338b10486d016df9,平台arm64;没有发布远程镜像。依赖层复用此前冻结Bun及npm生产依赖安装缓存,不宣称本轮重新下载并安装全部依赖。 - 独立Node检查确认
package-lock.json根节点dependencies/devDependencies与package.json完全相符。容器内实际检查Node v24.18.0、UID1000、SIGTERM配置,且没有/app/env、/app/src或Bun可执行文件,package.json无Hono直接依赖。容器运行绑定127.0.0.1:3001,数据库/Redis/NATS仅使用已确认的本地端点;显式development关闭生产Cron,未传入LLM凭据。 - 首次容器通过健康检查后发现启动命令把允许来源变量写作PUBLIC_WEB_URL,实际配置读取PUBLIC_WEB_ORIGINS。在任何登录前停机并移除该临时容器,改用正确变量重新创建;没有修改环境文件或产品配置。
- 最终镜像完成22项实际HTTP检查:健康检查中Redis/NATS/messaging均up;匿名未知命名空间及尾斜杠401、畸形JSON先鉴权、非法Origin403、普通未知路径404;具名查询编码别名优先级、重复参数、异常UTF-8以及1100个前置参数符合预期;local2登录后合法属性预览及资源读取200,受保护未知路径404、狩猎深层未知路径保留private/no-store,资源查询对象取首值且保留异常编码。未执行属性分配或其他游戏资源写入。
- 首轮协议检查错误地把
/api/hunts/missing当作未知路径,实际上它匹配既有:eventId路由并返回400;检查因此退出1,finally正常退出临时会话。查阅Controller后改用/api/hunts/missing/deep并完整重跑22项通过。没有把检查预期错误改成业务变更。两轮临时会话均已退出,未输出或保存Cookie及认证响应体。 docker stop -t 75后容器退出码0,日志依次记录HTTP排空、处理器排空、消息设施停止、数据库/Redis关闭和shutdown complete。本轮没有进行活跃业务结算停机,不能将正常空闲停机推广为其他SSE及后台发布故障恢复通过。日志为/tmp/daoyou-nest-current-docker-build.log和/tmp/daoyou-nest-current-docker-runtime.log。- 本轮仅追加验收文档,没有运行源码变更,未重复lint、完整前端构建或共享测试;共享测试仍保留最近2401通过/2失败记录。未运行数据库迁移、生产Compose或部署。临时验收容器在停机检查后移除,本地基础设施保留。
第三十二批:NATS重启与消费者/实时订阅恢复(2026-10-01)
- 启动单独的本地Nest进程(PID12043),复用当前构建;核对NATS容器属于daoyou-local项目及nats服务。整个验收中Nest没有重启,生产Cron未开启。数据库查询使用只读连接;没有修改角色、消费凭据、消息拓扑或数据库会话。
- 从真实JetStream读取系统邮件受众事件
9a0e64d4-5222-498e-ab12-b664da1e2a9e,原stream序号2293。数据库已有system-mail-projector-v1消费凭据;代码确认executeDomainEvent先领取唯一消费凭据,已处理时跳过邮件投影。此事件用于验证真实消费者重放,不创建新邮件业务事件。 - 首轮检查完成一次NATS停止/启动,但客户端finally等待未结束的status迭代器,Node报告unsettled top-level await并退出13,没有形成完整通过证据。随后只读复查:NATS健康、Nest健康200,最后事件序号及ACK仍为2293,没有待处理消息。未将这次检查记为消息消费恢复通过;后续修正客户端清理并完整重跑。
- 正式重跑:NATS停止时HTTP健康检查503且nats=down,重启后同一Nest进程健康200且messaging=up。重新发布原事件字节,不设置broker去重header,使应用消费凭据必须处理重复事件;保留原业务event.id。新stream序号2294,消费者ACK推进至2294,pending及ack_pending均为0。消费凭据及processed_at、全库邮件数量、资源事件数量、领域死信数量均与发布前相同。原服务端日志记录disconnect/reconnected,没有该次processing failed。此项证明已结算事件的消费恢复与幂等,不声称覆盖新消息中断时的业务结算或事务relay排空。
- 另用local7临时登录及一条player-state原生WebSocket验证NATS Core。经正式API取得当前版本5的最后一条兼容资源事件,使用既有实时subject/envelope格式发布原事件,socket收到一条player-state.events。再次停止/启动本地NATS,健康检查503→200;同一socket保持OPEN并在恢复后收到第二条相同事件,仅有一个ready帧,没有关闭/重连。API事件窗口及资源版本仍为5,没有资源写入或聊天消息。
- 所有NATS重启均有finally恢复保障。WebSocket正常关闭,临时local7会话退出,探测客户端连接关闭,本地NATS最终running且healthy。未输出或保存Cookie、认证响应体或凭据,也未保存一次性验收脚本。
- 本批只追加文档,未改运行源码,未重复lint/build/共享测试;共享测试沿用最近2401通过/2失败的明确记录。日志
/tmp/daoyou-nest-nats-recovery-runtime.log。没有数据库迁移或部署。 - 核对PID/命令/工作目录后向本轮Nest发送SIGTERM,进程退出143且日志包含shutdown complete。3001/5174无监听,PostgreSQL/Redis/NATS/Mailpit保持运行。Markdown结构检查及
git diff --check通过。
第三十三批:密码注册与邮箱验证链接(2026-10-01)
- 确认SMTP为本地Mailpit(127.0.0.1:11025)及数据库daoyou_local。复用已有Nest构建并启动Vite;浏览器localhost原有local1会话经账号设置正常退出,127.0.0.1的local2浏览器会话未操作。只读确认目标邮箱不存在后,通过密码注册页面创建
local-nest-password@daoyou.local,昵称「本地密码认证验收」,沿用项目文档的本地测试密码;没有创建角色或修改已有账号密码。 - 页面显示验证邮件已发送。数据库只读检查emailVerified=false、角色数0;使用正确密码登录返回403,页面提示邮箱尚未验证并重新发送邮件。Mailpit只读取该新账号的两封验证邮件,没有读取其他收件人的邮件正文。
- 原邮件验证URL位于127.0.0.1:5174,callbackURL为此次表单所在localhost:5174/game。以真实HTTP请求、手动处理重定向检查原链接,避免改变另一个浏览器域的既有会话;没有改写链接或配置。篡改token返回302且回调错误为INVALID_TOKEN,不签发Cookie,emailVerified仍false。原链接返回302到原callbackURL,数据库变为emailVerified=true,签发HttpOnly、SameSite=Lax、Path=/会话Cookie;使用该Cookie读取实际会话,身份属于新账号且邮箱已验证。
- API临时会话正常退出200后,重放原验证链接继续302到callbackURL,但不再签发Cookie。该行为符合当前Better Auth已验证用户分支,不把密码验证链接误当作OTP一次性验证码要求重放400。没有输出或保存验证token、Cookie、密码哈希或原认证响应体。
- 随后在原localhost密码登录页面再次提交,正常进入「尚未凝聚真身」;会话和玩家资源读取200。截图
/tmp/daoyou-nest-password-signup-success.png。本批完整检查的是浏览器注册/密码登录及实际HTTP验证链接,不声称已演练跨localhost/127.0.0.1域名自动登录跳转;新会话也不是时间到期续期证据。 - 新账号没有角色,页面暂无退出入口,因此在该页面调用正常sign-out接口退出200。再经正常密码登录恢复localhost的本地道友1,确认原角色洞府显示正常后关闭临时页面。只读终验新账号emailVerified=true、角色0、剩余会话0;保留新测试账号和两封本地验证邮件,没有直接改写认证表或删除数据。
- 本批无运行源码修改,未重复lint/build/共享测试,最近共享测试2401通过/2失败保持记录。执行只读数据库检查及真实浏览器/HTTP验收,未添加测试文件、一次性脚本、数据库迁移或部署。日志
/tmp/daoyou-nest-password-signup-runtime.log和/tmp/daoyou-nest-password-signup-web.log。 - 最后核对两个监听进程的命令及工作目录后发送SIGTERM。Nest日志确认shutdown complete,API、Vite及启动命令均已退出,3001/5174无监听;本地基础设施保留。Markdown结构检查和
git diff --check通过。
第三十四批:历练发布排空与突破叙事取消(2026-10-01)
- 只读确认local1历练积累超过24小时,local2炼气后期已有2580修为及90感悟。通过正式本地API进行各一次正常领取/突破,没有调整境界、寿元、物资或随机数来构造成功;数据库探测连接强制只读。以下业务进度与奖励作为正常测试结果保留。
- local1历练requestId=
a6526666-187c-4370-93f8-425b88b27ff1。暂停已核对归属的本地NATS容器,领取返回200/SSE;收到第一条真实模型chunk即Abort客户端。资源已正常结算,奖励8件,其事务消息da55545e-f4a5-4c6e-8ae1-7091d6126492尚未发布。等到数据库显示publish_attempts=2且published_at为空,证明立即发布与定时relay均尝试处理后,对自启动Nest发送SIGTERM。 - 日志到达request handlers drained/stopping message infrastructure后,250ms观察期进程仍存活、尚未出现closing database。恢复NATS,Nest完成清理退出。立即发布曾因暂停产生TIMEOUT,relay负责恢复;不将此预期依赖故障写成无错误运行。重启健康后,消息published_at非空,task-projector-v1和yield-reward-projector-v1均有消费凭据。
- local1灵石474197→483114、修为620→998、感悟49→73;历练奖励邮件由3封到4封,新邮件
c8ff08cc-a57e-479b-9718-d214918f196a有8件附件。原requestId重试返回相同result和state.replayed=true、无叙事;资源及邮件不再改变,player_journal对应yield_claim操作只有1条。此项实际覆盖一次新奖励消息在发布中断及停机后的恢复,不推广为所有业务消费者事务中断或其他发布器均通过。 - local2突破requestId=
a5a36bc4-b06e-4091-ac03-7a826c148ebc正常成功,炼气后期→圆满。收到第一条真实breakthrough-story片段后立即Abort并向Nest发SIGTERM;上游记录AbortError,处理器清理完成后才关闭依赖。重启只读确认突破历史由1条到2条,新增历史保存了2字符已生成叙事;并未等待完整故事或伪造叙事。修为2580→1780、感悟90→105,保留正常突破属性成长。 - 首轮突破检查在重试时错误地要求完整result与首次完全相同,因重试省略storyType而退出1;它已完成成功突破、取消、停机及历史核对,并正常退出临时会话。查阅现有retreatResultFromJournal确认重试仅返回action/summary,这是原共享契约。随后单独重启并复查原requestId:result与journal契约一致,state.replayed=true、changes为空、无chunk;属性、灵气、境界、修为、感悟及历史均未变化,突破journal恰好1条。没有改产品以迎合错误断言。
- 日志:
/tmp/daoyou-nest-yield-drain-{runtime,restart}.log、/tmp/daoyou-nest-retreat-abort-{runtime,restart}.log及/tmp/daoyou-nest-retreat-replay-runtime.log。所有临时API会话已退出,NATS已恢复running且未暂停;没有操作浏览器既有会话。剩余范围包括普通修炼及黑市取消、寿元耗尽分支、其他后台发布/消费者中断边界,不能将本批两个场景推广为全部长连接验收完成。 - 本批无运行源码修改,不重复lint/build/共享测试,最近2401通过/2失败状态继续保留。未新增测试文件或一次性脚本,没有数据库迁移或部署。
- 最后复查进程也已按PID/命令/工作目录确认后SIGTERM退出143,日志包含shutdown complete;全部五次启动均已结束,3001/5174无监听,本地基础设施保留。Markdown结构检查及
git diff --check通过。
第三十五批:普通修炼与黑市两阶段取消(2026-10-01)
- local3通过正常API闭关一年,requestId=
ae24ff21-a641-4c0d-858d-276d6f5d7381;收到result后断开。年龄18→19、闭关记录0→1,消耗4灵气,对应journal一条。同编号重试replayed=true、changes为空、summary一致,年龄、灵气、修行进度、condition和记录数不再变化。此次普通修炼没有LLM叙事,不记为生成中取消。 - local1在
TN_YUE_01与smiling-keeper正常进入黑市,session=1c42e737d19c96986e002f09fb3f8c9939930d52,复用已有免费入场凭据(cost=0、free=true、replayed=true)。观察生成首次因重复inspection topic失败,既有纠正重试成功;感知生成成功,开场ready、version=1、可交互6次。没有修改提示词、Schema或游戏规则。 - 首次询问物件纹路且明确不议价/成交,收到第一条真实reply-chunk后断开。Redis会话version=2、turnsUsed=1、pendingTurn清除;NPC正文为预提交的fallback。重试原version=1返回409,不额外消耗轮次。
- 第二次询问封泥裂纹且不报价。在响应头发出前,只读Redis观察到version=2的pendingTurn,随后断开请求并向自启动Nest发送SIGTERM。原领域服务虽然接收AbortSignal,却未将它传给proposeTurn;本次保留既有语义,完成已预留轮次。日志确认开始排空后准备工作继续完成,处理器结束后才关闭依赖。两次提案均因结构校验失败进入既有fallback;首次实际回复流生成了文本,不能将提案生成记为成功。
- 重启读取version=3、turnsUsed=2、turnsRemaining=4、pendingTurn清除,累计新增4条消息。正常重新进入返回同一ready会话和版本、免费入场凭据仍为replayed;重试旧version=2返回409,轮次仍为2。随后正常leave(version=3),最终phase=abandoned、version=4、turnsUsed=2,无pendingTurn。货币与背包物品条目数不变。
- 中断后的收尾复查确认普通修炼年龄19、记录1、journal1,以及上述黑市最终状态。
/tmp/daoyou-nest-black-market-runtime.log和/tmp/daoyou-nest-black-market-restart.log均含shutdown complete;临时API会话已退出,自启动进程已结束,3001/5174无监听。PostgreSQL、Redis、NATS、Mailpit保持运行,NATS未暂停。 - 四类实际SSE入口已有代表性取消/恢复证据;灵田培育/收获是接收AbortSignal的JSON接口,不计入SSE。寿元耗尽特殊分支未运行,也未为覆盖该分支强制角色死亡。本批没有运行源码修改,未重复lint/build/共享测试;继续保留最近2401通过/2失败的结果。没有新增测试脚本、数据库迁移、部署或Git提交。
第三十六批:收尾审计与剩余方案(2026-10-01)
当前结论:迁移实现已落地,整体运行验收尚未全部完成,生产发布未执行。框架迁移可行性已由本地实现、构建、镜像和代表性真实业务验证支持;不能据此承诺性能提升或全量玩法无回归。
| 审计范围 | 当前证据 | 结论 |
|---|---|---|
| 功能入口 | 全量旧路由静态核对;当前AppModule接入业务模块,末位NotFoundModule保留旧鉴权范围 | 已迁入;接口清单覆盖不等于全部分支运行通过 |
| 架构与注入 | 42个模块、显式构造器注入;HTTP身份/BYOK通过请求上下文传递;既有共享引擎与应用服务不依赖Nest | 符合本项目采用的Nest架构边界 |
| 认证与协议 | 密码/OTP/邮箱验证、ALTCHA、权限隔离、撤销会话多Cookie、请求体/查询/路径对照 | 已验证所列路径;自然到期续期仍待运行 |
| SSE与WS | 四类SSE取消/恢复;通用实时补读、握手排空、背压;擂台观战恢复、权限撤销、终局与回放 | 已有代表性证据;全量浏览器玩法清单仍未收口 |
| 消息与停机 | Nest生命周期持有Cron/消息设施;relay先排空,依赖后关闭;NATS重启恢复与新历练奖励发布中断恢复 | 消费者事务处理中断尚未实测 |
| 工具链与交付 | dev/prd命令、Vite服务端入口、Node Docker运行产物、Compose停机宽限期、固定镜像标签/回滚文档 | 已切换;arm64本地镜像通过,生产环境及amd64未演练 |
本次重新核对SessionService、AccessGuard和两类WS的会话响应头传递,以及消费者的事务和ACK顺序:消费凭据与资源变更共用事务,成功处理后才ACK,停机等待活动处理器。该静态证据支持实现设计,不能替代消费者事务中断的运行验证。未改变认证续期策略,也未读取历史会话令牌或修改会话日期。
锁文件审计发现bun.lock根工作区仍使用历史名称daoyou-hono;执行bun install --lockfile-only --ignore-scripts后Bun保留该旧元数据,因此仅将根包名对齐为wanjiedaoyou,没有更新任何依赖版本。随后bun install --frozen-lockfile --lockfile-only --ignore-scripts通过,内联校验确认两份锁文件的根包名、dependencies及devDependencies均与package.json一致,均无已解析的Hono包。ALTCHA依赖元数据中的可选Hono peer声明仍然保留,它不是项目运行依赖,不修改上游元数据。
后续按以下顺序收口,不再重复已完成批次或将所有业务规则重测扩展成框架改写:
- 会话续期与响应头:现有可用会话达到真实updateAge后,通过业务HTTP与WS路径检查续期Cookie、有效期及身份保持。当前已知会话创建于2026-10-01 09:41:47 UTC,默认一天后才具备续期条件;以届时实际会话状态为准。重复登录不算续期验证。
- 消费者处理中断:选一条正常本地玩法产生的新消息,在真实处理阶段中断/恢复依赖,核对消费凭据、资源、奖励和ACK;保留发布阶段恢复与消费阶段恢复的证据区别。
- 玩法回归收口:结合第三至十七批的待验证记录,优先补成功写入与恢复路径(如炼器/炼丹、拍卖购买、灵田、黑市成交及多人奖励玩法)。第二十六批已经覆盖擂台终局和回放权限,不重复列为完全空白;擂台切磋不发奖励,也不替代多人奖励玩法。缺少合法数据或权限的路径继续如实标注,不修改业务规则以制造成功。
- 发布前验证:复核两项共享测试失败,完成目标架构/生产配置的镜像验证及灰度/回滚演练。应用框架迁移不包含修正未改动共享规则的测试基线,不将2401通过/2失败改记为全绿;上线沿用固定镜像版本和匹配的Compose配置。
本批仅补文档和锁文件根包名,运行源码未变,未重复lint、应用构建、共享测试或Docker构建;最近源码的lint/build通过记录与2401通过/2失败的共享测试记录继续有效。当前本地镜像包含最新运行源码,但构建早于本次锁文件元数据修正。未部署、推送或执行数据库迁移。
第三十七批:奖励消费者事务中断与重投(2026-10-01)
- 只读确认local4已有超过24小时未领取的历练,使用正式API领取,requestId=
1d5f3a6a-55de-4b9d-b2eb-ac461c74f63e。没有修改角色资源、时间或消息凭据。检查前奖励消费者无pending及ACK pending,本地仅本次Nest进程运行。 - 为观察真实消费者事务,独立本地数据库连接短暂持有
wanjiedaoyou_mails表的SHARE锁,配置15秒空闲事务超时并以finally执行ROLLBACK。此连接只执行BEGIN/LOCK/ROLLBACK,不写业务行;其余数据库探测连接强制只读。正常历练提交并发布新事件后,pg_stat_activity与pg_locks确认消费者正在同一事务中等待邮件INSERT,事务XID为21180,已持有消费凭据表的RowExclusiveLock,且等待对象确为本次锁连接。 - 对自启动Nest PID16543发送SIGKILL,进程退出137,以模拟处理器执行中的进程丢失。首次检查错误地要求仍被表锁阻塞的PostgreSQL连接在释放锁前一秒内消失,导致检查程序退出1;finally释放表锁后再次只读确认所有相关连接已消失。原消息
8fb83afb-a572-4581-a62c-b824b6a42649已发布、task-projector-v1凭据存在,yield-reward-projector-v1凭据不存在,历练奖励邮件仍为0。证明角色领取事务已提交,而被中断的奖励事务没有留下已提交邮件或消费凭据。 - 检查程序的自动重启未成功,随后显式重启同一Nest产物(PID16573),健康检查200。实际JetStream显示ACK pending=1、pending=0;保持原两分钟ack_wait配置,不手工ACK、改消费位置或重新发布消息。2026-10-01 11:30:53 UTC完成原消息重投,最终ACK pending=0、pending=0,delivered及ack_floor均为consumer_seq=14、stream_seq=2303。
- 奖励邮件由0到1,新邮件
255be652-f36b-423b-b9b8-fd3e392a1e60含8件附件;消息的task-projector-v1与yield-reward-projector-v1消费凭据均存在。灵石4070→6195、修为360→554、感悟0→48,均来自正常领取,重投后未额外增长。 - 同requestId重试200、replayed=true、不再生成叙事,result与唯一journal中的结果一致。该路径会返回原有5条资源事件,scopeVersion=82;逐项核对事件ID/版本与数据库原事件一致,重试前后角色、邮件、凭据、journal及资源事件完全不变。首次重试检查误要求changes为空而失败,查阅既有
findPlayerMutationRequest与PlayerCommandExecutor确认此路径回放原事件;未修改产品契约。另一次检查误要求账号总会话数为1,因仍有原有会话退出1;最终复查仅清理本次会话,不撤销其他会话。 - 首次中断检查遗留的临时登录,通过local4正常认证的list-sessions/revoke-session接口,按当前会话之外且创建时间落在本次窗口的唯一会话定位并撤销;未读取数据库会话令牌。其余临时登录均正常sign-out200。最终只读确认local4在本轮开始时间之后的剩余会话数为0,原有会话保留。
- 所有表锁与检查连接均已释放;重启后的Nest收到SIGTERM,退出143,日志
/tmp/daoyou-nest-consumer-interrupt-restart.log含shutdown complete。被强制终止的首进程日志为/tmp/daoyou-nest-consumer-interrupt-runtime.log,不将SIGKILL记为优雅停机。3001/5174无监听,PostgreSQL/Redis/NATS/Mailpit保持healthy,无相关数据库连接残留。 - 本批没有运行代码修改、额外测试文件或保存的一次性脚本。使用真实本地API、数据库锁与NATS重投完成检查;未重复lint/build/共享测试,保留2401通过/2失败的最近结果。未部署、提交或迁移数据库。第三十六批的消费者处理中断待办由本批代表性验证补齐,自然会话续期与剩余玩法回归仍未完成。
第三十八批:炼器成功、页面重试与版本冲突(2026-10-01)
- 使用当前Nest产物与Vite,在浏览器localhost复用local1既有会话;127.0.0.1的local2会话未动。只读选择已有炼气期法兵图纸与自测玄铁,不发放物资或改写夹具。进入炼器室地火器炉,选剑形、一份玄铁;确认框显示100灵石、7天地灵气、一卷图纸和一份材料。
- 页面正常确认开炉,requestId=
02158a79-27d8-4d43-b466-813c6cf93503。真实LLM命名请求200、无重试,服务端POST200。返回道装0c4775ed-b98f-4a93-8441-db3e78c582e0「玄铁试锋剑」,10级法兵。背包40格已满且原堆叠仍有余量,产物正常进入storage。 - 仅对该Fetch响应临时拦截,在确认真实200与产物后丢弃响应,未伪造业务结果。页面出现Failed to fetch及「重试本次开炉」。清除拦截后通过该按钮重试,捕获POST200,请求编号和完整正文均与首次相同;replayed=true,返回产物对象与首次深比较一致。页面显示「玄铁试锋剑」「已收入洞府储藏室」,截图
/tmp/daoyou-nest-forging-retry-success.png。清除所有拦截并刷新后,页面正常读取剩余图纸3卷、玄铁6份。 - 数据库只读核对:灵石483114→483014;图纸4→3、revision6→7;玄铁7→6、revision8→9;bag条目保持40、storage条目77→78,产物恰好一件,对应forging journal恰好一条。页面开炉前灵气240/240、开炉后233/240;此前数据库缓存qi为233,不能用缓存前后同值误判为没有扣费,实际事务会先结算自然恢复。
- 再以临时local1 API会话验证两项冲突:新requestId携带原旧物品revision返回409「物品已变化,请重新备料」;原requestId改写intent返回409「同一幂等键不能用于不同的玩家状态事务」。两者均no-store,前后角色灵石/qi、全部背包与储藏室条目/版本、炼器journal均无变化。临时API会话正常退出200。
- 检查工具最初使用缺少resourceType的CDP拦截模式,被浏览器拒绝且尚未提交;随后明确限定Fetch。清理采用
Fetch.enable({patterns:[]}),因为该工具不支持直接Fetch.disable。第一次产物比较使用JSON.stringify,因字段顺序不同返回false,改用深比较确认内容完全相同。一次只读核对误将varchar库存ID数组转成uuid导致查询失败,按实际Schema改为text后完成检查。这些均未引起产品代码修改。 - 所有临时拦截清除、页面关闭,原浏览器登录保持。Nest与Vite/Bun父子进程均已停止;Nest退出143且
/tmp/daoyou-nest-forging-runtime.log含shutdown complete,前端日志/tmp/daoyou-nest-forging-web.log。保留正常铸造消耗、道装和修仙日志,不回写撤销玩法结果。 - 本批仅更新验收文档,无运行源码修改,未重复lint/build/共享测试,保留最近2401通过/2失败记录。没有新增测试文件或保存的一次性脚本,未部署、提交或执行数据库迁移。炼器成功与冲突缺口已补,宝库旧物品取出、其他玩法及自然会话续期仍按原清单继续验收。
第三十九批:随心炼丹与丹方炼丹成功、重试及冲突(2026-10-01)
- 使用当前Nest产物和Vite,浏览器localhost复用local1既有会话,只读选择已有材料及丹方。没有发放物资、改写夹具或调整随机结果;数据库核对连接强制只读,127.0.0.1的local2浏览器会话保留。
- 随心炼丹通过页面投入已有药材「10Q新系统奖励」5份,意图为温和补气、调养经脉,确认消耗1840灵石和1灵气。requestId=
dc701402-5c95-411e-a901-74bd4d53ea1f,POST/api/craft返回200,产出凡品「青木归元丹」1枚,物品ID=ddf420a8-a3b5-4f90-9cc7-d4adbf94ee7c。背包已满,产物进入storage;灵石483014→481174,材料10→5、revision5→6,页面灵气234→233。对应alchemy_improvisedjournal恰好一条。未返回formulaDiscovery,不将丹方发现确认记为通过。 - 使用临时API会话重试原随心炼丹请求,返回200、replayed=true、scopeVersion618,产物深比较与journal一致。新requestId携带原材料版本返回409「材料已变化,请刷新并重新投入」;原requestId改写意图返回409「同一幂等键不能用于不同的玩家状态事务」。三次检查前后角色资源、库存、journal与资源事件均不变。现有实现先准备LLM结果再校验材料版本,旧版本检查因此产生实际模型调用;本批未改变此顺序。临时会话正常sign-out200。
- 丹方炼丹在页面选择已有「青元养脉丹丹方」
0fbed80a-1dd0-4827-a6bc-e59985c60d5e,投入玄品鸣雷藤与三叶灵参各1份。正常药路推演POST返回200,analysisId=a4c9ceae-fbc6-4f4b-8f63-d8004f5991b2,预测玄品1枚。页面确认7360灵石和1灵气后,requestId=942dae63-adcd-44c4-a6fa-259dc8c6af1a正式制作返回200,产出玄品「青元养脉丹」1枚,ID=6d31d900-50a2-42cf-8063-dd0a34017062。两份材料行消耗后产物进入bag,最终39/40格;灵石481174→473814,页面灵气233→232,丹方熟练度exp3→4、level保持1,对应alchemy_formulajournal恰好一条。 - 原丹方请求经实际API重试返回200、replayed=true、scopeVersion620,结果与journal深比较一致;角色、库存、丹方熟练度、journal和资源事件均不再变化,临时会话sign-out200。两次成功结果截图分别为
/tmp/daoyou-nest-alchemy-success.png和/tmp/daoyou-nest-formula-success.png;随心炼丹后刷新成功,丹方成功页已目视核对成丹数量与熟练度。 - 初次只读快照误用
alchemy:%匹配操作键,后改为alchemy_%及精确操作键核对,未以错误零计数作历史journal结论。没有修改产品以满足检查工具的假设。 - 页面已关闭,本批未使用Fetch拦截。核对PID、命令及工作目录后停止Nest17555、Vite17558及Bun父进程17556/17557,启动会话均退出143,日志
/tmp/daoyou-nest-alchemy-runtime.log包含shutdown complete;前端日志为/tmp/daoyou-nest-alchemy-web.log。3001/5174无监听,PostgreSQL、Redis、NATS和Mailpit均保持healthy。保留正常炼制消耗与产物,不回写撤销结果。 - 本批没有运行源码修改,未重复lint/build/共享测试,最近2401通过/2失败记录保持。未新增测试文件或保存一次性脚本,未部署、提交或执行数据库迁移。自然会话续期、拍卖/灵田等剩余玩法及生产发布验收继续按清单收口。
第四十批:公开拍卖部分成交、售罄与邮件交付(2026-10-01)
- 复用当前Nest产物及Vite,数据库强制只读选取local1已有地品自测玄铁(6份、revision9),local2已有41479灵石;当前无有效在售货单。通过local1浏览器页面按每份100灵石公开寄售2份,requestId=
dc803544-d1ef-4f95-9df4-72e222f04000,生成货单5b5782d7-5310-4000-9f62-703ec589ffd2。材料变为4份、revision10,没有发放或直接改写准备数据。 - 打开127.0.0.1页面后,实际身份仍显示local1,与交接记录中local2的假设不符;没有据此购买或切换既有浏览器会话。关闭该临时页,买方改用local2独立临时API会话。因此本批证据为卖方浏览器+买方实际API,不宣称完成双账号浏览器购买流程。首次引用的浏览器变量已不存在,之后使用既有浏览器ID创建页面,没有重新选择浏览器或变更会话。
- 第一笔购买1份,requestId=
36614644-9249-4822-affe-5104830ea0c5,返回200;货单仍active且剩余1份,local2灵石41479→41379,local1灵石暂不变化。新增买方物品邮件97122b3a-f5f8-4108-8982-12b2a6d325a6(玄铁1份)与卖方成交款邮件7f662471-9f78-4c1b-b858-cd1ae3ba680d(97灵石)。卖方刷新页面显示剩余1份,截图/tmp/daoyou-nest-auction-partial.png。 - 第二笔使用新requestId=
1a6a3369-4cc1-4c51-8c69-f45aa09d7cee购入剩余1份,返回200;货单sold、剩余0,local2灵石41379→41279。新增买方邮件b4978395-25ae-4bc6-a795-d6855703deac及卖方邮件8d1ff772-ee51-49b2-8dcf-1edb55d511e8,附件各为玄铁1份及97灵石;卖方刷新后我的寄售为0单,没有遗留活跃货单。 - 两笔购买均各自重试原请求:200、replayed=true、data与原结果深比较一致,数据库角色、库存、货单、邮件、journal及资源事件不变。相同请求编号改quantity=2均返回409;新编号超出剩余量或在售罄后购买均返回404,同样无额外变更。该购买路径没有新增player_journal,实际幂等凭据位于player_mutation_requests;只读确认auction_buy下对应两个
auction-buy:<listingId>:<requestId>记录,不将零journal误判为没有幂等持久化。 - 买方尝试领取本批卖方邮件返回404且状态未变;随后正常领取两封买方邮件,材料数量合计增加2。每封原邮件再次领取均200、replayed=true且全量快照不变。卖方通过页面逐封领取本批两封成交款,不使用一键领取,最终灵石473814→474008。四封邮件均is_claimed=true,总支出200、卖方收入194、手续费6,与页面规则一致。截图
/tmp/daoyou-nest-auction-settled.png显示两封成交款已领取。 - 最后只读核对首次误把Better Auth会话列写作snake_case而查询失败;按既有Schema改为带引号的userId/createdAt后通过,未改认证表。三个临时local2 API会话均sign-out200,本批时间窗口内剩余临时会话0;浏览器既有会话保留。
- 页面已关闭,没有使用网络拦截。核对命令及工作目录后SIGTERM停止Nest18506、Vite18509及Bun父进程18507/18508,启动会话均退出143,日志
/tmp/daoyou-nest-auction-runtime.log包含shutdown complete,前端日志/tmp/daoyou-nest-auction-web.log;3001/5174无监听。保留正常交易及邮件领取结果。 - 本批仅更新验收文档;执行实际页面、HTTP及只读数据库检查,
git diff --check与Markdown结构检查通过。运行源码未变,未重复lint/build/共享测试,最近2401通过/2失败记录保持。未新增测试文件或保存一次性脚本,未提交、部署或执行数据库迁移。私有货单可见性、灵兽交易、灵田、黑市成交、自然会话续期等仍按原清单继续收口。
第四十一批:灵田播种、自然生长与收获验收(2026-10-01)
- 数据库只读确认local2的6块灵田均为空,已有凡品青木藤籽3份(revision0),各阶段基础时长4分钟。使用内置浏览器既有local2会话,Chrome既有local1会话未动。第四十批只检查了Chrome内的两个地址;本批明确找到内置浏览器中独立的local2,不能仅凭主机名推断浏览器身份。
- 正常页面播种第1畦,requestId=
field:89812bcb-69eb-466f-94bd-558b1e7923ab,材料ID=e86055ae-ab39-446d-b643-40ef878409a6。种子3→2、revision0→1,开始时间2026-10-01 12:01:22.047 UTC。未发放灵种或回写生长时间。 - 首阶段选择天地灵气催芽,requestId=
field:1660b6aa-af00-4b7a-a0d8-95f58c195ae8,页面灵气228→223。真实生成反馈为good,时长169200ms,结束时间12:04:33.878 UTC;田地version4、careCount1。正常等待后页面自动进入蕴灵期。 - 原播种与首阶段培育请求重试均200、replayed=true、结果与对应journal深比较一致;角色、田地、库存、journal及资源事件前后不变。新编号携旧灵种版本播另一空田409;原编号改田块或培育方式409;生长中再次培育及提前收获409,均无额外消耗或状态变更。首次检查误到player_mutation_requests中查凭据而失败,随后按实际自动journal路径完整重跑通过;两次临时API会话均sign-out200。
- 蕴灵期正常选择天地灵气催生,requestId=
field:4c29f3c4-999b-41d4-8edc-d0174a4d6785,页面灵气223→215,真实反馈good,时长169200ms;田地version5、careCount2,结束时间12:08:11.163 UTC。 - 成型期正常选择凝叶成药,requestId=
field:72c48751-2c87-488d-89d0-0f313cbb8e39,无需消耗;真实反馈strained,按现有规则时长268800ms,结束时间12:13:33.167 UTC。田地version6、careCount3,保留该实际反馈,没有调整结果以缩短等待。 - 在生长期间构建本地amd64镜像后,核对自启动Nest18765的命令/工作目录并SIGTERM退出143,日志含shutdown complete。用该镜像在相同本地API端口启动独立容器(development关闭Cron),数据库/Redis/NATS仅连接daoyou-local网络服务。健康检查200且三项设施up;页面刷新仍为原local2身份、成型期及原生长进度。四个原播种/培育请求在容器中重试均200、replayed=true,完整持久状态不变。镜像构建及运行检查另见第四十二批。
- 自然成熟后通过页面收获,requestId=
field:498c59e3-330c-4c50-b97b-9b06a5b1f4a4。amd64容器日志确认POST/api/spirit-field/harvest返回200(1974ms);实际生成凡品灵草材料「青木凝叶」5份,score65、无变异或降品。产物ID=7dec54dc-840e-447a-ba6f-c2cb5385daf8,journal ID=93abb865-12fa-4199-901a-f98d1e49a041。背包27→28行,既有库存行数量及版本不变;田地version7、careCount3、harvestCount1,6块田均为空。灵石保持41279,持久化灵气215,页面因自然恢复显示217;收获没有额外货币消耗。 - 收获后重试播种、三次培育及收获共五个原请求,均200、replayed=true,结果与各自journal深比较一致;完整角色、田地、库存、journal及资源事件快照不变,没有重新种植、重复扣费或多发产物。新编号收获空田409,原收获编号改plotIndex=1返回409,状态均不变。临时API会话均sign-out200。
- 页面确认收获次数1及空田,再到背包确认「青木凝叶」5份及预览。截图为
/tmp/daoyou-nest-field-success.png和/tmp/daoyou-nest-field-product.png。刷新后的浏览器网络记录未完整保留收获POST,本条HTTP状态证据来自容器日志,请求编号及持久结果来自journal,不记为浏览器网络捕获完整。 - 页面关闭,原有浏览器登录保留。核对命令及工作目录后停止Vite18768及Bun父进程18766/18767,启动会话退出143;amd64开发容器以
docker stop -t 75正常退出0,日志含shutdown complete,随后移除。日志为/tmp/daoyou-nest-field-runtime.log、/tmp/daoyou-nest-field-web.log和/tmp/daoyou-nest-field-amd64-runtime.log。没有活动种植或遗留验收进程,保留正常玩法消耗与产物。
第四十二批:amd64镜像与本地生产模式验收(2026-10-01)
- 执行
docker build --platform linux/amd64 -f docker/Dockerfile.app -t daoyou-nest:local-amd64 .成功。构建包含Bun frozen安装、服务端TypeScript检查与Vite构建、npm ci --omit=dev;构建日志/tmp/daoyou-nest-amd64-build.log。镜像ID=sha256:1f4c1874edc79887eedd61999e604a07c8f4c385ade52fb19ed721eafc5601f7,平台linux/amd64,在arm64宿主通过OrbStack模拟运行,并非目标生产服务器实测。 - 镜像内Node24.18.0、Nest12.1.2、UID1000、停止信号SIGTERM;Nest入口存在,未打包源码、env目录或Bun,没有直接Hono运行依赖。首次通过require读取Nest package.json受包exports限制,改为读取实际文件后确认版本,没有修改应用代码。该镜像在development模式完成第四十一批的恢复、收获及重试。
- 使用同一镜像、
NODE_ENV=production、APP_ENV=local及本地PostgreSQL/Redis/NATS连接进行独立验收,Cron密钥临时生成且未输出。健康检查200且各设施up;匿名auth/get-session200;拍卖列表401;开发物资接口404;Cron缺少或错误Bearer均401;验证码配置200;未知API404;匿名畸形JSON炼丹请求仍先返回401;非法Origin返回403。共10项检查通过,未调用正确密钥的Cron写入接口。 - 另启动生产模式缺少CRON_SECRET的本地容器,健康检查200,Cron入口500,符合当前Guard契约。两个生产模式容器均执行
docker stop -t 75退出0,日志确认shutdown complete并已移除;日志为/tmp/daoyou-nest-amd64-production-runtime.log和/tmp/daoyou-nest-amd64-production-missing-secret-runtime.log。3001/5174无监听,本地四项基础设施保持healthy。 - 安装报告6项依赖告警(4 moderate、2 high)。仓库执行只读
npm audit --omit=dev --json返回1;报告涉及nodemailer9.1.1、undici7.29.0及drizzle-kit/esbuild相关依赖。逐项与HEAD锁文件比较,涉及版本均未随本次迁移变化。没有运行audit fix或升级依赖,也不据告警直接断言应用可被利用;这些属于发布前需要独立评估的既有依赖问题。镜像没有项目锁文件,容器内audit未提供可用清单,以上审计来源为仓库锁文件。 - 本批没有运行源码修改;镜像构建已执行服务端类型检查/构建,未重复完整客户端构建、lint或共享测试。最近lint/完整build通过,共享测试仍为2401通过/2失败(炼器堆叠预期及技能内容哈希基线),不得记为全绿。没有新增测试文件或保存一次性脚本,未提交、推送、部署或执行数据库迁移。
- 当前剩余验收为自然会话续期、私有拍卖/灵兽交易、黑市成交、旧宝库取出及多人奖励等尚未覆盖的合法玩法路径。真实生产配置、目标服务器、灰度和回滚仍未执行;本地production模式通过只支持镜像可运行及所列安全分支的结论。
第四十三批:灵兽拍卖交付与私有寄售缺符回滚(2026-10-01)
- 复用当前Nest产物和Vite,数据库连接强制只读。local2在内置浏览器、local1在Chrome,各自既有登录保留。只读确认双方已有好友关系;统一背包没有
auction_private_listing符箓。使用local2已有闲置灵兽「岩甲猪」(物种钢背猪、11级、revision2),ID=f5cec4c2-d964-4ccd-a581-642a31e9c28b,没有发放资源或调整编组。 - 页面按100灵石选择好友local1专属寄售,requestId=
c0869f0b-e777-4763-90ec-fe9c214356a1,实际POST/api/auction/list-beast返回400「缺少随身拍卖行贵宾符」。角色灵石/condition、灵兽、编组、库存、货单、邮件和player_mutation_requests完整快照哈希均与提交前一致。仅证明缺符拒绝及回滚,不将私有货单可见性记为通过。 - 改为公开寄售,requestId=
223c31f0-7e75-45fe-8874-9005ae147cf3,页面POST200,生成货单d15e3a9b-e9fc-4963-93e6-7c0d92265f2e。灵兽暂离卖方仓,货单快照revision3。临时API会话重试原请求200、replayed=true;原编号改变价格409,新编号重复寄售已经离仓的灵兽409,卖方购买自己的货单403;上述持久快照均未再次变化。 - 买方Chrome页面确认卖家local2与100灵石后购入,requestId=
0d178fe9-8d5d-4878-a8fd-8107ef096fad,POST/api/auction/buy200。货单sold、剩余0,买方灵石474008→473908,卖方领取前仍41279;生成买方灵兽邮件b3416632-f8e5-4b8e-bfd2-9444f4f9ef84和卖方97灵石邮件aca3bf58-fe3a-461c-8079-ec34e3a48daf。领取前灵兽仍未归入任何角色仓。原购买请求重试200、replayed=true;同编号改数量409,新编号购买售罄货单404;快照均不变。 - 双方分别在页面逐封领取本批邮件,没有使用一键领取。卖方灵石41279→41376,买方灵兽仓22→23;灵兽ID和创建时间保留,归属改为local1,revision4,其余individual字段与寄售前逐项深比较完全一致。双方编组及统一库存均不变,没有自动携带或设为首发。两封邮件已领取。
- 领取后两封邮件原请求各重试200、replayed=true;卖方越权领取买方邮件404;再次重放最初上架与购买请求也均200、replayed=true。角色灵石/condition、灵兽、编组、库存、货单、邮件及mutation凭据完整快照不变,没有重新转移灵兽或重复扣款/交付。四个临时API登录均sign-out200。买方灵兽页面显示11级岩甲猪、成长1.021、寿命1000及原资质,截图
/tmp/daoyou-nest-beast-trade-success.png;两页控制台未见error。 - 初次只读查询误写
lineups列名,按Schema修正为lineup后通过;首次输出全量历史快照过长,改为内存深比较及摘要哈希,没有保存验收脚本或改动产品代码。 - 两个页面已关闭,原浏览器会话保留。核对PID/命令/工作目录后SIGTERM停止Nest20507、Vite20511和Bun父进程20509/20510,启动会话均退出143。日志为
/tmp/daoyou-nest-private-auction-runtime.log和/tmp/daoyou-nest-private-auction-web.log,Nest日志含shutdown complete。保留正常交易、手续费及交付结果,没有活动货单。 - 本批只更新文档,未改运行源码,未重复lint/build/共享测试;最近2401通过/2失败记录保持。执行浏览器、实际API、只读数据库核对及文档差异/结构检查;未提交、部署或迁移数据库。私有拍卖成功路径仍需合法贵宾符,其他未完成项沿用原验收清单。
第四十四批:旧宝库材料取出与整批回滚(2026-10-01)
- 只读查询确认旧consumables表同样没有
auction_private_listing贵宾符;local1旧材料3种、local2旧材料1种,各2份。复用当前Nest产物及Vite,在Chrome local1和内置浏览器local2的既有会话中验收,没有注入物资。实际旧宝库页面为/game/cave/storage,统一储物袋为/game/inventory。 - 正常取出前,用临时local1 API会话检查批量第二项数量不符、同一项重复出现,以及单项取出local2材料:均409。每次前后角色灵石/condition、旧材料/消耗品、统一库存及资源事件完整快照一致。批量首项已经进入事务操作后,后项失败仍完整回滚,没有先发一份新物品或删除旧材料。
- local1页面点击「取出本页」,实际POST
/api/combat-v6/forging/vault/withdraw-page200、Cache-Control为no-store。输入为10L验收凝血草a8518c43-71c6-485b-8714-fd6e56e5eb07、寒潭白泥839665b3-0be5-4a3b-94d8-6b7378cdd100和日志旧附件灵草8deadb94-6123-41f5-b7b3-748e3c201691,expectedQuantity均2。三条旧记录移除,转为三条material.v1库存:凝血草入bag(39→40格,ID=a04f82fb-dd9e-4552-be3e-bf8a7bfcf48c),白泥和日志灵草入storage(ID分别为bf66ec98-13b2-47b7-998a-1cb3128590ac、90d3a82d-db1e-4427-8bbf-4cf94f292579)。名称、类别、品质、元素、描述及数量逐项一致,既有库存哈希不变,灵石保持473908。页面进入储藏室确认两种溢出物品各2份。 - local2页面对「10Q历史草药」点击「全部取出」,POST
/api/combat-v6/forging/vault/withdraw200;旧ID=967b2dea-a761-44da-afc6-33a23125be44、expectedQuantity2。旧行移除,新material.v1 ID=2f358dc8-3c73-4be8-9c6e-4a6f82d245f6进入bag(28→29格),事实和数量保留,既有库存不变,灵石保持41376。 - 两次成功各增加6条资源事件。首次核对只按服务显式changes误预期5条;检查实际事件及ResourceEventCommitter后确认
withCharacterPanelInvalidations会补充player.condition / character.panel.changed,按真实六项重新检查通过。未改产品代码以满足检查假设。 - 对已取出的同组材料再次批量取出、对local2原单项再次取出,均返回409「物品已变化,请刷新宝库」,完整持久快照及资源事件不再变化。该旧接口没有requestId及replayed响应,依靠来源行/expectedQuantity检查防重复,本批不将其描述为返回原成功结果的幂等重放。
- 批量成功页截图
/tmp/daoyou-nest-vault-batch-success.png,储藏室截图/tmp/daoyou-nest-vault-storage-success.png。浏览器未见error,两个页面已关闭,四个临时API会话均sign-out200;原浏览器登录保留。核对PID、命令和工作目录后停止Nest21085、Vite21088及Bun父进程21086/21087,启动会话均退出143;日志/tmp/daoyou-nest-vault-runtime.log含shutdown complete,前端日志/tmp/daoyou-nest-vault-web.log。保留正常取出结果。 - 本批只改验收文档,未新增测试文件或保存一次性脚本,未重复lint/build/共享测试;最近2401通过/2失败结果保持。执行浏览器、实际HTTP、只读数据库、
git diff --check及Markdown结构检查。没有部署、提交或数据库迁移。旧消耗品/灵种取出与私有拍卖成功路径尚无合法存量用于本批验收,仍不记为通过。
第四十五批:黑市成交、交付与持久防重(2026-10-01)
- 当前Nest产物及Vite,本地Chrome复用local1。页面恢复
TN_YUE_01笑面掌柜的原会话1c42e737d19c96986e002f09fb3f8c9939930d52:重新进入后talking、version5、尚可交谈4次,入场cost0、free=true、replayed=true。保留第三十五批产生的观察和两次交谈结果,本批没有生成新提案或修改货品/定价。 - 成交前通过临时API分别提交旧version4和错误expectedPrice6231,均409;角色灵石/condition、旧库存、统一库存、mutation凭据及资源事件快照不变。页面实际报价6230,余额473908。
- 页面「按此价拿下」并确认「成交揭晓」,POST
/api/black-market/TN_YUE_01/sessions/1c42e737d19c96986e002f09fb3f8c9939930d52/commit输入{version:5,expectedPrice:6230}返回200。揭晓地品雷属性灵药「金雷竹心」1份,库存ID=d7141ef1-d549-4995-ab41-11e4d08d19c7;背包40格已满,产物进入storage。灵石473908→467678,既有库存行哈希不变,新增一条currency.black-market.spent事件(scopeVersion634)。截图/tmp/daoyou-nest-black-market-deal-success.png。 - 本路径通过自动player_journal保存防重结果,operationKey=
black_market_purchase:2026-10-01:TN_YUE_01:smiling-keeper,journal ID=00a93441-15c9-4118-9c12-0ae650dda634,仅一条;player_mutation_requests没有新增。首次核对误期待mutation凭据增加,随后又误用journal不存在的request_id列;根据Schema和CommandExecutors修正后完整验证通过,没有修改应用或数据库结构。 - 原成交请求重试200、replayed=true,返回结果与journal.event.result深比较一致;角色、库存、journal、mutation凭据及资源事件完整数据库快照不变。Redis会话保持completed且reveal相同,但version6→7、messages6→7:现有
commitBlackMarketPurchase在重放后仍同步会话并追加成交提示。该领域服务与HEAD无差异,本批保留既有行为;不能据数据库防重宣称所有会话状态完全不变。 - local2请求成交返回403,来自既有境界门槛,不将其记作已覆盖可入场账号的成交归属校验。local2请求离开local1会话返回404,数据库和Redis会话快照不变。本地其余测试角色均为炼气,无第二个满足黑市门槛的现有角色;没有调整境界以制造验收条件。
- 页面刷新显示「今日已成交」,点击「查看成交结果」仍显示原物品及余额467678;浏览器未见error。会话已completed,无待处理交谈。五个临时API会话均sign-out200,既有浏览器登录保留,页面关闭。核对PID/命令/工作目录后停止Nest21550、Vite21553及Bun父进程21551/21552,启动会话均退出143。日志
/tmp/daoyou-nest-black-market-deal-runtime.log含shutdown complete,前端日志/tmp/daoyou-nest-black-market-deal-web.log,保留实际成交结果。 - 本批只更新文档,无运行源码修改;未重复lint/build/共享测试,最近2401通过/2失败记录保持。执行页面、实际API、只读PostgreSQL/Redis核对及文档差异/结构检查。未新增测试文件或保存一次性脚本,没有提交、部署或数据库迁移;其余验收继续按清单收口。
第四十六批:双人讨伐落败、状态结算与回放权限(2026-10-01)
- 复用当前Nest产物与Vite,Chrome local1、内置浏览器local2保留既有登录。活动
hunt-v3-82911-0为金丹50级掠影妖貂,现有角色最高筑基;没有调整属性、注入物资或强制胜利。队伍d4eeafb2-b7a7-4f3e-bea6-0ed59dff158d由local1页面创建,招募炼气至筑基,local2页面加入;双方准备状态同步。队员用当前revision3请求开战返回403「只有队长可以开战」。 - 队长页面发起讨伐,进入战局
2e30acd6-63c0-4ae6-b5d8-d01d97891b2f,队员从大厅「进入战斗」进入同一战局。队长启用自动;队员未在首回合时限内提交,实际执行默认攻击。第1回合正常落败,双方倒地、队员灵兽战内死亡;两页显示同一战报及「此战未能得胜」。未将队员自动开关的未完成操作记作成功。 - 只读Redis确认stage=finished、terminalReason=battle-ended、winner=1、reason=wipe,资源策略persistent。数据库中
hunt-reward-v1、messageId=战局ID的消费凭据恰为1条;回放归档source_type=hunt、battle_type=pve、outcome=side-1、round_count=1,参与者两条。双方战内HP为0;持久condition按既有结算规则保留HP=1,local1法力830、local2法力900,与终局一致,lastBattleAt/lastRecoveryAt更新。双方战斗占用键均已释放。 - 开战前后对双方灵石/修为进度、153条统一库存、78封邮件及44条player_journal排序后完整内容哈希核对,均不变。local1灵石467678、local2灵石41376,落败没有发放奖励或邮件。两人奖励接口200、status=no-reward,重复读取后仍无新增变更;本批没有重投终局消息,不能据重复GET宣称已运行验证消费者重投幂等。
- 两名参战者私有回放均200;local3奖励读取403、私有回放404。队长刷新后恢复相同落败战报。截图
/tmp/daoyou-nest-hunt-defeat.png。终局队伍恢复assembling且双方未准备,队员、队长依次在页面离队;最终两个账号大厅myTeam=null、teams为空,没有遗留队伍或活动战斗。 - 页面控制台未见error,两个临时页面已关闭,原浏览器登录保留。本批恢复后使用的7个临时API会话均sign-out200。核对PID、命令与工作目录后SIGTERM停止Nest22021、Vite22024及Bun父进程22022/22023,启动会话均退出143;日志
/tmp/daoyou-nest-hunt-runtime.log含shutdown complete,前端日志/tmp/daoyou-nest-hunt-web.log,3001/5174已无监听。保留正常玩法消耗;未直接恢复角色气血。 - 本批仅更新验收文档,执行浏览器、实际API、只读PostgreSQL/Redis核对、
git diff --check及Markdown结构检查;未改运行源码或新增测试文件/一次性脚本。未重复lint/build/共享测试,最近lint/build通过及2401通过/2失败记录保持。未提交、推送、部署或迁移数据库。自然会话续期、私有货单成功可见性、旧消耗品/灵种取出、多人胜利发奖与其余未覆盖玩法,以及真实生产配置/灰度/回滚仍未验收。
第四十七批:发布文档与当前调度定义对齐(2026-10-01)
- 复核Nest启动、RuntimeService、CronService、请求上下文、会话服务及相关模块导入。继续保持Better Auth原始请求、单例服务不保存请求身份/BYOK、显式构造器注入、HTTP处理排空后关闭消息和数据设施。此次源码审阅没有发现需要新增适配代码的问题;不将审阅计作新的运行验收。
docs/development.md仍将CI触发条件写成master分支推送,且列有当前不存在的tower-enemy-sets、player-state-events-cleanupCron入口。按实际工作流修正为任意Git标签推送、版本/完整SHA/latest镜像标签,并明确工作流不执行服务器蓝绿脚本、没有独立lint/共享测试门禁。- 按
internal-cron.controller.ts与schedules.ts重写十项手动入口、command和Asia/Shanghai频率表,补齐材料库和赞助相关调度,移除旧入口示例。说明当前无独立内置调度开关,不能仅添加外部crontab就称为完成调度切换。没有改变任何实际Cron表达式或触发任务。 - 本地只读PostgreSQL查询发现物品库存在拍卖行贵宾符
ef138167-4841-4a47-83aa-b6008c748c7b,但status=archived;声望商店与宗门商店的item_snapshot均无auction_private_listing。结合此前库存检查,这两个现有商店入口无法提供本轮私有寄售验收所需贵宾符。未解归档、添加货架或发放测试物资,不推广为所有潜在玩法来源都不存在。 - 内联文档检查逐项比较10个HTTP路径、10个command及UTC转北京时间,全部通过;工作流标签触发及Markdown围栏检查、
bash -n scripts/blue-green-app.sh、git diff --check通过。没有保存一次性检查脚本。仅修改文档,未重复lint/build/共享测试,保留最近2401通过/2失败结果。没有启动应用、部署、提交或执行数据库迁移;剩余运行验收与上线门槛不变。
第四十八批:丹方自然发现、本人收录与重复确认(2026-10-01)
- 当前Nest产物与Vite、本地内置浏览器local2既有登录。只读确认没有待确认丹方,该角色持有丹方0份。首次以已有真品紫蕴灵参1份正常炼制,requestId=
b712289c-483f-4a30-984f-e2b6a4be2944,POST/api/craft返回400「本炉药蕴不足,无法凝成丹药」。前后29条统一库存、20条journal、丹方、灵石及持久qi/刷新时间快照一致,未扣除页面所列12800灵石或消耗灵参。 - 页面改用青纹藤叶3份(
9193e333-bf45-4e09-971d-ae38f2a77cfa)与第四十一批收获的青木凝叶5份(7dec54dc-840e-447a-ba6f-c2cb5385daf8),正常填写恢复气血意图并确认1600灵石、1灵气。requestId=4f9aca49-add9-49f0-8f1a-2083624b3b7c,POST200,成丹稳度79,产出凡品青木归元丹共3枚,分别为2枚ebd35453-e032-4605-8d23-9653bc3b3090、1枚6a085d4d-893b-4c80-bdd0-d4fde5f2da01,均入bag。两种药材行耗尽移除,紫蕴灵参仍1份,背包仍29格。灵石41376→39776;持久qi经自然恢复并支付后为223,页面确认前显示224。未改属性、随机值、判定或发放物资。 - 实际响应发现「青木归元丹丹方」,family=healing、木属性、两味凡品材料、restore_hp权重1、熟练度0。候选token=
822ef3d5-5425-40d1-9ee2-4c9d6a834cb4。local1提交该token确认返回404,local2候选Redis内容及角色/库存/日志/丹方快照不变。 - local2页面「保存丹方」POST
/api/alchemy/formulas/discovery/confirm200、saved=true,丹方ID=51859b13-ad34-40ad-a891-f6d8bb7acd44。丹方从0增至1,候选Redis键删除;确认本身没有再次改变灵石、qi、库存或journal。进入丹方玉简并刷新,仍展示疗伤、木、两味、凡品、Lv.0,余额39776,截图/tmp/daoyou-nest-formula-discovery-success.png。 - 本人重复相同token、accept=true返回404「待确认丹方已散去,可能已过期」;accept=false返回200、saved=false,全部持久快照不再变化。该接口成功后删除候选,并非返回原成功结果的幂等重放,不将404称为replayed成功。没有运行并发确认或修改候选TTL。
- 已保存后重放原炼丹请求200、state.replayed=true,丹方、库存、journal、灵石及持久qi快照不变,候选键未重建。原炼丹journal恰为1条,ID=
78910813-d505-4f85-bb0c-a278f4fd5bc7、operationKey=alchemy_improvised:4f9aca49-add9-49f0-8f1a-2083624b3b7c;重放响应不含formulaDiscovery,不能宣称包含候选的全部响应与首次完全相同。相关旧应用服务/前端与HEAD无差异,未调整原有发现机制。 - 第一次确认后快照比较将pg返回的Date与先前序列化ISO字符串直接深比较而失败,尚未创建API会话;统一快照序列化后重验通过,没有修改产品。三个临时API会话均正常sign-out200;临时页面关闭,既有登录保留。核对PID、命令与目录后停止Nest24287、Vite24290及Bun父进程24288/24289,启动会话退出143,日志
/tmp/daoyou-nest-discovery-runtime.log含shutdown complete,前端日志/tmp/daoyou-nest-discovery-web.log;3001/5174无监听,保留正常成丹和丹方。 - 本批只更新验收文档;执行真实浏览器/API、只读PostgreSQL/Redis、文档结构及
git diff --check。未新增测试文件或保存一次性脚本,未重复lint/build/共享测试,最近2401通过/2失败记录保持;未提交、部署或迁移数据库。自然会话续期、私有拍卖成功、旧消耗品/灵种取出、多人胜利发奖及其余既定门槛仍未完成。
第四十九批:已登录非管理员全量后台拒绝与角色归属(2026-10-01)
- 审阅历史待办后,补齐第十三至十六批普通已登录非管理员403的运行证据。由TypeScript AST读取当前admin和legacy-items Controller,提取
api/admin下55组method/path,逐项确认类级Access为admin或account-admin且无方法级覆盖。此清单为20 GET、26 POST、6 PUT、3 PATCH;不包含Better Auth认证管理拦截或未知路由。 - 只读本地数据库取得local3身份,以现有adminAccess函数确认其既不在管理员邮箱也不在用户ID授权范围;正常登录后先验证
/api/admin/session403,再逐项请求55个方法。动态ID替换为不存在的UUID;35个写方法携带畸形JSON。全部403,响应success=false及对应管理员错误文案,证明这些请求在业务解析/执行前被拒绝。没有修改授权配置、发起真实订单处理或成功发送邮件。 - 前后对16张相关业务表的全部行排序哈希和数量比较,完全一致:app_settings、feedbacks、item_library、redeem_codes/claims、两类shop_items、sponsorship的admin_actions/checkout_intents/claims/merit_profiles/merit_records/order_snapshots/orders、system_mail_campaigns及tower_enemy_floors。摘要比较不包含登录本身创建并正常退出的临时认证会话;未输出配置内容或凭据。
- 另以local1、local2各自正常登录,GET
/api/enemies/:id读取本人活跃角色200且返回ID匹配;读取对方或不存在UUID均404「敌人角色不存在」。补齐第八批已登录成功和归属边界,两账号各3项。三个旧排行榜挑战POST入口challenge、challenge-battle、challenge-battle/v5即使携带畸形JSON也均410,两账号共6项;没有创建新挑战或消耗挑战次数。 - 首次只读身份查询误用单引号引用Better Auth的user表,语法错误发生在登录前;改为双引号表名后全部检查通过,未改产品代码。三个临时会话均sign-out200,没有打开浏览器或改变原有浏览器登录。
- 核对PID、命令及目录后SIGTERM停止Nest24815,启动会话退出143,
/tmp/daoyou-nest-admin-deny-runtime.log含shutdown complete;3001/5174无监听。仅更新验收文档,执行实际HTTP、只读SQL摘要、AST清单、Markdown及git diff --check;未保存一次性脚本或新增测试,未重复lint/build/共享测试,保留最近2401通过/2失败结果。未部署、提交或迁移数据库;管理员成功写入、剩余玩法与自然续期等待办继续保留。
第五十批:宗门清扫任务生命周期与幂等(2026-10-01)
- local2通过本地内置浏览器正常承接清扫山门,任务记录
7912279e-b157-4a75-afb4-76d88eb4917a,periodKey=2026-10-01。accept请求键5eb0bc35-6a8c-40c2-92fe-259b0ea4fa8c、start请求键7ddd8950-0e1c-43f7-b202-e57051ff2df6均200;清扫sessionId=4264101c-a911-4e66-8995-6cf725a75cb0,rulesVersion=3。 - 首次键盘尝试后通过页面「重走」重置棋盘,再依据可见棋盘逐格点击,16步收集4片落叶并到达终点。页面自动提交真实moves,complete以sessionId为幂等键返回200;任务completed、progress=1,尚未领奖时贡献5、灵石39776、修为1780。没有伪造完成请求、改时间或注入棋盘状态。
- 返回照灯执事处正常复命,claim请求键
eea97527-4bbb-475d-a9ab-b805b9278cf9返回200。只读数据库确认贡献与累计贡献5→9、灵石39776→40776、修为1780→1830,库存行内容不变;任务claimed_at已写入,本周勤勉periodKey=2026-09-28、progress=1。刷新后功簿仍显示本期已经结清,截图/tmp/daoyou-nest-sect-task-claimed.png;清扫完成截图/tmp/daoyou-nest-sect-sweep-complete.png。 - 承接后重放accept200、replayed=true,缺失幂等键400、相同键改变input返回409,前后任务/贡献/灵石/库存快照一致。领奖后重放原accept、start、complete、claim四个请求均200、replayed=true;claim缺失键400、改变input复用键409,前后任务/贡献/修为/灵石/库存快照一致,未重新开启场次或重复发奖。
- 四个持久幂等凭据位于player_journal,operation_key分别为
sect_task_action:<请求键>,恰为四条。最初误查player_mutation_requests得到0条,修正核对位置后通过;未修改产品实现。不将本批串行重试推广为并发提交、场次过期或其他宗门任务均已验收。 - 本批三个临时API会话(含承接前读取任务的会话)均正常sign-out200,临时页面已关闭,原浏览器登录保留。核对PID、命令和目录后停止Nest25249、Vite25252及Bun父进程25250/25251,启动会话退出143;
/tmp/daoyou-nest-sect-task-runtime.log含shutdown complete,3001/5174无监听。正常玩法任务和奖励保留。 - 仅更新验收文档;执行浏览器/实际API、只读PostgreSQL、Markdown结构与
git diff --check,未新增测试文件或保存一次性脚本,未重复lint/build/共享测试。最近lint/build通过、共享测试2401通过/2失败的记录保持。未提交、推送、部署或执行数据库迁移;自然会话续期、部分玩法成功分支、管理员成功写入及目标生产配置/灰度/回滚仍未收口。
第五十一批:迁移前测试对照与后台草稿写入(2026-10-01)
- 为复核两项共享测试失败,在独立托管worktree检出迁移前HEAD
c0b267df8ef3a6f4ef38732c79a3020068c2b3dd,使用其原始package.json与bun.lock执行bun install --frozen-lockfile。该目录没有Nest源码,工作区保持干净;没有复用当前迁移目录的node_modules。 - 在迁移前与当前两个工作区分别执行
bun run test packages/shared/src/forging/forging.test.ts packages/shared/src/engine/combat-v6/content/skill-learning.test.ts,两边均11通过/2失败:材料堆叠预期[99, 2]、实际[101];宗门内容哈希预期2df399289489cf42dbdbe37fb504a3230c525fbda25c68545faef2572480e279、实际3419722218ff4dcf2d494bbee4100ef963a05031aeabb3fd3948b9dbf6779513。这为两项失败在迁移前已经存在提供直接运行证据;未修改领域规则或断言,也不将全套测试记为通过。 - 本地Nest使用现有local1管理员正常登录,
/api/admin/session200。POST/api/admin/system-mails创建无附件、仅面向local2的验收草稿834ac6ab-5626-4ed4-a307-e352257bb168,200、draft、revision=1。原请求重复200且返回同一记录;同requestId改变内容409。 - PUT更新草稿200、revision=2;旧revision=1更新409。两个合法请求同时以revision=2更新不同正文,恰为一个200、一个409;最终revision=3。详情与搜索列表均200且显示相同草稿;再重放最初创建请求200,返回当前revision=3,没有覆盖已更新正文或新增记录。
- 只读数据库确认仅一条该ID记录、created_by=local1、status=draft、published_at为空、deliveredCount=0。前后全部玩家邮件、统一库存与角色表的行数和排序内容哈希一致。未请求publish/stop,没有发送系统邮件或发放奖励;本批仅证明草稿写入及并发版本控制,不证明投递生命周期或其他后台写入。
- 临时管理员会话sign-out200,未打开浏览器或改动原有登录。核对PID、命令与工作目录后SIGTERM停止Nest26459,启动会话退出143,
/tmp/daoyou-nest-admin-draft-runtime.log含shutdown complete,3001/5174无监听;验收草稿保留为未发布状态。基线工作区测试已结束并已归档,附件状态为archived_worktree。 - 发布配置审阅确认Node健康检查、75秒停机宽限期和旧Bun镜像回滚需匹配旧Compose的说明保持一致;
bash -n scripts/blue-green-app.sh通过。仅更新验收文档,运行源码未改;执行上述两工作区定向测试、真实HTTP、只读SQL、Markdown结构及git diff --check,未重复完整lint/build/共享测试或Docker构建,未新增测试脚本、提交、部署或迁移数据库。自然续期仍未达到既有会话的一天阈值;其余玩法及目标生产环境验收继续保留。
第五十二批:双实例资源广播与旧实例退出后重连(2026-10-01)
- 当前Nest产物以两个本地进程运行,A监听127.0.0.1:3001,B监听127.0.0.1:3002,共用本地PostgreSQL/Redis/NATS。两个健康检查均200,Redis、NATS、messaging为up;不是生产部署或OpenResty切流。
- 通过B为local1、local2分别正常创建临时会话。local2在A、B各建立一条
/api/realtime?channels=player-state连接,local1在B建立隔离对照连接,均收到ready。通过A的正常背包API将local2现有青木归元丹库存ebd35453-e032-4605-8d23-9653bc3b3090从slotIndex=1移至空格29,revision=0→1;没有消耗物品或发放测试资源。 - 资源事件
6b0cd291-410e-49aa-84d2-378d63b58303在local2的A、B连接均收到,完整事件内容逐项等于HTTP提交响应;local1未收到该事件,证明此实例组合下既有NATS资源广播跨进程送达且保持角色作用域隔离。 - 核对A的PID、命令与目录后发送SIGTERM。A连接关闭码1006,B连接仍打开,B健康检查200;local2在B新增连接收到ready。通过B将该物品移回slotIndex=1,revision=1→2;资源事件
7d2bb32a-832a-4dc8-9a48-3432b303f61b在B既有及重连后的local2连接均收到且内容匹配,local1未收到。各参与连接收到的相应事件ID均无重复。 - 只读PostgreSQL确认所选物品位置、数量和实例内容恢复原状,仅revision及更新时间按两次合法移动更新;该角色其余库存行完整内容不变。不将1006称为正常关闭握手,也不将本批直连端口验证称为零中断发布、擂台长连接恢复或实际代理/DNS切流。
- 所有临时WebSocket关闭,两个临时认证会话sign-out200;未打开浏览器或改变原有浏览器登录。A27013、B27014最终均退出143,
/tmp/daoyou-nest-overlap-a.log与/tmp/daoyou-nest-overlap-b.log均含shutdown complete,3001/3002无监听。 - 审阅蓝绿脚本发现开发文档称其「原子切换」,实际通过cp写入配置、nginx -t校验并reload,失败则恢复备份;文档改为描述实际顺序,脚本本身未改。仅更新文档,执行真实HTTP/WS、只读SQL、Markdown结构、
bash -n scripts/blue-green-app.sh及git diff --check;未重复lint/build/共享测试或构建镜像,未保存一次性脚本、提交、推送、部署或迁移数据库。自然会话续期、剩余玩法与生产灰度/回滚继续保留。
第五十三批:当前源码、路由覆盖与构建交付审计(2026-10-01)
- 重新执行
bun run lint与bun run build,均退出0;构建包含客户端、服务端TypeScript检查及Vite产物,保留前端大分包提示。日志/tmp/daoyou-nest-final-audit-lint.log、/tmp/daoyou-nest-final-audit-build.log。本批为交付审计重新构建,没有改变运行源码。 - TypeScript AST扫描当前Nest源码:42个Module、77个Controller、84个带框架类装饰器的构造器,共362条展开后的HTTP method/path,无重复声明;静态模块imports图无循环。首次检查把手动构造的ZodPipe参数误作DI依赖;核对其调用方式及未注册为Module provider后,确认只有schema和errorContract是调用方显式传入,其余所检查构造器参数均有@Inject。没有为检查器假设改动产品代码。
- 对照第十七批实际旧Hono清单348条,规范化具名路径参数与框架通配写法后,仅
ALL /api/auth/*不在Controller清单,已逐行确认由configureHttp的Better Auth原始请求处理器承载。额外声明为旧战绩/蜃楼battle根路径与13条末位鉴权兜底,均对应此前已记录的兼容行为。NotFoundModule仍位于AppModule最后,开发工具仍为条件导入。该静态对照不重新证明所有路由成功业务或通配语义,运行证据以相应批次为准。 - package.json、package-lock.json根包、bun.lock根workspace的dependencies/devDependencies逐项一致,无Hono直接依赖或构建插件。packages/shared/src、apps/web/src及两个Drizzle迁移目录与HEAD无差异;共享领域、lib与utils中未发现Nest/Hono import。业务服务与规则没有因迁移变成Nest框架依赖。
- 当前
apps/api/dist/main.js及镜像daoyou-nest:local-amd64内/app/apps/api/dist/main.js的SHA-256均为db2030b36781078ee18a8b38889ff7d31459c703198be94a503eff3f0020115f。镜像ID仍为sha256:1f4c1874edc79887eedd61999e604a07c8f4c385ade52fb19ed721eafc5601f7;只运行sha256sum并自动移除临时容器,没有启动生产模式应用或重新部署。 - 两项共享测试已由第五十一批原提交/原锁文件运行证明为已有失败,本批未重复共享测试或修改断言。完成Markdown结构及
git diff --check;3001/3002/5174无监听。本批仅更新验收文档,未提交、推送、部署或执行数据库迁移。 - 当前证据仍缺少自然updateAge会话续期、私有寄售成功可见性、部分旧物品取出、多人胜利奖励及其余尚未覆盖玩法;不能以静态清单替代。目标生产环境配置、代理切流及回滚尚未执行,已向用户明确询问本轮交付是否包含生产发布,未收到回答前不擅自部署或将其记为通过。
第五十四批:自动战斗策略持久化与续期条件复核(2026-10-01)
- 只读检查local1/local2会话元数据,共12条未过期会话,其中8条距updatedAt超过一天;没有读取会话令牌、修改时间或认证配置。这些数据库记录不证明现有浏览器持有对应Cookie。
- 现有Chrome在127.0.0.1打开正常角色页面,身份为local1;观察get-session及业务资源GET均200且无Set-Cookie,12条既有会话的createdAt/updatedAt/expiresAt前后不变。因此当前Chrome所持会话未触发续期,不把页面已登录或数据库存在旧会话记为续期通过。内置浏览器local2先前新建会话的一天阈值仍需自然等待。
- local2正常登录后GET
/api/combat-v6/auto-strategy200,流派youdu.path.poison_master,customStrategy=null。通过PUT保存一条使用当前可用技能youdu.skill.siphon、target=best、无条件的合法策略,200;随后GET读回内容完全一致,只读数据库确认角色/流派主键下恰为一条记录。重复PUT200,记录仍为一条;该接口为upsert,不称为带请求号的幂等重放。 - 写入前分别提交错误流派、未知技能、未知战斗资源、不可用状态,均409;11条规则以及额外cultivatorId字段均400。每次拒绝后整个自动策略表内容与基线一致。成功保存后,对错误流派DELETE返回409,当前策略仍保持原保存内容。
- 对当前流派DELETE重置200,再次DELETE仍200,GET恢复customStrategy=null。整个策略表完整内容恢复测试前基线,其他角色策略未变;local2统一库存、灵石及修为进度快照不变。没有开始新战斗、改变流派或直接写数据库;仅覆盖策略接口与持久化,不证明战内执行或并发流派切换。
- 两个临时API会话均sign-out200,Chrome临时页面已关闭,既有浏览器登录保留。核对PID、命令与目录后停止Nest28745、Vite28749及Bun父进程28747/28748,启动会话退出143;
/tmp/daoyou-nest-renewal-runtime.log含shutdown complete,3001/5174无监听,前端日志/tmp/daoyou-nest-renewal-web.log。 - 本批仅更新验收文档,执行真实浏览器/HTTP、只读PostgreSQL、Markdown结构与
git diff --check。未新增测试文件或保存一次性脚本,未重复第五十三批已通过的lint/build,未修改既有共享测试断言、提交、推送、部署或迁移数据库。自然续期、私有寄售及其余未覆盖玩法、生产范围确认仍待收口。
第五十五批:跨实例库存写入竞争与版本冲突(2026-10-01)
- 当前Nest产物以A3001、B3002两个本地进程运行,共用原本地PostgreSQL/Redis/NATS,健康检查均200。local2正常临时登录,使用现有青木归元丹
ebd35453-e032-4605-8d23-9653bc3b3090,数量2、slotIndex=1、revision=2;只读确认格位29、30均为空。 - 同时向A、B的POST
/api/combat-v6/inventory提交同一物品revision=2,分别移动到29、30。A200;B在共享角色锁竞争阶段返回429「操作正在处理中,请稍后重试」,Retry-After=1。实际不是两次均进入事务后才发生版本冲突,不将此结果描述为B409。 - 数据库确认仅A提交:物品slotIndex=29、revision=3,数量与instance_data不变,角色其余库存行完整内容不变。该并发窗口新增资源事件恰一条
38ef07ab-ae37-44c6-92a6-f980f718e3a8,ID、scopeVersion、resourceVersion与A响应一致,没有第二条资源提交。 - 随后分别向A、B串行重试原revision=2请求,均409。前后库存与该角色全部资源事件快照不变。再通过B携带当前revision=3移回原格位1,200、revision=4;物品除合法移动引起的版本与更新时间外恢复原状,其余库存行仍不变。没有改写数据库或注入锁故障。
- 临时认证会话sign-out200,没有打开浏览器或改变原有浏览器登录。核对PID、命令与目录后SIGTERM停止A28952、B28960,启动会话均退出143;
/tmp/daoyou-nest-concurrent-a.log、/tmp/daoyou-nest-concurrent-b.log均含shutdown complete,3001/3002无监听。 - 仅更新验收文档,执行真实双进程HTTP、只读PostgreSQL、Markdown结构与
git diff --check;未新增测试文件或保存一次性脚本,未重复lint/build/共享测试。该检查只证明本次库存竞争及重试路径,不能推广为所有业务锁、失租或数据库故障均已验证。自然续期、剩余合法玩法与生产范围/发布验收仍未完成,未提交、推送、部署或迁移数据库。
第五十六批:剩余验收前置条件与受阻审计(2026-10-01)
- 将旧数据/贵宾符核对范围从主要使用的两个角色扩至docs/testing.md列出的local1—local8。只读确认八个账号各有活跃角色;六个炼气后期、一个炼气圆满、一个筑基中期。没有查询或输出认证凭据。
- 八个角色数量大于0的旧consumables为0、materials中type=seed为0,creation_products记录为0。统一库存中包含auction_private_listing场景的物品为0;物品库有一条该场景且status=archived,reputation_shop_items和sect_shop_items对应快照数均为0。没有解归档、发放物资、插入历史数据或将空结果当作成功取出/兑换。
- 读取当前纯配置生成的讨伐活动:最低金丹50级,其余依次70至170级,当前周期截至2026-10-01 16:00:00 UTC。结合第四十六批真实落败,不能宣称多人胜利发奖通过;也不将等级差推断为穷举证明任何队伍都无法胜利。
- 续期条件已在第五十四批复核;生产范围询问仍未收到答复。上述时间、数据和目标环境条件连续多轮尚未变化;当前没有已启动而待完成的应用/测试进程,3001/3002/5174无监听。后续以条件变化恢复对应验收,不重复既有成功样本或扩张为全部业务规则重测。
- 本批仅只读核对并将前置条件集中至文档顶部;Markdown结构、
git diff --check通过,未重复lint/build/共享测试。没有运行源码改动、测试脚本、Git提交、生产部署或数据库迁移;目标保留未完成并标记为等待外部条件的受阻状态。
第五十七批:Nest CLI 与 workspace 交付(2026-10-02)
- API、Web、共享规则各有package.json;运行依赖和构建依赖归属对应包,根目录维护检查、迁移与部署命令。Bun使用隔离安装,npm工作区生产安装保留两份锁文件;各workspace的依赖声明与npm锁条目逐项一致,Bun frozen安装通过。
- API构建入口为
nest build,采用CLI 12推荐的原生ESM Rspack构建器。保留显式构造器注入,关闭隐式装饰器类型元数据;Markdown提示词和共享源码打包,API直接依赖外置。旧服务端Vite配置已删除。nest build --watch首轮构建通过;Web保持Vite、version.json和独立apps/web/dist。 - LLM角色、材料及灵种编排迁至API;材料/灵种随机骨架、角色组装及修为/突破计算留在shared。角色纯组装接收随机源,原有AI mock测试调整为纯组装断言;爱发电协议由宿主提供签名函数,共享生产代码不依赖Node内置模块。未改变数值、奖励、库存事实或数据库结构。
- ConfigModule关闭dotenv发现,提供Zod校验后的不可变环境快照;框架无关基础库使用同一快照,服务端仅此处读取process.env。必需配置、连接池大小和数值边界在启动校验,生产要求cron密钥并禁止本地开发模式。错误只含字段和约束。
PORT=0及production缺少cron密钥已验证启动失败。 - DatabaseModule注册既有Drizzle客户端,Runtime在HTTP、处理器和消息排空后关闭同一个pg.Pool。健康检查增加PostgreSQL探测及失败503分支;本地实测 database、redis、nats、messaging全部up。两条迁移流、表结构、事务executor传递与生产TLS设定沿用现状。
- Docker通过npm workspace仅安装API及shared运行依赖,并省略dev/optional/未显式声明的peer,避免Better Auth可选Vitest peer把测试与前端构建工具带入镜像。非root用户、Node 24、SIGTERM及原75秒停机窗口保留。
- 检查:
bun run lint、bun run typecheck、bun run build、Nest watch构建、bun install --frozen-lockfile、完整Docker构建通过。集中共享检查7个文件27项通过;完整共享检查仍为237文件、2401通过/2失败,与调整前完全相同。原失败是forging材料堆叠(101与99+2)及宗门技能内容hash基线;没有修改断言掩盖失败。 - 浏览器复用本地道友2既有会话,迁移后洞府、资源栏、闭关/突破标签及80.5%概率展示正常,浏览器error日志为空。匿名角色资源请求401,验证码配置200。最终镜像检查确认无Vite、Vitest、Nest CLI与应用源码;裁剪依赖后的镜像再次启动及健康检查通过。生产模式本地镜像健康检查200,未提供Bearer的内部cron401,dev资源入口404;正常SIGTERM排空并退出。生产模式本地定时任务实际执行了一次market-refresh(24项),灵种LLM生成成功,停机等待其完成;该记录只涉及本地专用数据。
- 跳过:没有修改schema,因此没有生成/执行迁移;没有发布镜像或部署真实生产,没有向staging执行玩法写入;特殊历史存量、私有寄售、多人胜利、自然续期与生产灰度/回滚继续依前述条件验收。
第五十八批:pnpm workspace 与 Turborepo(2026-10-02)
- 根目录固定
pnpm@10.34.6,仅保留pnpm-lock.yaml。通过旧npm锁导入依赖解析,再添加Turbo及tsx;删除bun.lock、package-lock.json、bunfig.toml、Bun类型依赖和LLM fetch的Bun专属兼容属性。赞助页生成使用Node文件API,生成及同步检查通过。旧根dist/是先前构建产物,已删除;迁空的src/只剩Finder元数据,已一并移除。API/Web各自生成自己的dist。 pnpm-workspace.yaml声明三个包,应用内部依赖为workspace:*;禁用自动peer安装并显式补齐Nest CLI的webpack和Phaser插件的graphology-types。未升级应用运行依赖;Better Auth锁条目中的可选Hono peer声明不代表安装Hono,pnpm why -r hono无安装记录。turbo.json声明build依赖图、dist输出、构建环境缓存键、typecheck依赖图以及不缓存的persistent dev/prd任务。临时更改共享源码并恢复,dry-run证实API/Web构建hash均失效且恢复后一致。lint与共享Vitest继续集中在根目录,不缓存运行结果。- API包使用
nest build和nest start --watch --no-shell --env-file ...;Web包使用Vite并禁止隐式dotenv叠加。Node显式加载local/staging文件,Turbo开发任务使用loose环境模式;构建仍为strict并显式声明公开构建变量。没有将服务端密钥纳入构建缓存。 - Docker采用同一pnpm锁构建,并通过
pnpm --filter @daoyou/api deploy --prod /out生成可搬移目录。最终入口node dist/main.js,uid1000运行,无Bun、Vite、Turbo、Nest CLI;本地production容器健康检查200,PostgreSQL/Redis/NATS/messaging全部up。SIGTERM后先排空请求及消息,再关闭数据库与Redis,出现shutdown complete。 pnpm run dev同时启动API3001与Web5174;已有本地道友2会话可进入洞府与背包,显示29/40格及资源。源码变动触发Nest重建、旧进程排空和重新启动;结束Turbo任务后3001/3002/5174均无监听。临时浏览器页和本地验收容器已移除,依赖服务与原有用户数据保留。- 文档原称
env/local.env已纳入Git,实际被忽略。新增仅含专用本地容器凭据的env/local.example.env,首次复制后使用;现有环境文件及其真实密钥未改写或纳入Git。维护命令改用Node+tsx,两条宗门维护命令在本地dry-run均成功且记录数为0;历史验收日志保留原始Bun命令。 - 检查:
pnpm install --frozen-lockfile、pnpm run lint、pnpm run typecheck、pnpm run build、pnpm run sponsors:check、Docker构建/运行、浏览器读取、模块依赖审计和git diff --check通过。pnpm run test为237文件、2401通过/2失败,仍是forging材料堆叠及宗门技能内容hash,未改断言。该次本地启动中auction-expire还遇到持久寄售附件的Zod校验错误;未修改该业务服务或历史数据,不能把健康检查当作该业务分支成功证据。 - 跳过:未新增API/数据库单测,未改schema或执行数据库迁移,未执行staging测试写入,未推送镜像或部署真实生产,未重跑本批未修改的全部玩法。上方特殊数据/自然续期及生产发布验收继续保留。
第五十九批:拍卖、邮件、秘境与 Runtime 依赖收口(2026-10-04)
- 拍卖和玩家邮件应用服务由 Nest Module 组合;MailDeliveryService 强制加入调用方事务,邮件与通知 outbox 同时提交。Player/Redis 模块复用既有协调器和客户端,无第二套 Pool/Redis 连接。
- 秘境独立 DungeonRunStore 和结尾生成入口,Flow 保留状态机与确定性收益;Runtime 后台命令通过注入的 InternalCronService 创建处理映射,保持消息时间、ACK/重试和排空顺序。
- 本地公开材料上架/下架返还、跨账号成交、双方邮件领取以及请求重放通过。最新构建秘境启动后重启恢复第一轮,推进第二轮并安全退出,到账 210 灵石/60 修为;run FINISHED、结算账本及历史各一条,重复退出 409。
- lint/typecheck/build 与静态依赖审查通过;本轮未改 shared 引擎或镜像交付配置,未重复 shared 单测/Docker 构建。没有新增 API/Web 测试、执行 DB 迁移、提交/推送或部署。保留并行旧功能清理。
- 历史道装数据迁移排除;用户确认停机维护、SPA/API 配套更新,无旧 SPA/新 API 混合版本兼容要求。完整结果、未覆盖项与目标环境维护/回滚清单见 架构记录第 11 节,不能将架构完成等同于全部业务/生产验收完成。