QA验收 #1
open会议管理与话题管理功能验收(含 Markdown/BFF 跨端验证)
0%
Description
验收范围¶
会议管理与话题管理功能验收,包含 Markdown 编辑/渲染、历史 HTML 转换、BFF 跨端发布边界和基础权限检查。计划用例共 38 条。
本地环境¶
- NDB Web:http://127.0.0.1:8888
- NDB Backend:http://127.0.0.1:8000
- Conference API V2:http://127.0.0.1:3000
- 仅使用 QA- 前缀测试数据;禁止生产写入、部署、提交和推送。
候选分支与 HEAD¶
- frontend:feat/meeting-management @ d5027f431c14fe445ca0dc0f54e66176f5e61654
- backend:feat/meeting-management @ 3e60c89caa3dfd8a6af3c8bdf2e8da5e0509eea2
- mp-conference-api-v2:feature/migrate-legacy-mini-api @ 0223ab5a416edce0b76b4a4d10f386318da646f1
验收边界¶
- 不修改代码、配置或迁移。
- 不提交、推送、部署或执行生产操作。
- 缺少安全测试账号、专家、联系人、合同或清理入口时标记 Blocked,不以静态代码观察替代运行态验收。
证据¶
本地证据目录:/Users/gexiaowei/Documents/work/mindsetech/ndb/qa-evidence
Files
RA Updated by Redmine Admin about 2 months ago
开始执行会议管理与话题管理功能验收。
RA Updated by Redmine Admin about 2 months ago
- Subtask #2 added
RA Updated by Redmine Admin about 2 months ago
- Subtask #3 added
RA Updated by Redmine Admin about 2 months ago
- File final-round-note.md final-round-note.md added
- File supplemental-runtime-evidence.md supplemental-runtime-evidence.md added
- File mtg-created-detail.png mtg-created-detail.png added
- File mtg-required-validation.png mtg-required-validation.png added
- File tpc-created-detail.png tpc-created-detail.png added
- File tpc-published-list.png tpc-published-list.png added
- File mtg-cancelled.png mtg-cancelled.png added
- File tpc-archived-default-list.png tpc-archived-default-list.png added
本轮验收结果¶
38 条计划用例的最终归类:
- Pass:27
- Fail:3
- Blocked:6
- Skipped:2
Fail¶
-
TPC-LEG-001:历史 HTML 转 Markdown 后,脚本文本残留并被转换为数学块。缺陷 #2。 -
MTG-ERR-001:不存在会议详情页仍显示“加载中”和“编辑”操作。缺陷 #3。 -
TPC-ERR-001:不存在话题详情页仍显示“编辑”操作。缺陷 #3。
Blocked¶
-
MTG-PERM-001:缺少只读/受限角色测试账号,无法运行态覆盖会议权限矩阵。 -
TPC-PERM-001:缺少只读/受限角色测试账号,无法运行态覆盖话题权限矩阵。 -
MTG-REL-EXP-001:缺少可安全关联并可回收的 QA 专家记录。 -
MTG-REL-CRM-001:缺少可安全关联并可回收的 QA 联系人/合同记录。 -
MTG/TPC-DEL-001:没有安全的 QA 软删除种子或恢复入口,未执行不可逆删除链路。 -
XEND-DEP-001:依赖故障降级需要主动停止本地依赖服务,本轮未破坏当前三服务联调环境。
Skipped¶
-
MTG-IMG-001:会议背景图上传会写入外部对象存储,未准备可回收测试桶/测试图片。 -
TPC-IMG-001:话题图片上传会写入外部对象存储,未准备可回收测试桶/测试图片。
补测通过项¶
- 会议列表翻页与状态筛选。
- 话题列表翻页、上线状态筛选和归档状态筛选。
- 会议/专家关系非法 ID 校验,均返回 400 且没有脏数据。
- 会议名称与话题名称 256 字符上限校验,均返回 400 且没有脏数据。
- 已归档话题不再出现在默认列表,BFF 返回
NOT_FOUND。
数据清理¶
- QA 会议 #73 已取消并关闭报名。
- QA 话题 #155 已归档,默认列表隐藏。
- 本轮非法请求没有创建记录。
详细补充证据见附件 supplemental-runtime-evidence.md;本地截图目录为 /Users/gexiaowei/Documents/work/mindsetech/ndb/qa-evidence。
RA Updated by Redmine Admin about 2 months ago
Redmine REST 回读显示 allowed_statuses 为空;在不再修改全局配置的约束下,CLI 无法将本单从“新建”流转到“进行中”,状态/优先级/完成度请求被服务端静默忽略。验收结论、缺陷子单和附件均已成功保存,以本条日志说明实际状态限制。
RA Updated by Redmine Admin about 2 months ago
2026-09-22 QA 独立回归摘要:TPC-LEG-001、MTG-ERR-001、TPC-ERR-001 均 PASS。Node 定向测试 17/17;Ego Browser TaskSpace 14 实际加载 Vite 源模块验证危险脚本文本移除且正常标题/段落/列表保留;本地后端启动后,会议与话题不存在详情页均显示明确“详情不可用”与不存在 Result,编辑和状态操作不可见。证据已分别附加到 #2、#3。未改代码/数据库,未流转状态。
RA Updated by Redmine Admin about 2 months ago
补充确认:后端访问日志分别记录会议不存在接口与话题不存在接口返回 HTTP 404,本轮错误页结论覆盖真实 404。
RA Updated by Redmine Admin about 2 months ago
- File final-report.md final-report.md added
- File meeting-topic-view-guide.md meeting-topic-view-guide.md added
- File 01-meeting-list.jpg 01-meeting-list.jpg added
- File 02-meeting-detail.jpg 02-meeting-detail.jpg added
- File 02-topic-detail.jpg 02-topic-detail.jpg added
- File 03-topic-not-found.jpg 03-topic-not-found.jpg added
- File 04-meeting-not-found-v2.jpg 04-meeting-not-found-v2.jpg added
- File client-contact-9.png client-contact-9.png added
NDB 小程序会议与话题回归报告¶
- 测试日期:2026-09-22
- 环境:本地开发环境
- 小程序仓库:
projects/mp/mp-conference - 小程序分支/版本:
feat/meeting-v2-integration/065a20b - BFF 分支/版本:
feature/migrate-legacy-mini-api/0223ab5 - Backend 分支/版本:
feat/meeting-management/3e60c89 - 微信开发者工具:登录有效,wechatide skill
0.3.9与本地工具版本一致 - 模拟器:iPhone 12/13 Pro,SDK 3.16.3
测试数据¶
- 会议:ID
4,智算未来:AI芯片驱动的创新与机遇 - 话题:ID
5,9月第一周消费行业深度洞察 - 客户联系人:ID
9,小程序验收联系人,公司 ID3- 在职状态:
on - 软删除:否
- 已配置唯一测试手机号
-
resolve_contact(phone, "wechat")实测返回client_contact_id: 9
- 在职状态:
用例结果¶
MP-MTG-001 会议列表与详情¶
- 结果:PASS
- 步骤:从“敏思汇”会议列表打开会议 ID 4。
- 预期:详情可加载,会议时间、报名状态、专家、会议内容正常显示,不出现原始 HTML 或 Markdown 源码。
- 实际:会议详情正常显示,专家为“测试专家-458858”;当前会议已结束,报名与参会入口按结束状态关闭;未观察到原始 HTML/Markdown 源码。
- 请求:
GET /api/v2/meetings/4返回 HTTP 200。 - 证据:
01-meeting-list.jpg、02-meeting-detail.jpg。
MP-TPC-001 话题详情富文本¶
- 结果:PASS
- 步骤:从“敏思谈”进入话题 ID 5。
- 预期:话题背景和提纲正常显示,
<p>/<strong>等存储标签不能作为源码出现在界面。 - 实际:提纲按段落、粗体和列表结构展示;可见文本未出现 HTML 标签源码或脚本文本。
- 请求:
GET /api/v2/catalog/topics/5返回 HTTP 200。 - 证据:
02-topic-detail.jpg。
MP-TPC-LEG-001 历史危险 HTML¶
- 结果:SKIPPED(真实数据不具备覆盖条件)
- 步骤:只读分类本地开发库全部已发布话题的提纲格式。
- 预期:若存在带
script/style或事件属性的真实历史数据,则打开详情确认危险内容不显示。 - 实际:已发布话题均为普通 Markdown/安全富文本内容;没有检测到
script/style、事件属性或javascript:样本。按约束未修改数据库造数,因此没有执行真实存量危险 HTML 的持久化 E2E。 - 补充:话题 ID 5 的安全富文本已通过 MP-TPC-001 验证。
MP-ERR-001 不存在记录错误态¶
- 结果:PASS
- 步骤:分别打开新版会议详情
id=99999999&source=v2和话题详情id=99999999。 - 预期:显示稳定错误态和重新加载入口,不应卡死或显示实体操作。
- 实际:两页均显示“记录不存在”和重新加载按钮;没有编辑或业务操作入口。
- 请求:会议、话题 BFF 详情接口均返回 HTTP 404。
- 证据:
03-topic-not-found.jpg、04-meeting-not-found-v2.jpg。
运行日志¶
- simulator console 中
error检索为空。 - 观察到非阻断 warning:Vue feature flag、plugin install、
optionextraneous attribute、wx.getSystemInfoSyncdeprecated。 - 本轮未将这些既有 warning 归因为会议或话题功能失败。
联系人参与资格边界¶
- 联系人 ID 9 已满足 NDB 微信渠道手机号唯一解析条件,可作为小程序绑定/报名测试联系人。
- 当前模拟器用户未通过真实微信手机号授权提供该测试号码,因此没有绕过身份校验强行绑定,也没有创建报名或财务 Task。
- 真实“授权手机号 → 绑定联系人 → 报名 → 生成应收 Task”链路仍需能提供对应手机号的微信测试账号后执行。
仓库与操作边界¶
-
mp-conference、mp-conference-api-v2、backend测试结束时工作区均干净。 - 本轮没有修改源码或配置,没有提交、推送、PR、部署或预览上传。
- 联系人 ID 9 是用户明确授权的新建本地测试数据。
RA Updated by Redmine Admin about 2 months ago
- File final-report.md final-report.md added
- File meeting-topic-view-guide.md meeting-topic-view-guide.md added
- File 07-login-privacy-gate.jpg 07-login-privacy-gate.jpg added
- File 10-auth-binding-result.jpg 10-auth-binding-result.jpg added
- File 13-meeting74-after-register.jpg 13-meeting74-after-register.jpg added
- File 14-meeting74-favorite-subscribe.jpg 14-meeting74-favorite-subscribe.jpg added
- File 15-my-meetings.jpg 15-my-meetings.jpg added
- File 18-meeting74-join-link.jpg 18-meeting74-join-link.jpg added
- File 24-expert49-booking-result.jpg 24-expert49-booking-result.jpg added
- File 30-profile-edit-unsupported.jpg 30-profile-edit-unsupported.jpg added
- File 35-my-after-logout.jpg 35-my-after-logout.jpg added
- File 36-network-error.jpg 36-network-error.jpg added
QA 测试结果 - 小程序全功能回归 - 2026-09-22 18:15 Asia/Shanghai¶
- 环境:本地开发环境;微信开发者工具 iPhone 12/13 Pro,SDK 3.16.3
- 候选版本:Mini 065a20b / BFF 0223ab5 / Backend 3e60c89
- 测试范围:登录认证、会议、报名/取消、参会链接、收藏/纪要预约、我的会议/收藏、话题、专家、内容、搜索、个人资料、消息、隐私、Web 容器、异常态
- 汇总:Pass 29 / Fail 0 / Blocked 2 / Skipped 1,共 32 条
- 自动化补充:Mini 61/61、BFF 72/72、Backend 95/95、微信本地构建成功
阻塞与跳过¶
- MP-AUTH-004 Blocked:真实微信手机号与本地联系人 9 手机号不一致,不能真实完成联系人绑定;用于下游验证的临时本地绑定已恢复为 NULL。
- MP-SHARE-001 Blocked:自动化无法操作微信原生分享面板;仅有 hooks/参数自动化与源码覆盖。
- MP-TPC-002 Skipped:本地已发布话题没有 script/style/事件属性/javascript: 真实历史样本,未修改存量数据库造数。
关键结果¶
- 会议 74 完成开放报名、报名确认、重复幂等、Task 一致性、取消、收藏、纪要预约、我的会议/收藏、参会链接时间边界与复制验证。
- 会议 74 初建时间为 2026-10-22;为验证“进行中才开放参会链接”后续主动调整到 2026-09-22,因此截图和收尾 DB 月份不同不是日期偏移缺陷。
- 断网时新版会议详情显示“请求超时,请稍后重试”;恢复 BFF 后健康检查正常。
- 无实际产品失败,本轮不新增缺陷。
数据清理¶
- 会议 74 已 cancelled 且软删除;报名 1 已 cancelled;专家访谈申请 1 已 cancelled。
- Task 124 按业务规则保留,仍为 ongoing/unbilled/not_required;收藏与纪要订阅已删除。
- 未修改源码或配置,未提交、推送、部署或上传预览版。
完整 32 条用例矩阵、关系图、验证边界见附件 final-report.md;图文操作说明见 meeting-topic-view-guide.md。
RA Updated by Redmine Admin about 2 months ago
- File final-report.md final-report.md added
- File meeting-topic-view-guide.md meeting-topic-view-guide.md added
小程序责任校对已完成并修订附件:明确收藏与纪要预约的登录/联系人边界、报名取消的结算锁、参会链接的服务端授权条件、界面按钮“单独约访”、退出后公开会议仍可浏览,以及本地 QA 数据操作范围。测试统计与结果不变:29 Pass / 0 Fail / 2 Blocked / 1 Skipped。以本次新上传的同名附件为准。
RA Updated by Redmine Admin about 1 month ago
- File back-case-results.md back-case-results.md added
QA 测试结果 - 预约纪要统一意图 - 独立自动化第1轮 - Backend - 2026-10-07¶
- QA:Mindsetech Agent Team / NDB QA Agent
- Redmine:NDB #1(会议管理与话题管理功能验收,含 Markdown/BFF 跨端验证)
- 环境与共同前置:独立 Docker PostgreSQL16 tmpfs 127.0.0.1:56487;test_qa_minutes_20261007;crm_backend;不连接共享业务库
- 候选:Backend 444afbe / BFF cb70aee / Mini dda1473,加本次未提交实现;HEAD 本身不包含实现,最终差异摘要需协调方绑定。
- 操作:python manage.py test api.meetings --noinput -v 2;每行用例名称与源码文件定位对应实际断言。
- 执行日期:2026-10-07 Asia/Shanghai;各框架原始时间/耗时保留于本地日志。
- 汇总:Pass 126 / Fail 0 / Blocked 0 / Skipped 0。
- 预期:对应命名用例的所有断言成立;实际记录仅对应此层级。
| 编号 | 用例 | 源码/层级 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| BACK-001 | test_service_creation_task_snapshots_and_gate_boundaries_use_local_time | api.meetings.test_datetimes.MeetingDateTimeDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-002 | test_service_update_normalizes_aware_values_and_preserves_naive_values | api.meetings.test_datetimes.MeetingDateTimeDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-003 | test_ai_draft_future_and_other_consumer_minutes_do_not_block | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-004 | test_ambiguous_customer_projects_are_not_replaced_by_aggregate | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-005 | test_api_nullable_read_mine_and_idempotency_do_not_leak_money | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-006 | test_booking_replays_existing_fact_after_minutes_are_published | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-007 | test_both_orders_share_task_and_cancel_keeps_reservation | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-008 | test_cancelled_non_online_and_deleted_meetings_are_rejected | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-009 | test_free_does_not_use_another_company_or_non_meeting_project | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-010 | test_free_falls_back_only_to_companyless_meeting_project | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-011 | test_free_without_contract_uses_customer_project_and_zero_task | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-012 | test_hmac_scopes_app_isolation_and_contact_are_required | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-013 | test_invalid_shared_tasks_never_create_second_task | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-014 | test_minutes_only_and_cancelled_attendance_cannot_confirm_attendance | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-015 | test_minutes_only_creates_unified_record_without_join_permission | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-016 | test_missing_key_invalid_intent_and_unsupported_delete_are_rejected | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-017 | test_no_start_or_end_cutoff_and_registration_gate_stays_independent | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-018 | test_paid_without_contract_and_customer_project_returns_contract_error_first | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-019 | test_paid_without_contract_and_mismatched_reuse_leave_no_new_facts | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-020 | test_published_manual_minutes_block_even_without_attachments | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-021 | test_reservation_preserves_web_schedule_snapshot_guard | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-022 | test_settled_attendance_task_can_gain_reservation_without_financial_changes | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-023 | test_settled_reservation_does_not_bypass_registration_recovery_guard | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-024 | test_unbound_contact_is_rejected_without_financial_side_effect | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-025 | test_unified_api_both_intents_share_record_and_mine_filters | api.meetings.test_minutes_reservations.MinutesReservationTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-026 | test_aggregate_project_name_and_schedule_follow_meeting_without_rebinding | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-027 | test_aggregate_supports_multiple_client_companies_and_existing_task_views | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-028 | test_application_hmac_cannot_access_web_api | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-029 | test_attendance_failed_key_can_retry_after_end_and_preserves_task | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-030 | test_attendance_rejects_unfinished_and_cancelled_meetings | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-031 | test_auto_project_creation_permissions_and_replay_scope | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-032 | test_auto_project_creation_rolls_back_on_meeting_failure_and_retries | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-033 | test_background_image_accepts_uploaded_urls_and_rejects_unsafe_values | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-034 | test_batched_serialization_has_constant_queries_for_multiple_meetings | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-035 | test_business_fields_round_trip_track_editor_and_hide_soft_deleted_rows | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-036 | test_company_options_paginate_companies_not_project_rows | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-037 | test_create_is_user_owned_idempotent_and_needs_no_application_secret | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-038 | test_create_rejects_client_selected_consumer_and_project | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-039 | test_cross_company_receivable_task_requires_project_access | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-040 | test_deleted_industry_cannot_be_assigned_to_meeting | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-041 | test_edit_fixed_hours_and_application_ownership_are_rejected | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-042 | test_expert_link_freezes_schedule_and_repeats_keep_single_task | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-043 | test_fixed_application_configuration_errors_do_not_create_projects | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-044 | test_idempotency_is_isolated_by_user_and_from_application_keys | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-045 | test_malformed_update_is_rejected_without_mutation | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-046 | test_missing_key_rolls_back_and_failed_key_can_retry | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-047 | test_options_are_scoped_and_never_expose_application_credentials | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-048 | test_page_manage_and_settle_permissions_are_separate | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-049 | test_project_scope_applies_to_read_create_update_and_client_id_collisions | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-050 | test_real_jwt_succeeds_but_unauthenticated_and_revoked_tokens_fail | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-051 | test_registration_repeated_from_different_users_keeps_single_task | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-052 | test_replay_rechecks_current_project_permission | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-053 | test_schedule_can_change_only_before_start_and_before_task_links | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-054 | test_schedule_create_update_and_response_round_trip_use_shanghai | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-055 | test_settlement_has_separate_permission_and_keeps_task_snapshot | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-056 | test_started_ended_and_cancelled_edit_rules | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-057 | test_topic_management_crud_relations_and_status_round_trip | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-058 | test_topic_management_permissions_unknown_fields_and_relation_scope | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-059 | test_web_jwt_cannot_access_hmac_internal_api | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-060 | test_web_schema_uses_jwt_and_object_envelope | api.meetings.test_web.MeetingWebTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-061 | test_banner_meetings_have_images_are_active_sorted_and_limited | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-062 | test_cancelled_meeting_hides_join_link_after_start | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-063 | test_cancelled_registration_can_reregister_through_api | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-064 | test_catalog_only_exposes_published_application_scoped_records | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-065 | test_catalog_topic_relations_and_public_expert_projection | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-066 | test_create_meeting_idempotency_and_time_validation | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-067 | test_cross_application_publication_requires_separate_scope | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-068 | test_different_keys_use_natural_uniqueness | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-069 | test_failed_operation_rolls_back_task_and_idempotency_key | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-070 | test_future_meeting_hides_join_link_even_with_valid_registration | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-071 | test_hmac_attendance_rejects_future_and_accepts_ended_meeting | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-072 | test_hmac_schedule_creation_and_response_round_trip_use_shanghai | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-073 | test_interview_request_is_idempotent_and_rejects_unpublished_expert | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-074 | test_join_link_opens_exactly_at_meeting_start | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-075 | test_join_link_requires_scope_and_active_registration | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-076 | test_list_and_mine_order_latest_meeting_first_with_stable_ties | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-077 | test_management_publishes_to_consumer_without_granting_bff_write_scope | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-078 | test_missing_key_and_invalid_payload_do_not_write | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-079 | test_missing_scope_and_other_application_are_rejected | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-080 | test_new_nonce_same_key_replays_one_task_and_changed_payload_conflicts | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-081 | test_no_contract_code_and_no_financial_side_effect | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-082 | test_nonce_replay_is_rejected_even_with_same_business_key | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-083 | test_openapi_matches_envelopes_and_private_join_link | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-084 | test_publication_rejects_disabled_expired_or_unscoped_consumer | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-085 | test_resolve_contact_and_ambiguity | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-086 | test_resolve_contact_requires_new_auth_after_number_replacement | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-087 | test_scope_protected_join_and_current_mine_after_cancel | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-088 | test_wire_list_detail_and_registration_null | api.meetings.tests.MeetingApiTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-089 | test_attendance_accepts_exact_end_boundary_without_changing_task | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-090 | test_attendance_confirmation_requires_ended_status_and_elapsed_time | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-091 | test_attendance_does_not_automatically_bill | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-092 | test_automatic_context_and_contract_errors | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-093 | test_billed_invoiced_and_paid_tasks_lock_cancellation | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-094 | test_cancelled_registration_cannot_restore_after_meeting_starts | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-095 | test_catalog_import_is_idempotent_and_dry_run_rolls_back | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-096 | test_catalog_import_rejects_invalid_choices_and_attachment_shape | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-097 | test_cost_cannot_move_out_of_meeting_task | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-098 | test_cross_company_registration_uses_own_contract_and_project | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-099 | test_database_constraints_and_protected_task_mapping | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-100 | test_existing_task_edit_cannot_finish_unsettled_expert | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-101 | test_expert_task_cannot_be_invoiced_or_have_duplicate_cost | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-102 | test_finance_billing_list_and_batch_status_exclude_payable_task | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-103 | test_invoice_binding_locks_even_if_legacy_status_is_stale | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-104 | test_multiple_contracts_require_explicit_selection | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-105 | test_multiple_experts_have_separate_payable_tasks | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-106 | test_natural_duplicate_rejects_changed_billing_context | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-107 | test_negative_and_missing_rate_settlement_roll_back | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-108 | test_repeat_cancel_and_reregister_reuses_task | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-109 | test_same_company_each_contact_gets_one_receivable | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-110 | test_settled_cancelled_registration_cannot_restore | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-111 | test_settlement_reads_latest_expert_profile_and_snapshots_once | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-112 | test_task_guard_allows_manual_finish_and_cancel_without_snapshot_changes | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-113 | test_unpaid_settlement_adjusts_same_cost | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-114 | test_zero_customer_invoice_keeps_existing_positive_amount_rule | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-115 | test_zero_expert_hours_create_zero_unpaid_cost_and_lock_after_payment | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-116 | test_zero_hours_and_zero_rate_still_require_customer_billing | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-117 | test_zero_rate_expert_cost_and_default_project_pm | api.meetings.tests.MeetingDomainTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-118 | test_all_input_forms_are_shanghai_wall_time_in_winter_and_summer | api.meetings.test_datetimes.MeetingDateTimeSerializerTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-119 | test_legacy_naive_response_has_explicit_offset_and_round_trips | api.meetings.test_datetimes.MeetingDateTimeSerializerTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-120 | test_mixed_offsets_validate_chronological_order | api.meetings.test_datetimes.MeetingDateTimeSerializerTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-121 | test_intent_migration_preserves_existing_attendance_task | api.meetings.test_minutes_reservations.MinutesReservationConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-122 | test_parallel_booking_and_attendance_share_one_task | api.meetings.test_minutes_reservations.MinutesReservationConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-123 | test_parallel_same_key_replays_one_booking_response | api.meetings.test_minutes_reservations.MinutesReservationConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-124 | test_parallel_user_idempotency_creates_one_meeting | api.meetings.test_web.MeetingWebConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-125 | test_concurrent_business_key_persists_one_result | api.meetings.tests.MeetingConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
| BACK-126 | test_concurrent_natural_registration_returns_one_task | api.meetings.tests.MeetingConcurrencyTests / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | backend-tests.log |
边界与后续¶
本轮未进行共享业务写入、真实收费 Task 创建或真实员工邮件投递。Backend 测试库已由 Django 销毁;独立测试容器停止后其 tmpfs 测试数据不保留。BFF pg-mem 不能证明真实 PostgreSQL锁、回滚或进程重启后磁盘持久性。Node fixture 不代替真实微信认证、用户操作与截图。未来自动纪要分流/通知未实现,不在本轮完成声明中。
MINI-060 为已知卡片背景色静态断言与现有 UI 冲突;保留 Fail,不回退 UI。成功预约真实流程尚需免费 fixture 审定;图文手册与 UI/项目校对未完成。整体 QA 尚未完成。
RA Updated by Redmine Admin about 1 month ago
- File bff-case-results.md bff-case-results.md added
QA 测试结果 - 预约纪要统一意图 - 独立自动化第1轮 - BFF - 2026-10-07¶
- QA:Mindsetech Agent Team / NDB QA Agent
- Redmine:NDB #1(会议管理与话题管理功能验收,含 Markdown/BFF 跨端验证)
- 环境与共同前置:pg-mem 渠道 SQL fixture;mock NDB/微信/Notification HTTP;无真实邮件
- 候选:Backend 444afbe / BFF cb70aee / Mini dda1473,加本次未提交实现;HEAD 本身不包含实现,最终差异摘要需协调方绑定。
- 操作:npm test -- --verbose --json;每行用例名称与源码文件定位对应实际断言。
- 执行日期:2026-10-07 Asia/Shanghai;各框架原始时间/耗时保留于本地日志。
- 汇总:Pass 118 / Fail 0 / Blocked 0 / Skipped 0。
- 预期:对应命名用例的所有断言成立;实际记录仅对应此层级。
| 编号 | 用例 | 源码/层级 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| BFF-001 | HTTP channel flow runs health checks and Swagger | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-002 | HTTP channel flow logs in using wx.login code without leaking WeChat identifiers or session_key | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-003 | HTTP channel flow rejects forged login identity fields | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-004 | HTTP channel flow distinguishes missing session from missing contact binding | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-005 | HTTP channel flow binds a WeChat-verified phone then resolves contact server-side | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-006 | HTTP channel flow returns 503 without connection details when the channel database is unavailable | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-007 | HTTP channel flow clears contact on phone change and rejects stale contact resolver responses | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-008 | HTTP channel flow submits a verified email and business card and queues the review notification | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-009 | HTTP channel flow rejects a spoofed business-card MIME type | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-010 | HTTP channel flow invalidates binding if NDB no longer resolves the contact | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-011 | HTTP channel flow projects public meetings without private links or Task data | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-012 | HTTP channel flow returns the NDB-derived meeting banners without authentication | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-013 | HTTP channel flow forwards validated date and month calendar filters to NDB | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-014 | HTTP channel flow serves the V2 content, topic and public expert catalog without private fields | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-015 | HTTP channel flow derives a unique industry list from the public V2 catalog | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-016 | HTTP channel flow creates an expert interview request from the authenticated bound contact | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-017 | HTTP channel flow rejects an invalid interview idempotency key before calling NDB | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-018 | HTTP channel flow returns my meetings from NDB using bound contact | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-019 | HTTP channel flow forwards user idempotency key and derives contact from session | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-020 | HTTP channel flow cancels via NDB and keeps local finance absent | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-021 | HTTP channel flow keeps favorites and reminder preferences separate from registration/Task calls | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-022 | HTTP channel flow uses unified NDB minutes GET, PUT and mine DTOs without financial state or attend mutations | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-023 | HTTP channel flow projects one registration and Task across minutes-only, both intents, and attendance cancellation | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-024 | HTTP channel flow returns null from NDB despite a legacy minutes preference | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-025 | HTTP channel flow requires authenticated bound identity, validates keys, and refuses cancellation on /api/v2/meetings/1/minutes-subscription | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-026 | HTTP channel flow requires authenticated bound identity, validates keys, and refuses cancellation on /api/v2/notifications/subscriptions/1/minutes | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-027 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/my | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-028 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/minutes-reservations/mine | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-029 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/my | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-030 | HTTP channel flow passes explicit minutes keys and rejects stale identity and cross-contact upstream responses | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-031 | HTTP channel flow persists one no-contract refusal notice across both minutes paths without masking the rejection | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-032 | HTTP channel flow does not impose BFF time or pricing gates and preserves the NDB human-minutes refusal | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-033 | HTTP channel flow preserves NO_ACTIVE_CONTRACT even if the refusal cannot be persisted | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-034 | HTTP channel flow enforces ownership on favorites and message read operations | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-035 | HTTP channel flow retrieves join link with meeting:join scope only for a bound session | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-036 | HTTP channel flow hides join link on REGISTRATION_REQUIRED | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-037 | HTTP channel flow hides join link on MEETING_NOT_OPEN | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-038 | HTTP channel flow hides join link on JOIN_LINK_UNAVAILABLE | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-039 | HTTP channel flow guides contract errors and upstream downtime without exposing provider messages | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-040 | HTTP channel flow revokes all prior tokens on logout | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-041 | HTTP channel flow rejects expired JWT and legacy conference routes | http.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-042 | SQLite source preservation and database guard reads version 1 without upgrading it, preserving identities and defaulting new fields | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-043 | SQLite source preservation and database guard preserves version 3 binary cards, verification state and retry counters | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-044 | SQLite source preservation and database guard refuses an unsupported source version and never creates a missing file | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-045 | SQLite source preservation and database guard rejects missing required source columns rather than inventing identity fields | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-046 | SQLite source preservation and database guard refuses a non-channel connection target | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-047 | SQLite source preservation and database guard refuses a non-channel connection target | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-048 | SQLite source preservation and database guard refuses a non-channel connection target | sqlite-import.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-049 | NDB minutes business adapter uses a separate stable business key, fresh nonces and only the verified contact payload | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-050 | NDB minutes business adapter rejects malformed or cross-owner business facts {"meeting_id": 2} | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-051 | NDB minutes business adapter rejects malformed or cross-owner business facts {"client_contact_id": 21} | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-052 | NDB minutes business adapter rejects malformed or cross-owner business facts {"task_id": null} | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-053 | NDB minutes business adapter rejects malformed or cross-owner business facts {"minutes_requested": false} | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-054 | NDB minutes business adapter rejects malformed or cross-owner business facts {"created_at": "invalid"} | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-055 | NDB minutes business adapter returns authoritative null and read scope for state without writes | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-056 | NDB minutes business adapter projects attend-only as no minutes and retains minutes when attendance is cancelled | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-057 | NDB minutes business adapter maps published human-minutes and no-contract refusals without rewriting them | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-058 | NDB minutes business adapter does not automatically retry a timed-out business mutation | minutes-adapter.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-059 | identity state and contact events auto binds an initial or newly added number only after current NDB resolution | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-060 | identity state and contact events requires a full application after a WeChat phone change before accepting replacement number | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-061 | identity state and contact events blocks proactive auto binding during delayed MQ delivery of a replacement event | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-062 | identity state and contact events rejects a later replacement even when the same number was previously fully authenticated | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-063 | identity state and contact events does not let an old contact event revoke a newer completed authentication | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-064 | identity state and contact events keeps an unmatched application pending, then authorizes it when NDB adds the number | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-065 | identity state and contact events handles added and replaced contact events idempotently without undoing later full authentication | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-066 | identity state and contact events rejects an application if the verified phone changes away and back during NDB resolution | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-067 | identity state and contact events retries review notification submission with the same idempotency key | identity.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-068 | minutes refusal durable outbox marks missing configuration and resumes after restart without changing the refusal identity | minutes-outbox.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-069 | minutes refusal durable outbox persists missing service configuration across a retry tick, with no delivery claim | minutes-outbox.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-070 | minutes refusal durable outbox retries failures with the same dedup key after restart, applies backoff and honors the minutes recipient | minutes-outbox.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-071 | minutes refusal durable outbox deduplicates by meeting/contact across users without merging distinct meetings | minutes-outbox.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-072 | minutes refusal durable outbox additively upgrades version 4 without migrating legacy minutes into Tasks or notices | minutes-outbox.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-073 | WeChat boundary discards session_key and rejects absent openid | wechat-storage.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-074 | WeChat boundary maps expired codes and upstream network failure | wechat-storage.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-075 | WeChat boundary verifies phone watermark appid before binding | wechat-storage.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-076 | WeChat boundary coalesces token acquisition for concurrent phone requests | wechat-storage.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-077 | channel-only versioned PostgreSQL SQL contract preserves channel identities and favorite state over migration rerun | wechat-storage.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-078 | NDB transport and typed adapter accepts the real NDB envelope and strips Task state | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-079 | NDB transport and typed adapter sends a fresh nonce and stable business key for retries | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-080 | NDB transport and typed adapter returns original registration on duplicate conflict | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-081 | NDB transport and typed adapter fails closed on a cross-contact registration | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-082 | NDB transport and typed adapter returns null for no registration | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-083 | NDB transport and typed adapter maps MEETING_NOT_OPEN without leaking upstream text | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-084 | NDB transport and typed adapter maps NO_ACTIVE_CONTRACT without leaking upstream text | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-085 | NDB transport and typed adapter maps AMBIGUOUS_PROJECT without leaking upstream text | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-086 | NDB transport and typed adapter maps AMBIGUOUS_CONTRACT without leaking upstream text | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-087 | NDB transport and typed adapter maps IDEMPOTENCY_CONFLICT without leaking upstream text | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-088 | NDB transport and typed adapter maps upstream authentication 401 as server configuration, not user login | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-089 | NDB transport and typed adapter maps upstream authentication 403 as server configuration, not user login | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-090 | NDB transport and typed adapter maps upstream availability 429 | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-091 | NDB transport and typed adapter maps upstream availability 500 | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-092 | NDB transport and typed adapter maps upstream availability 503 | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-093 | NDB transport and typed adapter maps network timeout and does not blindly retry writes | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-094 | NDB transport and typed adapter rejects an incompatible contract {"data": [Array], "err": 0} | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-095 | NDB transport and typed adapter rejects an incompatible contract {"code": 200, "data": [Object]} | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-096 | NDB transport and typed adapter requires the confirmed public detail fields and excludes private expert data | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-097 | NDB transport and typed adapter reads the server-derived banner list with the conference read scope | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-098 | NDB transport and typed adapter maps an application-owned meeting miss to NOT_FOUND | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-099 | NDB transport and typed adapter refuses paths and scopes outside application credentials | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-100 | NDB transport and typed adapter validates catalog contracts and derives a stable interview idempotency key | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-101 | NDB transport and typed adapter deduplicates industries exposed by all public catalog collections | ndb-client.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-102 | NDB signature contract uses RFC3986, repeated keys, blanks and lexicographic key/value ordering | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-103 | NDB signature contract signs the exact six-line request and exact UTF-8 body | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-104 | NDB signature contract matches a vector generated by the existing NDB Python implementation | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-105 | NDB signature contract hashes an empty GET body | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-106 | NDB signature contract uses collision-safe tuple boundaries for business keys | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-107 | configuration and boundary validation accepts configured development | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-108 | configuration and boundary validation does not expose submitted secrets in validation errors | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-109 | configuration and boundary validation requires safe production configuration {"NDB_BASE_URL": "http://ndb.test"} | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-110 | configuration and boundary validation requires safe production configuration {"CHANNEL_DATABASE_URL": "sqlite://memory", "NDB_BASE_URL": "https://ndb.test"} | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-111 | configuration and boundary validation rejects non-origin NDB URL ftp://ndb.test | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-112 | configuration and boundary validation rejects non-origin NDB URL https://user:password@ndb.test | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-113 | configuration and boundary validation rejects non-origin NDB URL https://ndb.test/api | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-114 | configuration and boundary validation rejects non-origin NDB URL https://ndb.test/?secret=bad | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-115 | configuration and boundary validation rejects ID coercion and invalid idempotency headers | signature.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-116 | renderMiniProgramRichText converts Markdown into HTML supported by the mini program rich-text component | rich-text.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-117 | renderMiniProgramRichText keeps legacy HTML while removing unsafe markup and attributes | rich-text.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
| BFF-118 | renderMiniProgramRichText rejects unsafe links | rich-text.spec.ts / 隔离测试 | 命名场景断言全部成立 | 断言通过 | Pass | bff-results.json |
边界与后续¶
本轮未进行共享业务写入、真实收费 Task 创建或真实员工邮件投递。Backend 测试库已由 Django 销毁;独立测试容器停止后其 tmpfs 测试数据不保留。BFF pg-mem 不能证明真实 PostgreSQL锁、回滚或进程重启后磁盘持久性。Node fixture 不代替真实微信认证、用户操作与截图。未来自动纪要分流/通知未实现,不在本轮完成声明中。
MINI-060 为已知卡片背景色静态断言与现有 UI 冲突;保留 Fail,不回退 UI。成功预约真实流程尚需免费 fixture 审定;图文手册与 UI/项目校对未完成。整体 QA 尚未完成。
RA Updated by Redmine Admin about 1 month ago
- File mini-case-results.md mini-case-results.md added
QA 测试结果 - 预约纪要统一意图 - 独立自动化第1轮 - Mini - 2026-10-07¶
- QA:Mindsetech Agent Team / NDB QA Agent
- Redmine:NDB #1(会议管理与话题管理功能验收,含 Markdown/BFF 跨端验证)
- 环境与共同前置:Node 页面逻辑 fixture、mock 网络;不是微信运行态截图证据
- 候选:Backend 444afbe / BFF cb70aee / Mini dda1473,加本次未提交实现;HEAD 本身不包含实现,最终差异摘要需协调方绑定。
- 操作:node --test --test-reporter=tap tests/*.test.cjs;每行用例名称与源码文件定位对应实际断言。
- 执行日期:2026-10-07 Asia/Shanghai;各框架原始时间/耗时保留于本地日志。
- 汇总:Pass 76 / Fail 1 / Blocked 0 / Skipped 0。
- 预期:对应命名用例的所有断言成立;实际记录仅对应此层级。
| 编号 | 用例 | 源码/层级 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MINI-001 | login persists only short JWT/expiry; first phone bind uses server match | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-002 | unmatched phone sends email code and submitted application becomes pending | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-003 | expired session clears identity; a late profile read never restores logged-out state | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-004 | HTTP errors retain semantic code, status and requestId | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-005 | v2 transport uses /api/v2 and never clears a new JWT for a late old-session 401 | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-006 | multipart upload sends card and fields, and a late 401 cannot clear a newer session | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-007 | gather and search remove the duplicate online-meeting category | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-008 | content, topics and experts only use the V2 catalog API | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-009 | home recommendations and industry filters only use the V2 catalog API | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-010 | the mini-program has no legacy API origin or request client | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-011 | content cards open the dedicated V2 detail page | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-012 | catalog adapters preserve public presentation and never add private expert fields | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-013 | catalog error states are retryable except for unavailable content | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-014 | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-015 | list, detail and calendar render the same Beijing time from the real templates | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-016 | UTC and offset ISO timestamps convert across midnight independently of device timezone | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-017 | summary remains date-only; missing/invalid times are not shown as ISO or Invalid Date | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-018 | double tap sends once; next completed business action gets a new key | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-019 | timeout retains the key across page/app runner recreation | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-020 | ambiguous server outcomes retain keys; definitive validation failures release them | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-021 | different accounts, meetings and actions never share an in-flight request | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-022 | registration shows the customer charge before submitting; pending is never called confirmed | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-023 | meeting detail downloads and opens the generated minutes attachment | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-024 | meeting content requires a valid session before download and opens login only once | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-025 | meeting content login prompt can be cancelled without leaving or downloading | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-026 | registration is not submitted when the price prompt is cancelled | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-027 | timeout retries reuse the same key without optimistic registration | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-028 | favorites stay independent while minutes reservation requires customer authentication | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-029 | started meeting reserves minutes once with a price confirmation and authoritative reread | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-030 | attendance and minutes reservation coexist without changing registration or join authorization | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-031 | minutes-only reservation never creates a client-side attendance projection or join link | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-032 | cancelled price confirmation does not reserve minutes | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-033 | published analyst minutes block reservation even when the attachment is missing; AI minutes do not | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-034 | reservation read failures never become an unreserved state or consult legacy subscriptions | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-035 | reservation retries reuse the business key and never optimistically mark success | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-036 | reservation results from an old login session never pollute the current session | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-037 | minutes can never be written through the legacy notification subscription API | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-038 | missing active contract keeps reservation unconfirmed and points to staff handling | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-039 | cancellation asks only for confirmation and allows registration again | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-040 | unavailable registration read disables mutation, logout removes a visible link | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-041 | secondary failures stay local while meeting detail remains available | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-042 | completed and cancelled meetings override unbound identity guidance | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-043 | legacy IDs never enter v2 mutation routes or reveal the legacy public link | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-044 | phone, contact and meeting eligibility gate registration; settlement errors stay explicit | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-045 | offline home renders a persistent network/service error and a retry button, never the empty state | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-046 | only successful empty responses show empty state; loading and repeated retry clicks stay distinct | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-047 | ten home shows cache static requests, refresh dynamic data, and preserve visible cards | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-048 | home merges in-flight requests and ignores an older response resolved last | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-049 | login connection failure is Chinese and releases the button for a fresh login attempt | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-050 | login launched as the first page relaunches home after success | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-051 | transport errors are localized without losing HTTP business errors or diagnostic codes | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-052 | page owns the complete, deterministic mini-program token baseline | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-053 | tab bar fixed colors stay aligned with the page tokens | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-054 | native tab bar keeps all four primary destinations in a stable order | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-055 | shared button preserves loading and disabled semantics with an adaptive touch target | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-056 | header, search, calendar and tab controls consume the common touch target | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-057 | tabs use tokenized dual-cue state and compositor-only motion | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-058 | color tabs use the shared design-asset arc indicator | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-059 | round-two contrast and option hit-target fixes stay enforced | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-060 | cards, tags and skeleton share design tokens without hiding existing data | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 静态背景色断言不匹配:预期 ended 使用 surface-subtle;当前既有 UI 未匹配 | Fail | mini-tests.tap;既有 UI 基线冲突,缺陷记录待协调决定 |
| MINI-061 | scoped UI files stop using the four known low-contrast literals | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-062 | home hides the complete hot-topic section when there are no topics | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-063 | list pages share visual spacing and semantic layer tokens without changing their state machines | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-064 | talk and topic detail keep navigation and sharing titles unambiguous | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-065 | meeting detail gives the login-to-registration task primary weight while preserving terminal and billing guards | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-066 | my page uses one primary login CTA and retains gated routes | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-067 | home banners expose a readable purpose and press affordance | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-068 | secondary navigation arrows remain visible on white surfaces | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-069 | identity authentication shows phone, review states and form while preserving native WeChat actions | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-070 | Ardot visual mapping stays inside existing mini-program business boundaries | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-071 | home uses one swiper data source and stable layout prop | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-072 | meeting banners are filtered, sorted, limited, and never collide with fixed entries | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-073 | conference card layout API and press feedback are wired to the root | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-074 | tab and list transitions animate compositor properties only | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-075 | local v2 build is explicit and development config fails closed | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-076 | minutes and AI report disabled states remain independent | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
| MINI-077 | terminal meetings hide registration actions behind the terminal-state guard | tests/*.test.cjs / Node fixture | 命名场景断言全部成立 | 断言通过 | Pass | mini-tests.tap |
边界与后续¶
本轮未进行共享业务写入、真实收费 Task 创建或真实员工邮件投递。Backend 测试库已由 Django 销毁;独立测试容器停止后其 tmpfs 测试数据不保留。BFF pg-mem 不能证明真实 PostgreSQL锁、回滚或进程重启后磁盘持久性。Node fixture 不代替真实微信认证、用户操作与截图。未来自动纪要分流/通知未实现,不在本轮完成声明中。
MINI-060 为已知卡片背景色静态断言与现有 UI 冲突;保留 Fail,不回退 UI。成功预约真实流程尚需免费 fixture 审定;图文手册与 UI/项目校对未完成。整体 QA 尚未完成。
RA Updated by Redmine Admin about 1 month ago
- File final-run-report.md final-run-report.md added
- File mini-final-case-results.md mini-final-case-results.md added
- File fixture-plan.md fixture-plan.md added
- File 01-detail-final.jpg 01-detail-final.jpg added
- File 02-login-prompt.jpg 02-login-prompt.jpg added
- File 03-decline-login-return.jpg 03-decline-login-return.jpg added
QA 测试结果 - 预约纪要统一意图 - 最终候选自动化及只读运行 - 2026-10-07¶
预约纪要最终候选 QA(2026-10-07)¶
关联:Redmine NDB #1;本地验收,非发布证明。统一POST registrations intent=attend|minutes,同会议同联系人一个Registration/Task;取消参会保留minutes,minutes-only不获入会链接。不宣称自动纪要分发完成。
候选与隔离自动化¶
Backend feat/meeting-management HEAD 444afbe26f529dd59c23b29ca4309e5dfabeb105;BFF feature/migrate-legacy-mini-api HEAD cb70aee75e7230ea6eb57a2203021c403f1dccfb;Mini feat/meeting-v2-integration HEAD dda147326123846629dd16705ef51a4cf177a536,三端均含未提交改动。最终detail文件git diff SHA256 d771ce626f09f22c3272a2375b32e02fb1122bb72642258eff25da9e3a5efc8a。
| 轮次 | 结果 | 证据/边界 |
|---|---|---|
| Backend api.meetings | 126/126 Pass | backend-tests.log;crm_backend、Docker PostgreSQL16 tmpfs端口56487,邮件locmem;0009、同记录/Task、并发用例通过。测试库销毁,QA容器停止。 |
| BFF 第1轮 | 118/118 Pass | bff-results.json,9 suites;pg-mem、mock Notification,不证明真实PG锁或真实邮件。 |
| Mini 第1轮 | 76/77 Pass,1 Fail | mini-tests.tap;mini-case-results.md逐例。 |
| Mini 概览修复后第2轮 | 77/78 Pass,1 Fail | mini-final-tests.tap;新概览文案用例通过。失败仍为旧卡片样式静态断言,不回退现有UI。 |
| 最新Mini本地构建 | Pass | mini-build.log,yarn build:weapp:local exit0,不代表真机验收。 |
第1轮321用例320Pass/1Fail;最新三端322用例321Pass/1Fail。两轮不相加为独立用例总数。
协调方报告本地0009已应用、原两条报名仅attend=true/minutes=false、BFF schema5/outbox0;QA未独立读取业务库核实这些数值。
真实只读运行逐例¶
| ID | 前置及操作/预期 | 实际与状态 | 证据 |
|---|---|---|---|
| LIVE-01 | GET8000/schema/可读 | 200,Pass | QA curl |
| LIVE-02 | GET3000/health/ready就绪 | 200,Pass | QA curl |
| LIVE-03 | GET3001/health/ready就绪 | 200,Pass | QA curl;早期/health404为探测路径错误。 |
| LIVE-04 | 匿名GET3000/api/v2/meetings/my拒绝 | 401,Pass | QA curl |
| LIVE-05 | 最新构建,会议75未登录,上下预约提示一致 | 下一步“请先登录后预约纪要”、底部“登录后预约纪要”,Pass | 01-detail-final.jpg;发现旧提示矛盾→Mini最小展示修复→QA构建、实图复验。 |
| LIVE-06 | 点底部入口转登录,不预约 | 进入登录页,一键登录+未勾隐私政策,Pass | 02-login-prompt.jpg,是登录页而非原生弹窗。 |
| LIVE-07 | 不提交登录,返回原详情保留入口 | 返回同会议75,仍“登录后预约纪要”,Pass | 03-decline-login-return.jpg;不是点击原生“暂不登录”弹窗。 |
| LIVE-08 | 已发布人工纪要未登录查看→暂不登录 | Blocked | 当前75人工纪要未生成,没有已发布真实样例;未mock截图。 |
| LIVE-09 | 登录成功→回详情→再次查看/预约 | Blocked | 未执行真实微信、手机号、客户认证,不以注入token冒充。 |
| LIVE-10 | 免费0h成功、双意图、取消参会保留同Task | 真实运行Blocked;隔离自动化相应用例Pass | 无业务库fixture写入权限,未搭建独立全栈。 |
| LIVE-11 | 收费无合同拒绝与员工通知 | 真实运行Blocked;隔离自动化Pass | 不操作收费数据、不实际发员工邮件。 |
工具异常记录:旧.gather截图等待超时;错误.conference-detail/page选择器不存在;刷新异步回首页导致首次详情读取timeout waiting for automator response与.conference__info等待超时。确认首页并重新导航后最终截图成功,不用失败产物证明通过。
回写、手册及门禁¶
第1轮逐例126/118/77行已追加并回读:journals16/17/18,附件68/69/70。最终Mini增量与LIVE-01至11追加另一个journal,未覆盖历史。
产品手册候选 projects/mp/mp-conference/docs/user-manual/minutes-reservation.md;只写真实未登录入口、登录页、返回路径。UI复核、Mini业务校对待协调路由;成功预约、原生暂不登录、真实登录回跳未覆盖,手册不算最终完成。
隔离方案见fixture-plan.md,未执行。QA仅改授权outputs/产品手册与构建产物;无业务源码修改、现有业务写入、真实邮件、commit/push/部署/生产操作。
QA 测试结果 - 预约纪要统一意图 - Mini最终第2轮 - 2026-10-07¶
前置:本地当前未提交候选、Node test;命令 node --test --test-reporter=tap tests/*.test.cjs。HEAD dda147326123846629dd16705ef51a4cf177a536;概览文案修复后执行,日志 mini-final-tests.tap。78用例77Pass/1Fail。模拟执行/静态断言不等于真实登录或成功预约。
每行操作:执行命名测试中的断言;预期:所有断言成立;实际:Pass表示断言成立,Fail见指定日志。第1轮编号不沿用,按测试名称比对;新增最终030为概览文案;旧卡片失败从060变为061,非新增业务缺陷。
| ID | 用例/操作与预期 | 实际 | 证据/缺陷 |
|---|---|---|---|
| FINAL-MINI-001 | login persists only short JWT/expiry; first phone bind uses server match,命名行为断言应成立 | Pass | mini-final-tests.tap: 1 |
| FINAL-MINI-002 | unmatched phone sends email code and submitted application becomes pending,命名行为断言应成立 | Pass | mini-final-tests.tap: 2 |
| FINAL-MINI-003 | expired session clears identity; a late profile read never restores logged-out state,命名行为断言应成立 | Pass | mini-final-tests.tap: 3 |
| FINAL-MINI-004 | HTTP errors retain semantic code, status and requestId,命名行为断言应成立 | Pass | mini-final-tests.tap: 4 |
| FINAL-MINI-005 | v2 transport uses /api/v2 and never clears a new JWT for a late old-session 401,命名行为断言应成立 | Pass | mini-final-tests.tap: 5 |
| FINAL-MINI-006 | multipart upload sends card and fields, and a late 401 cannot clear a newer session,命名行为断言应成立 | Pass | mini-final-tests.tap: 6 |
| FINAL-MINI-007 | gather and search remove the duplicate online-meeting category,命名行为断言应成立 | Pass | mini-final-tests.tap: 7 |
| FINAL-MINI-008 | content, topics and experts only use the V2 catalog API,命名行为断言应成立 | Pass | mini-final-tests.tap: 8 |
| FINAL-MINI-009 | home recommendations and industry filters only use the V2 catalog API,命名行为断言应成立 | Pass | mini-final-tests.tap: 9 |
| FINAL-MINI-010 | the mini-program has no legacy API origin or request client,命名行为断言应成立 | Pass | mini-final-tests.tap: 10 |
| FINAL-MINI-011 | content cards open the dedicated V2 detail page,命名行为断言应成立 | Pass | mini-final-tests.tap: 11 |
| FINAL-MINI-012 | catalog adapters preserve public presentation and never add private expert fields,命名行为断言应成立 | Pass | mini-final-tests.tap: 12 |
| FINAL-MINI-013 | catalog error states are retryable except for unavailable content,命名行为断言应成立 | Pass | mini-final-tests.tap: 13 |
| FINAL-MINI-014 | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries,命名行为断言应成立 | Pass | mini-final-tests.tap: 14 |
| FINAL-MINI-015 | list, detail and calendar render the same Beijing time from the real templates,命名行为断言应成立 | Pass | mini-final-tests.tap: 15 |
| FINAL-MINI-016 | UTC and offset ISO timestamps convert across midnight independently of device timezone,命名行为断言应成立 | Pass | mini-final-tests.tap: 16 |
| FINAL-MINI-017 | summary remains date-only; missing/invalid times are not shown as ISO or Invalid Date,命名行为断言应成立 | Pass | mini-final-tests.tap: 17 |
| FINAL-MINI-018 | double tap sends once; next completed business action gets a new key,命名行为断言应成立 | Pass | mini-final-tests.tap: 18 |
| FINAL-MINI-019 | timeout retains the key across page/app runner recreation,命名行为断言应成立 | Pass | mini-final-tests.tap: 19 |
| FINAL-MINI-020 | ambiguous server outcomes retain keys; definitive validation failures release them,命名行为断言应成立 | Pass | mini-final-tests.tap: 20 |
| FINAL-MINI-021 | different accounts, meetings and actions never share an in-flight request,命名行为断言应成立 | Pass | mini-final-tests.tap: 21 |
| FINAL-MINI-022 | registration shows the customer charge before submitting; pending is never called confirmed,命名行为断言应成立 | Pass | mini-final-tests.tap: 22 |
| FINAL-MINI-023 | meeting detail downloads and opens the generated minutes attachment,命名行为断言应成立 | Pass | mini-final-tests.tap: 23 |
| FINAL-MINI-024 | meeting content requires a valid session before download and opens login only once,命名行为断言应成立 | Pass | mini-final-tests.tap: 24 |
| FINAL-MINI-025 | meeting content login prompt can be cancelled without leaving or downloading,命名行为断言应成立 | Pass | mini-final-tests.tap: 25 |
| FINAL-MINI-026 | registration is not submitted when the price prompt is cancelled,命名行为断言应成立 | Pass | mini-final-tests.tap: 26 |
| FINAL-MINI-027 | timeout retries reuse the same key without optimistic registration,命名行为断言应成立 | Pass | mini-final-tests.tap: 27 |
| FINAL-MINI-028 | favorites stay independent while minutes reservation requires customer authentication,命名行为断言应成立 | Pass | mini-final-tests.tap: 28 |
| FINAL-MINI-029 | started meeting reserves minutes once with a price confirmation and authoritative reread,命名行为断言应成立 | Pass | mini-final-tests.tap: 29 |
| FINAL-MINI-030 | started meeting overview guidance follows the minutes reservation action without changing registration gates,命名行为断言应成立 | Pass | mini-final-tests.tap: 30 |
| FINAL-MINI-031 | attendance and minutes reservation coexist without changing registration or join authorization,命名行为断言应成立 | Pass | mini-final-tests.tap: 31 |
| FINAL-MINI-032 | minutes-only reservation never creates a client-side attendance projection or join link,命名行为断言应成立 | Pass | mini-final-tests.tap: 32 |
| FINAL-MINI-033 | cancelled price confirmation does not reserve minutes,命名行为断言应成立 | Pass | mini-final-tests.tap: 33 |
| FINAL-MINI-034 | published analyst minutes block reservation even when the attachment is missing; AI minutes do not,命名行为断言应成立 | Pass | mini-final-tests.tap: 34 |
| FINAL-MINI-035 | reservation read failures never become an unreserved state or consult legacy subscriptions,命名行为断言应成立 | Pass | mini-final-tests.tap: 35 |
| FINAL-MINI-036 | reservation retries reuse the business key and never optimistically mark success,命名行为断言应成立 | Pass | mini-final-tests.tap: 36 |
| FINAL-MINI-037 | reservation results from an old login session never pollute the current session,命名行为断言应成立 | Pass | mini-final-tests.tap: 37 |
| FINAL-MINI-038 | minutes can never be written through the legacy notification subscription API,命名行为断言应成立 | Pass | mini-final-tests.tap: 38 |
| FINAL-MINI-039 | missing active contract keeps reservation unconfirmed and points to staff handling,命名行为断言应成立 | Pass | mini-final-tests.tap: 39 |
| FINAL-MINI-040 | cancellation asks only for confirmation and allows registration again,命名行为断言应成立 | Pass | mini-final-tests.tap: 40 |
| FINAL-MINI-041 | unavailable registration read disables mutation, logout removes a visible link,命名行为断言应成立 | Pass | mini-final-tests.tap: 41 |
| FINAL-MINI-042 | secondary failures stay local while meeting detail remains available,命名行为断言应成立 | Pass | mini-final-tests.tap: 42 |
| FINAL-MINI-043 | completed and cancelled meetings override unbound identity guidance,命名行为断言应成立 | Pass | mini-final-tests.tap: 43 |
| FINAL-MINI-044 | legacy IDs never enter v2 mutation routes or reveal the legacy public link,命名行为断言应成立 | Pass | mini-final-tests.tap: 44 |
| FINAL-MINI-045 | phone, contact and meeting eligibility gate registration; settlement errors stay explicit,命名行为断言应成立 | Pass | mini-final-tests.tap: 45 |
| FINAL-MINI-046 | offline home renders a persistent network/service error and a retry button, never the empty state,命名行为断言应成立 | Pass | mini-final-tests.tap: 46 |
| FINAL-MINI-047 | only successful empty responses show empty state; loading and repeated retry clicks stay distinct,命名行为断言应成立 | Pass | mini-final-tests.tap: 47 |
| FINAL-MINI-048 | ten home shows cache static requests, refresh dynamic data, and preserve visible cards,命名行为断言应成立 | Pass | mini-final-tests.tap: 48 |
| FINAL-MINI-049 | home merges in-flight requests and ignores an older response resolved last,命名行为断言应成立 | Pass | mini-final-tests.tap: 49 |
| FINAL-MINI-050 | login connection failure is Chinese and releases the button for a fresh login attempt,命名行为断言应成立 | Pass | mini-final-tests.tap: 50 |
| FINAL-MINI-051 | login launched as the first page relaunches home after success,命名行为断言应成立 | Pass | mini-final-tests.tap: 51 |
| FINAL-MINI-052 | transport errors are localized without losing HTTP business errors or diagnostic codes,命名行为断言应成立 | Pass | mini-final-tests.tap: 52 |
| FINAL-MINI-053 | page owns the complete, deterministic mini-program token baseline,命名行为断言应成立 | Pass | mini-final-tests.tap: 53 |
| FINAL-MINI-054 | tab bar fixed colors stay aligned with the page tokens,命名行为断言应成立 | Pass | mini-final-tests.tap: 54 |
| FINAL-MINI-055 | native tab bar keeps all four primary destinations in a stable order,命名行为断言应成立 | Pass | mini-final-tests.tap: 55 |
| FINAL-MINI-056 | shared button preserves loading and disabled semantics with an adaptive touch target,命名行为断言应成立 | Pass | mini-final-tests.tap: 56 |
| FINAL-MINI-057 | header, search, calendar and tab controls consume the common touch target,命名行为断言应成立 | Pass | mini-final-tests.tap: 57 |
| FINAL-MINI-058 | tabs use tokenized dual-cue state and compositor-only motion,命名行为断言应成立 | Pass | mini-final-tests.tap: 58 |
| FINAL-MINI-059 | color tabs use the shared design-asset arc indicator,命名行为断言应成立 | Pass | mini-final-tests.tap: 59 |
| FINAL-MINI-060 | round-two contrast and option hit-target fixes stay enforced,命名行为断言应成立 | Pass | mini-final-tests.tap: 60 |
| FINAL-MINI-061 | cards, tags and skeleton share design tokens without hiding existing data,命名行为断言应成立 | Fail | mini-final-tests.tap: 61;旧卡片样式断言,不回退UI,协调方决定缺陷归属 |
| FINAL-MINI-062 | scoped UI files stop using the four known low-contrast literals,命名行为断言应成立 | Pass | mini-final-tests.tap: 62 |
| FINAL-MINI-063 | home hides the complete hot-topic section when there are no topics,命名行为断言应成立 | Pass | mini-final-tests.tap: 63 |
| FINAL-MINI-064 | list pages share visual spacing and semantic layer tokens without changing their state machines,命名行为断言应成立 | Pass | mini-final-tests.tap: 64 |
| FINAL-MINI-065 | talk and topic detail keep navigation and sharing titles unambiguous,命名行为断言应成立 | Pass | mini-final-tests.tap: 65 |
| FINAL-MINI-066 | meeting detail gives the login-to-registration task primary weight while preserving terminal and billing guards,命名行为断言应成立 | Pass | mini-final-tests.tap: 66 |
| FINAL-MINI-067 | my page uses one primary login CTA and retains gated routes,命名行为断言应成立 | Pass | mini-final-tests.tap: 67 |
| FINAL-MINI-068 | home banners expose a readable purpose and press affordance,命名行为断言应成立 | Pass | mini-final-tests.tap: 68 |
| FINAL-MINI-069 | secondary navigation arrows remain visible on white surfaces,命名行为断言应成立 | Pass | mini-final-tests.tap: 69 |
| FINAL-MINI-070 | identity authentication shows phone, review states and form while preserving native WeChat actions,命名行为断言应成立 | Pass | mini-final-tests.tap: 70 |
| FINAL-MINI-071 | Ardot visual mapping stays inside existing mini-program business boundaries,命名行为断言应成立 | Pass | mini-final-tests.tap: 71 |
| FINAL-MINI-072 | home uses one swiper data source and stable layout prop,命名行为断言应成立 | Pass | mini-final-tests.tap: 72 |
| FINAL-MINI-073 | meeting banners are filtered, sorted, limited, and never collide with fixed entries,命名行为断言应成立 | Pass | mini-final-tests.tap: 73 |
| FINAL-MINI-074 | conference card layout API and press feedback are wired to the root,命名行为断言应成立 | Pass | mini-final-tests.tap: 74 |
| FINAL-MINI-075 | tab and list transitions animate compositor properties only,命名行为断言应成立 | Pass | mini-final-tests.tap: 75 |
| FINAL-MINI-076 | local v2 build is explicit and development config fails closed,命名行为断言应成立 | Pass | mini-final-tests.tap: 76 |
| FINAL-MINI-077 | minutes and AI report disabled states remain independent,命名行为断言应成立 | Pass | mini-final-tests.tap: 77 |
| FINAL-MINI-078 | terminal meetings hide registration actions behind the terminal-state guard,命名行为断言应成立 | Pass | mini-final-tests.tap: 78 |
RA Updated by Redmine Admin about 1 month ago
- Subtask #4 added
RA Updated by Redmine Admin about 1 month ago
- File http-case-results.md http-case-results.md added
- File http-round1-results.json http-round1-results.json added
- File http-round2-results.json http-round2-results.json added
- File http-integration-results.json http-integration-results.json added
- File final-run-report.md final-run-report.md added
- File minutes-reservation.md minutes-reservation.md added
QA 测试结果 - 预约纪要独立真实HTTP契约 - 2026-10-07¶
环境:独立PG16 tmpfs端口56488,ndb_qa/mp_conference_test;真实Backend18000+BFF13000,mockNotification13001。合成JWT/AK,没有真实微信或邮件。不读.env、不接现有库。候选与源码摘要见http-contract-defect.md。QA仅修改outputs辅助程序,产品业务源码未改。
当前第三轮:33计划,实际6,5Pass/1Fail/27Blocked。第1轮实际3,2Pass/1测试脚本Fail(error.code读取错误,已修正);第2轮实际6,5Pass/1真实契约Fail;第3轮相同缺陷附原始NDBGET及PG快照。重跑不累计成独立用例数。真实缺陷 NDB #4。第1轮脚本问题不是产品缺陷。
第1轮 (实际执行)¶
| ID | 名称/层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据/缺陷/时间 |
|---|---|---|---|---|---|---|
| R1-HTTP-001 | Real NDB+BFF channel readiness / HTTP+PG | Dedicated ports/databases;GET /health/ready | NDB signed ping and PG both up | {"status":"ok","channelDb":"up","ndb":"up"} | Pass | http-round1-results.json;2026-10-06T16:24:32.920Z |
| R1-HTTP-002 | Synthetic zero-contract empty baseline / HTTP+PG | Fresh migration and seed;Read isolated ORM snapshot | 0 Registration, 0 Tasks, 0 Contracts | {"registrations":[],"tasks":[],"contract_count":0} | Pass | http-round1-results.json;2026-10-06T16:24:32.921Z |
| R1-HTTP-003 | Anonymous minutes write denied / HTTP+PG | No JWT;PUT A minutes | 401 UNAUTHENTICATED, no mutation | Expected values to be strictly equal: + actual - expected + undefined - 'UNAUTHENTICATED' | Fail | http-round1-results.json;2026-10-06T16:24:33.711Z;QA脚本读取错误已修正(非产品缺陷) |
第2轮 (实际执行)¶
| ID | 名称/层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据/缺陷/时间 |
|---|---|---|---|---|---|---|
| R2-HTTP-001 | Real NDB+BFF channel readiness / HTTP+PG | Dedicated ports/databases;GET /health/ready | NDB signed ping and PG both up | {"status":"ok","channelDb":"up","ndb":"up"} | Pass | http-round2-results.json;2026-10-06T16:25:16.992Z |
| R2-HTTP-002 | Synthetic zero-contract empty baseline / HTTP+PG | Fresh migration and seed;Read isolated ORM snapshot | 0 Registration, 0 Tasks, 0 Contracts | {"registrations":[],"tasks":[],"contract_count":0} | Pass | http-round2-results.json;2026-10-06T16:25:16.992Z |
| R2-HTTP-003 | Anonymous minutes write denied / HTTP+PG | No JWT;PUT A minutes | 401 UNAUTHENTICATED, no mutation | {"status":401,"data":{"error":{"code":"UNAUTHENTICATED","message":"请先登录"},"requestId":"727c6e9f-eec0-4059-ae09-bd8e3a6ffd4b"}} | Pass | http-round2-results.json;2026-10-06T16:25:17.811Z |
| R2-HTTP-004 | Unbound synthetic JWT denied / HTTP+PG | User lacks phone/contact;PUT A minutes | 403 CONTACT_NOT_BOUND | {"status":403,"data":{"error":{"code":"CONTACT_NOT_BOUND","message":"请先绑定客户联系人"},"requestId":"1b04e380-2638-4bde-bbf8-562e538f5652"}} | Pass | http-round2-results.json;2026-10-06T16:25:17.814Z |
| R2-HTTP-005 | Legacy subscription is not reservation / HTTP+PG | Only old channel subscription seeded;GET A minutes | JSON null, no NDB Task | {"reservation":null,"taskCount":0} | Pass | http-round2-results.json;2026-10-06T16:25:17.824Z |
| R2-HTTP-006 | A started free minutes-only created / HTTP+PG | A started,0h,no contract;PUT A minutes | reserved+unified Registration/Task | {"status":502,"data":{"error":{"code":"NDB_CONTRACT_ERROR","message":"上游响应格式异常"},"requestId":"779c8c45-ea09-4ef1-86e0-beb00e029ebd"}} | Fail | http-round2-results.json;2026-10-06T16:25:18.628Z;缺陷#4 |
第3轮 (最终33项计划含依赖阻塞)¶
| ID | 名称/层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据/缺陷/时间 |
|---|---|---|---|---|---|---|
| R3-HTTP-001 | Real NDB+BFF channel readiness / HTTP+PG | Dedicated ports/databases;GET /health/ready | NDB signed ping and PG both up | {"status":"ok","channelDb":"up","ndb":"up"} | Pass | http-integration-results.json;2026-10-06T16:26:07.205Z |
| R3-HTTP-002 | Synthetic zero-contract empty baseline / HTTP+PG | Fresh migration and seed;Read isolated ORM snapshot | 0 Registration, 0 Tasks, 0 Contracts | {"registrations":[],"tasks":[],"contract_count":0} | Pass | http-integration-results.json;2026-10-06T16:26:07.205Z |
| R3-HTTP-003 | Anonymous minutes write denied / HTTP+PG | No JWT;PUT A minutes | 401 UNAUTHENTICATED, no mutation | {"status":401,"data":{"error":{"code":"UNAUTHENTICATED","message":"请先登录"},"requestId":"5b0eba33-be90-453c-94e7-8cd54ae9f0a9"}} | Pass | http-integration-results.json;2026-10-06T16:26:07.988Z |
| R3-HTTP-004 | Unbound synthetic JWT denied / HTTP+PG | User lacks phone/contact;PUT A minutes | 403 CONTACT_NOT_BOUND | {"status":403,"data":{"error":{"code":"CONTACT_NOT_BOUND","message":"请先绑定客户联系人"},"requestId":"d6fc51dc-c9be-4257-8bed-1865ca970fbe"}} | Pass | http-integration-results.json;2026-10-06T16:26:07.990Z |
| R3-HTTP-005 | Legacy subscription is not reservation / HTTP+PG | Only old channel subscription seeded;GET A minutes | JSON null, no NDB Task | {"reservation":null,"taskCount":0} | Pass | http-integration-results.json;2026-10-06T16:26:08.000Z |
| R3-HTTP-006 | A started free minutes-only created / HTTP+PG | A started,0h,no contract;PUT A minutes | reserved+unified Registration/Task | {"status":502,"data":{"error":{"code":"NDB_CONTRACT_ERROR","message":"上游响应格式异常"},"requestId":"c7586089-567e-4a07-8c1c-63832cead135"}} | Fail | http-integration-results.json;2026-10-06T16:26:08.827Z;缺陷#4 |
| R3-HTTP-007 | A same-key retry reuses ids / HTTP+PG | A reserved;Repeat PUT same key | Same registration/task ids | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-008 | A concurrent natural retries on real PG / HTTP+PG | A reserved; threaded real Backend;6 parallel PUT with distinct keys | All same ids and only one Task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-009 | A minutes-only has no attendance projection / HTTP+PG | A minutes requested only;GET A registration | JSON null | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-010 | A absent myMeetings and present myMinutes / HTTP+PG | A minutes-only;GET both lists | Attendance empty; minutes contains A | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-011 | A minutes-only cannot obtain join link / HTTP+PG | A already started;GET A join-link | visible=false,joinUrl=null | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-012 | A cannot add attendance after start / HTTP+PG | A started,minutes-only;POST A registration | MEETING_NOT_OPEN without new Task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-013 | B1 minutes first while not started / HTTP+PG | B1 future,0h;PUT B1 minutes | reserved | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-014 | B1 then attendance shares Registration/Task / HTTP+PG | B1 minutes first;POST B1 registration + isolated snapshot | same id/task, both flags | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-015 | B1 future join link withheld / HTTP+PG | B1 both intents before start;GET join-link | visible=false | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-016 | B2 attendance first while not started / HTTP+PG | B2 future,0h;POST B2 registration | confirmed | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-017 | B2 then minutes shares Registration/Task / HTTP+PG | B2 attend first;PUT B2 minutes + snapshot | same id,task, both flags | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-018 | Both intentions appear in separate lists / HTTP+PG | A minutes-only,B1/B2 both;GET both my lists | myMeetings=2,myMinutes=3 | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-019 | Future B1 cancel keeps minutes and Task / HTTP+PG | B1 future,both;DELETE registration | cancelled;same reserved minutes and ongoing Task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-020 | Future B1 reattend reuses id/Task / HTTP+PG | B1 cancelled but future;POST registration fresh key | confirmed,same ids,3 Tasks total | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-021 | Advance only isolated B fixtures to started / HTTP+PG | B1/B2 future registration complete;Guarded synthetic ORM time update | Only B1/B2 updated | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-022 | Started attendee B1 obtains link / HTTP+PG | B1 advanced,confirmed;GET join-link | visible=true synthetic invalid-domain link | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-023 | Started attendee B2 obtains link / HTTP+PG | B2 advanced,confirmed;GET join-link | visible=true | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-024 | Started B1 cancel preserves minutes Task / HTTP+PG | B1 started,both;DELETE registration + snapshot | cancelled and minutes same ids/ongoing Task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-025 | Cancelled started B1 loses link / HTTP+PG | B1 cancelled,minutes retained;GET join-link | visible=false,no link | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-026 | Started B1 cannot restore attendance / HTTP+PG | B1 cancelled after start;POST attend fresh key | MEETING_NOT_OPEN,no extra Task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-027 | Started B1 repeated minutes retained / HTTP+PG | B1 cancelled attendee,minutes active;PUT minutes fresh key | same reserved id/task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-028 | Started B2 cancel preserves same minutes Task / HTTP+PG | B2 opposite order;DELETE registration | cancelled,same minutes id/task | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-029 | All free Tasks remain zero and unique / HTTP+PG | A/B1/B2 complete;Read isolated snapshot | 3 registrations,3 unique Tasks,0 contracts,all prices0 | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-030 | Synthetic paid no contract rejects without mutation / HTTP+PG | D synthetic1h,no contracts;PUT D minutes | NO_ACTIVE_CONTRACT,still3 Tasks | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-031 | Real PG refusal outbox durable and deduplicated / HTTP+PG | D denied;Repeat rejection+PG SELECT | one pending row,not reservation | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-032 | Refusal persists across real BFF restart and mock acceptance / HTTP+PG | Outbox stored in real PG;Stop/restart BFF; bootstrap dispatch to mock13001 | same row accepted once;no real email | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
| R3-HTTP-033 | Accepted refusal never becomes successful reservation / HTTP+PG | D notice accepted by mock;GET D minutes;GET myMinutes;snapshot | null,D absent,3 Tasks | 未执行:依赖HTTP-006成功;NDB已写入但BFF502,等待#4修复后继续 | Blocked | http-integration-results.json |
最短根因与资源收尾¶
第三轮原始NDBGET200:id/meeting_id/client_contact_id/task_id为number 1/1/2/1;attend_requested=false、minutes_requested=true均boolean;status='reserved' string;created_at='2026-10-07T00:26:08.883534' string无offset。BFF日期校验独立safeParse=false。真实NDB内部一条Registration与一条Task,contract=null、费用0、Task ongoing;客户端502不代表后端没写入。同幂等键PUT重试及GET前端权威状态尚未完成,修复后必须实测。
三轮专用Backend/BFF PID均已停止,containerStopped=true;明确容器ndb-qa-minutes-http-20261007-56488 Exited(0),lsof核对56488/18000/13000/13001无监听。tmpfs只清除本轮合成数据,日志保留;现有业务库、共享小程序产物、员工邮件均未碰。
手册审核收口¶
minutes-reservation.md已改“无可用合同异常”和“分析师纪要显示未生成”,头部/尾部统一标UI与Mini复核通过,仅3图未登录入口→登录页→原会议返回。没有成功预约图或真实微信登录E2E,不能因HTTP进度扩张手册范围。源码修复由协调方路由BFF Agent,QA不实施;收到修复冻结和复验释放后复用既有独立验证权限。
RA Updated by Redmine Admin about 1 month ago
- File bff-final-case-results.md bff-final-case-results.md added
- File bff-final-results.json bff-final-results.json added
QA 测试结果 - BFF日期兼容修复后全量独立回归 - 2026-10-07¶
候选:cb70aee75e7230ea6eb57a2203021c403f1dccfb及未提交修复,adapter源码SHA25615bf6cbd4389fa97d863899680b0419f9fc1b647356c70459e5ca7d7ad83b5d7。QA独立npm test -- --verbose --json --outputFile=bff-final-results.json;9 suites127/127 Pass。pg-mem/mock Notification单元环境,不冒充真实PG(真实PG另见HTTP第4轮34/34)。前置:test配置/合成身份;每行操作为执行具名断言,预期全部断言成立,实际Pass表示成立。包含naive微秒/offset/Z保持原值及非法日期拒绝。
| ID | 用例/操作与预期 | 实际 | 证据/层级/源码 |
|---|---|---|---|
| BFF-FINAL-001 | HTTP channel flow runs health checks and Swagger,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-002 | HTTP channel flow logs in using wx.login code without leaking WeChat identifiers or session_key,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-003 | HTTP channel flow rejects forged login identity fields,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-004 | HTTP channel flow distinguishes missing session from missing contact binding,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-005 | HTTP channel flow binds a WeChat-verified phone then resolves contact server-side,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-006 | HTTP channel flow returns 503 without connection details when the channel database is unavailable,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-007 | HTTP channel flow clears contact on phone change and rejects stale contact resolver responses,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-008 | HTTP channel flow submits a verified email and business card and queues the review notification,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-009 | HTTP channel flow rejects a spoofed business-card MIME type,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-010 | HTTP channel flow invalidates binding if NDB no longer resolves the contact,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-011 | HTTP channel flow projects public meetings without private links or Task data,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-012 | HTTP channel flow returns the NDB-derived meeting banners without authentication,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-013 | HTTP channel flow forwards validated date and month calendar filters to NDB,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-014 | HTTP channel flow serves the V2 content, topic and public expert catalog without private fields,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-015 | HTTP channel flow derives a unique industry list from the public V2 catalog,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-016 | HTTP channel flow creates an expert interview request from the authenticated bound contact,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-017 | HTTP channel flow rejects an invalid interview idempotency key before calling NDB,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-018 | HTTP channel flow returns my meetings from NDB using bound contact,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-019 | HTTP channel flow forwards user idempotency key and derives contact from session,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-020 | HTTP channel flow cancels via NDB and keeps local finance absent,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-021 | HTTP channel flow keeps favorites and reminder preferences separate from registration/Task calls,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-022 | HTTP channel flow uses unified NDB minutes GET, PUT and mine DTOs without financial state or attend mutations,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-023 | HTTP channel flow projects one registration and Task across minutes-only, both intents, and attendance cancellation,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-024 | HTTP channel flow returns null from NDB despite a legacy minutes preference,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-025 | HTTP channel flow requires authenticated bound identity, validates keys, and refuses cancellation on /api/v2/meetings/1/minutes-subscription,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-026 | HTTP channel flow requires authenticated bound identity, validates keys, and refuses cancellation on /api/v2/notifications/subscriptions/1/minutes,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-027 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/my,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-028 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/minutes-reservations/mine,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-029 | HTTP channel flow rejects a wrong-intent or wrong-owner mine result on /api/v2/meetings/my,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-030 | HTTP channel flow passes explicit minutes keys and rejects stale identity and cross-contact upstream responses,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-031 | HTTP channel flow persists one no-contract refusal notice across both minutes paths without masking the rejection,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-032 | HTTP channel flow does not impose BFF time or pricing gates and preserves the NDB human-minutes refusal,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-033 | HTTP channel flow preserves NO_ACTIVE_CONTRACT even if the refusal cannot be persisted,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-034 | HTTP channel flow enforces ownership on favorites and message read operations,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-035 | HTTP channel flow retrieves join link with meeting:join scope only for a bound session,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-036 | HTTP channel flow hides join link on REGISTRATION_REQUIRED,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-037 | HTTP channel flow hides join link on MEETING_NOT_OPEN,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-038 | HTTP channel flow hides join link on JOIN_LINK_UNAVAILABLE,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-039 | HTTP channel flow guides contract errors and upstream downtime without exposing provider messages,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-040 | HTTP channel flow revokes all prior tokens on logout,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-041 | HTTP channel flow rejects expired JWT and legacy conference routes,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/http.spec.ts |
| BFF-FINAL-042 | SQLite source preservation and database guard reads version 1 without upgrading it, preserving identities and defaulting new fields,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-043 | SQLite source preservation and database guard preserves version 3 binary cards, verification state and retry counters,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-044 | SQLite source preservation and database guard refuses an unsupported source version and never creates a missing file,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-045 | SQLite source preservation and database guard rejects missing required source columns rather than inventing identity fields,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-046 | SQLite source preservation and database guard refuses a non-channel connection target,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-047 | SQLite source preservation and database guard refuses a non-channel connection target,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-048 | SQLite source preservation and database guard refuses a non-channel connection target,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/sqlite-import.spec.ts |
| BFF-FINAL-049 | minutes refusal durable outbox marks missing configuration and resumes after restart without changing the refusal identity,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-outbox.spec.ts |
| BFF-FINAL-050 | minutes refusal durable outbox persists missing service configuration across a retry tick, with no delivery claim,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-outbox.spec.ts |
| BFF-FINAL-051 | minutes refusal durable outbox retries failures with the same dedup key after restart, applies backoff and honors the minutes recipient,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-outbox.spec.ts |
| BFF-FINAL-052 | minutes refusal durable outbox deduplicates by meeting/contact across users without merging distinct meetings,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-outbox.spec.ts |
| BFF-FINAL-053 | minutes refusal durable outbox additively upgrades version 4 without migrating legacy minutes into Tasks or notices,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-outbox.spec.ts |
| BFF-FINAL-054 | identity state and contact events auto binds an initial or newly added number only after current NDB resolution,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-055 | identity state and contact events requires a full application after a WeChat phone change before accepting replacement number,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-056 | identity state and contact events blocks proactive auto binding during delayed MQ delivery of a replacement event,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-057 | identity state and contact events rejects a later replacement even when the same number was previously fully authenticated,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-058 | identity state and contact events does not let an old contact event revoke a newer completed authentication,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-059 | identity state and contact events keeps an unmatched application pending, then authorizes it when NDB adds the number,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-060 | identity state and contact events handles added and replaced contact events idempotently without undoing later full authentication,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-061 | identity state and contact events rejects an application if the verified phone changes away and back during NDB resolution,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-062 | identity state and contact events retries review notification submission with the same idempotency key,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/identity.spec.ts |
| BFF-FINAL-063 | WeChat boundary discards session_key and rejects absent openid,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/wechat-storage.spec.ts |
| BFF-FINAL-064 | WeChat boundary maps expired codes and upstream network failure,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/wechat-storage.spec.ts |
| BFF-FINAL-065 | WeChat boundary verifies phone watermark appid before binding,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/wechat-storage.spec.ts |
| BFF-FINAL-066 | WeChat boundary coalesces token acquisition for concurrent phone requests,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/wechat-storage.spec.ts |
| BFF-FINAL-067 | channel-only versioned PostgreSQL SQL contract preserves channel identities and favorite state over migration rerun,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/wechat-storage.spec.ts |
| BFF-FINAL-068 | NDB signature contract uses RFC3986, repeated keys, blanks and lexicographic key/value ordering,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-069 | NDB signature contract signs the exact six-line request and exact UTF-8 body,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-070 | NDB signature contract matches a vector generated by the existing NDB Python implementation,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-071 | NDB signature contract hashes an empty GET body,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-072 | NDB signature contract uses collision-safe tuple boundaries for business keys,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-073 | configuration and boundary validation accepts configured development,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-074 | configuration and boundary validation does not expose submitted secrets in validation errors,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-075 | configuration and boundary validation requires safe production configuration {"NDB_BASE_URL": "http://ndb.test"},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-076 | configuration and boundary validation requires safe production configuration {"CHANNEL_DATABASE_URL": "sqlite://memory", "NDB_BASE_URL": "https://ndb.test"},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-077 | configuration and boundary validation rejects non-origin NDB URL ftp://ndb.test,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-078 | configuration and boundary validation rejects non-origin NDB URL https://user:password@ndb.test,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-079 | configuration and boundary validation rejects non-origin NDB URL https://ndb.test/api,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-080 | configuration and boundary validation rejects non-origin NDB URL https://ndb.test/?secret=bad,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-081 | configuration and boundary validation rejects ID coercion and invalid idempotency headers,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/signature.spec.ts |
| BFF-FINAL-082 | NDB transport and typed adapter accepts the real NDB envelope and strips Task state,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-083 | NDB transport and typed adapter sends a fresh nonce and stable business key for retries,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-084 | NDB transport and typed adapter returns original registration on duplicate conflict,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-085 | NDB transport and typed adapter fails closed on a cross-contact registration,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-086 | NDB transport and typed adapter returns null for no registration,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-087 | NDB transport and typed adapter maps MEETING_NOT_OPEN without leaking upstream text,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-088 | NDB transport and typed adapter maps NO_ACTIVE_CONTRACT without leaking upstream text,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-089 | NDB transport and typed adapter maps AMBIGUOUS_PROJECT without leaking upstream text,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-090 | NDB transport and typed adapter maps AMBIGUOUS_CONTRACT without leaking upstream text,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-091 | NDB transport and typed adapter maps IDEMPOTENCY_CONFLICT without leaking upstream text,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-092 | NDB transport and typed adapter maps upstream authentication 401 as server configuration, not user login,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-093 | NDB transport and typed adapter maps upstream authentication 403 as server configuration, not user login,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-094 | NDB transport and typed adapter maps upstream availability 429,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-095 | NDB transport and typed adapter maps upstream availability 500,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-096 | NDB transport and typed adapter maps upstream availability 503,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-097 | NDB transport and typed adapter maps network timeout and does not blindly retry writes,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-098 | NDB transport and typed adapter rejects an incompatible contract {"data": [Array], "err": 0},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-099 | NDB transport and typed adapter rejects an incompatible contract {"code": 200, "data": [Object]},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-100 | NDB transport and typed adapter requires the confirmed public detail fields and excludes private expert data,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-101 | NDB transport and typed adapter reads the server-derived banner list with the conference read scope,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-102 | NDB transport and typed adapter maps an application-owned meeting miss to NOT_FOUND,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-103 | NDB transport and typed adapter refuses paths and scopes outside application credentials,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-104 | NDB transport and typed adapter validates catalog contracts and derives a stable interview idempotency key,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-105 | NDB transport and typed adapter deduplicates industries exposed by all public catalog collections,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/ndb-client.spec.ts |
| BFF-FINAL-106 | NDB minutes business adapter uses a separate stable business key, fresh nonces and only the verified contact payload,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-107 | NDB minutes business adapter preserves the NDB timestamp 2026-10-07T00:26:08.883534 for both business intents,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-108 | NDB minutes business adapter preserves the NDB timestamp 2026-10-07T00:26:08 for both business intents,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-109 | NDB minutes business adapter preserves the NDB timestamp 2026-10-07T00:26:08.883534Z for both business intents,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-110 | NDB minutes business adapter preserves the NDB timestamp 2026-10-07T00:26:08.883534+08:00 for both business intents,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-111 | NDB minutes business adapter continues rejecting invalid registration timestamps 2026-02-30T00:26:08.883534,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-112 | NDB minutes business adapter continues rejecting invalid registration timestamps 2026-10-07T24:26:08,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-113 | NDB minutes business adapter continues rejecting invalid registration timestamps 2026-10-07T00:60:08,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-114 | NDB minutes business adapter continues rejecting invalid registration timestamps 2026-10-07,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-115 | NDB minutes business adapter continues rejecting invalid registration timestamps garbage,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-116 | NDB minutes business adapter rejects malformed or cross-owner business facts {"meeting_id": 2},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-117 | NDB minutes business adapter rejects malformed or cross-owner business facts {"client_contact_id": 21},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-118 | NDB minutes business adapter rejects malformed or cross-owner business facts {"task_id": null},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-119 | NDB minutes business adapter rejects malformed or cross-owner business facts {"minutes_requested": false},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-120 | NDB minutes business adapter rejects malformed or cross-owner business facts {"created_at": "invalid"},命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-121 | NDB minutes business adapter returns authoritative null and read scope for state without writes,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-122 | NDB minutes business adapter projects attend-only as no minutes and retains minutes when attendance is cancelled,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-123 | NDB minutes business adapter maps published human-minutes and no-contract refusals without rewriting them,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-124 | NDB minutes business adapter does not automatically retry a timed-out business mutation,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/minutes-adapter.spec.ts |
| BFF-FINAL-125 | renderMiniProgramRichText converts Markdown into HTML supported by the mini program rich-text component,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/rich-text.spec.ts |
| BFF-FINAL-126 | renderMiniProgramRichText keeps legacy HTML while removing unsafe markup and attributes,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/rich-text.spec.ts |
| BFF-FINAL-127 | renderMiniProgramRichText rejects unsafe links,命名行为断言应成立 | Pass | bff-final-results.json;单元/模拟;test/rich-text.spec.ts |
RA Updated by Redmine Admin about 1 month ago
- File http-round4-case-results.md http-round4-case-results.md added
- File http-integration-results.json http-integration-results.json added
- File final-run-report.md final-run-report.md added
- File minutes-reservation.md minutes-reservation.md added
QA 测试结果 - 独立真实HTTP第4轮 - BFF日期兼容修复复验 - 2026-10-07¶
环境/候选/门禁¶
2026-10-07 00:29 Asia/Shanghai,QA Agent。本机PG16 tmpfs 56488,独立ndb_qa/mp_conference_test;真实NDB18000、最新源独立编译BFF13000、mockNotification13001,均仅localhost。合成JWT/应用签名,无真实微信/手机号认证、现有业务库或真实邮件。
Backend HEAD444afbe26f529dd59c23b29ca4309e5dfabeb105,BFF HEADcb70aee75e7230ea6eb57a2203021c403f1dccfb及未提交候选。Backend serializer SHA256611bc92ed9d1c5d84abd8318a50c9ae41232275a454cea0c5588831c0b1de958;修复后BFF adapter SHA25615bf6cbd4389fa97d863899680b0419f9fc1b647356c70459e5ca7d7ad83b5d7,隔离编译JS SHA256a937103e1890283f8fcd508e869a3316d3e7b128ac83239873ce29c7b3d2bb4d。
操作:激活crm_backend后运行outputs/http_integration.cjs;脚本屏蔽Backend .env读取、迁移新库、seed合成0h会议、启动真实HTTP、仅推进B1/B2时间并自动停止专用资源。新增“权威GET保留naive微秒”用例,原33变34,编号按名称比对旧轮。
汇总:34计划,34Pass/0Fail/0Blocked。前3轮失败和阻塞保留于http-case-results.md、http-round1/2/3-results.json,不改成通过。本轮证明缺陷#4真实HTTP复验通过,不代表真实微信完整流程。
逐例¶
| ID | 用例/层级 | 前置与操作 | 预期 | 实际 | 状态 | 证据/时间/缺陷 |
|---|---|---|---|---|---|---|
| R4-HTTP-001 | Real NDB+BFF channel readiness / HTTP+PG | Dedicated ports/databases;GET /health/ready | NDB signed ping and PG both up | {"status":"ok","channelDb":"up","ndb":"up"} | Pass | http-integration-results.json;2026-10-06T16:29:26.804Z;#4复验范围 |
| R4-HTTP-002 | Synthetic zero-contract empty baseline / HTTP+PG | Fresh migration and seed;Read isolated ORM snapshot | 0 Registration, 0 Tasks, 0 Contracts | {"registrations":[],"tasks":[],"contract_count":0} | Pass | http-integration-results.json;2026-10-06T16:29:26.804Z;#4复验范围 |
| R4-HTTP-003 | Anonymous minutes write denied / HTTP+PG | No JWT;PUT A minutes | 401 UNAUTHENTICATED, no mutation | {"status":401,"data":{"error":{"code":"UNAUTHENTICATED","message":"请先登录"},"requestId":"6def3d9e-6172-415e-863e-151132724f73"}} | Pass | http-integration-results.json;2026-10-06T16:29:27.556Z;#4复验范围 |
| R4-HTTP-004 | Unbound synthetic JWT denied / HTTP+PG | User lacks phone/contact;PUT A minutes | 403 CONTACT_NOT_BOUND | {"status":403,"data":{"error":{"code":"CONTACT_NOT_BOUND","message":"请先绑定客户联系人"},"requestId":"682e586e-8537-4a7a-95e8-eafc68a29d72"}} | Pass | http-integration-results.json;2026-10-06T16:29:27.558Z;#4复验范围 |
| R4-HTTP-005 | Legacy subscription is not reservation / HTTP+PG | Only old channel subscription seeded;GET A minutes | JSON null, no NDB Task | {"reservation":null,"taskCount":0} | Pass | http-integration-results.json;2026-10-06T16:29:27.567Z;#4复验范围 |
| R4-HTTP-006 | A started free minutes-only created / HTTP+PG | A started,0h,no contract;PUT A minutes | reserved+unified Registration/Task | {"id":"1","meetingId":"1","clientContactId":"2","taskId":"1","status":"reserved","createdAt":"2026-10-07T00:29:28.409211"} | Pass | http-integration-results.json;2026-10-06T16:29:28.357Z;#4复验范围 |
| R4-HTTP-007 | A same-key retry reuses ids / HTTP+PG | A reserved;Repeat PUT same key | Same registration/task ids | {"id":"1","meetingId":"1","clientContactId":"2","taskId":"1","status":"reserved","createdAt":"2026-10-07T00:29:28.409211"} | Pass | http-integration-results.json;2026-10-06T16:29:28.414Z;#4复验范围 |
| R4-HTTP-008 | A authoritative GET preserves server naive microseconds / HTTP+PG | A reserved after replay;GET A minutes | same ids and exact createdAt string | {"id":"1","meetingId":"1","clientContactId":"2","taskId":"1","status":"reserved","createdAt":"2026-10-07T00:29:28.409211"} | Pass | http-integration-results.json;2026-10-06T16:29:28.452Z;#4复验范围 |
| R4-HTTP-009 | A concurrent natural retries on real PG / HTTP+PG | A reserved; threaded real Backend;6 parallel PUT with distinct keys | All same ids and only one Task | {"responses":6,"registrationId":"1","taskId":"1","taskCount":1} | Pass | http-integration-results.json;2026-10-06T16:29:28.487Z;#4复验范围 |
| R4-HTTP-010 | A minutes-only has no attendance projection / HTTP+PG | A minutes requested only;GET A registration | JSON null | null | Pass | http-integration-results.json;2026-10-06T16:29:29.352Z;#4复验范围 |
| R4-HTTP-011 | A absent myMeetings and present myMinutes / HTTP+PG | A minutes-only;GET both lists | Attendance empty; minutes contains A | {"myMeetings":0,"myMinutes":1} | Pass | http-integration-results.json;2026-10-06T16:29:29.394Z;#4复验范围 |
| R4-HTTP-012 | A minutes-only cannot obtain join link / HTTP+PG | A already started;GET A join-link | visible=false,joinUrl=null | {"visible":false,"joinUrl":null,"reason":"REGISTRATION_REQUIRED"} | Pass | http-integration-results.json;2026-10-06T16:29:29.483Z;#4复验范围 |
| R4-HTTP-013 | A cannot add attendance after start / HTTP+PG | A started,minutes-only;POST A registration | MEETING_NOT_OPEN without new Task | {"status":409,"data":{"error":{"code":"MEETING_NOT_OPEN","message":"会议当前不可报名"},"requestId":"5f775969-8e2c-48fe-bd92-b16e7b15eb49"}} | Pass | http-integration-results.json;2026-10-06T16:29:29.527Z;#4复验范围 |
| R4-HTTP-014 | B1 minutes first while not started / HTTP+PG | B1 future,0h;PUT B1 minutes | reserved | {"id":"2","meetingId":"2","clientContactId":"2","taskId":"2","status":"reserved","createdAt":"2026-10-07T00:29:30.412283"} | Pass | http-integration-results.json;2026-10-06T16:29:30.361Z;#4复验范围 |
| R4-HTTP-015 | B1 then attendance shares Registration/Task / HTTP+PG | B1 minutes first;POST B1 registration + isolated snapshot | same id/task, both flags | {"projection":{"id":"2","meetingId":"2","status":"confirmed"},"record":{"id":2,"meeting_id":2,"client_contact_id":2,"task_id":2,"attend_requested":true,"minutes_requested":true,"status":"confirmed"}} | Pass | http-integration-results.json;2026-10-06T16:29:30.416Z;#4复验范围 |
| R4-HTTP-016 | B1 future join link withheld / HTTP+PG | B1 both intents before start;GET join-link | visible=false | {"visible":false,"joinUrl":null,"reason":"MEETING_NOT_OPEN"} | Pass | http-integration-results.json;2026-10-06T16:29:31.223Z;#4复验范围 |
| R4-HTTP-017 | B2 attendance first while not started / HTTP+PG | B2 future,0h;POST B2 registration | confirmed | {"id":"3","meetingId":"3","status":"confirmed"} | Pass | http-integration-results.json;2026-10-06T16:29:31.254Z;#4复验范围 |
| R4-HTTP-018 | B2 then minutes shares Registration/Task / HTTP+PG | B2 attend first;PUT B2 minutes + snapshot | same id,task, both flags | {"reservation":{"id":"3","meetingId":"3","clientContactId":"2","taskId":"3","status":"reserved","createdAt":"2026-10-07T00:29:31.297439"},"record":{"id":3,"meeting_id":3,"client_contact_id":2,"task_id":3,"attend_requested":true,"minutes_requested":true,"status":"confirmed"}} | Pass | http-integration-results.json;2026-10-06T16:29:31.301Z;#4复验范围 |
| R4-HTTP-019 | Both intentions appear in separate lists / HTTP+PG | A minutes-only,B1/B2 both;GET both my lists | myMeetings=2,myMinutes=3 | {"myMeetings":2,"myMinutes":3} | Pass | http-integration-results.json;2026-10-06T16:29:32.908Z;#4复验范围 |
| R4-HTTP-020 | Future B1 cancel keeps minutes and Task / HTTP+PG | B1 future,both;DELETE registration | cancelled;same reserved minutes and ongoing Task | {"registration":{"id":"2","meetingId":"2","status":"cancelled"},"reservation":{"id":"2","meetingId":"2","clientContactId":"2","taskId":"2","status":"reserved","createdAt":"2026-10-07T00:29:30.412283"},"taskStatus":"ongoing"} | Pass | http-integration-results.json;2026-10-06T16:29:32.989Z;#4复验范围 |
| R4-HTTP-021 | Future B1 reattend reuses id/Task / HTTP+PG | B1 cancelled but future;POST registration fresh key | confirmed,same ids,3 Tasks total | {"id":"2","meetingId":"2","status":"confirmed"} | Pass | http-integration-results.json;2026-10-06T16:29:33.910Z;#4复验范围 |
| R4-HTTP-022 | Advance only isolated B fixtures to started / HTTP+PG | B1/B2 future registration complete;Guarded synthetic ORM time update | Only B1/B2 updated | {"advanced":[2,3]} | Pass | http-integration-results.json;2026-10-06T16:29:34.732Z;#4复验范围 |
| R4-HTTP-023 | Started attendee B1 obtains link / HTTP+PG | B1 advanced,confirmed;GET join-link | visible=true synthetic invalid-domain link | {"visible":true,"joinUrl":"https://qa-meeting.example.invalid/join/B1_minutes_attend","reason":null} | Pass | http-integration-results.json;2026-10-06T16:29:35.508Z;#4复验范围 |
| R4-HTTP-024 | Started attendee B2 obtains link / HTTP+PG | B2 advanced,confirmed;GET join-link | visible=true | {"visible":true,"joinUrl":"https://qa-meeting.example.invalid/join/B2_attend_minutes","reason":null} | Pass | http-integration-results.json;2026-10-06T16:29:35.550Z;#4复验范围 |
| R4-HTTP-025 | Started B1 cancel preserves minutes Task / HTTP+PG | B1 started,both;DELETE registration + snapshot | cancelled and minutes same ids/ongoing Task | {"registration":{"id":"2","meetingId":"2","status":"cancelled"},"reservation":{"id":"2","meetingId":"2","clientContactId":"2","taskId":"2","status":"reserved","createdAt":"2026-10-07T00:29:30.412283"}} | Pass | http-integration-results.json;2026-10-06T16:29:35.586Z;#4复验范围 |
| R4-HTTP-026 | Cancelled started B1 loses link / HTTP+PG | B1 cancelled,minutes retained;GET join-link | visible=false,no link | {"visible":false,"joinUrl":null,"reason":"REGISTRATION_REQUIRED"} | Pass | http-integration-results.json;2026-10-06T16:29:36.486Z;#4复验范围 |
| R4-HTTP-027 | Started B1 cannot restore attendance / HTTP+PG | B1 cancelled after start;POST attend fresh key | MEETING_NOT_OPEN,no extra Task | {"status":409,"data":{"error":{"code":"MEETING_NOT_OPEN","message":"会议当前不可报名"},"requestId":"f261e04e-d31e-4dbc-ae31-145be5e9c02f"}} | Pass | http-integration-results.json;2026-10-06T16:29:36.520Z;#4复验范围 |
| R4-HTTP-028 | Started B1 repeated minutes retained / HTTP+PG | B1 cancelled attendee,minutes active;PUT minutes fresh key | same reserved id/task | {"id":"2","meetingId":"2","clientContactId":"2","taskId":"2","status":"reserved","createdAt":"2026-10-07T00:29:30.412283"} | Pass | http-integration-results.json;2026-10-06T16:29:37.344Z;#4复验范围 |
| R4-HTTP-029 | Started B2 cancel preserves same minutes Task / HTTP+PG | B2 opposite order;DELETE registration | cancelled,same minutes id/task | {"registration":{"id":"3","meetingId":"3","status":"cancelled"},"reservation":{"id":"3","meetingId":"3","clientContactId":"2","taskId":"3","status":"reserved","createdAt":"2026-10-07T00:29:31.297439"}} | Pass | http-integration-results.json;2026-10-06T16:29:37.390Z;#4复验范围 |
| R4-HTTP-030 | All free Tasks remain zero and unique / HTTP+PG | A/B1/B2 complete;Read isolated snapshot | 3 registrations,3 unique Tasks,0 contracts,all prices0 | {"registrations":[{"id":1,"meeting_id":1,"client_contact_id":2,"task_id":1,"attend_requested":false,"minutes_requested":true,"status":"confirmed"},{"id":2,"meeting_id":2,"client_contact_id":2,"task_id":2,"attend_requested":true,"minutes_requested":true,"status":"cancelled"},{"id":3,"meeting_id":3,"client_contact_id":2,"task_id":3,"attend_requested":true,"minutes_requested":true,"status":"cancelled"}],"tasks":[{"id":1,"status":"ongoing","contract_id":null,"charge_total_hours":"0.0000","actual_price":"0.00","total_price":"0.00"},{"id":2,"status":"ongoing","contract_id":null,"charge_total_hours":"0.0000","actual_price":"0.00","total_price":"0.00"},{"id":3,"status":"ongoing","contract_id":null,"charge_total_hours":"0.0000","actual_price":"0.00","total_price":"0.00"}],"contract_count":0} | Pass | http-integration-results.json;2026-10-06T16:29:37.464Z;#4复验范围 |
| R4-HTTP-031 | Synthetic paid no contract rejects without mutation / HTTP+PG | D synthetic1h,no contracts;PUT D minutes | NO_ACTIVE_CONTRACT,still3 Tasks | {"status":409,"data":{"error":{"code":"NO_ACTIVE_CONTRACT","message":"当前客户暂无有效合同,请联系客户经理开通后再报名"},"requestId":"e5e32c49-8b3e-48f0-ad21-a43a50da7cde"}} | Pass | http-integration-results.json;2026-10-06T16:29:38.248Z;#4复验范围 |
| R4-HTTP-032 | Real PG refusal outbox durable and deduplicated / HTTP+PG | D denied;Repeat rejection+PG SELECT | one pending row,not reservation | [{"meeting_id":"4","state":"pending","attempts":0,"accepted_at":null}] | Pass | http-integration-results.json;2026-10-06T16:29:39.079Z;#4复验范围 |
| R4-HTTP-033 | Refusal persists across real BFF restart and mock acceptance / HTTP+PG | Outbox stored in real PG;Stop/restart BFF; bootstrap dispatch to mock13001 | same row accepted once;no real email | {"outbox":{"state":"accepted","attempts":1,"accepted_at":"2026-10-06T16:29:39.777Z"},"mockRequests":1,"realEmails":0} | Pass | http-integration-results.json;2026-10-06T16:29:39.132Z;#4复验范围 |
| R4-HTTP-034 | Accepted refusal never becomes successful reservation / HTTP+PG | D notice accepted by mock;GET D minutes;GET myMinutes;snapshot | null,D absent,3 Tasks | {"reservation":null,"myMinutes":3,"taskCount":3} | Pass | http-integration-results.json;2026-10-06T16:29:39.930Z;#4复验范围 |
独立断言结论及边界¶
A:minutes-only,attend=false,registration GET null,myMeetings无A,myMinutes有A,已开始无join。相同键重放及6个并行新键请求仍1记录/Task,权威GET返回同id/task和原始naive微秒,不补Z。
B1 minutes→attend:Registration.id=2/Task.id=2;B2 attend→minutes:id=3/task=3。尚未开始时先完成两意图,然后只推进这两条合成会议时间,两者获得synthetic example.invalid入会链接。取消参会后minutes保留同id/task,B1无入会权且不能在开始后恢复参会。三个免费Task全部ongoing、contract=null、actual/total_price=0,数目3,无重复计费。
D为合成1h/no-contract,业务拒绝NO_ACTIVE_CONTRACT,仍只有3Task。PG outbox只有1条;BFF真实重启后同条outbox accepted/attempts=1,mock13001接收1次,实际员工邮件0。accepted只表示本地mock HTTP接受,不表示投递;拒绝不能变成成功预约,D不在myMinutes。
资源与手册¶
Backend PID53599、BFF PID53601/53625均SIGTERM停止;明确QA容器ndb-qa-minutes-http-20261007-56488停止,四端口lsof无监听。tmpfs丢失仅本轮合成数据,无现有数据删除;保留日志。未改业务源码/共享Mini产物,未commit/push/deploy。
UI+Mini已复核手册3图只读范围。HTTP成功不新增“成功预约”UI截图;原生暂不登录、真实微信/手机号认证和完整成功手册仍未覆盖。此前单元/模拟322项属于旧BFF候选;本轮BFF全量独立127/127,最新跨端单元/模拟汇总331项330Pass/1旧Mini样式Fail;HTTP34单列不混算。
RA Updated by Redmine Admin about 1 month ago
- File case-results.md case-results.md added
- File unit-tests.tap unit-tests.tap added
- File meeting-experts.md meeting-experts.md added
- File 01-meeting-expert.png 01-meeting-expert.png added
- File 02-expert-detail.png 02-expert-detail.png added
- File 03-login-gate.png 03-login-gate.png added
- File 04-login-page.png 04-login-page.png added
- File 05-return-meeting.png 05-return-meeting.png added
QA 测试结果 - QA-MEETING-EXPERT-20261007-R1 - 2026-10-07 22:31 Asia/Shanghai¶
- Redmine: NDB #1 会议管理与话题管理功能验收(含 Markdown/BFF 跨端验证)。
- 执行者: NDB QA Agent。环境: 本地微信开发者工具,skill/tool 0.3.9 equal,未登录的小程序访客;工具开发者账号登录不等于小程序用户登录。
- 候选: projects/mp/mp-conference,feat/meeting-v2-integration,HEAD dda147326123846629dd16705ef51a4cf177a536 上未提交候选。保留全部已有改动。
- 预检: effective pwd/Gitroot=/Users/gexiaowei/Documents/work/mindsetech/ndb/projects/mp/mp-conference,目标页readable/writable,docs writable;未写业务源码。
- 汇总: Pass 43 / Fail 0 / Blocked 7 / Skipped 0,共50条。36条单元/mock + 14条接口/模拟器/源码/E2E门禁。Pass严格按层级,不代表真实预约完成。
- 单元命令: node --test --test-reporter=tap tests/consultant-booking.test.cjs tests/catalog-v2.test.cjs tests/meeting-v2.test.cjs,36/36通过,无业务库POST。
- 原生tap工具限制: 多次tap/trigger仅返回success,页面未变,记录Blocked,不按回执认定交互成功。用编译页面既有eh分发tap(从真实outerWxml读取sid)后,详情导航和原生登录提示实际出现;不是源码修改,也不是真实触摸证明。
- 原生弹窗: WXML不包含按钮;本执行器无cua。尝试System Events只读遍历未在有界时间返回,已中断。未使用mock假冒原生点击。Mini本轮真实登录/返回图片已复核,独立复现仍Blocked。
- 当前模拟器经reLaunch回到会议75/source=v2;不继续占用模拟器,独占权释放。若原生模态仍在窗口上,由下一拥有者安全取消,不得点任何提交动作。
| 编号 | 用例/检查点 | 层级 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| EXP-UNIT-001 | gather and search remove the duplicate online-meeting category | 单元/mock | gather and search remove the duplicate online-meeting category | node:test ok 1,断言通过;无真实业务请求 | Pass | unit-tests.tap #1 |
| EXP-UNIT-002 | content, topics and experts only use the V2 catalog API | 单元/mock | content, topics and experts only use the V2 catalog API | node:test ok 2,断言通过;无真实业务请求 | Pass | unit-tests.tap #2 |
| EXP-UNIT-003 | home recommendations and industry filters only use the V2 catalog API | 单元/mock | home recommendations and industry filters only use the V2 catalog API | node:test ok 3,断言通过;无真实业务请求 | Pass | unit-tests.tap #3 |
| EXP-UNIT-004 | the mini-program has no legacy API origin or request client | 单元/mock | the mini-program has no legacy API origin or request client | node:test ok 4,断言通过;无真实业务请求 | Pass | unit-tests.tap #4 |
| EXP-UNIT-005 | content cards open the dedicated V2 detail page | 单元/mock | content cards open the dedicated V2 detail page | node:test ok 5,断言通过;无真实业务请求 | Pass | unit-tests.tap #5 |
| EXP-UNIT-006 | catalog adapters preserve public presentation and never add private expert fields | 单元/mock | catalog adapters preserve public presentation and never add private expert fields | node:test ok 6,断言通过;无真实业务请求 | Pass | unit-tests.tap #6 |
| EXP-UNIT-007 | catalog error states are retryable except for unavailable content | 单元/mock | catalog error states are retryable except for unavailable content | node:test ok 7,断言通过;无真实业务请求 | Pass | unit-tests.tap #7 |
| EXP-UNIT-008 | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries | 单元/mock | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries | node:test ok 8,断言通过;无真实业务请求 | Pass | unit-tests.tap #8 |
| EXP-UNIT-009 | logged-out expert booking can be cancelled or open login without posting | 单元/mock | logged-out expert booking can be cancelled or open login without posting | node:test ok 9,断言通过;无真实业务请求 | Pass | unit-tests.tap #9 |
| EXP-UNIT-010 | unauthenticated expert booking opens the existing authentication dialog without posting | 单元/mock | unauthenticated expert booking opens the existing authentication dialog without posting | node:test ok 10,断言通过;无真实业务请求 | Pass | unit-tests.tap #10 |
| EXP-UNIT-011 | concurrent expert booking posts the public profile id once and shows the success feedback | 单元/mock | concurrent expert booking posts the public profile id once and shows the success feedback | node:test ok 11,断言通过;无真实业务请求 | Pass | unit-tests.tap #11 |
| EXP-UNIT-012 | failed expert booking allows retry and rechecks access before the next post | 单元/mock | failed expert booking allows retry and rechecks access before the next post | node:test ok 12,断言通过;无真实业务请求 | Pass | unit-tests.tap #12 |
| EXP-UNIT-013 | registration shows the customer charge before submitting; pending is never called confirmed | 单元/mock | registration shows the customer charge before submitting; pending is never called confirmed | node:test ok 13,断言通过;无真实业务请求 | Pass | unit-tests.tap #13 |
| EXP-UNIT-014 | meeting detail downloads and opens the generated minutes attachment | 单元/mock | meeting detail downloads and opens the generated minutes attachment | node:test ok 14,断言通过;无真实业务请求 | Pass | unit-tests.tap #14 |
| EXP-UNIT-015 | meeting content requires a valid session before download and opens login only once | 单元/mock | meeting content requires a valid session before download and opens login only once | node:test ok 15,断言通过;无真实业务请求 | Pass | unit-tests.tap #15 |
| EXP-UNIT-016 | meeting content login prompt can be cancelled without leaving or downloading | 单元/mock | meeting content login prompt can be cancelled without leaving or downloading | node:test ok 16,断言通过;无真实业务请求 | Pass | unit-tests.tap #16 |
| EXP-UNIT-017 | registration is not submitted when the price prompt is cancelled | 单元/mock | registration is not submitted when the price prompt is cancelled | node:test ok 17,断言通过;无真实业务请求 | Pass | unit-tests.tap #17 |
| EXP-UNIT-018 | timeout retries reuse the same key without optimistic registration | 单元/mock | timeout retries reuse the same key without optimistic registration | node:test ok 18,断言通过;无真实业务请求 | Pass | unit-tests.tap #18 |
| EXP-UNIT-019 | favorites stay independent while minutes reservation requires customer authentication | 单元/mock | favorites stay independent while minutes reservation requires customer authentication | node:test ok 19,断言通过;无真实业务请求 | Pass | unit-tests.tap #19 |
| EXP-UNIT-020 | started meeting reserves minutes once with a price confirmation and authoritative reread | 单元/mock | started meeting reserves minutes once with a price confirmation and authoritative reread | node:test ok 20,断言通过;无真实业务请求 | Pass | unit-tests.tap #20 |
| EXP-UNIT-021 | started meeting overview guidance follows the minutes reservation action without changing registration gates | 单元/mock | started meeting overview guidance follows the minutes reservation action without changing registration gates | node:test ok 21,断言通过;无真实业务请求 | Pass | unit-tests.tap #21 |
| EXP-UNIT-022 | attendance and minutes reservation coexist without changing registration or join authorization | 单元/mock | attendance and minutes reservation coexist without changing registration or join authorization | node:test ok 22,断言通过;无真实业务请求 | Pass | unit-tests.tap #22 |
| EXP-UNIT-023 | minutes-only reservation never creates a client-side attendance projection or join link | 单元/mock | minutes-only reservation never creates a client-side attendance projection or join link | node:test ok 23,断言通过;无真实业务请求 | Pass | unit-tests.tap #23 |
| EXP-UNIT-024 | cancelled price confirmation does not reserve minutes | 单元/mock | cancelled price confirmation does not reserve minutes | node:test ok 24,断言通过;无真实业务请求 | Pass | unit-tests.tap #24 |
| EXP-UNIT-025 | published analyst minutes block reservation even when the attachment is missing; AI minutes do not | 单元/mock | published analyst minutes block reservation even when the attachment is missing; AI minutes do not | node:test ok 25,断言通过;无真实业务请求 | Pass | unit-tests.tap #25 |
| EXP-UNIT-026 | reservation read failures never become an unreserved state or consult legacy subscriptions | 单元/mock | reservation read failures never become an unreserved state or consult legacy subscriptions | node:test ok 26,断言通过;无真实业务请求 | Pass | unit-tests.tap #26 |
| EXP-UNIT-027 | reservation retries reuse the business key and never optimistically mark success | 单元/mock | reservation retries reuse the business key and never optimistically mark success | node:test ok 27,断言通过;无真实业务请求 | Pass | unit-tests.tap #27 |
| EXP-UNIT-028 | reservation results from an old login session never pollute the current session | 单元/mock | reservation results from an old login session never pollute the current session | node:test ok 28,断言通过;无真实业务请求 | Pass | unit-tests.tap #28 |
| EXP-UNIT-029 | minutes can never be written through the legacy notification subscription API | 单元/mock | minutes can never be written through the legacy notification subscription API | node:test ok 29,断言通过;无真实业务请求 | Pass | unit-tests.tap #29 |
| EXP-UNIT-030 | missing active contract keeps reservation unconfirmed and points to staff handling | 单元/mock | missing active contract keeps reservation unconfirmed and points to staff handling | node:test ok 30,断言通过;无真实业务请求 | Pass | unit-tests.tap #30 |
| EXP-UNIT-031 | cancellation asks only for confirmation and allows registration again | 单元/mock | cancellation asks only for confirmation and allows registration again | node:test ok 31,断言通过;无真实业务请求 | Pass | unit-tests.tap #31 |
| EXP-UNIT-032 | unavailable registration read disables mutation, logout removes a visible link | 单元/mock | unavailable registration read disables mutation, logout removes a visible link | node:test ok 32,断言通过;无真实业务请求 | Pass | unit-tests.tap #32 |
| EXP-UNIT-033 | secondary failures stay local while meeting detail remains available | 单元/mock | secondary failures stay local while meeting detail remains available | node:test ok 33,断言通过;无真实业务请求 | Pass | unit-tests.tap #33 |
| EXP-UNIT-034 | completed and cancelled meetings override unbound identity guidance | 单元/mock | completed and cancelled meetings override unbound identity guidance | node:test ok 34,断言通过;无真实业务请求 | Pass | unit-tests.tap #34 |
| EXP-UNIT-035 | legacy IDs never enter v2 mutation routes or reveal the legacy public link | 单元/mock | legacy IDs never enter v2 mutation routes or reveal the legacy public link | node:test ok 35,断言通过;无真实业务请求 | Pass | unit-tests.tap #35 |
| EXP-UNIT-036 | phone, contact and meeting eligibility gate registration; settlement errors stay explicit | 单元/mock | phone, contact and meeting eligibility gate registration; settlement errors stay explicit | node:test ok 36,断言通过;无真实业务请求 | Pass | unit-tests.tap #36 |
| EXP-HTTP-001 | 会议公开资料加法契约 | 只读接口 | 保留关联ID,增加公开profile | GET meetings/75:关联481208,publicProfile.id49,显示资料匹配 | Pass | GET摘要;卡片截图01 |
| EXP-HTTP-002 | 公开专家详情ID对应 | 只读接口 | 公开id49详情与卡片一致 | GET catalog/experts/49:秦贵军/某商业航空公司/联合创始人 | Pass | GET摘要;截图02 |
| EXP-SIM-001 | 完整公开专家卡片 | 模拟器只读 | 默认头像、昵称、公司、职位、独立按钮可见 | 截图确认;outerWxml默认头像URL,无内部姓名 | Pass | 01-meeting-expert.png |
| EXP-SIM-002 | 信息区详情导航 | 模拟器事件分发 | profileid49且保留conference_id75 | 分发既有tap后currentPage专家49/conference_id75;返回正常 | Pass | 02-expert-detail.png;runtimeInfo |
| EXP-SIM-003 | 未登录独立约访提示 | 模拟器事件分发 | 提示登录且不跳专家详情 | 分发既有tap后真实提示暂不登录/去登录;仍会议75 | Pass | 03-login-gate.png |
| EXP-SIM-004 | 原生取消登录独立复现 | 原生模拟器 | 取消留原会议不提交 | 原生弹窗不在WXML,当前未暴露cua;仅mock及Mini同轮证明 | Blocked | UNIT009;Mini同轮交付;无独立原生点击 |
| EXP-SIM-005 | 原生去登录独立复现 | 原生模拟器 | 去登录打开login页面不提交 | QA缺原生按钮点击工具;已复核Mini登录截图 | Blocked | 04-login-page.png(Mini来源) |
| EXP-SIM-006 | 原生登录页返回独立复现 | 原生模拟器 | 返回原会议75 | 独立前置去登录未完成;已复核Mini返回截图 | Blocked | 05-return-meeting.png(Mini来源) |
| EXP-SIM-007 | 原生tap自动化点击 | 模拟器工具 | tap信息区或action触发行为 | tap/trigger返回success但currentPage无变化;eh事件分发正常,不能认定原生点击通过 | Blocked | 工具输出;排查记录;需桌面工具 |
| EXP-STATIC-001 | 头像加载失败与空字段 | 源码检查 | 缺图默认头像,空字段省略,不回退内部姓名 | 源码有error回调及nickname专家占位;空avatar实测,图片加载失败未造运行故障 | Pass | ConsultantSimpleCard.vue源码;图01 |
| EXP-STATIC-002 | 会议上下文与事件隔离 | 源码检查 | 详情公开ID与conference_id,预约不冒泡 | card information独立;action @tap.stop;会议传conference-id;publicProfile映射测试通过 | Pass | 组件/会议源码;UNIT006 |
| EXP-E2E-001 | 真实微信登录与身份认证 | 真实E2E | 真实登录认证后允许申请 | 未执行真实微信登录/认证;安全范围仅mock门禁 | Blocked | UNIT010;无真实登录或认证截图 |
| EXP-E2E-002 | 真实专家预约成功落库 | 真实E2E | 申请接受且仅一条,反馈一致 | 禁止业务库POST与客户通知;成功及防双击仅mock通过 | Blocked | UNIT011;无业务库申请/通知 |
| EXP-E2E-003 | 真实专家预约失败恢复 | 真实E2E | 失败允许取消或重试且不误报成功 | 禁止真实预约POST;失败重试及资格重查仅mock通过 | Blocked | UNIT012;无真实故障POST |
候选源码指纹¶
- adapter.ts: bd1e0ffd45f9c3c20dbf2bf798bbfb9eb555c166ef8267723692a6cc2250a9a7
- types.ts: 242413af7ba64e4263acab5bfe87ac39dd7e8cdbaa74a51022b9047b080343a2
- ConsultantSimpleCard.vue: 27e9f7989a339a762ea2bca0222f7611a60fa0b46c35953c551248b8d66c5243
- booking.ts: ba66a8e623a308502a55ed8d8e5f4cd033afaaf941148a05bd97e2041ef8cb5c
- conference/detail/index.vue: 64a7b150743f53e61a9b3974706d6c7307bcb4e18fe4aa5ceff12a9014200620
风险、基线及未验证项¶
- 本轮不重复无关全量:统筹交付全量81/82,其中灰/白卡静态断言与已确认设计冲突为既有失败;明确保留,不回退设计、不声明全量绿。本轮43Pass/0Fail仅代表上述执行范围。
- Backend264/BFF136及Mini构建/lint/编译通过属于开发交付,不计入本轮QA独立结果。
- 真实微信登录、认证成功、真实预约成功/失败/通知与生产层均未验证。未对业务库预约POST,没有数据库或财务写入,没有外发通知。
- 多卡、长文本、无公开profile、图片加载失败的运行视觉验收未全覆盖;nullprofile/内部ID排除有UNIT006,长文本换行与默认图error有源码证据,不冒充运行通过。
- 图文手册: projects/mp/mp-conference/docs/user-manual/meeting-experts.md,5图(QA3图+Mini同轮2图,均已查看);UI结构复核和Mini业务校对待统筹安排,尚不能宣布手册最终完成。
- 禁止操作均未执行: commit/push/deploy/branch/worktree/业务DB写/真实预约/通知。
- 下一步: 主统筹安排手册双复核;提供可用桌面交互工具后重测SIM004-007;真实认证/预约仅在另行安全隔离环境与明确授权后执行。
RA Updated by Redmine Admin about 1 month ago
- File meeting-experts.md meeting-experts.md added
- File case-results.md case-results.md added
QA-MEETING-EXPERT-20261007-R1 定稿补充:journal25 已重新读取确认50条逐条记录,43 Pass / 0 Fail / 7 Blocked / 0 Skipped,Blocked7行与汇总一致。UI结构/视觉复核与Mini业务校对均已通过,全文和五图逐张检查无必修问题;QA已统一修订手册主线图注,将事件分发/资料ID等说明移至验证边界。五个图片引用本地检查全部存在。附更新后的定稿手册与报告,旧附件95为待复核稿,保留历史不覆盖。原生点击工具限制、取消/去登录/返回独立Blocked、真实登录认证及实际预约POST未做的边界不变,mock不代表真实申请成功。模拟器独占权释放;无业务源码/DB/通知/commit/push/deploy操作。
RA Updated by Redmine Admin about 1 month ago
- File button-compact-r2.md button-compact-r2.md added
- File meeting-experts.md meeting-experts.md added
- File 01-meeting-expert.png 01-meeting-expert.png added
- File 03-login-gate.png 03-login-gate.png added
- File 05-return-meeting.png 05-return-meeting.png added
QA 测试结果 - QA-MEETING-EXPERT-20261007-R2 - 2026-10-07 22:38 Asia/Shanghai¶
- 范围:用户要求“单独约访按钮有点高”的小幅视觉修订,仅一条视觉用例。
- 项目/版本:canonical projects/mp/mp-conference,feat/meeting-v2-integration,dda1473 上冻结未提交候选;已有改动保留。预检 pwd/Gitroot 匹配,读取当前 CSS。
- 前置:Mini 已交回模拟器;会议75公开专家49,未登录访客。没有真实预约或通知。
- 预期尺寸是750宽设计单位,不是物理像素。CSS可见140×64,hitbox140×88,字号26不变。
- 汇总:Pass 1 / Fail 0 / Blocked 0 / Skipped 0。本轮仅视觉层;R1 43Pass/7Blocked原样保留,不升级真实登录/认证/预约证据。
| 编号 | 用例 | 层级 | 操作/预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|
| EXP-VIS-R2-001 | 单独约访按钮降低、文案居中、完整描边 | 当前CSS核对+真实模拟器视觉 | 查看会议75专家卡片;可见高度88降64、宽140,文字居中、橙色边框无裁切,外层88触摸区保留 | QA查看Mini button-compact.png和独立新图01:按钮降低、文字居中、完整闭合描边;CSS核对外层140×88/::before140×64/pointer-events:none,未改业务事件 | Pass | Mini outputs/meeting-expert-restoration-20261007/mini/button-compact.png;手册 assets/meeting-experts/01-meeting-expert.png |
工具与证据边界¶
- automation_element_action size返回326×85.992,与小按钮实际对象不符;未用此回执宣称精确实测尺寸,尺寸结论仅当前CSS+截图视觉,不据此新增产品Fail或修改源码。
- 手册01/03/05旧高按钮可见,全部替换为QA R2真实图;02/04未影响,保留R1并明确来源。
- 03由当前编译页面既有tap事件分发,真实登录提示出现;不点击原生模态确认,不POST。
- 05由automation_navigate进入现有登录页,runtime确认login,再navigateBack会议75重拍;不是原生“去登录”选择或真实登录成功,不改变R1对应Blocked。
- 五个图片引用检查待交付执行;五图均已查看。UI/Mini本次更新只读review待统筹安排,QA唯一writer。
- 未运行unit/full/build或新镜像测试;开发交付lint/build/编译不计入本轮QA独立结果。
- 无业务源码/DB/实际预约/通知写入;无commit/push/deploy/切分支/worktree。
RA Updated by Redmine Admin about 1 month ago
- File meeting-experts.md meeting-experts.md added
- File button-compact-r2.md button-compact-r2.md added
QA-MEETING-EXPERT-20261007-R2 定稿补充:journal27已回读确认单条EXP-VIS-R2-001及Pass1/Fail0/Blocked0/Skipped0。UI更新图1/3/5视觉PASS,Mini业务复核无问题;唯一来源文案要求已由QA完成且回读:图4保留Mini R1来源;图5改为QA R2通过受控导航进入现有登录页再navigateBack采集,图注与最后验证边界均明确不证明原生去登录按钮点击或真实登录成功。五图链接均有效。附最终手册和R2报告,旧附件104保留历史。原R1的43Pass/7Blocked不变。模拟器独占释放,无业务源码/DB/真实预约/通知/commit/push/deploy操作。
RA Updated by Redmine Admin about 1 month ago
- File charge-label-r3.md charge-label-r3.md added
- File meeting-54-free-r3.png meeting-54-free-r3.png added
- File meeting-75-one-hour-r3.png meeting-75-one-hour-r3.png added
- File meeting-experts.md meeting-experts.md added
QA 测试结果 - QA-MEETING-EXPERT-20261007-R3 - 2026-10-07 22:43 Asia/Shanghai¶
- Redmine:NDB #1。范围仅用户文案“0小时显示免费”,两条收费展示用例。
- 执行者:NDB QA Agent。canonical pwd/Gitroot:/Users/gexiaowei/Documents/work/mindsetech/ndb/projects/mp/mp-conference。分支feat/meeting-v2-integration,HEAD dda1473上未提交候选;已有dirty完整保留。
- 层级:只读GET+真实模拟器展示。Mini已释放模拟器;QA不跑unit/full、构建或新镜像测试,不改业务源码,不提交实际业务请求。
- 汇总:Pass 2 / Fail 0 / Blocked 0 / Skipped 0。R1和R2历史结果及真实登录/预约限制不变。
| 编号 | 用例 | 前置/操作 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|
| EXP-CHARGE-R3-001 | 零小时显示免费 | GET meetings/54并读取当前详情会议收费,采集截图 | customerChargeHours为0时显示免费,不显示0小时 | GET id54/customerChargeHours0,.conference__section__content__item .desc文本免费,截图免费与专家卡同屏 | Pass | meeting-54-free-r3.png |
| EXP-CHARGE-R3-002 | 正收费小时数保持原展示 | 导航会议75,GET会议并读取会议收费,采集截图 | customerChargeHours1仍显示1小时,不显示免费 | GET id75/customerChargeHours1,页面文本1 小时,截图一致,原手册图仍正确 | Pass | meeting-75-one-hour-r3.png |
补充源码检查与工具边界¶
- detail.vue模板285-289:严格===0显示免费;number显示对应小时数;其余显示待工作人员确认。null/undefined分支仅源码检查,未使用实际未知收费API样本或模拟造数,不能声称未知态运行通过。
- 最初误用不存在的.conference-detail-card选择器,工具返回no such element;读取真实模板后改用现有.desc选择器成功。此定位错误不是产品Fail,也未将失败回执当作通过。
- 手册只在步骤1加一句零/正/未知收费文案,五图来源完全未改;会议75仍1小时,因此不替换旧图。新增免费图仅本轮QA证据,不扩手册流程。
- 两张新图均已逐张查看;UI/Mini仅需对新增一句只读文字复核,由root安排。
- 没有真实登录、认证、预约POST、财务或数据库写入,没有通知;未commit/push/deploy/branch/worktree。
- 当前模拟器停会议75专家卡片,独占权释放,不再操作。
RA Updated by Redmine Admin about 1 month ago
- File visual-results.md visual-results.md added
- File talk-hotspots.png talk-hotspots.png added
- File gather-meetings.png gather-meetings.png added
QA 测试结果 - QA-LIST-TAB-SPACING-20261007-R1 - 2026-10-07 23:02 Asia/Shanghai¶
- Redmine:NDB #1。执行者:NDB QA Agent。
- 范围:仅统一热点/专家与会议/纪要库页签圆弧至首内容卡片的留白,两条最小视觉用例。
- 候选:projects/mp/mp-conference,canonical /Users/gexiaowei/Documents/work/mindsetech/ndb/projects/mp/mp-conference,feat/meeting-v2-integration,现有未提交候选;预检pwd/Gitroot匹配,已有15个tracked修改与4项untracked完整保留。
- 本次talk index.scss diff只有新增 &__tabs { margin-bottom: var(--space-3); },gather使用同一token,src/app.scss定义16px。
- 证据来源:Mini在同设备/142%缩放实际采集的 talk-hotspots.png、gather-meetings.png;QA逐张独立查看并对照源码,不冒充QA重新采集或业务E2E。
- 汇总:Pass 2 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 层级 | 前置/检查 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|---|
| LIST-SPACING-001 | 敏思谈页签下方留白与横向布局 | 真实截图独立视觉复核+源码 | 查看热点选中页,核对热点/专家横排、选中圆弧、首内容卡片边缘 | tabs底部使用16px同token,圆弧与首卡分离,页签不重叠或裁切 | 热点/专家横向完整;圆弧下方有清晰留白,首卡未顶住圆弧;与敏思汇视觉间距一致,源码margin-bottom token一致 | Pass | ../mini/talk-hotspots.png;src/pages/talk/index.scss |
| LIST-SPACING-002 | 敏思汇基准页间距与布局未受影响 | 真实截图独立视觉复核+源码 | 查看会议选中页,核对会议/纪要库横排、圆弧、首会议卡 | 原16px留白保留,页签和首卡布局完整,与敏思谈一致 | 会议/纪要库横向完整;圆弧到首卡留白保留,无覆盖或裁切;与敏思谈一致 | Pass | ../mini/gather-meetings.png;src/pages/gather/index.scss |
简短页面导航说明¶
在小程序底部选择“敏思谈”,默认“热点”页可查看热点/专家横向页签;选择“敏思汇”,默认“会议”页可查看会议/纪要库横向页签。观察选中圆弧下缘到第一张内容卡片上缘。此次只统一留白,不改变页签、筛选或任何业务流程。没有验证切换到专家/纪要库后的新业务行为。
层级及边界¶
- 两张原始图1108×2398,同设备缩放;16CSS px在142%约23截图px是Mini提供的换算背景,不作为QA精密像素测量结论;QA结论是截图可见一致与相同CSS token。
- 纯CSS留白、无新增工作流:不改不相关专家详情手册、不新建长手册;本报告及真实图是本轮图文证据。
- 未重新编译、未跑全量或业务测试、未操作模拟器。此次独占权释放,Mini冻结后当前正常页状态未由QA更改。
- 无业务源码、数据库、实际POST、通知写入;无restore/reset/commit/push/deploy/branch/worktree。
- 既有真实登录/认证/实际预约未验证边界及先前R1 Blocked保持不变。
RA Updated by Redmine Admin about 1 month ago
- File visual-results.md visual-results.md added
- File talk-hotspots.png talk-hotspots.png added
- File gather-meetings.png gather-meetings.png added
QA 测试结果 - QA-LIST-HEADER-GAP-20261007-R2 - 2026-10-07 23:06 Asia/Shanghai¶
- Redmine:NDB #1。执行者:NDB QA Agent。范围:搜索框到热点/专家页签上方留白统一,并保持前轮页签下16px间距。
- canonical pwd/Gitroot:/Users/gexiaowei/Documents/work/mindsetech/ndb/projects/mp/mp-conference,分支feat/meeting-v2-integration。未提交候选,全部已有dirty保留。
- 当前源码talk和gather header padding-bottom均0;双方mb-6保留;tabs margin-bottom均var(--space-3)=16px。本轮只移除talk额外32px header padding,不将上/下留白混淆。
- 来源:Mini冻结后同设备真实采集 ../mini/header-gap-r2/talk-hotspots.png 与 gather-meetings.png。QA两图逐张独立查看并核对当前样式,不声称QA重新采集或业务E2E。
- 汇总:Pass 2 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 层级 | 前置/检查 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|---|
| LIST-HEADER-R2-001 | 敏思谈搜索框至页签上间距 | 真实截图独立视觉复核+源码 | 查看搜索框底缘、热点/专家文字与圆弧、首卡上缘 | 移除额外32px,上留白与敏思汇一致;热点/专家横向完整,tabs下16px保留 | 两图搜索框底缘与页签文字位于一致高度;热点/专家及圆弧完整,首卡与圆弧分离,当前CSS header0/tabs16 | Pass | mini/header-gap-r2/talk-hotspots.png;talk/index.scss |
| LIST-HEADER-R2-002 | 敏思汇上间距基准及下间距不回退 | 真实截图独立视觉复核+源码 | 对比会议/纪要库文字、搜索框和首会议卡 | 原header0不变,与敏思谈一致;tabs下16px仍保留,布局不重叠 | 搜索框至会议/纪要库与敏思谈视觉对齐;圆弧到首卡留白一致,页签/卡片无覆盖或裁切;源码header0/tabs16 | Pass | mini/header-gap-r2/gather-meetings.png;gather/index.scss |
简短导航及边界¶
底部“敏思谈”默认热点页,对比底部“敏思汇”默认会议页;先看搜索框到页签的上留白,再看选中圆弧到首卡的下留白。纯CSS间距改变,不新增业务流程,不改专家详情手册或另建长手册。
仅本轮两图复核,未重新采集/操作模拟器、未编译或全量/业务测试。没有实际POST、DB写或通知,未修改业务源码,无reset/restore/commit/push/deploy/branch/worktree。原业务登录/认证/实际预约未验证结论不变。模拟器使用权释放,状态未经QA更改。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 公开专家平台 HTTP R1 - 2026-10-07 23:39 Asia/Shanghai¶
- 环境:127.0.0.1:18000 隔离 Backend 与 127.0.0.1:15433 专用假数据 PostgreSQL;未触发真实通知。
- 候选:Backend
feat/meeting-management@444afbe上的未提交本地改动。 - 账号:隔离管理员、只读角色;凭据不入报告。
- 汇总:Pass 15 / Fail 0 / Blocked 0 / Skipped 0。
- 证据:
outputs/expert-public-platform-20261007/qa/http-results.json;run_http_cases.py。
| 编号 | 用例 | 层级与操作 | 预期 | 实际 | 状态 |
|---|---|---|---|---|---|
| EXP-API-001 | 初始三态与默认空平台 | HTTP:GET 3/4/5 public-profile | 未许可及草稿隐藏,已发布可见 | unlicensed hidden; draft hidden; published visible | Pass |
| EXP-API-002 | 只读角色可读且匿名拒绝 | HTTP:limited/anonymous GET public-profile | 只读可读,匿名拒绝 | limited read 200; anonymous 401 | Pass |
| EXP-API-003 | 无管理权限拒绝写入和预填 | HTTP:limited PATCH platform 与 GET prefill | 无管理权限403 | limited write 403; limited prefill 403 | Pass |
| EXP-API-004 | 平台值和越界字段校验 | HTTP:PATCH 未知/重复平台及越界字段 | 均400且平台不变 | unknown, duplicate, legacy boolean, application override: 400 | Pass |
| EXP-API-005 | 公开资料预填只读且不带联系方式 | HTTP:admin GET prefill 后再读 profile | 只给建议,不创建资料或返回联系方式 | suggestions returned; no profile created; no phone/email | Pass |
| EXP-API-006 | 未选平台禁止发布 | HTTP:4号禁用平台后 POST published | 409且仍为草稿 | disabled platform: 409; profile remains draft | Pass |
| EXP-API-007 | 人工确认后发布 | HTTP:4号无确认/有确认 POST published | 无确认400,有确认公开 | without confirmation 400; confirmed publication visible | Pass |
| EXP-API-008 | 发布后签名公开详情可见 | HTTP:HMAC GET catalog expert detail | 发布后200 | signed public detail 200 after publication | Pass |
| EXP-API-009 | 修改已发布资料立即下架 | HTTP:4号 PUT 编辑后 HMAC GET detail | 转草稿且对外404 | saved draft; signed detail 404 | Pass |
| EXP-API-010 | 公开姓名为空禁止发布 | HTTP:4号空姓名 PUT 后 POST published | 400 | blank public name publication 400 | Pass |
| EXP-API-011 | 资料保存幂等与冲突 | HTTP:4号同键同内容 PUT 两次、异内容一次 | 相同结果;异内容409 | same key same profile; changed payload 409 | Pass |
| EXP-API-012 | 取消平台隐藏会议话题及目录投影 | HTTP:6号禁用平台,GET 公开及内部会议话题 | 公开投影隐藏,内部关联保留 | platform off: public meeting/topic experts 0; internal links 1; signed detail 404; profile retained | Pass |
| EXP-API-013 | 重选平台恢复原已发布资料 | HTTP:6号恢复平台,GET 公开投影 | 原已发布资料重新可见 | reselected platform: catalog 200; meeting/topic experts 1 | Pass |
| EXP-API-014 | 不存在专家不可访问 | HTTP:GET 不存在 candidate profile | 404 | unknown candidate 404 | Pass |
| EXP-API-015 | 测试后假数据可见状态复原 | HTTP:GET 3/4/5/6 最终状态 | 假数据初始可见状态复原 | fixture public states restored | Pass |
风险与未验证项¶
- 浏览器真实交互、Mini 模拟器、有登录态预约和视觉截图尚待后续轮次。
- 未来发布时间、跨应用边界、Task 不重复将追加针对性验证。
- 首次脚本误将内部 Web 管理详情当作公开投影;已按契约改测 HMAC 对外接口,整轮重跑为 15/15。
下一步¶
- 继续 Mini mock/模拟器和 Web 浏览器验收;每轮追加 Redmine。
- 图文手册使用真实界面截图,并请 UI 与项目 Agent 复核。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 公开专家平台 Mini mock R2 - 2026-10-07 23:41 Asia/Shanghai¶
- 环境:本地 Mini Program 源码与 Node test runner;不连接真实小程序登录或业务数据库。
- 候选:Mini
feat/meeting-v2-integration@dda1473上的未提交本地改动。 - 命令:
node --test --test-reporter=tap tests/catalog-v2.test.cjs tests/meeting-v2.test.cjs tests/consultant-booking.test.cjs。 - 汇总:Pass 36 / Fail 0 / Blocked 0 / Skipped 0;TAP 证据:
outputs/expert-public-platform-20261007/qa/mini-focused.tap。
| 编号 | 用例 | 层级/检查点 | 预期 | 实际 | 状态 |
|---|---|---|---|---|---|
| EXP-MINI-001 | gather and search remove the duplicate online-meeting category | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 1 | Pass |
| EXP-MINI-002 | content, topics and experts only use the V2 catalog API | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 2 | Pass |
| EXP-MINI-003 | home recommendations and industry filters only use the V2 catalog API | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 3 | Pass |
| EXP-MINI-004 | the mini-program has no legacy API origin or request client | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 4 | Pass |
| EXP-MINI-005 | content cards open the dedicated V2 detail page | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 5 | Pass |
| EXP-MINI-006 | catalog adapters preserve public presentation and never add private expert fields | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 6 | Pass |
| EXP-MINI-007 | catalog error states are retryable except for unavailable content | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 7 | Pass |
| EXP-MINI-008 | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries | 源码断言/Mock;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 8 | Pass |
| EXP-MINI-009 | logged-out expert booking can be cancelled or open login without posting | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 9 | Pass |
| EXP-MINI-010 | unauthenticated expert booking opens the existing authentication dialog without posting | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 10 | Pass |
| EXP-MINI-011 | concurrent expert booking posts the public profile id once and shows the success feedback | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 11 | Pass |
| EXP-MINI-012 | failed expert booking allows retry and rechecks access before the next post | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 12 | Pass |
| EXP-MINI-013 | registration shows the customer charge before submitting; pending is never called confirmed | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 13 | Pass |
| EXP-MINI-014 | meeting detail downloads and opens the generated minutes attachment | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 14 | Pass |
| EXP-MINI-015 | meeting content requires a valid session before download and opens login only once | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 15 | Pass |
| EXP-MINI-016 | meeting content login prompt can be cancelled without leaving or downloading | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 16 | Pass |
| EXP-MINI-017 | registration is not submitted when the price prompt is cancelled | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 17 | Pass |
| EXP-MINI-018 | timeout retries reuse the same key without optimistic registration | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 18 | Pass |
| EXP-MINI-019 | favorites stay independent while minutes reservation requires customer authentication | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 19 | Pass |
| EXP-MINI-020 | started meeting reserves minutes once with a price confirmation and authoritative reread | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 20 | Pass |
| EXP-MINI-021 | started meeting overview guidance follows the minutes reservation action without changing registration gates | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 21 | Pass |
| EXP-MINI-022 | attendance and minutes reservation coexist without changing registration or join authorization | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 22 | Pass |
| EXP-MINI-023 | minutes-only reservation never creates a client-side attendance projection or join link | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 23 | Pass |
| EXP-MINI-024 | cancelled price confirmation does not reserve minutes | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 24 | Pass |
| EXP-MINI-025 | published analyst minutes block reservation even when the attachment is missing; AI minutes do not | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 25 | Pass |
| EXP-MINI-026 | reservation read failures never become an unreserved state or consult legacy subscriptions | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 26 | Pass |
| EXP-MINI-027 | reservation retries reuse the business key and never optimistically mark success | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 27 | Pass |
| EXP-MINI-028 | reservation results from an old login session never pollute the current session | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 28 | Pass |
| EXP-MINI-029 | minutes can never be written through the legacy notification subscription API | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 29 | Pass |
| EXP-MINI-030 | missing active contract keeps reservation unconfirmed and points to staff handling | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 30 | Pass |
| EXP-MINI-031 | cancellation asks only for confirmation and allows registration again | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 31 | Pass |
| EXP-MINI-032 | unavailable registration read disables mutation, logout removes a visible link | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 32 | Pass |
| EXP-MINI-033 | secondary failures stay local while meeting detail remains available | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 33 | Pass |
| EXP-MINI-034 | completed and cancelled meetings override unbound identity guidance | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 34 | Pass |
| EXP-MINI-035 | legacy IDs never enter v2 mutation routes or reveal the legacy public link | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 35 | Pass |
| EXP-MINI-036 | phone, contact and meeting eligibility gate registration; settlement errors stay explicit | Node Mock/单元;独立 TAP 子测试 | 该子测试断言全部成立 | TAP ok 36 | Pass |
风险与未验证项¶
- 这 36 条只证明源映射与 Mock 业务门禁;未完成从真实假数据 API 到微信模拟器的发布/取消同步或 404 返回页面复现。
- 用户登录、身份认证和真实专家约访 POST 未执行;不把 Mock 成功当作业务申请落库。
- 公开资料取消后,Mini
useDidShow刷新和错误页清除旧资料已做源码检查;待隔离 BFF 13000 与 Mini 测试构建就绪后做端到端确认。
下一步¶
- 连接隔离 BFF/假 fixture,验证发布可见、取消隐藏、旧详情 404 与返回刷新;捕获真实模拟器截图。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 公开专家平台 Mini 隔离运行 R3 - 2026-10-07 23:47 Asia/Shanghai¶
- 环境:微信开发者工具真实模拟器;Mini 一次性测试构建指向隔离 BFF
127.0.0.1:13000,后者仅连接隔离 Backend127.0.0.1:18000与假数据库。未连接原 BFF 3000、业务库或真实通知。 - 假数据:已发布专家 public profile 3 / candidate 6,关联 meeting 1、topic 1。仅对该假 candidate 的
WECHAT_MINI_APP许可做撤销与恢复;最终已恢复。 - 汇总:Pass 5 / Fail 0 / Blocked 0 / Skipped 0。图片证据在
outputs/expert-public-platform-20261007/qa/assets/mini-runtime/。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| EXP-MINI-RT-001 | 已许可专家在会议详情展示 |
source=v2 的 meeting 1 显示公开专家卡 |
模拟器显示假昵称、公司、职位和单独约访入口;01-meeting-visible.png;BFF meeting GET 200,experts 1 |
Pass |
| EXP-MINI-RT-002 | 从会议卡进入公开专家详情 | 点击卡片资料区,路由使用公开 profile ID | 页面进入 /pages/consultant/detail/index?id=3&conference_id=1,显示同一公开资料及关联会议;02-expert-visible.png
|
Pass |
| EXP-MINI-RT-003 | 取消平台许可后会议返回刷新 | 公开专家从会议卡消失,内部会议关联保留 | 假 candidate 6 许可撤销后 BFF meeting GET 200、experts 0;从专家详情返回 meeting 1,模拟器 .consultant-simple-card 为 0;03-meeting-hidden.png
|
Pass |
| EXP-MINI-RT-004 | 已撤销专家旧详情不可查看 | 旧公开 URL 返回不可用态,清除原资料 | BFF /catalog/experts/3 为 404;模拟器直达旧详情显示“记录不存在”,无旧姓名或约访按钮;04-expert-revoked.png
|
Pass |
| EXP-MINI-RT-005 | 恢复许可后重新显示 | 原已发布资料恢复公开,无需重建关联 | 假 candidate 6 重选平台后 BFF 专家详情 200;返回 meeting 1,模拟器再次检出 1 张专家卡。假数据最终状态已恢复 | Pass |
边界¶
- 首次无
source=v2的直达路由显示旧版内容停读提示;R3 的会议用例明确使用source=v2,与新目录导航一致。 - 没有执行微信登录、认证、预约 POST、真实专家发布、通知或生产验证。topic 1 的撤销前后投影仅经隔离 BFF GET 核实,未在模拟器打开话题页。
- 未验证并发旧响应竞态或全部九个专家承载页面;相关源码与 mock 结果记录在 R2。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 公开专家平台 Web 隔离运行 R4 - 2026-10-08 00:05 Asia/Shanghai¶
- 环境:NDB Web
127.0.0.1:18888,隔离 Backend127.0.0.1:18000、BFF127.0.0.1:13000、仅含假资料的 PostgreSQL。ego-browserTaskSpace 19;未连接原 8888、原 3000 或业务库。 - 账号:隔离假管理员与有专家页访问权限、无公开管理权限的假账号。所有专家与会议均为隔离 fixture。
- 候选:Web
feat/meeting-management未提交本地候选。汇总:Pass 10 / Fail 0 / Blocked 0 / Skipped 0;Web 截图在projects/ndb/frontend/docs/user-manual/assets/expert-public-platform/。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| EXP-WEB-RT-001 | 假管理员访问专家公开管理 | 专家详情显示平台许可、状态和公开资料入口 | 补齐隔离 fixture 专家页权限及 property 空对象后,/candidates/4 正常显示“平台公开”、微信小程序已勾选、草稿状态;图 01 |
Pass |
| EXP-WEB-RT-002 | 从内部资料一次带入 | 先提示覆盖,确认后只改当前表单,不自动发布 | 点击“从内部资料带入一次”出现覆盖确认;确认后公开姓名变为内部假专家名,原草稿仍未发布;图 02 | Pass |
| EXP-WEB-RT-003 | 人工确认门禁 | 未确认不能发布;填好并确认后可保存/发布 | 未勾人工确认时“发布”不可点击;勾选后按钮可用,确认行及表单见图 03 | Pass |
| EXP-WEB-RT-004 | 保存草稿 | 保存后仍不公开 | 假 candidate 4 人工填写并确认后保存,Backend profile status=draft、is_public=false | Pass |
| EXP-WEB-RT-005 | 发布公开资料 | 明示影响范围,发布后公开可见 | 出现“影响小程序专家列表及所有关联会议、话题”确认(图 04);确认后 Web 标“已发布 · 当前可见”(图 05),Backend published/true,BFF 目录出现 profile 1 | Pass |
| EXP-WEB-RT-006 | 取消微信平台许可 | 已发布资料保留状态,公开端立即隐藏 | 图 06 确认;取消后 Backend public_platforms=[]、profile 仍 published、is_public=false,BFF profile 1 GET 404,Web 标“未选择微信小程序”(图 07) |
Pass |
| EXP-WEB-RT-007 | 重新勾选微信平台 | 明确警告已有已发布资料可能恢复,符合条件时恢复可见 | 图 08 警告;确认后 Backend WECHAT_MINI_APP/published/true,Web 标“已发布 · 当前可见” |
Pass |
| EXP-WEB-RT-008 | 主动下架 | 告知公开端隐藏,完成后转草稿 | 图 09 确认;确认后 Backend draft/false,Web 标“草稿 · 尚未发布”(完成态见图 11) | Pass |
| EXP-WEB-RT-009 | 无公开管理权限账号 | 允许查看,禁止写入 | 假有限账号进入同一专家页,仅显示“查看公开资料”;抽屉有只读提示,启用输入框 0 个、启用按钮仅“关闭”;图 10 | Pass |
| EXP-WEB-RT-010 | 会议添加专家后选择仅添加 | 先建关联和应付 Task,再询问公开;选择仅添加不公开、不重复建 Task | meeting 1 添加未授权 fake candidate 3 后表格显示 1 条该专家记录及 Task #2;弹窗“专家已添加至会议”提供“仅添加(完成)/完善公开资料并发布”(图 12-13)。选择仅添加后表格仍为该 1 条记录和 Task #2;candidate 3 仍无平台许可和公开资料,BFF meeting 1 只返回原已公开 profile 3 | Pass |
隔离 fixture 前置修复与状态¶
- 首次 Web 登录时假管理员缺
/candidates页面权限,路由重定向;Ops 只在隔离数据库补页面权限后重登验证。首次详情渲染因假候选人property=null在旧模板读取cpt_face_to_face时中断;Ops 只给假 candidate 3/4/5/6 补合法空对象,未改业务源码或业务库。这两项为测试 fixture 前置问题,修复后上述用例均执行完成。 - 假 candidate 4 的平台许可、草稿状态和 9 个公开字段已与测试前快照逐项比对并恢复。假 candidate 6 的平台许可亦在 Mini R3 恢复。会议 1 新增的假 candidate 3 与 Task #2 保留,以验证“仅添加”不回滚既成关联;该临时数据库最终由 Ops 清理。
未执行¶
- 未使用真实专家或业务数据库,未发送通知、未执行微信登录与约访 POST,未验证生产或已部署版本。
- 未对所有公开资料字段(上传头像、行业搜索、标签)逐项做浏览器上传/选择;本轮聚焦平台许可、独立草稿、人工确认、发布下架、只读权限与会议提示。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 本地49份公开启用后只读验收 R5 - 2026-10-08 Asia/Shanghai¶
- 环境:原本地 BFF
127.0.0.1:3000,后端127.0.0.1:8000;只读核对 Opslocal-enable-result.md与权限受限的local-public-49-target-snapshot.json,不附快照内容。 - BFF 仓库预检:
projects/mp/mp-conference-api-v2,canonical/Users/gexiaowei/Documents/work/mindsetech/ndb/projects/mp/mp-conference-api-v2;分支feature/migrate-legacy-mini-api,upstream 同名,单 worktree,目标源码可读,已有 dirty 保留。原 BFF 3000 PID 17504、后端 8000 PID 62859 仍监听。 - 汇总:Pass 3 / Fail 0 / Blocked 0 / Skipped 0。仅 GET,无登录、浏览器、小程序模拟器或业务字段写入。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| EXP-LOCAL-001 | 原 BFF 专家目录全页公开 ID 集合 |
/api/v2/catalog/experts?page=1&pageSize=100 返回且仅返回快照中的49个公开资料ID |
HTTP 200;total 49、items 49、唯一ID 49,集合与受限快照精确一致 | Pass |
| EXP-LOCAL-002 | 公开资料49详情可读 |
/api/v2/catalog/experts/49 返回公开ID49 |
HTTP 200;返回 id=49。未输出真实姓名、背景等资料 |
Pass |
| EXP-LOCAL-003 | 会议75关联专家仍公开 |
/api/v2/meetings/75 中候选人481208投影到公开资料49,详情可读 |
HTTP 200;meeting专家项1条,其中指定candidate→publicProfile 49 精确匹配1条;详情49仍HTTP 200 | Pass |
边界¶
- 本轮是本地迁移和平台许可启用后的独立 API 只读验收;没有逐个读取49份详情、没有浏览器/模拟器重测、没有通知或约访 POST,也没有生产验证。
- 数据库备份、迁移、49位候选人许可与后端重启由 Ops 执行,详见
outputs/expert-public-platform-20261007/ops/local-enable-result.md;本报告不将 Ops 的数据库动作归为 QA 操作。 - 未改业务源码、业务字段、权限或环境配置;未提交、推送、部署、切分支或创建 worktree。
RA Updated by Redmine Admin about 1 month ago
独立测试 RabbitMQ QA 结果¶
时间:2026-10-08 11:50 Asia/Shanghai。目标仅为新建测试服务 ndb-rabbitmq-staging,62.234.192.45:5671、vhost ndb-staging-dev。执行根为 NDB 非 Git 协调目录。运维交接见同目录 rabbitmq-create-result.md;QA 独立读取本目录公 CA 证书并完成下表验证。
| 编号 | 检查 | 实际结果 | 状态 |
|---|---|---|---|
| QA-RMQ-001 | 指定目标 TCP 5671 可达 |
62.234.192.45:5671 一次 TCP 连接成功,随即关闭 |
Pass |
| QA-RMQ-002 | 专属 CA、证书 IP SAN 和 TLS | 客户端启用证书验证,专属 CA 验证成功;显式以 62.234.192.45 验证服务器证书 IP SAN 成功;协商 TLSv1.3。服务器证书 SHA256 指纹 ED:0A:A5:8B:1C:06:36:DB:FC:36:34:B0:B9:2F:25:75:C6:C7:93:D8:36:A3:E3:1D:BE:2A:6E:8B:65:0A:A0:50,与运维交接一致 |
Pass |
| QA-RMQ-003 | 独立账号 AMQP 认证并立即断开 | 从指定 Bitwarden 条目精确读取测试账号密码,仅用于此连接;对指定 vhost 完成一次 AMQPS 认证连接并正常关闭。创建 channel 0、declare/consume/publish 0 | Pass |
汇总:Pass 3 / Fail 0 / Blocked 0 / Skipped 0。只连接测试目标,没有连接生产、读取或打印密码/私钥;没有业务消息或拓扑写入。
边界¶
- 本次只验证从当前客户端到新测试 broker 的 TCP/TLS/AMQP 认证路径;不证明业务服务已接入、交换机/队列/绑定存在、消息可投递或消费。
- 未复核远端生成 Compose、容器实际资源限制、私钥文件权限、重启持久性、性能、日志或既有服务健康。它们的运维观察及限制以
rabbitmq-create-result.md为准。 - 没有仓库代码、环境配置、容器或云资源写入;未提交、推送、切分支、创建 worktree 或部署。
RA Updated by Redmine Admin about 1 month ago
QA-RMQ R1 报告措辞更正:journal #37 汇总句中的“没有读取密码”不准确。QA-RMQ-003 为完成获准的认证测试,确实从指定 Bitwarden 条目读取测试密码,仅在本次进程内存中用于一次 AMQPS connect-close;未打印或落盘密码,也未读取私钥。三项 Pass 结论不变。已同步修正 outputs/test-dependencies-switch-20261008/rabbitmq-qa-result.md。
RA Updated by Redmine Admin about 1 month ago
两个新 staging 库与本机五服务独立 QA¶
时间:2026-10-08 13:25 Asia/Shanghai。执行根为 /Users/gexiaowei/Documents/work/mindsetech/ndb(非 Git 协调目录)。对照运维 two-databases-result.md,仅通过健康 GET、进程状态及 PostgreSQL BEGIN READ ONLY / ROLLBACK 独立复核;测试密码仅从指定 Bitwarden 条目进入本次进程内存,未打印或落盘。
| 编号 | 检查 | 实际结果 | 状态 |
|---|---|---|---|
| QA-DB-001 | 五服务进程 | Backend PID89250、Web父 PID84438、Miniwatch PID84439、BFF父 PID22146、Notification父 PID22145 均存活 | Pass |
| QA-DB-002 | Backend基础健康 |
127.0.0.1:8000/v1/version/ HTTP200,业务响应 code200 |
Pass |
| QA-DB-003 | Web基础访问 |
127.0.0.1:8888/ HTTP200 |
Pass |
| QA-DB-004 | BFF存活与就绪 | 源码确认健康路径为 /health/live、/health/ready;3000两项HTTP200,ready报告 channelDb=up、ndb=up
|
Pass |
| QA-DB-005 | Notification存活与就绪 | 源码确认健康路径为 /health/live、/health/ready;3001两项HTTP200,ready报告 postgres/rabbitmq/redis=up
|
Pass |
| QA-DB-006 | Mini watch状态 | PID84439存活;本轮 runtime 日志含 Compiled successfully 和 Watching
|
Pass |
| QA-DB-007 | BFF新库身份、权限与schema | READ ONLY连接 mp_conference_staging,current_user/owner同名,事务只读on;superuser/createdb/createrole/replication/bypassrls均false,PUBLIC CONNECT=false;schema_migrations=[4,5]、public表11张,两个通知outbox均0 |
Pass |
| QA-DB-008 | Notification新库身份、权限与schema | READ ONLY连接 notification_staging,current_user/owner同名,事务只读on;五项高权flag均false,PUBLIC CONNECT=false;schema_migrations仅001_initial.sql、public表5张,notifications/deliveries/outbox_events均0 |
Pass |
| QA-DB-009 | 既有业务库迁移记录 | READ ONLY连接 slime_crm_staging,django_migrations仍109条 |
Pass |
汇总:Pass 9 / Fail 0 / Blocked 0 / Skipped 0。所有数据库连接均设置默认只读并显式执行 BEGIN READ ONLY,结束时 ROLLBACK;未执行任何迁移、业务记录写入或服务重启。
验证边界¶
- 健康接口和迁移表只证明本次观察到的基础运行与新库初始化状态;未调用会议、专家、报名等业务 API。既有业务库源码迁移差异仍在,不能据此声明完整业务流程可用。
- 未测试真实微信登录、通知发送或邮件接收;未发布/消费 MQ 消息,也未检查业务拓扑。Notification ready 的 RabbitMQ
up只说明其就绪检查通过。 - 未验证 ES、OSS、测试微信 AppID/secret、PostgreSQL/Redis TLS 或长期稳定性。本轮未操作浏览器、模拟器、生产、Docker、源码、环境文件、分支/worktree、提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
staging 业务库迁移后独立 QA¶
时间:2026-10-08 14:07 Asia/Shanghai。执行根为 /Users/gexiaowei/Documents/work/mindsetech/ndb;目标仓库 projects/ndb/backend,分支 feat/meeting-management,原有 21 条工作区改动未触碰。目标仅 slime_crm_staging。凭据经 Bitwarden 取入进程内存,未打印或落盘;PostgreSQL 连接强制 default_transaction_read_only=on,显式 BEGIN READ ONLY / ROLLBACK。Django 检查使用 crm_backend 与既有外置 dev_staging_settings,真实未 patch 的 MigrationLoader / MigrationExecutor 和标准 migrate --plan。
| 编号 | 检查 | 独立观察 | 结果 |
|---|---|---|---|
| QA-MIG-001 | 目标库与只读保护 |
current_database=slime_crm_staging,服务端 172.18.0.3:5432,transaction_read_only=on
|
Pass |
| QA-MIG-002 | 单行 ledger 更名 |
django_migrations=119;id109 为 projects.0021_meeting_task_finance,原 applied 2026-09-14 14:06:57.634569 保留;旧 0022_meeting_task_finance 记录数 0 |
Pass |
| QA-MIG-003 | 精确 10 项 | 目标 10 项均已记录,依次为 id120–129:accounts0011/0012、candidates0014、companies0006/0007、meetings0007/0008/0009、projects0022type/0023merge;旧 id92、116 记录仍存在 | Pass |
| QA-MIG-004 | 真实 Django history 与计划 | 未修改 check_consistent_history 通过;全局 leaf 计划 0,标准 migrate --plan 报无待执行操作 |
Pass |
| QA-MIG-005 | 新列与事件表 | candidates1、clients4、meetings7、meeting_registrations2、projects1,共 15 个目标列均存在;client_contact_events 表可查询且当前 0 行。只读列元数据类型、NULL 属性与迁移定义一致,DB default 均为 NULL(应用层 default 不等于 DB default) |
Pass |
| QA-MIG-006 | 权限种子 |
/topics、/topics/manage、/candidates/public-platform/manage 三条记录均存在,名称、类型及 parent_path 与迁移定义一致 |
Pass |
| QA-MIG-007 | 业务行数与默认分类 | projects19(全 interview)、project_tasks75(全 standard)、candidates373384;meetings、registrations、public profiles、contact events 均 0;非空 public_platforms 0。与统筹转述的运维计数一致;未独立取得逐表迁移前基线 |
Pass |
| QA-MIG-008 | 五服务进程及 Mini watch | Backend 新 PID43315、Web84438、Mini84439、BFF22146、Notification22145 均存活;Mini 日志包含 Compiled successfully、Watching
|
Pass |
| QA-MIG-009 | 五服务基础健康 | Backend /v1/version/、Web /、BFF /health/live/ready、Notification /health/live/ready 全部 HTTP200;Notification ready 报 postgres/rabbitmq/redis up
|
Pass |
汇总:Pass 9 / Fail 0 / Blocked 0 / Skipped 0。
验证边界¶
- 本次只读抽样确认 ledger 身份、目标迁移集合、计划、目标结构、权限、行数及本机健康;未逐行比对整个业务库与迁移前备份。
id>116还包含既有 finance id117–119;本轮精确十项为 id120–129。 - 未执行真实微信登录、会议/专家/报名业务流程、邮件或通知发送、MQ publish/consume、ES/OSS 测试或长期运行观察。健康 GET 与 schema 通过不等于业务端到端验收。
- 未运行迁移、修改源码/环境、导入 fixture、停止或重启服务、访问生产、提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
测试会议内容导入独立 QA(初轮)¶
时间:2026-10-08 Asia/Shanghai。目标仅 slime_crm_staging 与本地 BFF 3000。仓库 projects/ndb/backend 位于 feat/meeting-management,原有 21 条工作区改动保留。本报告在本地 BFF 超时修复前记录真实初轮结果;待统筹另行放行后补充重测。
测试用例¶
| 用例 | 实际结果 | 状态 |
|---|---|---|
| QA-TRANSFER-001 来源与目标身份 | 固定来源归档 SHA 与受限结果相同;目标库 slime_crm_staging、服务端 172.18.0.3:5432、事务 transaction_read_only=on;DB anchor 的完整 manifest 与外置映射一致 |
Pass |
| QA-TRANSFER-002 映射及公开字段 | 77 Candidate 映射(49公开 fixture+28非公开)、22行业、68项目、49Task、71会议、155话题、49公开专家档案、63内容、49会议专家、34话题专家、1话题会议、0话题内容,目标记录均找到;按固定来源归档逐条比对 4,546 个公开白名单字段,差异 0;对应 FK 映射差异 0,589条新增记录逐行 hash 差异 0 | Pass |
| QA-TRANSFER-003 公开许可与非公开边界 | 49个已发布公开档案均关联已获 WECHAT_MINI_APP 许可的 fixture;28新增Candidate 均 platforms []、available=false、电话/邮箱/描述为空且无公开档案。49条会议专家关系对应45个distinct专家,其中31条涉及公开49人之外的28个distinct;未把两组49等同 |
Pass |
| QA-TRANSFER-004 原有记录保护 | anchor 保存的受保护表摘要重新计算差异0;既有fixture除平台许可外字段逐行 hash 差异0,其他既有Candidate整体摘要一致;原75Task、19Project、2Industry属于受保护集合 | Pass |
| QA-TRANSFER-005 数量与状态 | 提交后 candidates373412、industries24、projects87、project_tasks124;meetings71(68 ended/2 cancelled/1 scheduled)、topics155(143 published/11 draft/1 archived)、profiles49、content63(62 published/1 draft)、ME49/TE34/TM1/TC0,与目标映射及来源状态一致 | Pass |
| QA-TRANSFER-006 正常公开 GET 与详情 | 本地 BFF 会议10条页 HTTP200/total70(源71场有1场 is_deleted)、话题20条首页 HTTP200/total143、专家20条首页 HTTP200/total49、内容100条页 HTTP200/total62;会议/已发布话题/公开专家/内容详情 HTTP200,抽查ID及会议专家、话题专家、内容会议关联匹配映射;draft/archived话题及draft内容详情均404 | Pass(抽样) |
| QA-TRANSFER-007 真实日历大页 |
GET /api/v2/meetings?page=1&pageSize=100 返回 HTTP503、NDB_UNAVAILABLE,约5009ms;后端日志同请求稍后返回200,说明BFF的5秒等待先超时。真实小程序日历有100条页入口 |
Fail(待本地BFF超时修复后重测) |
| QA-TRANSFER-008 默认话题分页 |
GET /api/v2/catalog/topics?page=1..6&pageSize=20 均200;第7页第一次返回HTTP503,BFF日志 durationMs=5010,requestId 98eac16b-9357-48ca-9c14-c5c28ccba4d0。先前50条页也曾503;10条页的15页请求曾全部返回200。20条页是小程序默认入口,不能据10条页成功宣称其通过 |
Fail(待本地BFF超时修复后重测) |
初轮:Pass 6 / Fail 2。没有对失败页高频重试。READ ONLY SQL 使用 BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY 与 ROLLBACK;凭据仅通过已批准的 Bitwarden 测试项进入进程内存,不打印或落盘。公开 GET 仅使用本地 BFF,不调用报名、预约、结算、通知或 MQ 写入接口。
边界¶
- 受保护摘要与迁移前基线来自数据库同事务 anchor;本轮独立从当前目标重新计算并比较,没有对迁移前备份逐行恢复检查。源公开白名单字段与目标逐字段比对,不代表源私有资料被复制或验证。
- 初轮公开列表的全量分页与ID集合因两处5秒超时未完成;当前只确认首批/已完成页的总量和抽样详情。未测试真实微信登录、模拟器、ES/OSS、长期稳定性或生产。
- Notification 3001 的旧进程中断发生在导入之前;不作为本次会议数据导入失败。源码、服务配置、数据库写入、真实通知、提交、推送、部署均非本轮 QA 操作。
RA Updated by Redmine Admin about 1 month ago
测试会议内容导入 QA 定向重测 R2¶
运维另行将本地 test BFF 的有效 UPSTREAM_TIMEOUT_MS 从 5000 调整到 30000,重启BFF并确认 live/ready。QA 未改配置或重启服务。只重测初轮失败的真实入口及两个代表请求,没有重跑已通过的数据库全量验证;Redmine 原失败记录保留。
| 用例 | R2 实际结果 | 结果 |
|---|---|---|
| QA-TRANSFER-007 |
GET /api/v2/meetings?page=1&pageSize=100 HTTP200、4703ms;total70/items70,70个唯一ID与来源71场排除1条 is_deleted 后的目标映射精确一致,缺失0/多余0;标题与公开状态逐条差异0 |
Pass(原5秒超时已解决) |
| QA-TRANSFER-008 |
GET /api/v2/catalog/topics?page=1..8&pageSize=20 全部HTTP200,页数20/20/20/20/20/20/20/3;total143,143个唯一ID与来源已发布且发布时间不晚于当前的目标映射精确一致,缺失0/多余0。原失败第7页 7893ms;第3/6页分别5129/5130ms,超过原5秒等待 |
Pass(原5秒超时已解决) |
| QA-TRANSFER-006 代表请求 | 专家20条首页HTTP200、4726ms、total49;内容100条页HTTP200、713ms、total62/items62 | Pass |
最终本轮:Pass 8 / Fail 0(初轮 2 个 Fail 已由 R2 定向重测转为 Pass)。话题第7页约7.9秒,仍有本地测试环境的响应时间风险;此结果不代表生产性能或真实微信登录通过。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 纪要库第 1 轮 - 2026-10-08 18:25 Asia/Shanghai¶
- 环境:本地微信开发者工具模拟器;本机 BFF 127.0.0.1:3000;受控函数夹具。用户状态:未登录。
- 候选:
projects/mp/mp-conference/feat/meeting-v2-integration当前未提交工作区;有附件纪要重复正文修复后重刷。 - 操作摘要:从搜索“纪要库”进详情,检查标题/摘要/附件;未登录点查看并分别取消、去登录后返回;进入关联会议 id=71;访问不存在内容 id=999999;受控夹具覆盖无附件、非 PDF URL、下载/打开失败。
- 汇总:Pass 4(001、005、006、007);部分 Pass 且有未验证子项 3(004、008、009);Blocked 2(002、003)。没有真实登录/真实 PDF 打开。
| 编号 | 层级/前置 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|
| QA-MINLIB-001 | 模拟器、公开 BFF、未登录 | 列表和详情用会议标题、保留摘要,会议页不误改 | 首卡/详情“海外AI大模型探讨”;content/1 关联 meeting 71;会议页同题 | Pass | 本地 outputs/minutes-library-20261008/minutes-list.png、minutes-detail-fixed.png、meeting-71.png
|
| QA-MINLIB-002 | 适配器测试、公开数据 | 无会议名回退原题,搜索/分页不丢卡 | 13 项聚焦测试含分页隔离通过;真实列表没有回退样例,未逐页核对全部 | Blocked |
node --test tests/content-detail.test.cjs tests/catalog-v2.test.cjs 13/13;需真实样例 |
| QA-MINLIB-003 | 模拟器未登录、受控有效会话 | 点有效附件按下载后打开原目标 | UI有入口且门禁有效;夹具 downloadFile→openDocument 顺序通过;真实微信登录/PDF打开未验 | Blocked |
minutes-detail-fixed.png、登录弹窗;需真实可用身份和文档查看器 |
| QA-MINLIB-004 | 受控无附件/非 PDF URL | 无有效地址不可用;有地址沿会议既有文档路径 | 无附件无下载/打开且正文保留;非 PDF URL 也走原生文档路径,真实打开未验 | 部分 Pass/Blocked | 定向夹具输出 NO_ATTACHMENT_PASS、NON_PDF_ACTUAL;原矩阵 PDF-only 禁用预期经统筹澄清为不适用,不记源码缺陷 |
| QA-MINLIB-005 | 受控函数夹具 | 下载/打开失败显示错误且 loading 复位 | 两类故障均弹“会议服务”,downloading=false | Pass(受控) | DOWNLOAD_ERROR_PASS、OPEN_ERROR_PASS;真实网络故障未验 |
| QA-MINLIB-006 | 模拟器未登录、id=1 | 暂不登录留在原页且不下载 | 符合预期 | Pass |
docs/user-manual/assets/minutes-library/03-login-prompt.png、模拟器页面栈 |
| QA-MINLIB-007 | 模拟器未登录、id=1 | 去登录进登录页,返回原纪要仍受门禁 | 符合预期;没有执行真实微信登录 | Pass |
login-page.png、返回页面栈与再次弹窗 |
| QA-MINLIB-008 | 模拟器会议 id=71、未登录 | AI/分析师状态与会议名不受影响,附件仍受门禁 | AI未生成、分析师纪要有查看;点击出现登录弹窗;真实打开未验 | 部分 Pass/Blocked |
meeting-71.png、meeting-login-modal.png
|
| QA-MINLIB-009 | 模拟器、公开数据 | 未发布/不存在内容不泄露;空/错误有提示 | id=999999显示“内容不存在或尚未发布”;真实空列表/网络错未触发 | 部分 Pass/Blocked |
not-found.png;自动测试含错误状态 |
风险与下一步¶
- 真实微信登录与 PDF 文档查看器端到端、无附件及非 PDF 实际数据、真实网络异常需后续专用环境验证;本轮不能据此宣告完整验收。
- 用户手册草稿:
projects/mp/mp-conference/docs/user-manual/minutes-library.md,4 张当前候选截图;待 UI/Mini 复核。 - 本轮未提交、推送、部署或进行生产验证;未调用认证、发信或数据库写接口。QA 执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 目录性能第 1 轮 - 2026-10-08 Asia/Shanghai¶
- 环境:本地 Backend 8000(Ops 重启并确认健康 200),本地 BFF 3000;只读顺序 GET,无认证/通知/数据库写。候选
projects/ndb/backend/feat/meeting-management未提交工作区,现有 22 项脏状态保留。 - 基线:
outputs/catalog-performance-20261008/baseline.json,同日修复前相同 BFF 路由、数据集。 - 汇总:5 Pass / 0 Fail / 0 Blocked;下列性能为一次顺序量测,不能作为长期 SLA。
| 编号 | 层级与前置 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|
| QA-CATPERF-001 | BFF只读 GET,page1 size1 | 200、完整响应不变、耗时不劣于基线 | topic 859→698ms、expert 840→717ms;两者完整响应SHA-256精确匹配 | Pass | outputs/catalog-performance-20261008/qa-http-results.json |
| QA-CATPERF-002 | BFF只读 GET,page1 size20 | 200、完整响应不变、批量耗时明显下降 | topic 4402→775ms、expert 3770→802ms;完整响应哈希精确匹配 | Pass | 同上 |
| QA-CATPERF-003 | BFF只读 GET,topic page7 size20 | 200、完整响应不变、深页耗时下降 | 7724→894ms;完整响应哈希精确匹配 | Pass | 同上 |
| QA-CATPERF-004 | BFF只读 GET,末页及单详情 | 保留total/页边界/ID,详情可读 | topic page8 total143/3条,expert page3 total49/9条;topic28、expert18详情200且ID一致 | Pass | outputs/catalog-performance-20261008/qa-boundary-results.json |
| QA-CATPERF-005 | 静态审查与开发自动测试证据 | 预取不放宽公开/跨应用门禁,SQL数量随页大小受控 | Topic/Expert列表详情仍用应用及published发布时间条件,expert仍经visible_public_experts;预取同应用过滤且排除取消会议/未发布内容;34 focused及完整160 meeting测试均Pass(34包含在160);5组SQL 6→5、8→5、82→5、76→5、143→8,序列化响应一致 | Pass |
api/meetings/test_catalog_performance.py、focused-tests.log、meeting-regression.log、readonly-query-comparison.json
|
限制:首次采集脚本只读GET后因未处理根级响应结构报错,因此 topic size1 实际请求两次;余组一次。结果文件中的 item_count=0/total=null 是采集脚本取错层级,完整响应哈希仍匹配,末页total另行以根级结构核对。未执行并发压力、长时稳定性、真机或生产验证。无新增UI流程,不更新手册;无源码修改、提交、推送或部署。执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 本地微信配置恢复 - 2026-10-08 Asia/Shanghai¶
- 环境:本地 BFF
projects/mp/mp-conference-api-v2/feature/migrate-legacy-mini-api,外置测试启动器;本轮无真实微信身份。仓库原有 19 tracked + 4 untracked 改动保留。 - 汇总:3 Pass / 0 Fail / 0 Blocked。仅验证配置引用、健康与无效 code 负向路径;真实微信登录成功未验。
| 编号 | 层级与前置 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|
| QA-WXCFG-001 | 外置运行配置只读复核 | 引用原 BFF .env 两项微信配置,失败即停止;不改业务源码或其他测试基础设施 |
helper只取两项并做缺失/占位/不匹配校验;启动器引用helper,保留上游30秒等待;运维报告确认新BFF父/子75129/75172,其他四服务未动 | Pass |
outputs/test-dependencies-switch-20261008/wechat-runtime-result.md、外置helper/start-apis.cjs只读检查 |
| QA-WXCFG-002 | 本地健康GET | BFF live/ready可用 | 两项均HTTP200 | Pass | 本轮curl状态摘要;运维报告依赖检查 |
| QA-WXCFG-003 | 公开登录接口、固定无效code | BFF将微信invalid code映射为HTTP400/WECHAT_CODE_INVALID且不创建用户 | HTTP400、error.code=WECHAT_CODE_INVALID;未提供真实身份。首次结果过滤器仅取到400,因错误码字段嵌套重测同一固定无效code一次才完整确认 |
Pass(负向路径) | 本轮BFF响应摘要;运维侧直接微信固定无效code为HTTP200/errcode40029 |
限制:固定无效code不等于真实 wx.login 成功;未用真实code、手机号或邮箱,未创建用户、发送认证邮件/通知、写测试库、部署或测试生产。无新用户可见流程,不新增手册。执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 纯纪要预约不建 Task 源码候选轮 - 2026-10-08 Asia/Shanghai¶
- 环境:三个本地仓库候选源码与既有隔离测试证据。未对测试库执行 0010 迁移、服务重启或真实预约;无需生产动作。
- 候选分支:Backend
feat/meeting-management;BFFfeature/migrate-legacy-mini-api;Minifeat/meeting-v2-integration。原有工作区改动保留。 - 汇总:5 项源码/文档检查中 5 项相应范围通过;QA-MNT-001/002/004 的运行态子项 Blocked(等待用户批准测试库 DDL 与后续独立业务写 release)。不把开发隔离测试升级为 staging 成功。
| 编号 | 层级/前置 | 预期 | 实际 | 状态 | 证据/后续 |
|---|---|---|---|---|---|
| QA-MNT-001 | 迁移源码/SQL只读 | 仅task可空且attend=>Task CHECK,不改历史行 | 0010及正向SQL吻合;FK/唯一关系保留,无数据DML | Pass(静态);Blocked(测试库DDL) |
outputs/minutes-no-task-20261008/0010-forward.sql;待用户批准后Ops执行 |
| QA-MNT-002 | 后端源码与隔离测试证据 | 纯预约零Task、后续参会一Task、旧Task和财务值不变 | register分支符合;开发隔离PG证据165 meeting +74 finance Pass,含并发、迁移往返/旧财务 | Pass(审查/隔离);Blocked(运行态) |
implementation.md、测试日志;待授权真实fixture写 |
| QA-MNT-003 | BFF契约、独立焦点测试 | task_id必有且可显式null,参会不能null,DTO透传 | schema/refine与DTO符合;独立重跑76/76 Pass | Pass |
src/ndb-client/meeting.adapter.ts、BFF Jest输出 |
| QA-MNT-004 | Mini类型、独立焦点测试 | taskId允许null,预约状态不等于参会权限 | 类型和断言符合;独立重跑24/24 Pass | Pass(源码/夹具);Blocked(真实界面预约) |
src/api/v2/types.ts、Mini测试输出;待真实微信身份/授权 |
| QA-MNT-005 | 文档/手册 | API/数据流/手册与新规则一致且不虚报已验 | 根目录两指南及Mini集成文档同步;手册仅增候选规则与未实测说明,原三张未登录图保留 | Pass(文档);Mini业务校对待确认 |
outputs/mini-program-data-flow-20261006.md、outputs/ndb-application-api-guide-20261006.md、docs/user-manual/minutes-reservation.md
|
下一步:用户批准测试库0010精确迁移后由Ops备份/迁移/重启并提供schema/进程证据;QA获单独真实写release后再验 Task计数、幂等及历史/双意图。当前没有staging业务写、提交、推送、部署或生产验证。执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 纯纪要预约不建 Task 迁移后只读轮 - 2026-10-08 Asia/Shanghai¶
- 环境:本地测试库
slime_crm_staging已执行精确 meetings 0010,Backend/BFF 已重启;QA 只做只读证据复核和少量健康/公开目录 GET。没有真实预约、Task、用户、通知写入或微信登录。 - 汇总:运行态只读 3 Pass、业务端到端 1 Blocked;独立数据库直连取凭据失败,schema依据Ops只读快照,未重试扩大权限。之前 journal46 的源码候选轮记录保留。
| 编号 | 层级/前置 | 预期 | 实际 | 状态 | 证据/后续 |
|---|---|---|---|---|---|
| QA-MNT-R2-001 | Ops迁移后只读快照,目标测试库 | 仅0010登记、Task可空、attend=>Task CHECK有效,原FK/Unique不失 | ledger120且0010=1;task_id nullable YES、新CHECK validated;原Task FK/unique与meeting/contact unique validated;报名0/违规0。QA独立BW直连在取凭据时空JSON失败,未发DB查询 | Pass(Ops证据复核);独立直连未完成 |
ops-after-drift.private.json、ops-migrate-execution.private.json;不声称QA直接查库 |
| QA-MNT-R2-002 | Backend/BFF新本地进程,公开只读请求 | 服务可用且目录无明显回归 | Backend /schema 200(/health/ 非项目路由为404),BFF live/ready均200;topic首条200/total143、expert首条200/total49;新Backend86754/BFF87266+87314及其他3原PID存活。Ops确认原微信/JWT/测试基础设施配置在新进程保留,QA未读取其值 |
Pass | 本轮curl/Node只读摘要、delivery.md;真实微信登录未验 |
| QA-MNT-R2-003 | Ops前后只读104表比对 | 不改Task/预约等历史业务数据 | 103表行数/全行hash相同;仅api_applications一行变。Ops字段级只读比对仅last_used_at变化,符合成功应用鉴权更新使用元数据的源码机制 | Pass(限定范围) |
ops-after-drift.private.json、ops-app-drift.private.json、api/application_auth/authentication.py
|
| QA-MNT-R2-004 | 真实客户预约/参会链路 | 纯预约后零Task,后续参会一Task,幂等和历史Task不变 | 未提供此轮业务写入release或真实微信身份,故未提交预约、参会或通知 | Blocked | 待独立授权后专用测试身份及数据进行端到端验收 |
用户明确取消本任务备份,停止后留下的600 .partial 不是可用备份;不宣称备份成功。本轮不更新既有三张截图,只将手册规则改为本地0010和服务已生效、真实预约未验;Mini业务校对Pass。未提交、推送、部署或验证生产。执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 认证页按钮视觉轮 - 2026-10-08 Asia/Shanghai¶
- 环境:本地微信开发者工具模拟器,
projects/mp/mp-conference/feat/meeting-v2-integration未提交候选。仅只读截图、元素尺寸/位置检查与页面滚动;既有脱敏登录状态未变。 - 汇总:五按钮普通视觉态 5 Pass;验证码倒计时/disabled 子状态 Blocked(没有安全的页面字段夹具);所有真实点击业务行为未执行。
| 编号 | 层级/前置 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|
| QA-AUTHBTN-001 | 模拟器,已验证手机号 | 更换手机号按钮文字居中、边界完整 | 宽290/高45逻辑px、左69,文字居中且未截断;未触授权 | Pass(视觉) | outputs/authentication-buttons-20261008/qa-main.png |
| QA-AUTHBTN-002 | 模拟器,待提交资料 | 上传名片按钮文字居中、边界完整 | 宽328/高45、左31,视觉符合;未选图/上传 | Pass(视觉) | 同上 |
| QA-AUTHBTN-003 | 模拟器,验证码普通态 | 窄按钮文案可读、不截断 | 宽94/高45、左265右359,普通“获取验证码”居中完整;倒计时长文/disabled未安全造态,未发邮件 | Pass(普通态);Blocked(倒计时/disabled) | 同上;page data cooldown 未暴露 |
| QA-AUTHBTN-004 | 模拟器,待提交资料 | 提交按钮文字居中、边界完整 | 宽328/高45、左31,视觉符合;未提交认证 | Pass(视觉) | 同上 |
| QA-AUTHBTN-005 | 模拟器底部 | 联系按钮完整居中 | 宽358/高45、左16右374,视觉符合;未打开客服 | Pass(视觉) | outputs/authentication-buttons-20261008/qa-contact.png |
实施方 build:weapp:local、认证聚焦1项通过;设计系统全集18/19,旧ConferenceCard断言失败,既有Vue Prettier25条阻lint,无Stylelint配置。本轮没有把全套/lint写成通过。未验证真实手机号授权、验证码发送、名片上传、认证提交、客服、真机或生产;没有账号/session/数据库写、业务源码修改、提交、推送或部署。CSS修复不新增手册业务步骤。执行人:NDB QA Agent。
RA Updated by Redmine Admin about 1 month ago
【QA 2026-10-08|首页会议日历圆点与取消会议】
环境:projects/mp/mp-conference,feat/meeting-v2-integration,本地微信开发者工具模拟器 pages/index/index,本地 BFF 127.0.0.1:3000。逐例结果:
- CAL-01 9 月圆点位置:切换 2026-09,2/15/23 的橙色圆点在日期数字正下方。通过;证据 qa-september.png。
- CAL-02 已结束会议日期列表:点 9/15,选中日期并显示已结束的「海外AI大模型探讨」15:00–16:00 北京时间。通过;证据 qa-september-15.png。
- CAL-03 取消会议无圆点:切换 2026-10,整月无圆点;公开 GET 该月唯一会议 10/20 状态 cancelled。通过;证据 qa-october.png、GET HTTP 200。
- CAL-04 取消会议日期列表:点 10/20,日期选中但无圆点、无会议列表。通过;证据 qa-october-20.png。
- CAL-05 数据核对:公开 GET 2026-09 得 3 条(9/2、9/15 completed,9/23 published),2026-10 得 1 条(10/20 cancelled)。通过;两次 HTTP 200。
- CAL-06 聚焦自动化:node --test tests/calendar-markers.test.cjs tests/conference-time.test.cjs,6/6 通过;覆盖真实 API 函数经 stub 的取消过滤、原始分页统计、日历 CSS 与北京时间。
手册:projects/mp/mp-conference/docs/user-manual/calendar.md,附 3 张本轮真实模拟器截图;Mini 业务和 UI 可读性复核待主统筹协调。
限制:未测真机、其他账号、生产及网络错误恢复。未执行业务 POST、提交、推送、部署。完整 QA 记录:outputs/calendar-markers-20261008/qa-result.md。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Backend 双历史迁移兼容候选独立复核 - 2026-10-09 14:23 Asia/Shanghai¶
- 环境:canonical projects/ndb/backend,feat/meeting-management,HEAD c88c75af6d53ef0b1fd0e05dae27c9b148db61f0;Ops 对真实 slime_crm_staging 测试库执行只读 gate,QA 复核其回执。候选七文件未暂存、未提交。
- 范围:冻结七文件、Django 双历史图/state、隔离库测试与 SQL 证据、Ops 真实库只读 activation gate;无真实迁移写入。
- 汇总:Pass 7 / Fail 0 / Blocked 0 / Skipped 0(仅此候选复核范围)。
| 编号 | 用例/层级与前置 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|
| CMP-01 | 候选完整性/文件;冻结七文件 | hash 一致、无混入修改 | 独立 SHA-256 七项全匹配;Git 一改六新未暂存,diff check 通过 | Pass | backend-compatibility-candidate-20261009.md,QA 报告 |
| CMP-02 | 旧迁移边界/静态;102 原迁移 | 只允许 meetings0001 依赖改动,F/P 操作一致 | Git 仅该已跟踪迁移一行依赖差异;F/P 静态 diff 仅依赖;operation.deconstruct 比较用例在冻结日志通过。preview 原制品字节一致由 Backend 报告,QA 未直读远端原件 | Pass | git diff、test_original_finance_operations_are_identical |
| CMP-03 | 双历史/state/隔离证据;source-only、preview-only、fresh | 单目标 replacement、最终无冲突/重复约束,二次计划空 | 源码满足;冻结运行日志 250/250(compat11、meetings165、finance74),QA 未重跑全套 | Pass | final-tests.log、compat test 源码 |
| CMP-04 | 非空旧库/漂移/隔离证据 | 旧 Task 保留、默认 standard;部分/异定义 schema 在写入前拒绝 | 测试覆盖非空 pre-finance、缺列/索引/CHECK、异定义 CHECK、已应用 replacement 后漂移,冻结日志通过 | Pass | compat test 源码、final-tests.log |
| CMP-05 | 实际 SQL/隔离证据;source/preview 两旧历史 | finance 不重复 DDL | QA 读取捕获 SQL:source 17 语句/0 DDL;preview 99 语句/36 候选 DDL,无 project_tasks finance DDL;仅会议报名 FK 引用 project_tasks | Pass | sql/source-actual.sql、preview-actual.sql、两 plan.json |
| CMP-06 | activation gate/静态;冻结脚本 | 只读验证 schema、history、forward plan,无 migrate | 脚本显式 SET TRANSACTION READ ONLY、校验完整 finance schema/meetings0010、输出 plan,不调用 migrate;实际 ledger 模式仍需 Ops/统筹核对 | Pass | readonly_activation_gate.py |
| CMP-07 | 真实测试库只读 gate/证据复核;Ops 执行 | 同目标、同哈希,实际仅获准向前 plan,0 写入 | Ops JSON exit0、hash7/身份/只读均匹配;ledger120,plan 仅 projects0025→0026;写语句/DDL 0、潜在并发迁移查询及 AccessExclusive 锁 0。QA 只复核,不声称亲自连库 | Pass | ops-readonly-activation-gate-20261009.json |
风险与未验证项¶
本轮结论仅对七文件兼容候选及上述只读证据为 PASS;真实数据库 migration 未执行,也未由 QA 放行。Ops 执行前须维持相同哈希、目标与 ledger/plan,单 migration runner;发生任何变化须重跑只读 gate 并停止意外步骤。隔离 fixture 不等于真实全量数据副本;Backend/BFF 远端公开 GET 另行验收。
完整 QA 报告:outputs/server-staging-release-20261008/qa-backend-compatibility-final-review-20261009.md。QA Agent,未改迁移/Git/DB,未重跑 250 项。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 测试服务器 Backend 发布后独立只读版本验证 - 2026-10-09 14:31 Asia/Shanghai¶
- 环境:Backend
https://tcrm-api.mindsetech.com;Ops 提供 commit6781d6f、tagv1.20.0b0。QA 仅执行公开 GET,不使用 NDB 签名或账号。 - 汇总:Pass 1 / Fail 0 / Blocked 0 / Skipped 0(本轮已执行用例)。
| 编号 | 用例/层级 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|
| TSR-01 | Backend 版本/真实远端 HTTP GET /v1/version/
|
HTTP 200,envelope code=200,data.version=1.20.0b0 | 2026-10-09 14:31 Asia/Shanghai,HTTP 200,application/json,code=200,version=1.20.0b0,响应 57 bytes | Pass | outputs/test-server-readonly-20261009/qa-result.md |
BFF v0.1.0-beta.0 尚待 Ops 发布/主统筹 freeze,本轮未访问 https://mp-test.mindsetech.com,不将其健康或目录标为通过。版本 GET 仅证明该远端接口当时的响应;镜像 digest、DB activation 和完整业务契约需各自证据。无认证/报名/预约/邮件等写请求;未提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 测试服务器 BFF 公开 GET 独立验收 - 2026-10-09 14:37 Asia/Shanghai¶
- 环境:
https://mp-test.mindsetech.com;Ops/统筹冻结 source commite63c7e420e44359ec4e103a2ee030c35088b26ed、tagv0.1.0-beta.0、CNBcnb-7mi-1k4flp9sesuccess。BFF 无公开版本端点,registry digest 不能证明当前运行容器身份。 - 层级/前置:真实测试服务器匿名 HTTPS GET;不使用登录凭据,不执行认证、报名、纪要预约、通知 POST/PUT/DELETE。
- 汇总:Pass 11 / Fail 1 / Blocked 0 / Skipped 0(BFF-01~12)。全部响应有 X-Request-Id。
| 编号 | 用例/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|
| BFF-01 | GET /health/live → 200 status=ok | 200 status=ok | Pass | bff-http-results.json |
| BFF-02 | GET /health/ready → 200 channelDb/ndb=up | 200 status=ok、channelDb=up、ndb=up | Pass | bff-http-results.json |
| BFF-03 | GET /api/v2/catalog/industries → 200 行业数组 | 两次 404 NOT_FOUND;requestId faba45e8-4dbe-4f3e-8034-d4de192dfe34、e387254c-9b45-4f3f-9059-e5c353ccc9ad | Fail | 缺陷待定位/登记;冻结源码有此 GET 路由,相关 content/topics/experts pageSize100 及 topics page2 各自 200;请 Ops 按 requestId 核对运行制品/代理路由 |
| BFF-04 | GET /catalog/content?type=summary&pageSize=2 → 分页纪要 | 200,2/total62,字段形状符合 | Pass | bff-http-results.json |
| BFF-05 | GET /catalog/topics?pageSize=2 → 分页专题 | 200,2/total143,字段形状符合 | Pass | bff-http-results.json |
| BFF-06 | GET /catalog/experts?pageSize=2 → 分页公开专家 | 200,2/total49,顶层无私有字段 | Pass | bff-http-results.json |
| BFF-07 | GET /meetings?pageSize=2 → 分页会议 | 200,2/total70,无参会链接/内部管理字段 | Pass | bff-http-results.json |
| BFF-08 | GET /meetings/banners → 最多3条数组 | 200,空数组,空态契约符合 | Pass | bff-http-results.json |
| BFF-09 | GET /catalog/content/1 → 纪要详情 | 200,ID一致,type及附件字段白名单符合 | Pass | bff-qa-result.md |
| BFF-10 | GET /catalog/topics/36 → 专题详情 | 200,ID一致,outline未见危险HTML模式 | Pass | bff-qa-result.md |
| BFF-11 | GET /catalog/experts/31 → 专家详情 | 200,ID一致,公开字段符合,无顶层私有字段 | Pass | bff-qa-result.md |
| BFF-12 | GET /meetings/1 → 会议详情 | 200,ID一致,status/experts符合,无参会链接 | Pass | bff-qa-result.md |
风险与未验证项¶
BFF-03 为真实远端可复现失败,不能将 BFF 全链路标为通过。缺陷 ID 尚未创建,待主统筹/责任 Agent 定位后关联;复现步骤与两个 requestId 已给出。没有独立运行容器 digest 证据;不把 CI/registry digest 等同于当前进程版本。未测受保护接口、实际用户/业务写入、通知送达;BFF 内部签名 GET 可能正常更新 NDB 应用 last_used 元数据。完整报告:outputs/test-server-readonly-20261009/bff-qa-result.md。未改源码、Git、DB或部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - BFF beta.1 测试服务器独立只读复测 - 2026-10-09 15:10 Asia/Shanghai¶
- 环境:
https://mp-test.mindsetech.com;冻结候选 BFF8599affb5f133153c50cfa708a4a86293e235c7e/v0.1.0-beta.1,健康脚本修复源94bef55,Ops 提供 CNBcnb-ee5-1k4fno176success 与新容器健康/滚动更新日志。本地 HEAD/tag 已核对;HTTP 无公开版本接口,未独立 inspect 运行 digest。 - 层级/前置:真实远端匿名 HTTPS GET;无登录/认证/报名/预约/通知业务写请求。上一轮 beta.0 的 BFF-03 Fail 保留在 journal 52,本轮为新复测,不覆盖旧记录。
- 汇总:Pass 12 / Fail 0 / Blocked 0 / Skipped 0。全部响应含 X-Request-Id。
| 编号 | 用例/预期 | 本轮实际 | 状态 | 证据 |
|---|---|---|---|---|
| BFF-01 | GET /health/live → 200 ok | 200 status=ok | Pass | bff-retest-http-results.json |
| BFF-02 | GET /health/ready → channelDb/ndb up | 200 status=ok、channelDb=up、ndb=up | Pass | bff-retest-http-results.json |
| BFF-03 | GET /api/v2/catalog/industries → 行业数组 | 200,21 条唯一 id/name 字符串;requestId 47225dec-627a-4bb8-b372-06ea2a79f995 | Pass(beta.0 404 已恢复) | bff-retest-http-results.json |
| BFF-04 | GET /catalog/content?type=summary&pageSize=2 → 纪要分页 | 200,2/total62 | Pass | bff-retest-http-results.json |
| BFF-05 | GET /catalog/topics?pageSize=2 → 专题分页 | 200,2/total143 | Pass | bff-retest-http-results.json |
| BFF-06 | GET /catalog/experts?pageSize=2 → 公开专家分页 | 200,2/total49 | Pass | bff-retest-http-results.json |
| BFF-07 | GET /meetings?pageSize=2 → 会议分页 | 200,2/total70 | Pass | bff-retest-http-results.json |
| BFF-08 | GET /meetings/banners → 最多3条数组 | 200,空数组,空态符合 | Pass | bff-retest-http-results.json |
| BFF-09 | GET /catalog/content/1 → 纪要详情 | 200,ID一致,summary type/附件白名单/无顶层私有字段 | Pass | bff-retest-qa-result.md |
| BFF-10 | GET /catalog/topics/36 → 专题详情 | 200,ID一致,outline未见危险HTML模式 | Pass | bff-retest-qa-result.md |
| BFF-11 | GET /catalog/experts/31 → 公开专家详情 | 200,ID一致,无顶层手机号/邮箱/费率/支付字段 | Pass | bff-retest-qa-result.md |
| BFF-12 | GET /meetings/1 → 会议详情 | 200,ID一致,status/experts符合,无顶层参会链接 | Pass | bff-retest-qa-result.md |
限制¶
本轮只证明当前测试地址的公开 GET 契约;运行 commit 身份依赖 Ops 部署证据,registry digest 不能替代运行容器 inspect。未测受保护接口、真实用户/业务写入、通知送达;横幅只有空态。NDB 内部签名 GET 可能正常更新应用 last_used 元数据。完整报告:outputs/test-server-readonly-20261009/bff-retest-qa-result.md。未改源码/Git/DB/部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 小程序 CNB 手动测试上传配置独立复核 - 2026-10-09 15:52 Asia/Shanghai¶
- 环境/候选:projects/mp/mp-conference,feat/meeting-v2-integration,HEAD dda147326123846629dd16705ef51a4cf177a536;Ops 新增
.cnb.yml、.ci/wechat-upload.cjs、.ci/wechat-upload.test.cjs、docs/cnb-wechat-ci.md。原 33 项脏改动保留、新增 3 status、index 0。仅本地 mock/语法/Schema 与静态检查。 - 初轮发现:8/8 mock 及 YAML/Schema 通过,但 SDK 安装失败分支只用
rmdir,npm 留下文件时目录残留且 endStages 无导出路径。QA 已回传,Ops 改为受限--cleanup-tools并新增写 partial 后失败的 stage-shell mock;以下为冻结修复候选新复测,未修改旧报告。 - 汇总:Pass 13 / Fail 0 / Blocked 0 / Skipped 0(仅配置/mock范围)。
| 编号 | 用例/层级与预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|
| CI-01 | mock:projectPath根与dist配置 | 通过 | Pass | qa-result.md、node --test |
| CI-02 | mock:拒绝非upload/非测试HTTPS/非法版本/AppID不符 | 通过 | Pass | node --test |
| CI-03 | mock:拒绝缺dist/app.json或测试API注入 | 通过 | Pass | node --test |
| CI-04 | mock:拒绝无效base64/密钥且不泄漏 | 通过 | Pass | node --test |
| CI-05 | mock:工具删除路径限制 | 通过 | Pass | node --test |
| CI-06 | mock:成功上传模拟的临时私钥0700/0600及清理 | 通过;未调用SDK | Pass | node --test |
| CI-07 | mock:模拟上传失败仍清理私钥 | 通过 | Pass | node --test |
| CI-08 | mock+静态:仅手动web_trigger、upload stage导入密钥、固定依赖 | 通过;无push/tag/PR自动触发 | Pass | node --test、.cnb.yml |
| CI-09 | mock:npm安装写partial后失败仍清理工具目录 | 新增stage-shell用例通过,exit1/stdout空/目录消失 | Pass | node --test |
| CI-10 | 配置:CNB YAML语法、语义、Schema | 三项均通过 | Pass | cnb-pipeline validator |
| CI-11 | 脚本:两个.cjs语法 | node --check均exit0 | Pass | node --check |
| CI-12 | 配置:CI_ACTION/upload、CI_VERSION与测试HTTPS --check | exit0,提示未上传 | Pass | --check 输出 |
| CI-13 | Git/静态范围:保留既有工作、无business/package/lock修改、无自动审核发布 | 33原dirty+3新增status、index0;只测试开发版配置 | Pass | git status、.cnb.yml |
限制与下一步¶
密钥 import URL 仍为 REPLACE_WITH_PRIVATE_SECRET_IMPORT_URL,未接真实凭据,不能运行远端上传。Node22/Yarn安装、Taro构建、固定SDK在ignore-scripts下可用性、上传IP白名单、微信开发版可见性、真机与业务链路均未测;本轮 PASS 不证明远端 pipeline 或上传成功。未运行build/SDK真实安装/上传,未读取secret,未commit/push/tag。完整 QA 报告:outputs/mini-cnb-pipeline-20261009/qa-result.md。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 小程序 CNB 密钥接入配置补验 - 2026-10-09 16:28 Asia/Shanghai¶
- 环境/候选:projects/mp/mp-conference,feat/meeting-v2-integration,HEAD dda147326123846629dd16705ef51a4cf177a536;四文件冻结配置。原33 dirty保留、配置3新status、用户本地私钥1未跟踪,共37,index空;.gitignore无diff。
- 层级/前置:本地只读源码、mock、语法、CNB Schema;本地私钥仅检查 stat/Git 元数据,不读内容;CNB Secret 仅引用 Ops 不含值的布尔回执,不访问 Secret 页面。
- 汇总:Pass 8 / Fail 0 / Blocked 0 / Skipped 0(仅本轮补验范围)。
| 编号 | 用例/预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|
| KEY-01 | 本地私钥元数据/Git:0600、未跟踪、未忽略、未暂存 | 普通文件,mode0600,tracked/ignored/staged均false;.gitignore无diff | Pass | stat/Git摘要,qa-key-integration-result.md |
| KEY-02 | 本地CNB配置:准确Secret URL、仅上传stage imports、手动触发 | 唯一imports指向 mp-conference-wechat-ci.yml,无placeholder、无push/tag/PR自动触发 |
Pass | .cnb.yml静态审查 |
| KEY-03 | Ops Secret限制元数据 | Ops报告最终Secret commit b66e103e0706c3cf06a8b2bb938b397caa4533e6;parse/secretMatches/slugRestricted/eventRestricted/branchRestricted/onlyExpectedFields均true。QA未独立读值;先前前缀脱敏事故已由主统筹另行告知用户,本记录不复述材料 | Pass(仅Ops元数据证据等级) | 主统筹/ops布尔回执摘要 |
| KEY-04 | SDK配置:排除根及递归 private.*.key | ignores含根与递归规则,mock静态断言通过 | Pass | .ci/wechat-upload.cjs/test |
| KEY-05 | dist含私钥文件名即fail closed | 根/嵌套假文件均触发 PRIVATE_KEY_IN_BUILD,不读文件内容 | Pass | node --test |
| KEY-06 | 聚焦mock | 10/10 PASS;未调用真实SDK、未读取用户私钥 | Pass | node --test .ci/wechat-upload.test.cjs |
| KEY-07 | 两脚本语法+CNB YAML/语义/Schema+diff | node --check、validator三项、git diff --check均PASS | Pass | 本轮命令摘要 |
| KEY-08 | 测试API配置 --check | 测试HTTPS/版本/动作校验exit0,输出明确未上传 | Pass | --check输出 |
限制与后续¶
真实Node22/Yarn/Taro构建、SDK安装、CNB web_trigger、微信上传白名单与开发版本可见性未执行;不能声称上传成功。用户要求私钥不Gitignore,因此后续提交必须逐文件暂存并核对index不含私钥。本轮无真实密钥值读取/输出、无build/install/upload、无commit/push/tag。完整报告:outputs/mini-cnb-pipeline-20261009/qa-key-integration-result.md。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 小程序手动测试上传按钮配置复核 - 2026-10-09 17:00 Asia/Shanghai¶
- 环境/候选:projects/mp/mp-conference,feat/meeting-v2-integration,HEAD dda147326123846629dd16705ef51a4cf177a536;新增
.cnb/web_trigger.yml,测试与文档更新,当前 38 status 项/index 0。仅本地配置与 mock,不触发远端流水线。 - 汇总:Pass 5 / Fail 0 / Blocked 0 / Skipped 0(本轮配置范围)。
| 编号 | 用例/层级与预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|
| BTN-01 | 静态:按钮仅匹配任务分支、web_trigger、必填测试版本 | 正则 ^feat/meeting-v2-integration$,event=web_trigger,CI_VERSION required input/default 1.0.0-test.20261009.1;无密钥值/导入 |
Pass | button-qa-result.md |
| BTN-02 | Schema:.cnb/web_trigger.yml 合法 |
官方CNB web-trigger-schema-zh.json HTTP200,YAML解析/Schema验证无错 | Pass | button-qa-result.md |
| BTN-03 | Schema:现有 .cnb.yml 合法且对应按钮事件 |
CNB validator YAML语法/语义/Schema三项通过 | Pass | validator输出 |
| BTN-04 | mock:按钮新增用例及既有上传安全回归 | node --test 11/11通过,未调用真实SDK | Pass | .ci/wechat-upload.test.cjs |
| BTN-05 | 语法/输入:脚本有效、默认版本与测试HTTPS可用 | 两脚本node --check、--check、git diff --check均通过;--check明确未上传 | Pass | button-qa-result.md |
结论仅配置可进入Git发布候选门禁,不是远端CI或微信开发版上传成功。业务候选freeze、私钥不进commit的逐文件stage、Node22/Yarn/Taro/SDK真实运行、微信平台可见性尚待后续。未build/trigger/readkey/Secret/upload/commit/push/tag;无正式审核/生产发布。完整报告:outputs/mini-test-upload-20261009/button-qa-result.md。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 小程序测试上传候选静态与业务回归 - 2026-10-09 17:06 Asia/Shanghai¶
- 环境:本地 macOS;
projects/mp/mp-conference;Node 自带 test runner;不连接微信平台。 - 候选版本/提交:
feat/meeting-v2-integration,87a486c7273cc7568a8b25f30642613104130332;计划开发版1.0.0-test.20261009.1。 - 范围:冻结清单与提交边界、指定六个测试文件的 47 项业务/时间回归。
- 汇总:Pass 49 / Fail 0 / Blocked 0 / Skipped 0(仅本轮已执行检查;真实流水线与微信开发版待验)。
- 执行人:NDB QA Agent。
| 编号 | 用例 | 层级与前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-QA-001 | 冻结业务清单一致性 | 静态;54 文件清单 | 对每个受限路径计算 SHA-256,均应匹配 | 54/54 匹配,无越界/排除路径 | Pass |
business-candidate.json;无缺陷 |
| MP-UP-QA-002 | 提交边界与凭据排除 | Git;候选 HEAD | 比较提交 59 个路径(54 业务+5 CI),检查私钥/outputs/dist 不在树或 index | 精确 59/59;多余 0;禁入 0;index 空;私钥仍仅 untracked | Pass |
git diff-tree/git ls-tree/git status --short 摘要;无缺陷 |
| MP-UP-QA-003 | calendar day API excludes cancelled meetings and keeps completed meetings | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-004 | calendar statistics filters after raw pagination and counts mixed visible meetings | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-005 | calendar marker stays in the date cell flow directly below its number | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-006 | gather and search remove the duplicate online-meeting category | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-007 | content, topics and experts only use the V2 catalog API | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-008 | home recommendations and industry filters only use the V2 catalog API | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-009 | the mini-program has no legacy API origin or request client | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-010 | content cards open the dedicated V2 detail page | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-011 | catalog adapters preserve public presentation and never add private expert fields | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-012 | catalog error states are retryable except for unavailable content | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-013 | catalog lists isolate pagination, stop at total, preserve time ranges, and expose retries | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-014 | list, detail and calendar render the same Beijing time from the real templates | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-015 | UTC and offset ISO timestamps convert across midnight independently of device timezone | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-016 | summary remains date-only; missing/invalid times are not shown as ISO or Invalid Date | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-017 | logged-out expert booking can be cancelled or open login without posting | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-018 | unauthenticated expert booking opens the existing authentication dialog without posting | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-019 | concurrent expert booking posts the public profile id once and shows the success feedback | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-020 | failed expert booking allows retry and rechecks access before the next post | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-021 | minutes detail uses the meeting title and opens its first attachment | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-022 | logged-out minutes prompt once and navigate only after confirmation | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-023 | logged-out minutes can cancel without navigation or download | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-024 | industry reports keep their own title and do not enter the minutes attachment flow | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-025 | body is hidden only when minutes already have a viewable attachment | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-026 | registration shows the customer charge before submitting; pending is never called confirmed | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-027 | meeting detail downloads and opens the generated minutes attachment | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-028 | meeting content requires a valid session before download and opens login only once | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-029 | meeting content login prompt can be cancelled without leaving or downloading | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-030 | registration is not submitted when the price prompt is cancelled | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-031 | timeout retries reuse the same key without optimistic registration | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-032 | favorites stay independent while minutes reservation requires customer authentication | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-033 | started meeting reserves minutes once with a price confirmation and authoritative reread | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-034 | started meeting overview guidance follows the minutes reservation action without changing registration gates | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-035 | attendance and minutes reservation coexist without changing registration or join authorization | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-036 | minutes-only reservation never creates a client-side attendance projection or join link | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-037 | cancelled price confirmation does not reserve minutes | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-038 | published analyst minutes block reservation even when the attachment is missing; AI minutes do not | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-039 | reservation read failures never become an unreserved state or consult legacy subscriptions | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-040 | reservation retries reuse the business key and never optimistically mark success | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-041 | reservation results from an old login session never pollute the current session | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-042 | minutes can never be written through the legacy notification subscription API | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-043 | missing active contract keeps reservation unconfirmed and points to staff handling | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-044 | cancellation asks only for confirmation and allows registration again | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-045 | unavailable registration read disables mutation, logout removes a visible link | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-046 | secondary failures stay local while meeting detail remains available | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-047 | completed and cancelled meetings override unbound identity guidance | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-048 | legacy IDs never enter v2 mutation routes or reveal the legacy public link | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
| MP-UP-QA-049 | phone, contact and meeting eligibility gate registration; settlement errors stay explicit | Node 单元/静态;候选 HEAD | 运行指定六文件聚焦回归;该断言应通过 | 通过 | Pass |
focused-47.tap,无缺陷 |
风险与未验证项¶
- 本轮未运行全量测试、UI/离线 UI、ESLint 或重建 dist。既有证据显示 UI 25/26,
ConferenceCard.vue表面 token 断言不匹配;离线 UI 曾超时;目标 ESLint 45 项错误。主统筹将这些作为测试上传非阻断已知例外,不得称全套通过。 - MP-UP-02 至 MP-UP-08 的 CNB 触发、依赖安装、实际构建包体、SDK 上传、微信平台可见性与真机运行,需要 Ops 的构建编号/日志或平台证据后逐项验收。本轮 49 项 Pass 不代表开发版已上传成功。
- 本轮无代码改动、无私钥内容读取、无构建/上传/正式发布;未执行真实登录、认证、报名/预约或邮件发送。
下一步¶
- 收到 Ops 的 CNB SN、commit SHA、版本与脱敏执行证据后完成 MP-UP-02 至 MP-UP-07;MP-UP-08 单独保留真机门禁。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 首次真实测试上传 - 2026-10-09 17:10 Asia/Shanghai¶
- 环境:CNB
mindsetech/mp-conference,手动web_trigger;流水线 cnb-25i-1k4fujhdn。 - 候选:
feat/meeting-v2-integration/87a486c7273cc7568a8b25f30642613104130332,输入版本1.0.0-test.20261009.1。 - 汇总:Pass 3 / Fail 2 / Blocked 2 / Skipped 0(仅本轮七个上传检查点)。执行人:NDB QA Agent。时间:2026-10-09 17:10 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作与预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-02 | 手动触发与提交绑定 | CNB;已冻结提交 | 指定分支手动触发,SN 与提交/版本可追踪 | 唯一 SN cnb-25i-1k4fujhdn;远端 SHA 与本地候选一致 |
Pass | CNB status API、git ls-remote 摘要;无缺陷 |
| MP-UP-03 | 安装依赖与测试构建 | CNB;Node22/Yarn | 依赖和 build:weapp stage 成功 |
stage-1 依赖安装 success;stage-2 构建 success | Pass | CNB status API;无缺陷 |
| MP-UP-04A | 隔离上传工具安装 | CNB;固定 SDK 2.1.31 | 隔离安装成功并导出目录 | stage-3 success;日志声明 set env for key: WECHAT_CI_TOOLS_DIR
|
Pass | CNB stage-3 脱敏摘要;无缺陷 |
| MP-UP-04B | 实际上传包安全 | CNB;构建完成 | 上传前检查包体测试 API 与私钥排除 | stage-4 在约 0.1s 内统一错误退出,无法证明包体检查已执行 | Blocked | CNB stage-4;待修复导出变量后重测 |
| MP-UP-05 | 微信开发版上传 | CNB;构建与工具安装完成 | SDK 上传 stage 成功并返回版本记录 | stage-4 error;未取得 SDK 成功或微信版本证据 | Fail | CNB stage-4;缺陷待创建,疑似 .cnb.yml 使用 exports.info 混入 npm stderr |
| MP-UP-06 | 临时工具目录清理 | CNB;流水线结束 | endStage 成功清理隔离工具 | endStage error,约 0.1s 统一错误;不能证明清理 | Fail | CNB stage-endStages-0;同一疑似导出变量缺陷待创建 |
| MP-UP-07 | 微信平台开发版可见 | 微信平台;上传应成功 | 同 AppID 同版本开发版可见 | 前置上传失败,本轮无法验收 | Blocked | CNB 最终 status error;待成功重跑后只读核查 |
根因线索与后续动作¶
- CNB 官方环境变量文档把脚本
info定义为 stdout 与 stderr 的混合输出;当前.cnb.yml用exports: info: WECHAT_CI_TOOLS_DIR,而安装阶段实际产生多条 npm stderr 警告。变量可能混入警告,不再是单一绝对路径。stage-4与清理 stage 都在入口约 0.1 秒退出,符合toolsPath()路径校验失败;这是高置信推断,未取得脚本内部错误码,仍需 Ops 在不打印秘密的前提下确认。 - 修复导出来源后,仅重测受影响的包体检查、上传、清理与平台可见性;不能预断 SDK、AppID/私钥配对和微信上传 IP 白名单会通过。
- 本轮未读取私钥或 Secret 值,未重触发,也未做正式审核/发布、生产切换或邮件发送。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 上传变量导出修复候选 - 2026-10-09 17:11 Asia/Shanghai¶
- 环境:本地
projects/mp/mp-conference,feat/meeting-v2-integration,修复尚未提交;原远端 HEAD87a486c7273cc7568a8b25f30642613104130332。 - 范围:首次 SN
cnb-25i-1k4fujhdn失败后的精确三文件修复;未重跑业务47项、未构建、未触发真实上传。 - 汇总:Pass 3 / Fail 0 / Blocked 0 / Skipped 0。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-FIX-01 | 冻结范围与导出来源 | Git 静态;原 HEAD | 仅三文件变化,运行逻辑只把 exports.info 改为 exports.stdout,不涉及业务/Secret/版本 |
tracked diff 恰三文件;三 SHA256 匹配 Ops 冻结值;私钥仍 untracked | Pass | Git diff、SHA256;原故障关联 Redmine #1 journal 58 |
| MP-UP-FIX-02 | SDK上传脚本 mock 与污染回归 | Node 测试;本地无真实密钥 | 12用例全过;模拟 npm stderr 警告时 stdout 为唯一工具路径、cleanup 成功 | 12/12 Pass,新增 shell 假 npm 回归通过 | Pass |
node --test .ci/wechat-upload.test.cjs;无新缺陷 |
| MP-UP-FIX-03 | CNB pipeline 配置有效性 | 本地 validator | YAML 语法、语义、Schema 通过 | 3/3 Pass | Pass | cnb-pipeline validator;无新缺陷 |
- 三文件 SHA256:
.cnb.yml949ca26f90a55110ffb2e4a6bc6f0e7a28bb25739dbeb1e4d0f21c32ec622f73;.ci/wechat-upload.test.cjsc614598540183a73614943cb6ea2f5e38d276173800edf94b2068f3d55adaca5;docs/cnb-wechat-ci.md5485dc6dbbd0743c535107b59b3f8e5f12fdedeb962435f57363d0292dcbdf2f。 - 后续:Ops 提交推送精确修复并重新手动触发;QA 按新 SHA/SN 复测上传、清理及微信平台可见性。此轮本地 Pass 不替代远端验收。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 第二次真实测试上传 - 2026-10-09 17:20 Asia/Shanghai¶
- 环境:CNB
mindsetech/mp-conference,手动web_trigger;SN cnb-p05-1k4fuu3t2。 - 候选:
feat/meeting-v2-integration/11f63e90c9ed7ec8ce71e4ed911389f8a30393f9,输入版本1.0.0-test.20261009.1。远端 SHA 与本地一致;修复提交只有.cnb.yml、上传脚本测试和文档三文件。 - 汇总:Pass 5 / Fail 1 / Blocked 1 / Skipped 0。执行人:NDB QA Agent;2026-10-09 17:20 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-R2-01 | 手动触发与修复提交绑定 | CNB;修复 SHA 已推送 | 仅手动触发,SN/SHA/版本可追踪 | SN cnb-p05-1k4fuu3t2、本地/远端 SHA 同为 11f63e90...
|
Pass | CNB status API 与 Git 只读摘要;无缺陷 |
| MP-UP-R2-02 | 依赖安装与测试构建 | CNB;Node22/Yarn | 安装和 build stage success | stage-1 与 stage-2 success | Pass | CNB status API;无缺陷 |
| MP-UP-R2-03 | 隔离上传工具安装 | CNB;固定 SDK 2.1.31 | 工具 stage success | stage-3 success | Pass | CNB status API;无缺陷 |
| MP-UP-R2-04 | 上传前脚本前置校验 | CNB;构建已完成 | 检查 dist/app.json、测试 API、私钥排除和工具路径 | 上传 stage 持续 300442ms,且清理成功;据脚本控制流推断已越过同步前置校验并进入上传 worker,未独立打开实际包体 | Pass |
.ci/wechat-upload.cjs 控制流 + CNB stage 耗时;推断范围已说明 |
| MP-UP-R2-05 | 微信开发版上传 | CNB;前置 stage 通过 | SDK 上传 stage 成功 | stage-4 error,耗时 300442ms,近似 worker 300000ms 超时;无微信上传成功返回 | Fail | CNB stage status;缺陷待创建/关联,根因未定 |
| MP-UP-R2-06 | 临时上传工具清理 | CNB;流水线结束 | endStage 成功清理 |
Remove isolated upload tool success,1382ms |
Pass | CNB status API;无缺陷 |
| MP-UP-R2-07 | 微信开发版可见性 | 微信平台;上传应成功 | 同 AppID/版本开发版可见 | 上传失败,未获微信平台版本证据 | Blocked | CNB status error;待上传成功后复验 |
后续动作与界限¶
- 失败进入真实上传工作进程后约 300 秒。SDK 子进程的标准输出/错误被脚本抑制;当前证据只能确认 stage 超时附近退出,不能确认 IP 白名单、网络、AppID/密钥配对或微信服务的具体原因。由 Ops 在不泄露敏感材料的前提下诊断。
- 首轮 SN
cnb-25i-1k4fujhdn的上传与清理失败仍见 Redmine #1 journal 58;本轮清理已恢复,但上传仍未成功。不得宣称开发版可见、真机可用或邮件发送成功。 - 本轮未读取私钥/Secret、未操作 Ops 浏览器、未自行重触发、未做微信审核/正式发布或生产切换。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 上传诊断修复候选 - 2026-10-09 17:23 Asia/Shanghai¶
- 环境:本地
projects/mp/mp-conference;基线 HEAD11f63e90c9ed7ec8ce71e4ed911389f8a30393f9;诊断候选尚未提交。 - 范围:第二次 SN
cnb-p05-1k4fuu3t2上传约300秒失败后的受影响脚本/测试/文档,不重跑业务47项、不调用真实微信或密钥。 - 汇总:Pass 4 / Fail 0 / Blocked 0 / Skipped 0。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-IPC-01 | 冻结范围与安全边界 | Git 静态;原 HEAD | 仅脚本、测试、文档三文件,私钥排除/清理/300秒超时不放宽 | 精确三文件;三 SHA256 对应冻结值;私钥仍 untracked | Pass |
git diff、shasum;关联前轮 Redmine #1 journal 60 |
| MP-UP-IPC-02 | IPC 与 SDK 假体回归 | Node 测试;不使用真密钥 | 白名单诊断、SDK成功/异常/挂起的退出与清理符合预期 | 16/16 Pass,含无密钥环境、拒绝恶意 IPC、数值错误码和超时强终止 | Pass |
node --test .ci/wechat-upload.test.cjs;无新缺陷 |
| MP-UP-IPC-03 | Node 语法 | 本地 Node | 脚本与测试文件 node --check 通过 |
两文件均退出0 | Pass |
node --check;无缺陷 |
| MP-UP-IPC-04 | CNB配置有效性 | 本地 validator | YAML语法、语义、Schema通过 | 3/3 Pass | Pass | cnb-pipeline validator;无缺陷 |
- SHA256:脚本
43717346a70c12470171192be732b70715572d77a17a6f99ea2897ef727e2364;测试c6a8fa8b442e8314b080106a6c57c16e04f659de1bdebfb24890dd444b4cf68c;文档8b06dde12b9667a68143ae524138e99a695e6e60f3d483afefd3c984c2d21794。 - 结论边界:本地 mock 通过仅证明安全诊断和退出控制;微信 SDK、网络、IP 白名单、密钥配对及开发版可见性仍待新 SN 实测。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 第三次真实测试上传 - 2026-10-09 17:27 Asia/Shanghai¶
- 环境:CNB
mindsetech/mp-conference手动 web_trigger;SN cnb-4pv-1k4fvisrc。 - 候选:
feat/meeting-v2-integration/51b286eaccc43b241f399fdb6b85dca4cc848a53,本地与远端 SHA 一致;版本1.0.0-test.20261009.1。 - 汇总:Pass 5 / Fail 1 / Blocked 1 / Skipped 0。执行人:NDB QA Agent;2026-10-09 17:27 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-R3-01 | 手动触发与提交绑定 | CNB;修复 SHA 已推送 | SN/SHA/版本一致 | 唯一 SN cnb-4pv-1k4fvisrc,本地与远端 SHA 51b286e... 一致 |
Pass | CNB status API、Git 只读摘要;无缺陷 |
| MP-UP-R3-02 | 依赖安装与测试构建 | CNB;Node22/Yarn | 安装、构建 success | stage-1 与 stage-2 success | Pass | CNB status API;无缺陷 |
| MP-UP-R3-03 | 隔离 SDK 安装 | CNB;SDK 2.1.31 | stage-3 success | stage-3 success | Pass | CNB status API;无缺陷 |
| MP-UP-R3-04 | 上传前校验与 SDK 入口 | CNB;构建完成 | 通过脚本校验并进入真实 SDK 上传 | 安全阶段依次 SDK_LOAD_BEGIN、SDK_READY、PROJECT_READY、UPLOAD_BEGIN
|
Pass | CNB stage-4 固定白名单诊断;无缺陷 |
| MP-UP-R3-05 | 微信开发版上传 | CNB;SDK 已进入上传 |
UPLOAD_COMPLETE、exit0、stage success |
无完成阶段;RESULT exit=1 signal=NONE elapsed_ms=8789 timeout=false;stage error,无数值 ERROR_CODE |
Fail | CNB stage-4;缺陷待创建/关联,具体 SDK 错误未定位 |
| MP-UP-R3-06 | 隔离工具清理 | CNB;流水线结束 | endStage success |
Remove isolated upload tool success,947ms |
Pass | CNB status API;无缺陷 |
| MP-UP-R3-07 | 微信开发版平台可见 | 微信平台;上传应成功 | 同 AppID/版本开发版可见 | 上传 stage 失败,无平台版本证据 | Blocked | CNB 最终 status error;待成功上传后复验 |
结论与下一步¶
- 此轮已证实 SDK 加载、Project 创建、Upload 调用入口正常,并排除导出目录污染与超时挂起作为本轮直接失败;SDK 调用后约8.8秒失败,脚本按安全设计未输出原始异常,且异常中没有允许的数值错误码。不能从现有证据判断私钥配对、上传 IP 白名单、网络或微信服务的哪一项导致失败。
- Ops 需在不泄露密钥、原始异常 payload 的前提下决定下一步诊断;本轮未自行重触发,也未做微信正式审核、生产发布、真机测试或邮件发送。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 安全错误码分类候选 - 2026-10-09 17:32 Asia/Shanghai¶
- 环境:本地
projects/mp/mp-conference;基线 HEAD51b286eaccc43b241f399fdb6b85dca4cc848a53;修复尚未提交。 - 范围:第三次 SN
cnb-4pv-1k4fvisrc在 UPLOAD_BEGIN 后退出且无数值码的受影响脚本/测试/文档;不运行真实 SDK/微信上传/私钥。 - 汇总:Pass 4 / Fail 0 / Blocked 0 / Skipped 0。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-CODE-01 | 精确冻结范围与安全边界 | Git 静态 | 仅脚本、测试、文档三文件;超时/密钥清理/SDK原始输出抑制不放宽 | 3文件 SHA256 匹配冻结值,相关 guard 保持 | Pass | Git diff、SHA256;关联 Redmine #1 journal 62 |
| MP-UP-CODE-02 | 数值码与 SDK 异常形状回归 | Node mock | 仅受限整数和固定 class/state 可输出,恶意/超长/含秘密正文拒绝 | 21/21 Pass,含官方2.1.31 CodeError 形状和真实子进程假SDK | Pass |
node --test .ci/wechat-upload.test.cjs;无新缺陷 |
| MP-UP-CODE-03 | Node 语法 | 本地 Node | 脚本与测试语法检查通过 | 两个 node --check 均退出0 |
Pass | 命令摘要;无缺陷 |
| MP-UP-CODE-04 | CNB 配置结构 | 本地 validator | YAML语法、语义、Schema通过 | 3/3 Pass | Pass | cnb-pipeline validator;无缺陷 |
- SHA256:脚本
3dcd1e8856cc6333ad6432e11dcd873a9a2c04eeb9106a348ba80ad5edf308bb;测试a6fb76433de1ac09a1aa0c2ca44baa8b5ac74c52e0c9102a6d98626d32798714;文档89681217f39f5257550b98c0a51b97a4a20e76cab9cf031d64ebe5cbcbb90fca。 - 本地结果仅允许提交受限诊断并复测;真实上传、微信平台开发版可见性和任何邮件发送仍未获成功证据。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 第四次真实测试上传 - 2026-10-09 17:37 Asia/Shanghai¶
- 环境:CNB
mindsetech/mp-conference手动 web_trigger;SN cnb-ahl-1k4g05dgn。 - 候选:
feat/meeting-v2-integration/282d4152f7c18a368b1453e3adec6546b7772737,本地与远端 SHA 一致;版本1.0.0-test.20261009.1。 - 汇总:Pass 5 / Fail 1 / Blocked 1 / Skipped 0。执行人:NDB QA Agent;2026-10-09 17:37 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-R4-01 | 手动触发与提交绑定 | CNB;诊断 SHA 已推送 | SN/SHA/版本一致 | 唯一 SN cnb-ahl-1k4g05dgn,本地与远端 SHA 282d415... 一致 |
Pass | CNB status API、Git 只读摘要;无缺陷 |
| MP-UP-R4-02 | 依赖安装与测试构建 | CNB;Node22/Yarn | 安装、构建 success | stage-1 与 stage-2 success | Pass | CNB status API;无缺陷 |
| MP-UP-R4-03 | 隔离 SDK 安装 | CNB;SDK 2.1.31 | stage-3 success | stage-3 success | Pass | CNB status API;无缺陷 |
| MP-UP-R4-04 | 上传前校验与 SDK 入口 | CNB;构建完成 | 通过脚本校验并进入 SDK 上传 | SDK_LOAD_BEGIN、SDK_READY、PROJECT_READY、UPLOAD_BEGIN 均出现 | Pass | CNB stage-4 白名单诊断;无缺陷 |
| MP-UP-R4-05 | 微信开发版上传 | CNB;SDK 已进入上传 | UPLOAD_COMPLETE、exit0、stage success | ERROR_CODE 20003 / UPSTREAM_CODE -10008 / UPSTREAM_STATE FOUND / ERROR_CLASS UPLOAD_CGI;exit1、8747ms;stage error | Fail | CNB stage-4;缺陷待创建/关联,上传 IP 白名单是高概率线索,未由官方码表或平台配置证实 |
| MP-UP-R4-06 | 隔离工具清理 | CNB;流水线结束 | endStage success | Remove isolated upload tool success,1130ms | Pass | CNB status API;无缺陷 |
| MP-UP-R4-07 | 微信开发版平台可见 | 微信平台;上传应成功 | 同 AppID/版本开发版可见 | 上传 stage 失败,无微信开发版证据 | Blocked | CNB 最终 status error;待成功上传后复验 |
证据界限与后续动作¶
- 微信官方 miniprogram-ci README 明确要求上传前配置 IP 白名单。固定 SDK 2.1.31 的
ci/upload.js把上传 CGI 非零响应包装为外层20003,包内未见-10008的正式映射。公开同类错误记录把-10008伴随的服务端消息解释为 invalid ip,但本轮为保护敏感资料只输出数值,不读取原始消息;因此将白名单列为高概率线索,不作为已证实根因。 - 下一步由 Ops 只读核对微信公众平台该 AppID 上传 IP 白名单和 CNB 的真实公网出口;未经核实不修改白名单、关闭限制或更换密钥。开发版上传、真机及邮件链路仍未通过。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - CNB 第五次真实测试上传 - 2026-10-09 22:42 Asia/Shanghai¶
- 环境:CNB
mindsetech/mp-conference手动 web_trigger;SN cnb-acn-1k4ghjcv6。 - 候选:
feat/meeting-v2-integration/282d4152f7c18a368b1453e3adec6546b7772737;版本1.0.0-test.20261009.1。本次沿用第四次 HEAD/业务包,未修改源码/Secret。 - 汇总:Pass 6 / Fail 0 / Blocked 1 / Skipped 0。执行人:NDB QA Agent;2026-10-09 22:42 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-R5-01 | 手动触发与冻结候选绑定 | CNB;已推送候选 | SN、分支、SHA、版本可追踪 | SN cnb-acn-1k4ghjcv6,沿用 SHA 282d415... 与测试版本 1.0.0-test.20261009.1
|
Pass | Ops 触发元数据与 CNB status API;无缺陷 |
| MP-UP-R5-02 | 依赖安装与小程序测试构建 | CNB;Node22/Yarn | 安装、构建 success | stage-1/stage-2 success | Pass | CNB status API;无缺陷 |
| MP-UP-R5-03 | 隔离 SDK 安装 | CNB;固定 SDK 2.1.31 | 工具安装 success | stage-3 success | Pass | CNB status API;无缺陷 |
| MP-UP-R5-04 | 上传前校验与 SDK 入口 | CNB;构建完成 | 通过前置检查进入 SDK 上传 | SDK_LOAD_BEGIN、SDK_READY、PROJECT_READY、UPLOAD_BEGIN 均出现 | Pass | CNB stage-4 固定安全诊断;无缺陷 |
| MP-UP-R5-05 | 微信开发版 SDK 上传 | CNB;SDK 已进入上传 | UPLOAD_COMPLETE、exit0、stage 和 pipeline success | UPLOAD_COMPLETE;RESULT exit=0 signal=NONE elapsed_ms=10519 timeout=false;上传 stage 与整条流水线 success | Pass | CNB stage-4/status API;无缺陷;仅证明 SDK 上传成功 |
| MP-UP-R5-06 | 隔离工具清理 | CNB;流水线结束 | endStage success | Remove isolated upload tool success,991ms | Pass | CNB status API;无缺陷 |
| MP-UP-R5-07 | 微信公众平台开发版可见性 | 微信平台;SDK 已报告上传成功 | 同 AppID/版本开发版在平台可见 | 尚未收到或独立取得平台版本元数据,无法确认 | Blocked | 待 Ops 平台只读证据及 QA 核对;无缺陷 |
结论与后续¶
- 本次 SDK 上传及 CNB 流水线均成功,但微信公众平台开发版页面的同 AppID/版本可见性须单独核对。不得把 CI success 扩展为平台可见、真机可用、审核/正式发布或邮件链路成功。
- 第四次同 SHA/SN
cnb-ahl-1k4g05dgn返回20003/-10008,本次成功说明当前调用可以上传;微信后台目前显示未开启 IP 白名单保护,不能据此倒推第四次失败的历史根因。本轮未读取私钥/Secret 或 SDK 原始输出。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 微信开发版平台可见性复核 - 2026-10-09 22:43 Asia/Shanghai¶
- 环境:微信公众平台目标 AppID
wx207bf9944d794a24的版本管理页面;证据由 NDB Ops Agent 在其已授权浏览器空间只读获取,QA 审阅元数据并与 CNB SNcnb-acn-1k4ghjcv6对时;QA 未亲自操作页面。 - 候选:
feat/meeting-v2-integration/282d4152f7c18a368b1453e3adec6546b7772737;目标版本1.0.0-test.20261009.1。前轮 CNB 上传结果见 Redmine NDB #1 journal 65。 - 汇总:Pass 1 / Fail 0 / Blocked 0 / Skipped 0。执行人:NDB QA Agent;2026-10-09 22:43 Asia/Shanghai。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| MP-UP-VIS-01 | 微信平台开发版本与本次上传一致 | 微信公众平台只读 DOM;Ops 已核目标 AppID | 开发版区域可见目标版本、机器人1、备注与 CNB 上传时间一致 | Ops 报告版本位于 div.code_mod.code_version_dev 内独立 div.code_version_log;版本 1.0.0-test.20261009.1、开发者 ci机器人1、备注 CNB manual test build、提交时间 2026-10-09 22:41:20;QA 将 CNB stage-4 endTime 1791556880940 换算为同日 22:41:20,与页面一致 |
Pass | Ops 真实 DOM 只读元数据 + CNB SN cnb-acn-1k4ghjcv6 stage-4/status API;无缺陷 |
界限¶
- 这证明 Ops 所见微信公众平台开发版区域中有与本次 SDK 上传相匹配的版本记录。QA 审阅的是 Ops 回传的页面元数据,没有独立登录或截图复核;未设置体验版、未提交审核、未正式发布。
- 真机/模拟器启动与请求合法域名、认证、报名/预约及邮件发送均未在本轮执行,不能从平台可见性推断其通过。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - NDB Web 测试环境 API 只读预检 - 2026-10-09 23:32 Asia/Shanghai¶
- 环境:
https://tcrm-api.mindsetech.com/v1与当前 Web.env.staging配置的旧 HTTP 入口;无账号、无写请求、无凭据。 - 候选:Web
feat/meeting-management,HEADe54f54afd838522999c75705c1ba366e1304088f,当前业务候选仍未提交;Backend 当前本地仓库分支preview不作为测试部署版本证明。 - 汇总:Pass 5 / Fail 1 / Blocked 0 / Skipped 0。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| WEB-STG-API-01 | 测试 API 版本 | 无凭据 HTTP GET |
/v1/version/ 可达且返回版本 |
HTTPS 200,1.20.0b0
|
Pass |
curl 响应摘要;无缺陷 |
| WEB-STG-API-02 | 公开资料路由与鉴权门 | 无凭据 HTTP GET |
/v1/candidates/1/public-profile/ 命中路由并拒绝未授权 |
HTTPS 401 | Pass |
curl 状态;仅证明路由/认证门,不证明授权后响应契约 |
| WEB-STG-API-03 | 平台许可路由与鉴权门 | 无凭据 HTTP GET |
/v1/candidates/1/public-platform/ 命中路由并拒绝未授权 |
HTTPS 401 | Pass |
curl 状态;仅证明路由/认证门 |
| WEB-STG-API-04 | 带入建议路由与鉴权门 | 无凭据 HTTP GET |
/v1/candidates/1/public-profile/prefill/ 命中路由并拒绝未授权 |
HTTPS 401 | Pass |
curl 状态;仅证明路由/认证门 |
| WEB-STG-API-05 | 未知路由负对照 | 无凭据 HTTP GET | 随机不存在路径返回404,区分全局401 |
/v1/qa-route-never-exists-20261009/ HTTPS 404 |
Pass |
curl 状态;无缺陷 |
| WEB-STG-API-06 | 当前 Web staging 配置的旧 API 入口 | 无凭据 HTTP GET |
.env.staging 所指 /v1/version/ 应可达且可供 HTTPS 页面使用 |
http://8.159.137.15:8000/v1/version/ 返回空响应,curl 52 / HTTP 000;且是 HTTP,与 HTTPS Web 页面不匹配 |
Fail | live .env.staging 与 curl;配置修正由 Ops 负责,缺陷待创建/关联 |
边界与下一步¶
- 当前测试 API 已注册公开资料相关 GET 路由并施加认证,但 401 不证明登录后的读写响应格式、权限、迁移和真实 Web 页面工作。发布后需使用授权的测试账号与隔离假专家执行受控浏览器验收。
- Ops 正准备仅修正测试 API 构建目标;本轮没有修改配置或部署。修复后应重新检查构建产物中的 HTTPS API 与运行页面请求,再定向重测 WEB-STG-API-06。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - NDB Web 测试发布候选静态及聚焦回归 - 2026-10-09 23:39 Asia/Shanghai¶
- 环境:本地 canonical
projects/ndb/frontend;分支feat/meeting-management,基线 HEADe54f54afd838522999c75705c1ba366e1304088f,候选仍是未提交改动。测试不连接业务库、不执行发布。 - 范围:22文件冻结清单 SHA256、41项 Node 聚焦回归、Ops 现有 staging dist API origin 只读检查、preview 分叉风险。
- 汇总:Pass 44 / Fail 0 / Blocked 0 / Skipped 0。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| WEB-STG-CAND-001 | 冻结候选文件边界 | 静态;Ops候选清单 | 7业务+14手册/图片+1 staging env 的22个路径存在且SHA256一致,排除AOCI/产物/密钥 | 22/22匹配,越界0、缺失0,.aoci/config.json 不在清单 |
Pass |
outputs/frontend-test-release-20261009/candidate.md;无缺陷 |
| WEB-STG-CAND-002 | staging构建产物 API 来源 | 静态;Ops已有dist | index存在,JS包含正确HTTPS API且不含旧HTTP地址 | dist/index.html存在;217个JS中2个含 https://tcrm-api.mindsetech.com/v1,旧 http://8.159.137.15:8000/v1 命中0 |
Pass | 本地dist只读字节检查;无缺陷 |
| WEB-STG-CAND-003 | preview分叉与选择性移植风险 | Git静态;双分支 | 确认不能整仓merge/整文件覆盖,保留preview独有权限和会议代码 | preview/source分叉14/5;preview含 response?.code === 200,meeting文件相差181/62行;当前源permissions多TOPIC_MANAGE,必须只移本次公开权限 |
Pass |
git rev-list/git diff --numstat/git show preview: 摘要;无缺陷 |
| WEB-STG-CAND-004 | removes script and style elements together with their content | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-005 | removes other dangerous containers case-insensitively | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-006 | drops the remainder after an unclosed dangerous element | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-007 | preserves normal paragraphs, lists, and inline formatting | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-008 | status label distinguishes platform, draft, future publication, and visible publication | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-009 | newer candidate load wins when an older response arrives later | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-010 | candidate switch invalidates an in-flight write and its final state | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-011 | canceling publication after save keeps the confirmed draft without publishing | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-012 | 409 refreshes platform state but preserves the user's draft input | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-013 | validates meeting background image type and size | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-014 | upload success stores the returned URL without base64 persistence | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-015 | failed replacement keeps the previous image and supports retry | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-016 | removing an uploaded image clears the submitted URL | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-017 | normalizeMeetingPage supports meeting and legacy pagination envelopes | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-018 | meeting API records normalize lifecycle aliases before rendering | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-019 | meeting background field maps to ready, empty, invalid and failed display states | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-020 | clipboard copies raw links and normalized hours with success, failure and empty handling | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-021 | unknown statuses never expose raw backend enums | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-022 | buildMeetingPayload sends fixed planned hours and trims text | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-023 | buildMeetingUpdatePayload only sends fields allowed by backend | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-024 | create and update payloads never submit application or meeting project ownership | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-025 | repeat save reuses its idempotency key until form data changes | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-026 | calendar value persists and backend-created project is displayed | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-027 | meeting actions follow lifecycle and do not recreate settlement | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-028 | taskGenerationSummary exposes missing linked tasks | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-029 | meeting forms do not expose application or meeting project ownership fields | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-030 | meeting background is upload-only and cannot be entered as a URL | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-031 | read-only edit mode cannot be re-enabled by child form controls | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-032 | meeting list owns a single retryable Chinese error state | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-033 | registration selection gates downstream resources and submission | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-034 | meeting list and detail render the shared background display without exposing its URL | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-035 | detail copy actions are gated and use raw link plus normalized hours | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-036 | meeting pages follow shared responsive page patterns | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-037 | meeting edit and detail expose retryable load failures | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-038 | meeting detail error state hides entity actions and loading status | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-039 | meeting business fields are editable and visible without exposing soft-delete state | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-040 | meeting metadata shares one row, tags follow schedule, and join link owns a textarea row | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-041 | topic detail error state uses an explicit title and hides entity actions | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-042 | normalizeTopicPage accepts the web pagination envelope | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-043 | topicOutlineSummary creates readable text from legacy HTML and Markdown | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
| WEB-STG-CAND-044 | topicPayload trims and deduplicates tags and relations | Node聚焦;未提交源候选 | 运行七个指定测试文件;该断言通过 | 通过 | Pass |
focused-41.tap;无缺陷 |
证据界限与下一步¶
- QA 独立运行41/41 Node 测试,未重复构建或lint。Ops候选报告称
pnpm run lint、scoped format 与pnpm run build:staging通过(18.44秒);QA只读复核当前dist中的API origin,不能把当前源分支构建当作未来preview选择性移植后的制品。 -
.env.staging已由 Ops 改为https://tcrm-api.mindsetech.com/v1。此前旧HTTP入口失败见 Redmine #1 journal67;需在获授权的preview候选上重新构建,再用最终部署页面/网络证据定向重测。 - 手册当前03截图已显示人工确认勾选、文字与footer同屏;11截图显示下架后的草稿状态。旧隔离浏览器10/10和UI/业务审阅是先前证据,本轮未重新运行浏览器或创建/修改专家数据。
- 本轮未提交、切分支、推送、部署或触及
.aoci。AOCI历史49项未对齐,不能把其治理状态写成通过。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - NDB Web preview 测试发布候选 - 2026-10-09 23:45 Asia/Shanghai¶
- 环境:canonical
projects/ndb/frontend,preview,候选提交2830967cd375c8cc6e0674ae285965e7dadef0c2;尚未打测试版本/tag/push/deploy。 - 范围:21文件选择性移植、preview原有代码保留、preview适用28项Node聚焦、现有staging dist API来源、7业务文件scoped lint/format和patch空白检查。
- 汇总:Pass 33 / Fail 0 / Blocked 0 / Skipped 0(仅本轮 QA 独立执行或直接检查的33项)。执行人:NDB QA Agent。
| 编号 | 用例 | 层级/前置 | 操作/预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| WEB-PREV-001 | 精确选择性移植 | Git静态;源候选22文件 | preview提交只含源业务/手册21文件;env在preview已正确且不产生净变更,AOCI独立保留 | 提交恰21路径、缺失/额外0;19路径与源SHA逐字相同;permissions与meeting因preview上下文不同;仅原 .aoci/config.json dirty |
Pass |
git show/SHA256 与 Ops source manifest;无缺陷 |
| WEB-PREV-002 | preview现有权限与会议流程保留 | Git静态;preview基线 | 只移公开权限和会议提示,保留preview成功判定、其他权限及源码历史 | permissions仅新增公开管理key;meeting仅新增组件/ref/专家ID捕获/关联后提示五行;response?.code === 200 原样保留;没有整分支merge |
Pass |
git diff HEAD^ HEAD;无缺陷 |
| WEB-PREV-003 | staging产物正确API来源 | 静态;Ops preview build | index存在、JS只含HTTPS测试API,不含旧HTTP或生产API | dist/index存在;207 JS 中2个含 https://tcrm-api.mindsetech.com/v1;旧HTTP及生产API均0 |
Pass | 当前dist字节只读检查;无缺陷 |
| WEB-PREV-004 | 七业务文件质量门禁 | 本地CLI;无文件写入 | scoped oxlint/oxfmt及patch whitespace通过 | oxlint exit0,oxfmt 7/7,git diff --check origin/preview HEAD exit0 |
Pass | CLI摘要;无缺陷 |
| WEB-PREV-005 | Ops preview构建与既有回归证据复核 | Ops报告;同SHA候选 | 记录实际完成且与QA产物匹配,不扩写为QA独立全量测试 |
preview-verification.md 报Vite20.34s完成、全仓109/109与full lint通过;QA核当前dist及候选SHA,未独立重跑109或构建 |
Pass |
outputs/frontend-test-release-20261009/preview-verification.md,本轮证据审阅;无缺陷 |
| WEB-PREV-006 | status label distinguishes platform, draft, future publication, and visible publication | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-007 | newer candidate load wins when an older response arrives later | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-008 | candidate switch invalidates an in-flight write and its final state | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-009 | canceling publication after save keeps the confirmed draft without publishing | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-010 | 409 refreshes platform state but preserves the user's draft input | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-011 | validates meeting background image type and size | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-012 | upload success stores the returned URL without base64 persistence | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-013 | failed replacement keeps the previous image and supports retry | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-014 | removing an uploaded image clears the submitted URL | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-015 | normalizeMeetingPage supports meeting and legacy pagination envelopes | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-016 | meeting API records normalize lifecycle aliases before rendering | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-017 | meeting background field maps to ready, empty, invalid and failed display states | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-018 | clipboard copies raw links and normalized hours with success, failure and empty handling | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-019 | unknown statuses never expose raw backend enums | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-020 | buildMeetingPayload sends fixed planned hours and trims text | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-021 | buildMeetingUpdatePayload only sends fields allowed by backend | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-022 | create and update payloads never submit application or meeting project ownership | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-023 | repeat save reuses its idempotency key until form data changes | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-024 | calendar value persists and backend-created project is displayed | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-025 | meeting actions follow lifecycle and do not recreate settlement | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-026 | taskGenerationSummary exposes missing linked tasks | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-027 | meeting forms do not expose application or meeting project ownership fields | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-028 | meeting background is upload-only and cannot be entered as a URL | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-029 | read-only edit mode cannot be re-enabled by child form controls | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-030 | meeting list owns a single retryable Chinese error state | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-031 | registration selection gates downstream resources and submission | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-032 | meeting list and detail render the shared background display without exposing its URL | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
| WEB-PREV-033 | detail copy actions are gated and use raw link plus normalized hours | Node聚焦;preview候选 | 运行四个现有公开资料/会议测试文件;断言通过 | 通过 | Pass |
preview-focused-28.tap;无缺陷 |
证据界限和后续¶
- 源分支聚焦41项包含13项不在preview当前模块/断言范围内,本轮按preview已有四个文件真实执行28/28;没有拷贝源测试或改preview业务文件凑数。Ops全仓109/109是独立执行的补充证据。
- 当前build是本地preview候选验证,尚不是CNB打tag、测试部署或浏览器运行证明。Ops完成获授权的版本与测试部署后,QA再只读核浏览器入口/版本、HTTPS API请求、专家公开资料入口与会议专家提示组件加载,Redmine追加新轮。
- 不对测试专家做发布/撤销,不新建fixture或改业务数据。
.aoci/config.json历史治理状态仍未对齐,未纳入候选提交。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 小程序内容管理平台使用文档初稿核查 - 2026-10-10 Asia/Shanghai¶
- 环境:NDB Web 测试站
https://tcrm.mindsetech.com;前端标签v2.15.4-beta.0/5633eab;协调根文档初稿。 - 范围:会议管理、专家公开资料、会议关联专家提示;话题/纪要管理当前版本入口边界。
- 汇总:Pass 3 / Fail 0 / Blocked 1 / Skipped 0。
| 编号 | 用例 | 层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|---|
| DOC-MP-01 | 测试版本识别 | 浏览器/版本 | 未登录打开测试站,核页脚并核本地标签 | 能明确文档适用版本 | 登录页显示 Frontend v2.15.4-beta.0;标签指向 5633eab | Pass | Ego TaskSpace 18 登录页快照;git rev-parse v2.15.4-beta.0^{}
|
| DOC-MP-02 | 功能范围对照 | 源码静态 | 检查精确标签的会议路由/页面、公开资料组件、话题和纪要入口 | 只写本版本存在的管理步骤 | 会议管理、专家公开资料及关联后提示有实现;无话题/纪要管理入口,文档已标版本限制 | Pass | 标签 5633eab 的 src/config/router.config.js、src/views/meetings/、src/views/candidates/components/CandidatePublicProfile.vue
|
| DOC-MP-03 | 历史图片完整性 | 文档/资产 | 检查文档图片引用、逐图 SHA256 比对历史标签图 | 引用均存在且不冒当前截图 | 13/13 引用存在,13/13 与历史原图字节一致;各图标明 2026-10-08 隔离来源 | Pass |
docs/user-manual/mini-program-management-platform.md 与 assets/mini-program-management-platform/
|
| DOC-MP-04 | 当前部署的登录后逐步复现与截图 | 浏览器 | 需要测试站已登录管理账号 | 按手册操作并采当前版本真实截图 | Ego TaskSpace 19 已在登录页 handOff;尚无已登录会话,本轮未执行任何业务写入 | Blocked | 登录页 /users/sign_in;待账号持有人完成登录后继续 |
风险与下一步¶
当前文档是初稿;历史隔离图不能代替当前部署截图。待登录、UI Agent 视觉复核、Web Agent 业务校对后补图并复现,再追加新 QA 轮次。本轮未创建/修改业务数据,未提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 小程序内容管理平台使用文档复核 - 2026-10-10 Asia/Shanghai¶
- 环境:协调根文档
docs/user-manual/mini-program-management-platform.md;NDB Web 测试标签v2.15.4-beta.0/5633eab。 - 范围:手册内容、历史隔离截图、版本链接与当前部署复现边界。
- 汇总:Pass 3 / Fail 0 / Blocked 1 / Skipped 0。
| 编号 | 用例 | 层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|---|
| DOC-MP-F01 | 手册结构及版本边界 | 文档静态 | 复核会议/专家操作、权限、公开状态和未上线模块 | 操作可读,话题/纪要无入口不写成可用 | 文首标草稿;当前标签三类已实现操作有步骤;话题/纪要明示无管理入口;目录4处跳转可解析 | Pass |
docs/user-manual/mini-program-management-platform.md;Web Agent 按 5633eab 业务校对通过,UI Agent 结构复核通过 |
| DOC-MP-F02 | 图片、图注与来源 | 文档/资产 | 检查13处引用、13个编号图注、逐图 SHA256 比对固定标签原图 | 所有图存在、来源明确且未冒当前截图 | 13/13 引用与图注匹配,13/13 与 2026-10-08 历史隔离原图字节一致,每图注明历史来源 | Pass |
docs/user-manual/assets/mini-program-management-platform/;UI Agent 图片可读性复核通过 |
| DOC-MP-F03 | 固定标签专项手册引用 | 文档/版本 | 核链接目标在精确标签中存在 | 不指向当前占用的功能分支或不存在文件 |
git cat-file -e 证明标签内旧专项手册存在;本文链接固定 tag,并提示旧抬头为隔离阶段元数据 |
Pass | v2.15.4-beta.0:docs/user-manual/expert-public-platform.md |
| DOC-MP-F04 | 当前测试站完整复现和真实截图 | 浏览器 | 需要有权测试账号登录 tcrm | 逐步复现手册并补当前版本截图 | 当前只有登录页版本证据;Ego TaskSpace 19 已 handOff,用户尚未完成登录;无业务写入,不能宣称已完成当前部署操作验收 | Blocked |
https://tcrm.mindsetech.com/users/sign_in;Frontend v2.15.4-beta.0 |
风险与下一步¶
本轮交付为可审阅初稿,尚缺当前部署的登录后截图与逐步复现。待用户登录后在同一 Ego TaskSpace 19 只读采图、复现,并追加新 QA 轮次。未改前端业务仓库,未提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 专家详情平台公开位置调整 - 2026-10-10 Asia/Shanghai¶
- 环境:NDB Web 本地
projects/ndb/frontend,preview,检查时 HEADf2205c5;本地未提交布局改动。 - 范围:只读模板 diff、左列顺序和跨产品使用文档版本边界。
- 汇总:Pass 3 / Fail 0 / Blocked 1 / Skipped 0。
| 编号 | 用例 | 层级 | 前置/操作 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|---|
| DOC-PUBLIC-POS-01 | 组件位置及作用域 | 源码静态 | 对比 candidate.vue diff、检查模板中组件出现次数与左右列边界 |
平台公开位于 Comments 卡片下方、左列结束前,组件属性及其他逻辑不变 | diff 仅1行删除/1行添加;组件唯一,位于 Comments 后、左列闭合前;左列顺序为背景说明→工作经历→访谈历史→Comments→平台公开 | Pass |
src/views/candidates/candidate.vue diff;新位置约472行,左列闭合约473行 |
| DOC-PUBLIC-POS-02 | 改动空白检查 | 源码静态 | 对该文件运行 git diff --check
|
无空白错误 | 退出码0 | Pass | git diff --check -- src/views/candidates/candidate.vue |
| DOC-PUBLIC-POS-03 | 手册版本边界 | 文档静态 | 检查协调根手册的本地待发布小节与全部图片引用 | 不将旧版本截图当作新布局验收 | 已加“本地待发布的位置调整”,说明 v2.15.4-beta.0 测试站仍按旧位置;13/13历史图片引用存在 | Pass | docs/user-manual/mini-program-management-platform.md |
| DOC-PUBLIC-POS-04 | 新位置浏览器视觉与截图 | 浏览器 | 需布局版本部署且有已登录账号 | 实际观察新位置并更新真实截图 | 当前仅本地未提交改动,尚未部署;测试站登录也待用户完成,无法验收新布局 | Blocked | 待部署和登录后补新截图;不得使用2026-10-08隔离图冒充 |
限制与下一步¶
本轮只证明源码模板位置及文档说明,未证明浏览器布局、权限交互或线上可见性。待部署并登录后补视觉验收和截图,另开 QA 轮次。QA 未修改前端业务文件,未提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
2026-10-10|QA:小程序管理平台使用说明 + 数据流转合并 PDF 验收(本轮)
成品:output/pdf/mini-program-management-and-data-flow-20261010.pdf(68 页);质检记录:outputs/mini-program-guide-20261010/qa-report.md。
逐条用例:
- [PASS] 三部分源文档合并:管理平台使用说明、2026-10-07/08 小程序数据流快照、NDB 应用 API v1 附录均在 PDF;目录页码可见,68 页均可抽取文本。
- [PASS] 图文完整性:13 张历史隔离截图、22 张由 Mermaid 关系重绘的流程图及各自图注均在;未残留原始 Mermaid 代码。历史截图不充当前部署证据。
- [PASS 修复复测] 原第 12/13 页关键截图过小:最终第 12 页人工确认及保存/发布按钮、第 13 页发布确认框已由 PDF 布局局部放大,原图未修改;UI Agent 最终复核通过。
- [PASS 修复复测] 原流程图 18 图注跨页:最终图、图注及说明同在第 48 页;UI Agent 最终复核通过。
- [PASS] NDB Web 操作边界按 v2.15.4-beta.0(5633eab)源码校对,Web Agent 对管理平台部分业务复核通过;历史登录页版本观察不表示当前部署版本。
- [PASS 静态复核] 内容详情的纪要附件行为按小程序 218d4c6 更新:有效附件未登录提示登录、登录后再点击、无附件提示“文件未上传”;查看或下载不创建预约/Task。
- [BLOCKED/未执行] 当前测试站登录后逐步操作、当前部署版本、真实微信端到端、真实邮件收件箱送达均无本工作包运行证据,不计为通过。
未提交、推送或部署;本轮为文档与 PDF 产物验收。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Web beta.2 部署前门禁 - 2026-10-11 00:00 Asia/Shanghai¶
- 环境:NDB Web 测试发布;候选 preview/tag v2.15.4-beta.2,提交 ccfdca5666aa7e217c281fca64b5e6ee6680c70c。
- 范围:专家详情公开区域位于 Comments 下方,以及会议/话题页面的部署后只读浏览器验收。
- 汇总:Pass 0 / Fail 0 / Blocked 2 / Skipped 0。尚未开始浏览器操作。
| 编号 | 用例 | 层级 | 预期 | 实际 | 状态 | 证据 |
|---|---|---|---|---|---|---|
| WEB-BETA2-001 | 新版专家详情公开区域位置 | 测试环境浏览器 | 当前候选部署后,公开区域紧随 Comments,截图可辨 | CNB 依赖缓存 stage1 在 Corepack 请求 registry.npmjs.org/pnpm/latest 时 TLS ECONNRESET;镜像、staging alias、部署触发均未执行,当前测试页面不是本候选 | Blocked | outputs/production-release-preparation-20261010/web-test-release-package.md;CNB cnb-ph5-1k4j8keu3 |
| WEB-BETA2-002 | 会议与话题页面只读加载 | 测试环境浏览器 | 当前候选部署后页面正常读取 | 同一部署门禁未通过,未在旧版本页面执行本轮验收 | Blocked | 同上 |
风险与下一步:修复 CI 国内镜像和 pnpm 版本固定后,以新的准确候选 tag 完成镜像及测试部署,核直接版本,再在独立 Ego Browser QA space 执行两条用例并更新截图手册。此轮未触发专家发布、报名或邮件。
RA Updated by Redmine Admin about 1 month ago
- Subtask #5 added
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Web beta.3 有限只读浏览器验收 - 2026-10-11 00:16 Asia/Shanghai¶
- 环境:https://tcrm.mindsetech.com;独立 Ego Browser QA TaskSpace 25;现有测试管理员会话。
- 候选:v2.15.4-beta.3 / a5f9d1112577a2276480f0496a89b9bfcfa80192;CNB cnb-2mr-1k4j8qikj。实际入口 /assets/index-p0ugFSvk.js,登录脚本 HTTP 200 含 beta.3 且不含 beta.2。
- 汇总:Pass 3 / Fail 1 / Blocked 1 / Skipped 0。
| 编号 | 用例 | 层级 | 预期 | 实际 | 状态 | 证据/缺陷 |
|---|---|---|---|---|---|---|
| WEB-BETA3-001 | 精确测试前端版本 | 环境/浏览器 | 加载 beta.3 制品 | 入口脚本匹配 Ops 直接检查,登录脚本含 beta.3、不含 beta.2 | Pass | outputs/production-release-preparation-20261010/qa-web-beta3-result.md |
| WEB-BETA3-002 | 菜单与会议只读列表 | 浏览器 | 导航可用,会议列表正常读取 | 首页→专家/会议/话题可导航;会议列表加载后70条,测试会议#3可读 | Pass | 同上 |
| WEB-BETA3-003 | 话题只读列表 | 浏览器 | 话题列表正常读取 | 显示「话题列表加载失败:未配置会议小程序应用,请联系管理员。」计数0 | Fail | 新缺陷 #5,已创建并回读 |
| WEB-BETA3-004 | Comments 后专家公开区 | 浏览器 | 公开区紧接 Comments | 测试专家#1 的实际DOM直接子元素 Comments 后紧接 public-profile-panel,面板标题「平台公开」 | Pass | 同上;截图见下一条阻塞 |
| WEB-BETA3-005 | 当前布局截图及手册更新 | 浏览器/文档 | 本候选真实截图可用于手册 | Ego截图及CDP Page.captureScreenshot均超时,45秒诊断仍失败,无PNG产物;手册未用旧图冒充 | Blocked | 同上;需恢复截图后再更新手册、UI/项目Agent复核 |
限制:只读;未发布专家、创建报名、发邮件或保存业务记录。前端版本证据不证明 Backend/BFF/生产版本。现有手册未完成本轮截图更新;修复截图能力和话题配置后追加新轮次,不改本轮结果。
RA Updated by Redmine Admin about 1 month ago
QA 真实 PostgreSQL 导入器验收 - 2026-10-11 Asia/Shanghai¶
对象:root bff-legacy-channel-importer.cjs SHA256 8ce46f980642a90830342ddb7d51182c70e48413198ba709693640375fb4e951。隔离 PostgreSQL 16.15,network none、无端口映射、listen_addresses 空,仅 Unix socket。使用 BFF schema.ts 原始 4/5 SQL 与全假数据。8 Pass / 0 Fail。
| ID | 执行结果 | 状态 |
|---|---|---|
| PG-001 | 原始 schema 4/5、10张保护表、用户/收藏及 ledger 列与实际 PG catalog 对齐 | Pass |
| PG-002 | READ ONLY dry-run 前后10表 counts/stateHash、ledger 均不变;无 sequence | Pass |
| PG-003 | 错 release / manifestHash 在 execute 前被拒 | Pass |
| PG-004 | 首次写入2用户、1收藏、1 run、3 row_map;默认phone/contact NULL,显式phone需reauth,旧sid/code及其它会话/验证码/outbox均未导入 | Pass |
| PG-005 | 同manifest重跑 alreadyImported=true,无重复行 | Pass |
| PG-006 | 源行/manifest漂移拒旧approval及已有目标新导入 | Pass |
| PG-007 | 目标postimage漂移拒同manifest重放 | Pass |
| PG-008 | row_map注入故障后 users/favorites/run/row_map 全部事务回滚 | Pass |
证据:outputs/production-release-preparation-20261010/qa-bff-importer-real-pg.md;可重审 harness 为同目录 qa-bff-importer-harness.cjs。真实目标 PG 版本/权限、真实源映射、生产执行及用户流程未验证。BFF业务仓库未修改;未提交、推送、部署。
RA Updated by Redmine Admin about 1 month ago
QA Backend importer 静态审阅与 PG15 副本证据复核 - 2026-10-11¶
对象:backend-legacy-importer.cjs SHA f0a48a06b054431bc9c3cb0a7916bee519b91536ba6e65689ca341160505b366。以下52项为Node模拟client测试,全部PASS,不代表真实PG。
- PASS offline plan is nonconnecting and accepts independent legacy topic155
- PASS no hardcoded application1; target app42 preserved
- PASS source SHA mismatch rejected
- PASS namespace is not staging or modern archive
- PASS archive extras preserved outside batch without blocking independent row
- PASS archive origin cannot be disguised as executable entity
- PASS missing mapped industry defers only dependent row
- PASS duplicate same source key rejected
- PASS foreign payload column cannot copy old numeric FK
- PASS Task and payment entities forbidden
- PASS raw SQL identifier and unsupported column rejected
- PASS values parameterized, SQL source text never interpolated
- PASS 49 approval exact cardinality mandatory
- PASS candidate mapping cannot conflate two source identities
- PASS invalid datetime rejected without now correction
- PASS no INSERT into protected Task table
- PASS true dryrun uses only SELECT SET and rollback
- PASS wrong application identity fails closed and rollback
- PASS execute requires exact release manifest before BEGIN
- PASS preimage drift stops before any DDL/INSERT
- PASS simulated execute persists map atomically and verifies postcommit
- PASS SQL DDL contains hashes and identifiers, no raw source JSON
- PASS same source rerun validates postimages and skips existing row
- PASS changed source payload is never an overwrite on reentry
- PASS imported row drift rejects new preview
- PASS sequence behind max fails without nextval or setval
- PASS impossible calendar date rejected
- PASS timestamp parameters explicitly cast with timezone
- PASS missing target schema column rejects dryrun before DDL
- PASS busy advisory lock fails without business writes
- PASS same source cannot be both approved and pending
- PASS unreviewed write trigger blocks preview before execute
- PASS postcommit check failure reports committed rather than claiming rollback
- PASS business protection drift before commit aborts rather than accepting imported rows
- PASS profile mapped to real production candidate and actual app, no source FK copy
- PASS public profile outside approved49 cannot publish
- PASS future publication time rejected
- PASS missing true production candidate mapping fails instead of creating fixture
- PASS raw source and transform provenance mandatory
- PASS null relation endpoint rejected, never creates fictitious endpoint
- PASS two content source tables may share PK without conflating provenance
- PASS required display title cannot be blank
- PASS unaccounted nonnull target column blocks before insert
- PASS RLS cannot hide business rows from protection scan
- PASS active application without expiry and with read scope is eligible
- PASS active application future expiry uses DB clock
- PASS active but expired at database clock rejects and rollback
- PASS expiry equal to database now is expired, strictly greater required
- PASS active application missing conference read scope rejects
- PASS null or malformed scopes cannot imply read authorization
- PASS inactive application still rejects even with future expiry and read scope
- PASS minimal read scope suffices, no invented additional scopes required
额外 QA 反例:FAIL - published_at比source.referenceTime晚1微秒仍被validate接受,因Date.parse只保留毫秒。应使用完整微秒和时区瞬时值比较,改后重冻SHA。README暂态旧SHA已由作者同步更新,复核当前一致。
PG15生产dump隔离恢复副本:QA独立审阅本地ops-pg-clone-check.py和Ops报告;报告23 migration完成、88旧表1429949旧行旧列hash不变、6140 Task standard、三个CHECK validated、二次plan空。QA未直接登录远端,PG14同版本演练/生产窗口仍未通过。证据:outputs/production-release-preparation-20261010/qa-backend-importer-review.md、qa-migration-gate.md、qa-backend-importer-node-tests.log。未改业务repo、未提交/推送/部署。
RA Updated by Redmine Admin about 1 month ago
QA Backend importer 修复版复测 - 2026-10-11¶
冻结脚本SHA bb8ce6e5e0839cef0d2a9c17200233ab9ffc80973be69ea270797b08710ca156;测试SHA bc700f00e1379b555b039fac2afa6e216cf3b5a5deedd8628d4bfcbc8d09ba39。语法检查PASS;Node模拟client 59/59 PASS。此前journal #78 的微秒缺陷在当前源码由BigInt instantMicros修复,新用例覆盖跨时区同一瞬时、晚1微秒拒绝、会议1微秒时长接受。逐项结果:
- PASS offline plan is nonconnecting and accepts independent legacy topic155
- PASS no hardcoded application1; target app42 preserved
- PASS source SHA mismatch rejected
- PASS namespace is not staging or modern archive
- PASS archive extras preserved outside batch without blocking independent row
- PASS archive origin cannot be disguised as executable entity
- PASS missing mapped industry defers only dependent row
- PASS duplicate same source key rejected
- PASS foreign payload column cannot copy old numeric FK
- PASS Task and payment entities forbidden
- PASS raw SQL identifier and unsupported column rejected
- PASS values parameterized, SQL source text never interpolated
- PASS 49 approval exact cardinality mandatory
- PASS candidate mapping cannot conflate two source identities
- PASS invalid datetime rejected without now correction
- PASS no INSERT into protected Task table
- PASS true dryrun uses only SELECT SET and rollback
- PASS wrong application identity fails closed and rollback
- PASS execute requires exact release manifest before BEGIN
- PASS preimage drift stops before any DDL/INSERT
- PASS simulated execute persists map atomically and verifies postcommit
- PASS SQL DDL contains hashes and identifiers, no raw source JSON
- PASS same source rerun validates postimages and skips existing row
- PASS changed source payload is never an overwrite on reentry
- PASS imported row drift rejects new preview
- PASS sequence behind max fails without nextval or setval
- PASS impossible calendar date rejected
- PASS timestamp parameters explicitly cast with timezone
- PASS missing target schema column rejects dryrun before DDL
- PASS busy advisory lock fails without business writes
- PASS same source cannot be both approved and pending
- PASS unreviewed write trigger blocks preview before execute
- PASS postcommit check failure reports committed rather than claiming rollback
- PASS business protection drift before commit aborts rather than accepting imported rows
- PASS profile mapped to real production candidate and actual app, no source FK copy
- PASS public profile outside approved49 cannot publish
- PASS future publication time rejected
- PASS missing true production candidate mapping fails instead of creating fixture
- PASS raw source and transform provenance mandatory
- PASS null relation endpoint rejected, never creates fictitious endpoint
- PASS two content source tables may share PK without conflating provenance
- PASS required display title cannot be blank
- PASS unaccounted nonnull target column blocks before insert
- PASS RLS cannot hide business rows from protection scan
- PASS active application without expiry and with read scope is eligible
- PASS active application future expiry uses DB clock
- PASS active but expired at database clock rejects and rollback
- PASS expiry equal to database now is expired, strictly greater required
- PASS active application missing conference read scope rejects
- PASS null or malformed scopes cannot imply read authorization
- PASS inactive application still rejects even with future expiry and read scope
- PASS minimal read scope suffices, no invented additional scopes required
- PASS all publication kinds reject one microsecond in the future
- PASS all publication kinds accept exact microsecond equality and earlier instant
- PASS publication UTC equivalence honors positive and negative offsets across date boundary
- PASS offset publication one microsecond after UTC reference rejects
- PASS meeting one microsecond duration is valid and timestamptz input remains exact
- PASS meeting equal instants across offsets and reversed microseconds reject
- PASS fractional precision is padded rather than truncated and timezone stays mandatory
证据:outputs/production-release-preparation-20261010/qa-backend-importer-review.md、qa-backend-importer-node-tests-bb8ce6.log。仍待Ops隔离PG真实执行各kind/Profile/grant及生产身份与许可证据;本复测不批准生产execute。未改业务仓库、未提交/推送/部署。
RA Updated by Redmine Admin about 1 month ago
QA 门禁更新 - PG14 原生备份来源归属 - 2026-10-11¶
MIG-PG14-IDENTITY:PASS(基于 Ops 只读运行证据复核)。server-2 实际 Backend 运行容器以 runtime settings 在只读事务查得 slime_crm/172.17.0.10:5432/system_identifier=7615449968045083019/PostgreSQL14.22,exit0;server-1 原生 peer 连接 slime_crm 的 system_identifier 和版本一致,主机 IP 包含 172.17.0.10。因此原生PG14新dump来自 Backend 当前连接的同一生产集群。隔离 clone 的 system_identifier应独立;两个不同时点dump SHA不必相同。QA未直接连接生产库。
MIG-PG14-EXECUTION:BLOCKED。新 PG14 dump SHA 672bcc2eb6471caa7de87c41f160e70b89a64217b26301eebc79cc72b5f55da3 已在私有socket/55432隔离集群恢复成功,但候选a8111cb的23项迁移、旧行指纹、约束、Task状态和二次空计划尚未执行/返回。生产Backend schema migration保持NO-GO。证据:outputs/production-release-preparation-20261010/qa-migration-gate.md、live-data-audit.md。未生产写入、提交、推送或部署。
RA Updated by Redmine Admin about 1 month ago
QA PG14.24隔离候选迁移复核 - 2026-10-11 Asia/Shanghai¶
范围仅Backend schema migration,候选a8111cbfb3022a7191b255f741779691c6805269,319文件包SHA7357d74885e3b4c9abd27dd853872b8ce465cce0fd7f5a666ce3032b91baec50;同源dump SHA672bcc2eb6471caa7de87c41f160e70b89a64217b26301eebc79cc72b5f55da3;PG14.24隔离clone network none/Unix socket55432。Ops完整migrate日志11957bytes/0600/SHA30819b345039834c54eefab42107a2f33ba3121cff1e12f95e0394e3a05b5bc5。QA读本地runner与Ops结果,未连库或读远端完整日志。
| 用例 | 实际 | 状态 |
|---|---|---|
| MIG-PG14-PLAN | 23项forward、conflicts空、history一致 | Pass |
| MIG-PG14-MIGRATE | 实际23项迁移exit0,进程内二次pending0 | Pass |
| MIG-PG14-OLD-ROWS | 88旧业务表1429949旧行旧列逐行指纹前后完全一致 | Pass,依据Ops报告 |
| MIG-PG14-TASKS | 原6140 Task financial_role全standard | Pass,依据Ops报告 |
| MIG-PG14-CHECKS | 三个meeting_* CHECK均validated | Pass,依据Ops报告 |
| MIG-PG14-SECOND-PLAN | 独立新进程二次plan0/history一致 | Blocked,Ops补证中 |
| MIG-PG14-OLD-CATALOG | 迁移前后旧index/constraint定义与有效性对比 | Blocked,Ops补证中 |
生产进程14.22、clone14.24,不能称精确补丁版演练;基于候选SQL与PG14.23/14.24官方更新说明未发现补丁差异构成具体硬阻断。当前生产Backend schema migration仍NO-GO,待两项补证及正式窗口生产目标/备份/停写/权限门禁。以上不是旧渠道切流或生产已迁移。证据:outputs/production-release-preparation-20261010/qa-migration-gate.md、live-data-audit.md。
RA Updated by Redmine Admin about 1 month ago
QA Backend schema迁移最终门禁 - 2026-10-11 Asia/Shanghai¶
冻结候选a8111cbfb3022a7191b255f741779691c6805269,已核同源生产PG14.22 dump恢复至network none/私有socket55432的PG14.24 clone;23项迁移实际exit0。QA只读复核Ops报告及本地runner,未直接连接DB。
| 用例 | 实际 | 最终状态 |
|---|---|---|
| MIG-PG14-SOURCE | Backend运行连接与原生源pg_control_system system_identifier同为7615449968045083019;生产源归属明确 | Pass |
| MIG-PG14-PLAN | 23 forward/conflicts空/history一致 | Pass |
| MIG-PG14-MIGRATE | PG14.24 clone实际迁移exit0 | Pass |
| MIG-PG14-OLD-ROWS | 88旧业务表1429949行旧列全行指纹不变 | Pass |
| MIG-PG14-TASKS | 原6140 Task financial_role均standard | Pass |
| MIG-PG14-CHECKS | 三个新增meeting_* CHECK validated | Pass |
| MIG-PG14-SECOND-PLAN | 独立新进程plan exit0/conflicts空/plan[],日志SHA051158cdc7d22d6fcaf3fe1f4b4259562354c6994271bb41985201a59d929306 | Pass |
| MIG-PG14-OLD-CATALOG | 源301旧index+222旧constraint共523对象在clone无missing/different,定义/validated/deferrable一致;v2受限结果SHAab443113594b0c6ed19d85620c9c57d75e52eba93bead7ccdb86a99d9b2773c4 | Pass |
第一次多语句psql只读到ROLLBACK、0对象收据无效,明确不计通过;最终v2以只读单SELECT与>100断言取得真结果。PG14.24与生产14.22补丁不同,不能称精确同补丁演练;候选SQL未见具体不兼容项,差异本身不构成硬阻断。
结论:仅冻结Backend schema migration候选的QA兼容性门禁GO。生产原库未迁移,执行仍需根/Operations核真实目标、候选digest、最新只读schema/ledger前置、备份/停写/执行角色和失败即停,再获生产写入授权;任何漂移GO失效。不涵盖旧业务importer、V2并行部署、旧入口切流或邮件。证据:outputs/production-release-preparation-20261010/qa-migration-gate.md、live-data-audit.md。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Legacy normalizer 离线审查 - 2026-10-11 00:55 Asia/Shanghai¶
环境:本机 Node,合成数据;未读 PII/raw/生产 DB。候选:normalizer d27ff91768a4795646d007e12560230fa7eee7e6ed77f5c2fb606ce79429a10a;test 05d495c3b46e062d163ff96630329382bdff27237f615a824b8222eb92847b3c;importer bb8ce6e5e0839cef0d2a9c17200233ab9ffc80973be69ea270797b08710ca156。
步骤:node --check backend-legacy-normalizer.cjs;node --test backend-legacy-normalizer.test.cjs。QA Agent;离线单元层级;前置为上述冻结文件及合成 fixtures。汇总 Pass 22 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| NORM-001 | 有效归一输入 | importer 接受且证据摘要绑定 | 符合 | Pass |
| NORM-002 | 缺决策与全 pending | 无可导入 input | 符合 | Pass |
| NORM-003 | 显式排除 | 每行仅一条 coverage | 符合 | Pass |
| NORM-004 | 缺字段规则/来源列 | 该行 pending | 符合 | Pass |
| NORM-005 | 缺 kind 规则/枚举映射 | 该行 pending | 符合 | Pass |
| NORM-006 | 依赖缺证与独立行 | 依赖 pending,独立行可用 | 符合 | Pass |
| NORM-007 | 无审批时区/错误规则 | 整份 spec 拒绝 | 符合 | Pass |
| NORM-008 | 操作时间限制 | 需批准且不能填会议起止 | 符合 | Pass |
| NORM-009 | 字节摘要/冻结版本/快照证据 | 缺失或不符拒绝 | 符合 | Pass |
| NORM-010 | raw 结构/数字 ID/不安全整数 | 错误输入拒绝 | 符合 | Pass |
| NORM-011 | 重复行/未知决定 | 整批拒绝 | 符合 | Pass |
| NORM-012 | 行及 schema 摘要篡改 | 拒绝 | 符合 | Pass |
| NORM-013 | 原 49 人与 application | 不能由选择器推断 | 符合 | Pass |
| NORM-014 | 策略证据绑定 | 不同策略改写摘要 | 符合 | Pass |
| NORM-015 | 独立行与坏字段行 | 独立行保留、坏行 pending | 符合 | Pass |
| NORM-016 | 来源 ID 与目标映射 | 不自动提升为目标 ID | 符合 | Pass |
| NORM-017 | Task/错误源表 | 拒绝导入目标实体 | 符合 | Pass |
| NORM-018 | 显式 JSON/枚举映射 | 不猜测解释 | 符合 | Pass |
| NORM-019 | 49 人名单外 Profile | 仍 pending | 符合 | Pass |
| NORM-020 | 已批 Profile | 显式 Candidate 映射且无联系方式 | 符合 | Pass |
| NORM-021 | Project code | 只从声明来源列生成 | 符合 | Pass |
| NORM-022 | CLI 文件安全 | 仅 plan、0600、独占、不执行 | 符合 | Pass |
证据:Node TAP 显示 tests 22、pass 22、fail 0;QA 报告 outputs/production-release-preparation-20261010/qa-normalizer-review.md。无缺陷关联。未验证真实 raw、外部证据真实性、隔离副本或生产导入;这些仍由 Ops/后续门禁处理。本轮不继承 schema 迁移 GO。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 实际生产 Backend schema 执行证据复核 - 2026-10-11 01:07 Asia/Shanghai¶
环境:Ops 的实际生产执行收据与本地 runner 源码;QA 未连接生产或读取远端完整日志。候选 a8111cbfb3022a7191b255f741779691c6805269。层级:生产执行证据复核;前置:根已放行 schema 迁移、四 writers 停写、新鲜备份完成。操作:核对 production-schema-execution-package.md 与 ops-production-host.py/ops-production-schema.py 的条件及断言。汇总 Pass 7 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| MIG-PROD-01 | 目标身份与停写 | 目标为已审生产集群且四 writers 停写 | Ops 收据为 slime_crm/public PG14.22 cluster 7615449968045083019;17:01:30Z 四 writers 停写 | Pass |
| MIG-PROD-02 | 新鲜冻结备份 | 完成备份后才执行迁移 | 17:04:46Z 完成;exit0/stderr0;216826731 bytes/899 TOC/0600;SHA 23f33218c9e39137812b1fda0ef99a2a3c73d94bba1558eaf9f1500908313079 | Pass |
| MIG-PROD-03 | 精确计划与迁移 | 冻结候选 23 项 forward 全 atomic 且 migrate 成功 | Ops 执行收据报告 23 项,migrate exit0;migrate.log SHA 4e7069469f25c3eb82452a586b669557f3f28e917e30c695766e4b8284aec246 | Pass |
| MIG-PROD-04 | 独立后验 | 新进程 plan 空、history 一致、无冲突 | postcheck exit0;plan[]/history consistent/conflicts{};log SHA 05a6b4bdfbc3b7769bcdfdd94a60dd7d1ebbabe421722221f8992416c743350b | Pass |
| MIG-PROD-05 | 旧业务数据与 catalog | 88 表旧列指纹及 523 旧对象不变 | Ops 报告 1429949 旧行旧列 hash 不变;523 旧 index/constraint 定义状态不变 | Pass |
| MIG-PROD-06 | Task 与约束 | 旧 Task 全 standard,3 CHECK validated | Ops 报告原 6140 Task 全 standard,3 meeting CHECK validated | Pass |
| MIG-PROD-07 | 系统身份 | 从实际生产后验读取新增身份 | Ops 报告生产 meeting-finance-v1 expert574314/client1010 | Pass |
证据路径:outputs/production-release-preparation-20261010/qa-migration-gate.md;Ops server-2 /data/backups/ndb-release-20261011/production-schema-20261011T010500。日志 SHA 由 Ops 报告,QA 未远端重算;本轮无 Fail/缺陷关联。结论限实际生产 Backend schema 迁移及独立后验 PASS。writers 仍停;兼容代码部署/运行核对、旧数据 importer、BFF 激活与完整发布未验证、未放行。QA Agent,2026-10-11 01:07 Asia/Shanghai。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Backend 兼容代码恢复证据复核 - 2026-10-11 01:09 Asia/Shanghai¶
环境:Ops 生产运行收据 + QA 独立无凭据 HTTPS GET;候选 main 21763c61524323440bff4b12b0f06ca3af073714 / v1.20.0。层级:生产运行证据复核及公开接口。前置:schema 迁移及独立 postcheck 已通过。操作:核 production-schema-execution-package.md,并 GET https://crm-api.mindsetech.com/v1/version/ 一次。汇总 Pass 5 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| MIG-REC-01 | 远端版本与流水线 | 正式 tag 指向获审 main 且生产流水线成功 | Ops:main/tag 21763c61524323440bff4b12b0f06ca3af073714 一致;CNB cnb-t16-1k4jcg9ju SUCCESS;生产 image/alias/deploy trigger 成功;staging skipped | Pass |
| MIG-REC-02 | 四个新 writers | 四进程运行且版本和 digest 一致 | Ops:四个均 running/__version__1.20.0,RepoDigest sha256:2d2a63a7ffcf7095dec74fce140f218b073c1559aaa24aa75631996c651dc97e,Started 17:07:45Z | Pass |
| MIG-REC-03 | 自动 migrator | 新版启动后无剩余迁移 | Ops:exit0;No migrations to apply | Pass |
| MIG-REC-04 | 公开版本入口 | 独立无凭据 GET 返回 1.20.0 | QA 17:09:03Z 实测 HTTP/2 200;JSON code200/data.version=1.20.0 | Pass |
| MIG-REC-05 | 维护窗口及恢复收据 | 运行恢复记录完整且未恢复旧 writer | Ops runtime-acceptance.json confirmed17:08:26.660318Z;17:01:30.255055Z 起约6m56;旧 writer 未恢复,DB/旧小程序未停 | Pass |
证据:outputs/production-release-preparation-20261010/qa-migration-gate.md;Ops runtime-acceptance.json 收据摘要;独立 GET 响应 HTTP/2 200、{code:200,data:{version:1.20.0}}。Ops 的 CI/容器/migrator/窗口信息本轮 QA 未远端独立查询;无 Fail/缺陷关联。结论限 Backend 兼容代码恢复;Web/BFF、应用绑定、旧业务导入、邮件和业务流程仍需独立门禁。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - Web v2.16.0 生产版本有限只读验收 - 2026-10-11 01:18 Asia/Shanghai¶
环境:公开 https://crm.mindsetech.com/;无登录/无业务写;候选 main 4e1d44ae209ea39ebfe5fa6c3a284266b5fae59d/v2.16.0。层级:生产 HTTP 静态制品与 Ops 发布收据。前置:Ops 已完成生产部署。操作:QA 独立 GET HTML、入口、登录资源;检查版本/域名;核本地 Git;复核 Ops 流水线包。汇总 Pass 5 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| WEB-PROD-VERSION-001 | 生产 HTML | HTTP 200 且引用获审入口资源 | QA:HTTP/2 200;index-C_41MRQQ.js;17:18:09 GMT | Pass |
| WEB-PROD-VERSION-002 | 入口与登录静态资源 | 均可 GET 且登录资源声明2.16.0 | QA:入口67031 bytes,链接login-CFE9elUV.js;登录4098 bytes;2.16.0一次/2.15.3零次 | Pass |
| WEB-PROD-VERSION-003 | 目标 API 域名 | 生产入口含prod、不含staging域名 | QA:crm-api.mindsetech.com一次,tcrm-api.mindsetech.com零次 | Pass |
| WEB-PROD-VERSION-004 | 本地版本锚点 | main HEAD 精确匹配v2.16.0 | QA:HEAD/tag 4e1d44ae209ea39ebfe5fa6c3a284266b5fae59d;main clean | Pass |
| WEB-PROD-VERSION-005 | 远端发布流水线 | 正式流水线成功且仅生产阶段触发 | Ops 收据:CNB cnb-pb9-1k4jd0a30 SUCCESS 78.230s;production build/image/alias/deploy trigger SUCCESS;staging2 SKIPPED | Pass |
证据:outputs/production-release-preparation-20261010/qa-web-production-version.md、web-production-release-package.md。Ops 远端流水线事实非 QA 独立登录核查;QA 独立 HTTP 响应如表。本轮无 Fail/缺陷关联。只证明生产制品版本可达;Topic 应用绑定、Web/BFF 业务联调、旧数据导入与完整发布未验收。无浏览器截图,本轮未执行交互/手册检查。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 生产应用身份绑定证据复核 - 2026-10-11 01:34 Asia/Shanghai¶
环境:Ops生产执行收据与事前应用契约;QA不连接生产DB/Coolify/BW,不发HMAC/ready ping,不启动BFF。层级:生产证据复核。前置:Backend1.20.0已恢复;候选新身份mp-conference-v2-production。操作:核production-application-identity-execution.md与bff-production-application-contract.md。汇总 Pass 5 / Fail 0 / Blocked 1 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| APP-ID-001 | 新身份/权限 | 唯一生产身份且七 scope 精确 | Ops:id1/unique name mp-conference-v2-production/active/actor7/secret_version1/expires null;七 scope 与契约一致 | Pass |
| APP-ID-002 | CIDR/凭据兼容 | 窄来源且AKSK可解密、master不变 | Ops:175.102.135.237/32;BW与Backend解密摘要一致;master摘要不变 | Pass |
| APP-ID-003 | Backend最小重建 | 配置生效且只重建Web进程 | Ops:CoolifyDB+managed.env 持久,native compose仅重建ndb-server同1.20.0镜像;其他3进程ID/Started未变、无migrator | Pass |
| APP-ID-004 | 运行绑定/HMAC | web_application解析新ID且受控ping通过 | Ops:web_application() ID1/active/7scope;最终HTTPS HMAC ping200、ID/name/last_used_ip一致 | Pass |
| APP-ID-005 | 业务隔离 | 应用绑定不创建业务行 | Ops:Meeting/Topic/ContentItem/PublicExpertProfile/ExpertInterviewRequest 仍全0 | Pass |
| APP-ID-006 | 新BFF secret运行生效 | 部署后能确认实际secret/ready认证 | 仅runtime-only写入ACK/flags;API脱敏无法回读值,BFF尚未部署;待独立运行门禁 | Blocked |
证据:outputs/production-release-preparation-20261010/qa-production-application-identity.md。以上Pass均为Ops收据复核,不代表QA独立生产探测;无Fail/缺陷关联。APP-ID-006受API脱敏和BFF未部署阻塞,后续在单独运行门禁验证。当前不重复HMAC ping:last_used会改变受manifest保护的api_applications全行SHA。Topic业务归属/旧数据导入未验收。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 新生产 channel schema 初始化证据复核 - 2026-10-11 01:37 Asia/Shanghai¶
环境:Ops生产执行收据与本地冻结源码/wrapper;QA未连接生产DB或执行写入。候选 BFF 93f78358326741f2e2af8d38851ce4df16ec8d95。层级:生产执行证据复核。前置:新建空库与根限定授权。操作:核channel-production-schema-execution.md、src/storage/schema.ts、ops-channel-schema-oneoff.js。汇总 Pass 6 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| CH-SCHEMA-001 | 目标身份 | 目标库/role/schema/PG14 cluster 精确匹配 | Ops:mp_conference_production/public,同名受限owner,PG14.22@172.17.0.10:5432,cluster7615449968045083019 | Pass |
| CH-SCHEMA-002 | 写前空库与guard | 空catalog后才写,错误guard不触发DDL | Ops:relations[]/functions0;name[]格式失败在迁移前;只读guard改array_to_json | Pass |
| CH-SCHEMA-003 | 冻结制品/隔离入口 | 仅精确编译storage与锁定依赖,一次性无HTTP | Ops:HEAD93f78358326741f2e2af8d38851ce4df16ec8d95;4JS+13pg包SHA0a5904182be2ac0ad192e6c4ccb88fd21effb68e6884305ae698192309047bc6;Node24.20/pg8.23.1;CMD覆盖 | Pass |
| CH-SCHEMA-004 | 迁移执行 | 仅migrate.js完成4/5 | Ops:node dist/storage/migrate.js exit0;本地源码版本4,5/advisory741032004 | Pass |
| CH-SCHEMA-005 | schema后验 | ledger/表/约束/索引符合候选 | Ops:ledger[4,5],11表,22 validated约束(11PK7FK3CHECK1UNIQUE),15索引 | Pass |
| CH-SCHEMA-006 | 空业务与操作边界 | 业务仍空且BFF未启动 | Ops:9 runtime表+sqlite_imports全0;无BFF启动/HMAC/DNS/MQ/outbox/legacy操作 | Pass |
证据:outputs/production-release-preparation-20261010/qa-channel-production-schema.md;远端包SHA及DB后验由Ops收据报告,QA未远端独立重算/连接。无Fail/缺陷关联。结论限空库schema4/5;新BFF部署/ready/业务接口/旧数据导入未验收。当前application全行SHA保护,不为QA再发HMAC ping。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 测试环境当前只读可用性 - 2026-10-11 01:54 Asia/Shanghai¶
环境:Ego Browser TaskSpace25现有测试Web登录会话 + 测试Backend/BFF有限GET。候选观测Web2.15.4-beta.3/Backend1.20.0b1,BFF精确运行版本未证。层级:浏览器/公开接口。前置:测试现有会话;无生产访问。操作:只读列表/详情/版本GET,不发通知邮件/验证码、生产HMAC或业务POST。汇总 Pass 9 / Fail 0 / Blocked 2 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| STG-RO-001 | Web版本 | 当前测试Web可读且精确beta3 | Ego会话;index-p0ugFSvk.js/login-BNphO4pk.js均HTTP200;仅2.15.4-beta.3 | Pass |
| STG-RO-002 | Backend版本 | 测试Backend返回版本 | GET tcrm-api.mindsetech.com/v1/version/ HTTP200 code200 version1.20.0b1 | Pass |
| STG-RO-003 | BFF存活 | 测试BFF进程可用 | GET mp-test.mindsetech.com/health/live HTTP200 statusok;未调ready | Pass |
| STG-RO-004 | BFF精确运行版本 | 能独立确认运行镜像精确版本 | live不含版本;本轮无当前运行镜像tag/digest只读证据,需Ops补 | Blocked |
| STG-RO-005 | 会议列表 | 页面加载且有数据 | Ego /meetings?page=1&page_size=20 显示70条 | Pass |
| STG-RO-006 | 会议详情 | 会议#3可读 | Ego /meetings/3 显示已发布、专家1、Task1/1 | Pass |
| STG-RO-007 | Topic列表 | 页面加载且有数据 | Ego /topics?page=1&page_size=20 显示154条、#32可进入 | Pass |
| STG-RO-008 | Topic详情 | 话题#32可读 | Ego /topics/32 含话题信息及相关会议/专家区,无加载失败 | Pass |
| STG-RO-009 | 公开专家列表 | BFF返回分页目录 | GET mp-test.mindsetech.com/api/v2/catalog/experts?page=1&pageSize=1 HTTP200 total49/items1 | Pass |
| STG-RO-010 | 公开专家详情 | 首项ID可读且契约完整 | GET mp-test.mindsetech.com/api/v2/catalog/experts/31 HTTP200、ID匹配、字段形状符合 | Pass |
| STG-RO-011 | 通知配置 | 隔离通知可用且可证明投递 | 本轮禁止发码/邮件未重试;此前发码503 AUTH_SERVICE_UNAVAILABLE,待通知责任方配置及独立投递验收 | Blocked |
证据:outputs/production-release-preparation-20261010/qa-staging-readonly-20261011.md。未输出PII/令牌;Web SPA页面以DOM可用性为证,不伪称路由HTTP200。BFF公开GET可能触发测试Backend应用认证last_used/nonce内部记录,本轮未直接DB写。截图此前同TaskSpace超时,本轮未重试;无新手册。Blocked项分别需Ops运行镜像只读版本证据、通知责任方完成隔离配置和授权投递验收。无Fail/缺陷关联。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 65 Project clone importer 收据复核 - 2026-10-11 02:05 Asia/Shanghai¶
环境:Ops冻结catalog-rehearsal-progress.md与本地wrapper/工具摘要;QA未连接远端/clone/生产DB、未读受限raw/manifest正文。候选 normalizer d27ff91768a4795646d007e12560230fa7eee7e6ed77f5c2fb606ce79429a10a/importer bb8ce6e5e0839cef0d2a9c17200233ab9ffc80973be69ea270797b08710ca156。层级:隔离clone执行证据复核。操作:核来源、覆盖、dryrun、execute、独立reentry与边界。汇总 Pass 6 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| CL-01 | 来源与clone边界 | 冻结工具/源/clone身份一致 | Ops:PG14.24 clone7695078412934166696/slime_crm_rehearsal/127.0.0.1:55432;本地normalizer/importer SHA一致 | Pass |
| CL-02 | 逐行覆盖 | 563源行=65included+498pending | Ops原因69+162+126+92+49=498;仅65最小Project,其余pending | Pass |
| CL-03 | 只读dry-run | 旧表/序列前后不变并产精确manifest | Ops exit0、104表1430186旧行/全序列零变化;manifest fa9ade0048bdccba7ea86a40b92d49f83d47a7eff65fd0ed931fea321d1b67c2;140.3368s/2642884KiB | Pass |
| CL-04 | 首次execute | 同manifest COMMIT/postcommit且仅创建65 | Ops exit0、committed/postcommitVerified true、created65/skipped0/outside498;125.7466s/2045012KiB;旧业务保护不变 | Pass |
| CL-05 | 独立重入 | 新manifest全skip且再次执行不重复创建 | Ops新manifest3197f2a1867fe29b23239a3c6357ea45619f26d2b99663906e4f0219d7a359e5;preview零变化/65skip;execute committed/postcommitVerified、created0/skipped65/outside498;本地wrapper SHA匹配远端,结果重读 | Pass |
| CL-06 | 失败与范围边界 | 前置wrapper错误未进入importer,最终仅clone | Ops报告前置mount/launcher错误均执行前;最终容器退出;无生产Importer/Task财务Candidate/通知HMAC/BFF写 | Pass |
证据:outputs/production-release-preparation-20261010/qa-catalog-clone-receipt-review.md;Ops冻结进展报告。全部Pass均为收据复核,QA未亲自执行数据库操作,远端完整日志/manifest未重算;无Fail/缺陷关联。此结论仅65 Project的clone工具门禁;组合catalog、drift/atomic、映射/时间/附件/49许可、生产manifest与生产execute均未完成或未放行。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 完整catalog隔离clone批次收据复核 - 2026-10-11 02:36 Asia/Shanghai¶
环境:Ops catalog-rehearsal-progress.md与本地冻结工具/wrapper;QA未连接clone/生产DB、未读受限raw/PII或重跑mock。候选normalizer d27ff91768a4795646d007e12560230fa7eee7e6ed77f5c2fb606ce79429a10a/importer bb8ce6e5e0839cef0d2a9c17200233ab9ffc80973be69ea270797b08710ca156。层级:PG14.24隔离clone执行证据复核。汇总 Pass 6 / Fail 0 / Blocked 2 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| CC-01 | r14输入恒等 | 仅精确相同时复用r13 manifest | Ops:六项产物逐字节同r13,独占r13-reuse-binding;manifest b16c5bda4261397ab3be35e4c52fbbd9d6653a68426391a34312a5ca89dec2d1 | Pass |
| CC-02 | 覆盖与pending | 563行全覆盖且不猜测坏源 | Ops:373included+190pending;63Project/64Meeting/162Topic/49Profile/34TopicExpert/1draftContent;pending分类合计190 | Pass |
| CC-03 | clone只读前像 | 目标隔离且dryrun零变化 | Ops:干净slime_crm_catalog_rehearsal/PG14.24clone;104表1430186旧行及序列前后相同,dryrun125.7061s/RSS1756328KiB | Pass |
| CC-04 | 真实clone execute | 同manifest COMMIT并保护旧业务 | Ops:exit0/committed/postcommitVerified/created373/skipped0/outside190;132.0087s/RSS2307820KiB;旧业务保护通过 | Pass |
| CC-05 | 49人平台grant独立后验 | 49 grant ledger及非授权Candidate不变有实库摘要 | 仅49Profile和映射、importer代码/postcommit平台检查;缺独立grant计数及未批准Candidate前后摘要,待受限只读补证 | Blocked |
| CC-06 | 实际会议时间 | PG/serializer保持受审上海walltime | Ops:64Meeting/128起止值,PGtimestamptz/sessionAsiaShanghai/USE_TZFalse,候选a8111cb转换回环均一致 | Pass |
| CC-07 | 独立重入 | 新manifest全skip且无重复创建 | Ops:新manifest19f9d7afbfa4cb33102113d14346219a7983c7a6c0d6f04f6c94c976ba713457;104表1430559行/序列只读零变化;execute created0/skipped373/postcommitVerified | Pass |
| CC-08 | 漂移/原子失败路径 | 实库漂移拒绝及受控ROLLBACK有最终收据 | Ops drift probes仍运行,fault DB受控回滚未冻结;不能从成功路径推断 | Blocked |
证据:outputs/production-release-preparation-20261010/qa-catalog-combined-receipt-review.md;Ops冻结进展收据。Pass均是收据复核,不是QA亲自数据库执行。CC-05需受限grant/非授权Candidate只读摘要;CC-08需漂移与faultDB ROLLBACK最终收据;补证后追加新轮次。附件126来源行仍pending;生产旧catalog importer未执行/未放行,不能宣布完整发布。无Fail/缺陷关联。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 补证复测 - 373 catalog 隔离clone剩余门禁 - 2026-10-11 02:43 Asia/Shanghai¶
环境:Ops catalog-rehearsal-progress.md冻结收据与本地冻结wrapper摘要;QA未连clone/生产DB、未读PII/raw。承接原轮次Redmine#1 journal92的CC-05/CC-08 Blocked,不覆盖原记录。层级:实际PG隔离clone证据复核。汇总 Pass 3 / Fail 0 / Blocked 0 / Skipped 0。
| 编号 | 用例 | 预期 | 实际 | 状态 |
|---|---|---|---|---|
| CC-05-R1 | 49人平台grant聚合 | 授权49/越权0/ledger49且其他列保护 | Ops只读聚合:authorizedTargets/activeUnlocked/Granted/globalGranted各49,unauthorizedGranted0,App1published49/越权0,grantLedger49;receiptSHA d0b46effeefa7cf574c463ba4cff6a967d6994465856553ad88487c5941552e5 | Pass |
| CC-08A-R1 | 实际PG漂移拒绝 | 源变与manifest前像变在写入前拒绝 | Ops:SOURCE_CHANGED_REFUSE_OVERWRITE/PREIMAGE_DRIFT,均DDL-DML0+ROLLBACK;drift-result SHA6f5594adcdc77ba3480d389664d25e82912aae8f97bb65c27d0b4e3d386d7d55 | Pass |
| CC-08B-R1 | 真实首次写入故障回滚 | 写入中故障后旧业务与ledger/run恢复,序列差异明确 | Ops faultDB:373catalog+49grant+1run+首ledger成功后注入异常并ROLLBACK;独立连接104表1430186旧行hash/schema不变、ledger/runDDL不存在;6seq非事务推进、无setval;faultSHA173e6a5d9ef24a55fba7935a904bedc6824d491e6bf15f1725c3a22edc27da3f | Pass |
证据:outputs/production-release-preparation-20261010/qa-catalog-combined-receipt-review.md;Ops远端文件SHA由其报告,QA未远端重算。至此373条catalog隔离clone工具门禁有界GO;包含首次COMMIT/reentry/grant/drift/rollback。6条sequence可在ROLLBACK后推进,不能称物理零变化。63附件Content未入本批,1个N_A父项不能假定公开;生产Importer DML/tag/deploy未授权或执行,最终批仍独立门禁。无Fail/缺陷关联。QA Agent。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 最终 435 catalog 隔离 clone - 2026-10-11 03:08 Asia/Shanghai¶
- 环境:Ops 的 PG14.24 独立 fault clone
slime_crm_catalog_fault_rehearsal,system 7695078412934166696;QA 仅读本地 Ops 冻结回执,未直接连接 DB。 - 候选:冻结 normalizer d27ff917、importer bb8ce6e5、spec 6d713546、input 1d4d50ea;首次 manifest 3422add2,重入 manifest f44b6bdb。完整 SHA 见本地 QA 报告。
- 范围:最终 435 catalog、49 平台 grant、63 附件 Content 的真实隔离 clone dry-run/execute/reentry/只读聚合与候选时间字段验收。
- 汇总:Pass 8 / Fail 0 / Blocked 0 / Skipped 0。层级均为实际 PG 隔离 clone 收据复核;无 Fail,无缺陷关联。QA Agent。
| 编号 | 用例与前置/检查点 | 预期 | 实际及证据 | 状态 |
|---|---|---|---|---|
| FF-01 | 冻结输入、新 clone;核 dry-run/manifest | 435 create,旧业务 104 表及序列零变 | 104 表 1,430,186 行/schema/序列不变;manifest 3422add2;dry-run PASS | Pass |
| FF-02 | 同 manifest 执行首次真实导入 | COMMIT/postcommitVerified,435 新建,无旧数据漂移 | exit0,created435/skipped0/outside128;旧业务/Task/财务/Candidate 非授权列保护通过;execute result SHA 94fdab9e | Pass |
| FF-03 | 新 manifest 独立重入 | 435 全 skip,再执行不重复建实体 | 104 表 1,430,621 行/序列零变;created0/skipped435/postcommitVerified;reentry result SHA 4bfd54e5,终端断连后只读恢复、未重跑 | Pass |
| FF-04 | 实库 Content 状态/关系/时间 | 63 Content、62 发布/1 草稿、4 NULL 关联、时间精确 | READ ONLY 聚合均符合;188 Content 时间、128 Meeting 时间、49 原 Profile 时间精确;候选 a8111cb MeetingDateTimeField 64/128 +08 往返 PASS,结果 SHA 7e6e3ee0 | Pass |
| FF-05 | 63 个附件对象及受限 PDF 证据 | DB 稳定源 URL/字段与冻结输入一致,size/SHA 受证据绑定 | 63 对象字段精确;PDF 63/63 共 57,908,817 bytes;fileSha 是证据,不是 DB 列;未声称逐个首跳 302 | Pass |
| FF-06 | 49 人平台 grant 只读聚合 | 授权 49、未授权 0、grant ledger49 | authorized/activeUnlocked/granted/global 均 49、unauthorized0;grant ledger49;非授权列保护通过 | Pass |
| FF-07 | ledger/run 与源行覆盖 | 首次 ledger484/run1,重入后 ledger484/run2;覆盖闭合 | 实际 ledger484、grant49、run2,无第二次实体/grant;563=435 included+64 represented+64 real pending | Pass |
| FF-08 | 执行范围和资源 | 仅隔离 clone,生产无 DML/tag/deploy | 首次 128.2943s/RSS2641556KiB;重入 260.7761s/RSS2646704KiB;生产未执行 | Pass |
证据:outputs/production-release-preparation-20261010/qa-catalog-final-files-receipt.md 与 Ops catalog-rehearsal-progress.md 03:06 节;组合私有收据 4232 bytes/SHA ba0c90eb48adb68709f5e655007208581100f8b4cd4905ceeab16cecc24caeb9。QA 未远端重算私有 SHA,也未直接查询 DB。最终 435 条 catalog 隔离 clone 门禁有界 GO。
风险/下一步:生产仍需 fresh backup、冻结输入/目标前像、生产 dry-run 与精确 manifest gate;本轮 GO 不授权生产 importer DML、tag 或 deploy。represented64 与 real pending64 须分别保持,4 个 Meeting NULL 关联保持 pending。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 生产 catalog 首次冻结失败与人工恢复 - 2026-10-11 03:50 Asia/Shanghai¶
- 环境:生产 writer host/PG14.22 原集群;Ops 本地冻结事件及只读恢复回执。QA 仅收据复核,未直接操作生产 API/DB/容器。
- runId:catalog-prod-20261011-1791659970540;合同 SHA 10d3b3bb1c9de612cb0d8e4c4e925ab9f4a9a5160d5ac76d8f3a1e826801871a。
- 汇总:Pass 4 / Fail 2 / Blocked 1 / Skipped 0。层级:生产运行态收据复核。QA Agent。
| 编号 | 用例/前置与检查点 | 预期 | 实际与证据 | 状态/缺陷 |
|---|---|---|---|---|
| PFI-01 | 首次 freeze,核四 writer 静止 | 全部停稳才进备份 | 03:42:13.668 beat/Web 已停;recorder Python PID1 未处理 TERM,Docker stop 30s 超时;worker 未停,freeze 未完成 | Fail;recorder TERM 处理缺陷 ID 待建 |
| PFI-02 | 原 PG READ ONLY/本 run 产物 | 未冻结不启动 backup/dry-run/execute | 03:46:33 cluster7615449968045083019;run backend0、ledger/run 不存在、exact-run 容器0;无 native backup/dry-run/execute | Pass |
| PFI-03 | 自动恢复适配器,核 stop 错误 | 部分停止后自动恢复 | Docker 小写 error: no such object 未匹配旧适配器的大写预期,自动恢复失败;restored.json 不存在 |
Fail;大小写错误匹配缺陷 ID 待建 |
| PFI-04 | 人工恢复原四 writer | 同原容器/镜像恢复运行 | Web/beat 03:46:48 复起,worker 原样运行;recorder 授权一次 SIGINT exit130 后 03:47:35.804 同原容器复起;03:48 四者 Running/同镜像 | Pass |
| PFI-05 | 恢复后公开版本 GET/旧 watchdog | 版本入口响应,旧 watchdog 退出 |
/v1/version/ HTTP200/code200/1.20.0;旧 watchdog 精确身份核对后一次 TERM、退出已证实;不代表业务链路全通 |
Pass |
| PFI-06 | 失败事件持久化与旧 run 边界 | 不伪报自动恢复或复用旧 run | 原日志、两份私有 fsync 恢复收据保留;旧 executor/watchdog 已退出,旧 run 未重启;终态 FAILED_NO_IMPORT_MANUALLY_RECOVERED | Pass |
| PFI-07 | MQ 回调与完整业务恢复 | 独立确认回调排空/业务链路 | Ops 未验证 MQ callback drain;公开版本 GET 不足以替代 | Blocked;待 Ops 独立核验 |
证据:outputs/production-release-preparation-20261010/qa-production-catalog-freeze-incident.md、Ops production-catalog-freeze-incident-20261011.md;远端私有回执由 Ops fsync,QA 未直接读取。两项 Fail 保持真实失败,独立缺陷记录待主统筹安排。没有生产导入或 ledger/run;旧 run 永不重启。下一次须修复 recorder 信号处理与错误匹配,使用新合同、新 run 重新审查冻结门禁。无提交/推送/部署。
RA Updated by Redmine Admin about 1 month ago
QA 测试结果 - 生产 catalog r2 数据与恢复门禁 - 2026-10-11 04:02 Asia/Shanghai¶
- 环境:生产 PG14.22 与四原 writer;QA 仅读 Ops 本地冻结收据,未直接连接生产 DB/API/容器。
- runId:catalog-prod-r2-20261011-1791661900000;合同 SHA 9894120c9a337b56505811e0d5e9b7163ae184b73d9dd2621cfa058d73c51936;新生产 manifest SHA c8976c752d9b0a5f4c5bc2786ee98391a88d0704b80512bdbd3e2c1fc7cf29b4。
- 层级:生产数据/运行态收据复核。汇总:Pass 9 / Fail 0 / Blocked 0 / Skipped 0。QA Agent。前次冻结失败 journal #95 保留原 Fail。
| 编号 | 用例与前置/检查点 | 预期 | 实际/证据 | 状态 |
|---|---|---|---|---|
| PR2-01 | 新 signal/absent 修复候选 | 两根因有针对性验证 | Ops supervisor13+DBadapter4=17 tests PASS;Backend 两处 diff 静态复核 PASS | Pass |
| PR2-02 | 四 writer 停稳后同 run native backup | 新鲜 PG14 dump 可追溯 | 冻结后 native backup exit0,217328407 bytes/1068 TOC,SHA 1a0e0dfe4fd6ba951e2a04ad53968761c9058e55448a32f254d765e4b97a0c49 | Pass |
| PR2-03 | 生产 READ ONLY dry-run | 新 manifest 与输入/目标一致,435 create | manifest c8976c75;input 7a9d7c68;435create/0update/0skip/outside128;104表1430256旧行97序列基线 | Pass |
| PR2-04 | WAIT_ROOT_RELEASE 精确授权后 execute | exact run/input/manifest 一次性放行 | 主统筹单独发布未过期 root release;一次 execute-started,无重复执行/生产全量重入 | Pass |
| PR2-05 | 冻结 importer 事务/提交后保护 | COMMIT_verified,新建435,旧业务基线稳定 | committed/postcommitVerified true,created435/skipped0/outside128;104表保护事务内及提交后通过;importer-result SHA980b7b8a | Pass |
| PR2-06 | Content/附件/时间独立只读后验 | 63 Content 与冻结输入一致 | 62published/1draft/4meetingNULL;附件引用及188Content/128Meeting/49Profile时间均匹配 | Pass |
| PR2-07 | 49平台grant及账本 | 授权49、未授权0、账本闭合 | authorized/activeUnlocked/granted/globalGranted均49;ledger484,grant49 | Pass |
| PR2-08 | 独立主库结论/进程退出 | COMMIT结论明确,writer恢复前后端退出 | primary resolve COMMIT_VERIFIED/verificationError null;backendExited/importerExited true、cancelled[];transaction-outcome SHA13f103ff | Pass |
| PR2-09 | 四原writer恢复与公开版本入口 | exact IDs/image Running,旧接管者退出 | 04:00四原writer Running、同ID/image;executor/watchdog exited;公开GET /v1/version/ HTTP200/code200/1.20.0;restored SHA bfaa5dc7 | Pass |
Ops 最终终态:03:59:20.056 COMMIT_VERIFIED 后 RESTORED。证据:outputs/production-release-preparation-20261010/qa-production-catalog-r2-data-gate.md 及 Ops production-catalog-r2-progress.md。QA 未远端重算私有收据 SHA、未直接扫库。数据与恢复门禁有界通过;MQ callback drain 和微信/BFF 端到端未验证,生产 BFF tag/deploy 暂缓。无本轮 Fail/缺陷;前次 journal #95 两项 Fail 不覆盖。
RA Updated by Redmine Admin 29 days ago
QA 测试结果 - 小程序1.0.6生产候选公开读链路 - 2026-10-13 14:29 Asia/Shanghai¶
- 环境:生产BFF
https://mp-api.mindsetech.com;Mini本地 HEAD153aeb86feef7826c90f968f189bd0cf97c3748d、tagv1.0.6指向该提交;BFF源候选93f78358326741f2e2af8d38851ce4df16ec8d95。生产robot2开发候选上传由主统筹/CI报告成功,尚未审核或正式发布。 - 层级:公开 HTTPS GET 小分页 smoke 与发布门禁。QA 使用系统证书信任链,无
-k,所有成功请求ssl_verify_result=0。QA主机经回环代理访问;一次绕开代理的直接DNS在5秒超时,故直连路径未由QA证实。没有私有API/微信/通知/DB写入。 - 汇总:Pass 6 / Fail 0 / Blocked 3 / Skipped 0。QA Agent。
| 编号 | 用例/检查点 | 预期 | 实际/证据 | 状态 |
|---|---|---|---|---|
| MP106-01 | GET /health/live;标准TLS | 200/status ok | HTTP200、verify0、status=ok | Pass |
| MP106-02 | GET /health/ready | 200且channelDb/NDB均up | HTTP200、verify0、status=ok/channelDb=up/ndb=up | Pass |
| MP106-03 | GET /api/v2/meetings?page=1&pageSize=5 | 分页数组、基本DTO类型有效、无500 | HTTP200、verify0、items5/total64;ID/title/起止时间/experts类型校验true | Pass |
| MP106-04 | GET /api/v2/catalog/topics?page=1&pageSize=5 | 分页数组、基本DTO类型有效、无500 | HTTP200、verify0、items5/total155;ID/name/关联数组类型校验true | Pass |
| MP106-05 | GET /api/v2/catalog/experts?page=1&pageSize=5 | 分页数组、基本DTO类型有效、无500 | HTTP200、verify0、items5/total49;ID/displayName/meetings/publishedAt类型校验true | Pass |
| MP106-06 | GET /api/v2/catalog/content?page=1&pageSize=5 | 分页数组、基本DTO类型有效、无500 | HTTP200、verify0、items5/total62;ID/title/attachments/publishedAt类型校验true;未访问PDF | Pass |
| MP106-07 | 生产通知/MQ端到端 | 配置可用并证明投递 | Notify/MQ尚未配置;QA未触发消息。需Ops/责任Agent配置后独立验收 | Blocked |
| MP106-08 | 微信真机登录/业务流 | 真机账号完整链路有本轮实证 | 本轮无真机/账号实证;公开GET不替代认证与业务流。需真机验收 | Blocked |
| MP106-09 | 1.0.6审核/正式发布 | 现网用户可用1.0.6 | 仅robot2开发候选上传成功;未审核/正式上线,现网仍1.0.5。需微信平台审核与正式发布回执 | Blocked |
证据:outputs/mini-program-production-release-20261013/qa.md。curl仅执行每个公开路径一次;发现回环代理后额外做过一次直连health,DNS超时,无重复扫描。生产BFF基础公开读链路有界通过;不将ready200或开发候选上传称为微信正式发布。无Fail/缺陷关联。
RA Updated by Redmine Admin 28 days ago
QA 测试结果 - 生产BFF Notify配置后公开读复测 - 2026-10-14 09:31 Asia/Shanghai¶
- 环境:生产
https://mp-api.mindsetech.com,目标IP175.102.135.237,BFF源候选 exact93f。使用直IP+域名SNI/Host、正常TLS证书和主机名校验,无-k、无代理;每个公开路径仅GET一次,ssl_verify_result=0。QA未操作源码、数据库、浏览器登录、微信或邮件。 - Ops/主统筹转述:Notify URL/key已配置且一次BFF重启后持久网络接通,Notification服务未重启、无积压/发信;本轮QA没有直接验证通知原生鉴权与投递。
- 层级:生产公开接口小分页及发布门禁复测。汇总:Pass 6 / Fail 0 / Blocked 3 / Skipped 0。QA Agent;保留前轮journal #101。
| 编号 | 用例/前置与检查点 | 预期 | 实际与证据 | 状态 |
|---|---|---|---|---|
| MP106-R2-01 | GET /health/live;strictTLS | HTTP200/statusok | 直连175.102.135.237、verify0、HTTP200、status=ok | Pass |
| MP106-R2-02 | GET /health/ready | HTTP200、channelDb/NDB up | 直连、verify0、HTTP200、status=ok/channelDb=up/ndb=up | Pass |
| MP106-R2-03 | GET /api/v2/meetings?page=1&pageSize=5 | 分页和基本DTO有效 | HTTP200、items5/total64;ID/title/startsAt/endsAt/experts类型校验true | Pass |
| MP106-R2-04 | GET /api/v2/catalog/topics?page=1&pageSize=5 | 分页和基本DTO有效 | HTTP200、items5/total155;ID/name/关联数组类型校验true | Pass |
| MP106-R2-05 | GET /api/v2/catalog/experts?page=1&pageSize=5 | 分页和基本DTO有效 | HTTP200、items5/total49;ID/displayName/meetings/publishedAt类型校验true | Pass |
| MP106-R2-06 | GET /api/v2/catalog/content?page=1&pageSize=5 | 分页和基本DTO有效 | HTTP200、items5/total62;ID/title/attachments/publishedAt类型校验true;未访问PDF | Pass |
| MP106-R2-07 | Notify/MQ原生鉴权、发信与送达 | 配置后真实链路有证据 | Ops报告URL/key与网络就绪,但本轮未触发消息;原生鉴权、MQ生产契约及收件箱送达待Ops/Backend验证 | Blocked |
| MP106-R2-08 | 微信真机登录/业务流 | 真机流程有本轮实证 | 无本轮真机/账号/流程回执;公开GET不替代认证与业务验收 | Blocked |
| MP106-R2-09 | 1.0.6审核/正式发布 | 现网可用1.0.6 | 无审核通过或正式上线新回执;开发候选上传不足以证明现网切换 | Blocked |
证据:outputs/mini-program-production-release-20261013/qa.md 的2026-10-14追加节。所有成功GET remote_ip=175.102.135.237、ssl_verify_result=0,四个列表本地jq类型检查true。此前journal101经回环代理,本轮独立直IP+SNI消除了该QA主机的代理路径限制。ready200不证明Notify/MQ、真邮件或真实微信。
RA Updated by Redmine Admin 28 days ago
QA 测试结果 - 小程序BFF MQ hotfix与原四事件补偿 - 2026-10-14 10:19 Asia/Shanghai¶
- 环境:生产 BFF
https://mp-api.mindsetech.com,目标IP175.102.135.237。Ops immutable hotfix index/image SHA6d0d56eb86fa70d14aa17781597a894b8f82d5de92897afd1f2d0af0ee7a436a,deployment qxzcxklhsacywfhw51yt4hba finished。QA仅独立执行六个公开GET;DB/MQ/容器/补偿数据取自Ops冻结报告,未直接操作。 - 原失败历史保留:先前 exact93f 的四个 naive occurredAt 事件被discard,processed0;队列无DLX。新结果不改写原失败或journal #102的当时Blocked。
- 层级:Ops生产收据复核+QA公开HTTPS小页回归。汇总:Pass 10 / Fail 0 / Blocked 2 / Skipped 0。QA Agent。
| 编号 | 用例/检查点 | 预期 | 实际/证据 | 状态 |
|---|---|---|---|---|
| MP106-MQ-01 | hotfix制品与实际部署 | 受审修复部署、原4payload可解析 | Ops两文件/21focused+lint/build PASS;新image/healthy容器绑定;deployed schema原4接受4/4 | Pass |
| MP106-MQ-02 | 原四事件补偿 | 原4精确处理,无多发/丢失 | Ops一次publish4confirm/0return,processed恰4;两集合SHA同为821e1fc12f8acf4222a42de9e7d20d85737e9f827c38a61f7c215aca040c0be2;discard/retry0 | Pass |
| MP106-MQ-03 | publisher/队列稳定 | 恢复发布且无积压 | Ops仅同镜像worker重建,pending0/published4/total4;queue ready0/unacked0/consumer1,其他组件未重启 | Pass |
| MP106-MQ-04 | Notify基础配置保持 | 原服务稳定,BFF配置可用 | Ops Notify原ID/start/image/healthy不变;AUTH/分钟fallback/URL检查通过;无POST/发信 | Pass |
| MP106-MQ-05 | GET /health/live | strictTLS 200/statusok | QA直IP+SNI、verify0、HTTP200/statusok | Pass |
| MP106-MQ-06 | GET /health/ready | strictTLS 200且channelDb/NDB up | QA verify0、HTTP200/statusok/channelDb=up/ndb=up | Pass |
| MP106-MQ-07 | GET /api/v2/meetings?page=1&pageSize=5 | 分页DTO有效 | QA HTTP200、items5/total64、基本类型检查true | Pass |
| MP106-MQ-08 | GET /api/v2/catalog/topics?page=1&pageSize=5 | 分页DTO有效 | QA HTTP200、items5/total155、基本类型检查true | Pass |
| MP106-MQ-09 | GET /api/v2/catalog/experts?page=1&pageSize=5 | 分页DTO有效 | QA HTTP200、items5/total49、基本类型检查true | Pass |
| MP106-MQ-10 | GET /api/v2/catalog/content?page=1&pageSize=5 | 分页DTO有效 | QA HTTP200、items5/total62、基本类型检查true;未访问PDF | Pass |
| MP106-MQ-11 | 真实邮件送达 | 实际投递/收件回执 | 未发测试邮件、无收件箱或供应商送达证据;Notify配置和outbox0不足以证明 | Blocked |
| MP106-MQ-12 | 微信真机/审核/正式发布 | 完成真机与1.0.6现网验收 | 管理员域名二维码待完成保存,真机/审核/正式发布无证据;开发版1.0.6可见,现网仍1.0.5 | Blocked |
QA六个GET均一次、remote_ip=175.102.135.237、TLS verify0,使用--noproxy '*' --resolve保留域名SNI/Host,未用-k。证据:outputs/mini-program-production-release-20261013/qa.md最终节、Ops release.md的10:15 hotfix闭环与preflight.md补充。Ops原四processed集合SHA与队列/worker状态不是QA直查。hotfix两文件尚未提交;微信域名保存/正式发布和真邮件继续独立门禁。