订单中心交付:故障演练、独立变化与技术答辩

课前先保留判断:课前预习;课后用你的结果复验:课后复习。

今天从哪里开始

今天请没有参与开发的同学接手订单中心。他会登录、下单、刷新、尝试越权,还会重启应用。我们从他的操作出发,把页面、接口、数据库和运行说明一起验一遍。

先复跑已有能力,再定位一个跨层故障,最后每人完成自己模块内的小变化。团队系统能运行和个人能解释、能修改,分别留下记录。

能力与项目增量

今天要学会什么

回溯 Decimal/容器/函数/类/异常/生成器/上下文/测试/async/线程进程;跨层追踪、恢复与同伴复现。新增能力都落到:前三周累计商城交付与个人 Python 应用证据。

  • 端到端追踪
  • 个人变化
  • 恢复验证
  • 同步异步与队列选型解释

课堂结束时,用自己的项目检查:

  • 能做出来:抽取一张未见故障卡,独立定位修复,并展示正常输入的结果。
  • 能查出问题:针对“只演示成功、团队成果代替个人能力、缓存或登录绕过”中的风险,说明输入、预期与实际差异;失败后核对数据没有被误改。
  • 能解释修改:提交代码、测试和修改前后结果,讲清自己接受或拒绝了哪一处 AI 建议。

用商城任务检查前三周 Python 是否真的用得上

今天不再增加 Python 主概念。我从自己的一段业务代码开始,说明当初为什么需要它,再改变一个输入验证解释。

商城中的证据回溯知识现场变化
商品金额到订单快照类型、Decimal、函数、类与 JSON换价格/数量,解释显示和计算的区别
商品导入与批次处理文件、迭代器、生成器、异常一条坏行或空文件,核对内存与拒绝规则
事务失败无半张订单上下文管理与异常传播第二条明细失败,证明释放资源并回滚
物流批查与库存竞争Thread、Lock、Queue、Future一项超时不冒充全成功;锁范围能解释
订单 CSV 汇总进程、spawn、模块入口、序列化换批大小,三种方式金额仍一致;解释小样本变慢
权限拒绝与请求定位装饰器识读、异常、logging、pytestviewer 越权,既有状态不变且日志不泄露凭据

前四周以后遇到 LLM 网络请求、批量文档处理或任务流,使用这份判断继续迁移,不再把线程、进程、异常或生成器首次讲解推迟。交付时对本人没完成的项目写待补,不能凭课件覆盖宣称已经掌握。

单点都绿,为什么端到端仍会暴露故障

API(应用程序接口) 测试绿。

MySQL 事务测试绿。

前端商品页能打开。

Docker 容器 running。

这些事实仍不能保证:

  • fetch 字段对得上;
  • 409 能被页面处理;
  • request_id 能关联日志;
  • README(项目说明文档) 能让同伴重建;
  • 每个成员都真正理解。

所以要做端到端联调。


今天的完整用户旅程

完整用户旅程

统一 Core(核心部分):

  1. 浏览器 GET(读取请求方法) 商品;
  2. 用户选择商品与数量;
  3. 浏览器 POST(提交请求方法) 订单;
  4. API 返回 201;
  5. 页面读取 order_id;
  6. 浏览器 GET 订单详情;
  7. MySQL 中订单与库存事实一致。

每一步都能沿同一个 ID 追踪。


先复跑旧能力

周五第一件事不是加功能。

先复跑:

  • W02-D03:201 / 404 / 422 / 409 / ErrorResponse(统一错误响应);
  • W02-D02:双明细失败 rollback(回滚);
  • W03-D01 / D04:查询计划与浏览器 GET;
  • W02-D04 / D05:Docker 五段记录与 CI;
  • W03-D02 / D03:缓存失效、登录与权限拒绝。

旧能力红灯先修。

不要让集成建立在已知失败上。


把一次请求串起来

完整旅程已经列出,现在给它留下可查的线索。出现问题时,用订单编号查业务数据,用请求编号查这一次调用,再按时间核对浏览器与服务日志。

记录三类关联键:

  • order_id;
  • request_id;
  • 时间窗口。

浏览器 Network 中找到 POST。

服务日志中找同一 request_id。

MySQL 中找同一 order_id。

三处结果必须描述同一件事。

页面截图只能辅助,不能替代这条关联。


