You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

6.6 KiB

通知业务关联与已读:开发验证记录

日期:2026-10-28。结论范围为本地开发与定向回归,不是完整发布验收。

1. 身份与边界

  • 仓库:C:\Users\15642\Desktop\zhilai。
  • 分支:fix/mysql57-module-migrations-20261009。
  • 开始 HEAD:9fdb72a8e819e2a46397596483dd14b19792f9b1。
  • 原有注销、评分、配置及文档修改保留,不纳入本批。基线记录及全部原始日志在 D:\Acceptance\qsp-notification-links-20261027\,文件夹日期为开始执行日期。
  • 本批不改前端、线上数据库、迁移、鉴权策略或业务通知接收者;不提交、不推送、不触发 Jenkins、不发布。

2. 修改清单与用途(13 文件)

文件(仓库相对路径) 用途
mydreamjob-server/src/main/java/com/mydreamjob/notification/NotificationService.java 显式返回 businessType/businessId;通知条目局部序列化保留 null;分页增加 id 倒序保证同刻通知稳定
mydreamjob-server/src/main/java/com/mydreamjob/notification/NotificationController.java 为已有列表响应绑定精确的运行时 OpenAPI schema,不改业务返回类型
mydreamjob-server/src/main/java/com/mydreamjob/notification/NotificationListResponseDoc.java 新增仅用于文档的响应/分页/条目 schema,采用 OpenAPI 3.1 null 类型联合
mydreamjob-server/src/test/java/com/mydreamjob/notification/NotificationAssociationIntegrationTest.java 新增 H2 + 完整认证过滤链,覆盖序列化、历史空字段、已读、跨页、隔离、禁用 Token、分页和运行时契约
mydreamjob-server/src/test/java/com/mydreamjob/notification/NotificationServiceTest.java 关联保留、不泄露内部键、原始 readAt 幂等、发布事件与创建测试
mydreamjob-server/src/test/java/com/mydreamjob/notification/NotificationConsumerTest.java 事件序列化、消费者落库、关联字段和历史 null 传递
mydreamjob-server/src/test/java/com/mydreamjob/application/ApplicationServiceTest.java 投递成功/撤回/状态变更通知必须使用投递 ID,不是岗位 ID
mydreamjob-server/src/test/java/com/mydreamjob/interview/InterviewServiceTest.java 邀请/改期/取消/完成/学生响应通知必须使用面试 ID
mydreamjob-server/src/test/java/com/mydreamjob/offer/OfferServiceTest.java 发送/响应/提醒通知关联 Offer ID
docs/openapi-rc.json 仅扩展通知列表响应 schema;无新增路径或方法
docs/verify_openapi.py 校验条目键集、类型/null 联合、业务 ID int64、开放类型及原有已读路径
docs/notification-links-frontend-handover-20261028.md 字段与接口参考、点击/已读流程、全部已查来源映射和联调限制
本文 记录开发验证范围、历史失败、未执行项与后续验收要求

3. 核查结果与直接相关修复

  1. 表已有 business_type/business_id,直接创建、事件发布及消费者均已传递;已核查生产者的关联表在前端说明中。本批无生产者语义修正、数据库迁移或历史回填。
  2. 全局 spring.jackson.default-property-inclusion=non_null 原本省略 Map 中 null。仅使用 Map 子类 JsonInclude 注解的尝试仍会被全局 Map 内容过滤影响,实际 HTTP 测试抓到此问题;最终使用通知视图专用 serializer 明确输出键,普通 Map 的全局 null 省略行为有回归断言,不修改全局配置。
  3. 原“全部已读”遍历页时只有 createdAt 排序。同刻通知的排序不确定,首轮 105 条中先读 1 条,剩余应标记 104 条而实际只变更 103 条。查询增加 id 倒序作为同刻 tie-breaker;回归特意构造 105 条完全相同 createdAt 的通知,检验分页不漏、另一个账号不变、重复操作 marked=0。
  4. 通知不存在沿用 HTTP 400 / 9105,初始验收用例误期望 404 已修正为实际既有规则,没有扩大全局异常映射改动。
  5. OpenAPI 运行时为 3.1.0,单用 nullable 注解没有生成预期 null 语义;改用 type: [基础类型, null],保留 required 字段存在性,并比较静态及运行时字段类型/format。
  6. MATCH 的 businessId 是投递 ID;VERIFICATION 是认证申请 ID;REPORT 是举报单 ID。保留既有类型,不擅自统一为其他业务类型。

4. 执行证据与结论口径

定向命令(在 mydreamjob-server 执行,两个付费 Live 开关保持 false):

mvn '-Dmaven.repo.local=D:\DevCache\maven' '-Dtest=Notification*Test,ApplicationServiceTest,ApplicationAcceptanceServiceTest,InterviewServiceTest,OfferServiceTest,OfferExpiryWorkerTest,MatchNotificationServiceTest' test

覆盖 10 个类,含已有企业接受投递及匹配通知测试。H2 测试使用完整 Spring 认证过滤链及真实持久化,不是 standalone MockMvc;消费者测试使用序列化 round-trip 与模拟持久化,不是实际 RabbitMQ broker 端到端验收。

执行静态契约 python docs/verify_openapi.py、静态/运行时路径方法集及通知字段比较、9 个契约反向变异和精确文件 git diff --check。最终机器结果以验收目录 verification-summary.json、contract-negative.json 与 targeted-final2.log 为准;不是仅凭本文认定通过。

历史证据保留:

  • targeted-run1.log:174 项,4 failures;null 过滤和多页漏标被发现,另有既有错误码及 3.1 schema 测试期望不符。
  • targeted-run2.log:中途中断,无最终 Maven 结论,不计为成功或产品失败。
  • targeted-run3.log:181 项,1 failure;剩余 null 过滤问题。
  • targeted-run4.log、targeted-final.log:181/0/0/0,成功;随后进一步补正文 null 的契约和回归,再执行最终 targeted-final2.log。

5. 未执行与下一阶段

  • 完整 mvn clean verify:NOT EXECUTED。当前定向验证不替代全量;本轮预检 Docker daemon 不可用,不把缺 Docker 的全量或 MySQL 项记为通过。
  • 真实 MySQL 8.4 / 5.7.36:NOT EXECUTED;此批无 DDL,但分页和 null 输出仍应补真实库专项。
  • 同次成功全量构建 JAR 的真实 HTTP、持久化重启:NOT EXECUTED;未用旧 JAR 代替。
  • 实际 RabbitMQ 发送/消费、前端点击/跳转/红点联动、线上部署:NOT EXECUTED。

不需要新增产品决策才能完成本批代码。后续若要回填历史无关联通知、改变业务类型含义、调整“不存在”的 HTTP 状态或新增详情接口,应另行设计和授权;恢复 Docker 后建议建立 HEAD + 本批 13 文件的隔离基线做全量及真实库/JAR 验收,不把原仓库其他未提交改动混入。