第一个成功旅程:201

执行前记录:

  • 商品 P1001 的 available_qty;
  • reserved_qty;
  • 当前订单数。

执行 POST。

执行后记录:

  • 201;
  • order_id;
  • total_amount_yuan;
  • OrderItem(订单明细) 快照;
  • available / reserved 变化;
  • 服务日志 request_id。

再 GET 同一订单。


第二个失败旅程:409

把 quantity 设置为超过可用库存。

预期:

{
  "code": "INSUFFICIENT_INVENTORY",
  "message": "...",
  "request_id": "..."
}

前端要展示可理解信息。

数据库不得出现半张订单或部分库存变化。

前端提示正确不等于事务正确。


企业接收系统时,为什么要同时看正常路径和失败后的数据?

正常路径说明功能存在;越权、库存不足和依赖故障暴露安全与一致性边界。检查失败后没有错误扣库存或新增残单,才能说明失败处理有效。

跨层排错

跨层排错路径

从用户可见现象开始:

  1. Network 是否发出;
  2. 状态与响应是什么;
  3. request_id 对应哪条服务日志;
  4. Service(服务层) 走了哪个分支;
  5. 事务是否 commit(提交记录) / rollback;
  6. MySQL 最终事实是什么。

找到第一处不一致后,只做最小修复。


Bad Case:路径写成 /order

OpenAPI 是 /orders。

AI 候选写成 /order。

表现:

  • Network 有请求;
  • 返回 404;
  • 服务业务日志可能没有进入创建订单;
  • MySQL 没有变化。

正确修复是对齐路径。

不要因此修改后端冻结合同。


Bad Case:把 409 当网络错误

fetch 对 HTTP(超文本传输协议) 409 通常不会自动抛出网络异常。

如果只写 try/catch:

try {
  const response = await fetch(...);
} catch (error) {
  // 这里只能捕获部分网络/运行错误
}

业务错误会漏掉。

必须检查 response.ok 或状态码并读 ErrorResponse。


Bad Case:页面正确,库存错

页面显示“订单创建成功”。

但 MySQL 里:

  • 订单存在;
  • 只扣了第一件商品;
  • 第二件失败。

这不是前端问题。

回到 W02-D02 的事务与回滚证据。

修复 Service 事务边界,并复跑 rollback 测试和主旅程。


Bad Case:API 对,页面错

Network Response 字段正确。

服务日志是 201。

MySQL 也正确。

页面显示 undefined。

回到:

  • fetch 字段名;
  • JSON 解析;
  • render 函数;
  • DOM 选择器。

不要改后端来迁就前端猜错的字段。


刷新和持久化复查

页面刷新后查询同一 order_id。

如果 W02-D04 的 Docker 环境已验证可用:

  • 按相同 Volume(数据卷) 方案删除并重建容器;
  • 重新查询同一订单;
  • 复查库存。

如果 Docker 尚不可用:

  • 浏览器本地证据可以单独判断;
  • Docker 状态保持 Pending(待验证);
  • 不用教师环境补签。

团队 Variant 与统一 Core

系统主链验证完,再看小组差异和个人贡献。不同团队可以有不同展示与样本,但共同的状态、接口和失败边界不能为了演示顺利而删掉。

所有团队都必须通过统一 Core。

团队差异可以来自:

  • 不同虚构商品数据;
  • 不同失败 Pack;
  • 不同页面信息组织;
  • 不同业务规则变体;
  • 不同质量目标。

不能改变:

  • 五个核心对象;
  • 冻结字段;
  • 核心端点;
  • 状态语义;
  • 共同验收。

Micro Individual Variant

Micro Individual Variant(个人微型变式) 可以理解为“个人微型独立变化”。

每名学生完成一个与你模块相关的小变化:

理解需求 → 修改 → 测试 → 解释

规模要小,但必须独立。

它不是完整版 Individual Challenge(个人独立挑战)。

W03 不额外叠加大作业。


个人变体要留下什么

  • 需求理解;
  • 修改前预测;
  • 受影响文件;
  • diff;
  • 正常案例;
  • 错误或边界案例;
  • 自动测试;
  • Network 或 SQL(结构化查询语言) 证据;
  • 设计取舍;
  • 口头解释。

只提交一个 commit 链接不够。


如何证明这是自己的能力而不是团队作品?

固定起点后,每人独立解释一条调用链并完成未预告变化,保留修改和结果;团队演示不能替代个人完成记录。

团队交付与个人证据分开

团队与个人证据

团队交付证明系统整体可用。

个人记录证明你:

  • 负责过明确模块;
  • 写过可追溯 commit;
  • 修过一个 Bad Case(失败或边界案例);
  • 完成独立变化;
  • 能解释设计和调试。

团队成功不能代签个人通过。


小组交付同一个系统,每人怎样说明自己真正完成的工作?

明确负责模块、提交记录、独立变化及调试证据;你能解释一条调用链并当场修改测试。团队展示不能替代个人能力证据。

Ownership / Contribution Ledger

Ledger 可以理解为贡献记录表。

每名成员写:

  • owned_module;
  • issue;
  • commit;
  • code review(评审);
  • Bad Case;
  • design decision(决策);
  • debug(调试) evidence(验证证据);
  • Micro Variant;
  • 答辩结果。

当天更新,不在周五凭记忆倒填。


Peer Clean Start

同伴清洁启动

同伴从空目录开始:

  1. clone 指定 commit;
  2. 只读 README;
  3. 配置 .env.example;
  4. 运行统一命令;
  5. 调 /health;
  6. 调一个读取端点;
  7. 记录第一个失败。

作者不能在旁边口头补步骤。


W04 需要什么

W04 会把商城能力接入 LLM(大语言模型) 客服。

它需要:

  • 稳定 OpenAPI;
  • Product(商品) / Order(订单) 只读入口;
  • 虚构样本数据;
  • ErrorResponse;
  • 运行方式;
  • 验收案例;
  • 证据状态;
  • 已知限制。

它不应该直接访问 W03 MySQL。


为下一周的客服接入,应交接哪些接口信息与运行条件?

交接商品和订单接口合同、错误语义、样本与启动步骤;说明公开信息与受保护数据的边界。服务凭据仅在后端配置,不能放进提示词或浏览器。

新增能力要进入交付验收

我在原有订单成功、库存不足和重启旅程之外,再核对未登录、只读账号越权、缓存失效和缓存故障。缓存失败与身份服务失败分别记录,不用关闭鉴权换取页面成功。

每个人抽取一处同规模变化:修改角色允许动作、修改缓存 TTL、增加一个输入边界或定位一个请求错误。提交前解释预期,再做最小改动和回归。消息队列只要求解释入队、消费、ACK 和重复处理的区别;自主搭建 MQ 作为选做证据,不影响核心交付。

为什么交付要同时有成功和失败旅程?

成功路径只能展示主流程;无权限、超时、重复操作、依赖故障和重启更能暴露边界。每条旅程都要核对数据是否按合同变化。

交给 W04 的接口包含身份前置

商品只读查询仍可按公开合同使用;订单和运营数据需要可信身份。交接包必须包含新端点、401/403/503、Cookie/CSRF、角色规则和教学账号配置方法。后续代码不能用伪造 customer_id 绕过身份,也不能把旧版无鉴权测试当作新版集成通过。

后续大模型调用会遇到网络等待,沿用 W02 的同步/异步判断;后续对话和工作流课程只迁移已学流式、取消和并发上限;持久恢复作为业务可靠性问题继续深化。已经讲过的概念通过业务复杂度升级复习,避免重新上一遍入门课。

下一周的 AI 服务应该怎样访问订单?

用受限的服务集成账号和受保护客户端读取业务数据,凭据只在后端配置,不放进 Prompt 或前端。商品公开信息和员工订单权限继续分开。

学生自己动手,AI 只能改你允许改的地方

我先保存当前可运行版本,再完成“抽取一张未见故障卡,独立定位修复”。让 AI 一次只修改负责该行为的文件;修改前预测正常与失败结果,检查差异,再运行回归。每人需要解释一处接受或拒绝的建议。

错误与边界怎样验收

今天重点检查:只演示成功、团队成果代替个人能力、缓存或登录绕过。保留输入、预期、实际输出和修复后的结果,不能只贴全绿截图。未验证的外部依赖如实记为待验证。

留给下一阶段

前三周的交付链是业务规则、持久化、服务接口,再到可控、安全的使用入口。W04 会在商城中加入客服入口,复用受约束的商品和订单能力;大模型不会替代这套事实来源与权限检查。

官方资料