QA验收 #30
open银联开始支付手机号可选及本批收款快照修复
0%
Description
来源任务:01a181d7-ab0d-7940-a9ea-729f930f790b。用户确认取消银联开始支付的手机号必填,并处理本次准确28笔中的身份证/国家缺项。代码范围仅后端手机号可选,保留其他校验及phone字段/导出;线上数据仅从匹配主档或可靠历史来源恢复身份证、核实境内账户后补中国,不触发支付,不改金额或状态,不广泛回填。共享证据:outputs/payment-phone-optional-20261028/index.md。开发自测后由独立QA按影响矩阵验收并逐项记录,生产数据操作与代码发布分别取证;本记录创建时尚未宣称任何测试或修复完成。
RA Updated by Redmine Admin 14 days ago
#30 QA评审与结果记录¶
2026-10-28,Asia/Shanghai。主任务 01a181d7-ab0d-7940-a9ea-729f930f790b,Redmine #30。正式放行后,本地增量QA 5个测试方法Pass/0 Fail,另生产数据修复源收据评审 DATA-01 Pass;按层级合计6条结果,无待执行必需项。复用开发自测中未重跑的37项,不计QA新增Pass。代码未部署,不宣称线上手机号阻断已解除。
DATA-01:精确生产数据包提交与后验源收据 — Pass(收据评审层级)¶
- manifest:
0c74101ba5005f6ecbfb8225ddfacb82d6936e9e6805e7c1503e12674c1ad971。ops-execution-package.json、ops-write-release.json、state、readback及final均相同;发布包的executor/transport/apply/compiler/源SQL/plan/guard hash与精确release对应字段相同。 - Ops系统修复,唯一生产writer;state显示COMMIT confirmed,2026-10-28 18:09:38 Asia/Shanghai完成。
ops-readback-receipt.json为随后独立READ ONLY回查并ROLLBACK,所有checks为true、sqlIdle=true。本QA未执行该事务或回查。 - QA实际复算
ops-final-receipt.json列出的6个公开证据文件SHA,全部一致;逐条解析脱敏data-preview.md,28个唯一成本ID、19笔有变化、12个identify_code/9个bank_country、14笔仍有阻断均与收据一致。仅project_task_costs.payment_info的上述两键获准变更,合计21字段;不改phone。 - Ops readback证明28行完整postimage符合冻结计划,18来源主档未变,其他成本、相关Task及全部支付账户主档保全。状态、金额、币种、付款人/时间、冻结标记、时间戳未改变;QA依既有脱敏源收据判定,不访问受限前像或PII,也不冒称逐个身份证明文独立核验。
- 未触发真实付款/通知/业务事件、不冒用员工Activity;没有主档更新、部署、commit/push或额外数据库备份。受限系统修复审计文件及权限由Ops收据确认,QA未打开这些受限文件,亦不把其hash当成自己已逐字复算。
剩余项及措辞澄清¶
- 剩余14笔缺可靠身份证,其中6笔也缺国家依据;集合重叠,不能相加为20笔。
- 这14笔中的6550、6596、6606、6639、6645已按可靠依据补国家,但仍缺身份证;不能笼统称“剩余14整行均保持原样”。其余9笔未变,未解决字段不强填。Ops已定向更正最终机器收据与交付文字;只改描述,不改变原COMMIT/readback。最终版证据链已再次核对,无需重复生产回查。
- 另外14笔按“phone可选”的目标规则已无本次身份证/国家阻断;该代码尚未部署,不能据此说线上已允许空phone开始支付或原100笔全部可支付。不调用真实开始支付来验证。
源证据与hash¶
| 文件(同目录) | SHA256/用途 |
|---|---|
| ops-final-receipt.json |
25549ad242fd7a18e2498799869aaf101ef64a218de6f174a977d7c44b4dac50;最终脱敏来源(剩余缺项措辞修订,原事务/回查未变) |
| ops-readback-receipt.json |
bdaaff5cfe4ec6db1e7c0289bec451d0526b0aa4aa591230534b3e335cc2048d;独立后验 |
| ops-state-0c74101ba500-attempt1.json |
eb324152eb9598828a6b453ed8ba34e49b70cc2ddf72736731ae3d9e270288af;COMMIT状态 |
其他精确公开证据链沿ops-final-receipt.json.systemRepairAudit.publicEvidenceSha,本QA实际复算一致。受限readback/transaction hash仅沿Ops公开收据引用,不在QA重新读取。
QA本地候选、隔离与实测¶
-
projects/ndb/backend,分支bugfix/payment-phone-optional,HEAD239804a8bff97192bd75d99fc60819911e69e907。QA执行前后业务SHA0785bdea81286a9c1835b602e2e4b7c80c3aebf6266f00467bc1e6950db4d462、测试SHA89e3092f8b32d37b09cc73a1bbbad7a79e16310edacbc8e9f32b904aae79a992均匹配放行候选;仅一行业务变化(银联必填移除phone),未改事务/锁/权限/schema/导出实现。 - 审阅
run-isolated.py:environ.Env.read_env在settings导入及测试执行阶段均禁用;明确--engine sqlite默认选择内存库,实际日志为file:memorydb_default?mode=memory&cache=shared;locmem缓存/邮件,MQTT关闭,Python socket/HTTP/SMTP/Celery外发入口拒绝。没有启动PG、读取业务凭据、触发通知或真实付款。 - 激活方式
conda run --no-capture-output -n crm_backend python .../run-isolated.py,设置PYTHONDONTWRITEBYTECODE=1及仅QA目录PYTHONPATH。选择4个新增影响链测试方法和QA额外XLSX roundtrip测试类;详见qa-incremental-sqlite-r1.log。命令exit0,Ran 5 tests in 0.149s / OK,内存测试数据库已销毁。 - 使用真实Django APIClient路由、ORM和SQLite事务;合成账号以force_authenticate进入财务角色,不借用真实账号,不宣称验证了登录/凭据流程。外围阻断是Python级护栏,不是操作系统网络沙箱。
| QA结果ID / impact映射 | 实际执行方法及操作/预期 | 实际与状态 |
|---|---|---|
| QA-01 / I01 P01–P03 |
test_unionpay_optional_phone_single_real_route_preserves_snapshot;单笔真实路由,缺键/null/空串/空白/历史mask/原非空phone |
HTTP200/code200;processing且冻结、主体正确、paid_at空、Task仍unpaid、审计+1,phone及完整payment_info原样;Pass |
| QA-02 / I02 P04 |
test_unionpay_optional_phone_batch_real_route_preserves_each_snapshot;同批缺键/null/空串 |
HTTP200/code200,返回3条;逐笔processing/快照原形/冻结,审计+3;Pass |
| QA-03 / I02 P05 |
test_optional_phone_does_not_allow_other_incomplete_batch_fields;合法空phone成本与分别缺身份证/账号/户名/银行/国家/company_payment成本混批 |
6个子场景仍PAYMENT_SNAPSHOT_INCOMPLETE;两笔均unpaid、未冻结、主体空、快照/Task不变且审计零增加;Pass
|
| QA-04 / I07 P10 |
test_unionpay_optional_phone_frozen_export_never_fills_from_master;缺键/null/空串/有值phone冻结导出 |
原空值保持空,非空保留;未出现主档哨兵phone;Pass |
| QA-05 / I07 P10 | QA新增PaymentPhoneExportQa.test_unionpay_optional_phone_xlsx_roundtrip_preserves_columns;相同4形态生成工作簿,BytesIO保存并重新load |
四种均25列、整行与序列化前值一致(Excel空串标准化为空单元格),Task/账号/户名/身份证/国家位置正确、phone仍第7列,原快照不变、无主档回填;Pass |
上表5是测试方法数;6种单笔输入、3笔批量、6个拒绝变体和导出子场景不重复加成额外Pass。DATA-01为另一层的源收据评审,生产数据修复与本地代码验证各自有边界,不把它计为5个本地测试之一。
开发证据复用与覆盖结论¶
已核对impact-regression.md I01–I07/P01–P10与实际调用链、开发原始green-sqlite-r1.log:41 tests/OK。4个影响链方法在本QA再次执行,其余37项只复用,未重跑或计QA新增Pass。业务及依赖场景未变,复用适用:
- I03/P06:前端单/多笔契约不变,本地两条真实API路由响应证明接口层;没有页面变更,不新增整套前端浏览器验收,不宣称UI已实测。
- I04/P07:开发同候选的角色检查、完成时间与冻结主体、撤回原因及审计、成本编辑/删除锁、Task/会议guard;源逻辑未变,可复用。
- I05/P08:旧unpaid→paid直付与取消已付;I06/P09:16项收款主档/引用及普通编辑防脱敏回写测试,同候选通过且本次未改对应路径,可复用。
- I01/I02相邻缺金额/币种/付款主体、其他支付类型及必填脱敏拒绝沿同次开发支持测试复用;QA-03独立核对改变phone条件后整批失败语义。
- 不沿用无关#13或其他任务的Pass;旧#102用例只是源码/测试来源,不被计为本轮线上验收。
纯格式收尾适用性¶
Backend在本QA测试结束后串行Black格式化测试单文件,见format-receipt.json:测试SHA变为0fac5c1a76f94a32abf82992a3dd379e7bbdc639bd73f33110f04ec521e8f023,前后AST等价,业务SHA未变。QA独立复算当前测试文件SHA及无位置属性AST摘要1a10317f0ef4b0691f232955f867393e65ff2984e5321dade57ff1f8a07dd90b与该收据一致;因此复用刚通过结果,不为纯格式重跑5或41项。Backend Black/Ruff/diff-check成功沿原收据引用;QA执行前后git diff --check通过,不冒称QA另跑lint。AOCI最终语义维护尚有authoring_required,按Backend交接另行跟进,不作为本地支付业务测试已运行的证据。
限制、交付与回写¶
- SQLite模型测试不证明PG行锁/并发/迁移、共享Redis、多进程或真实外部支付;本次未改锁或schema,不能虚称新增PG验证。未测浏览器、桌面Excel/银行导入、真实登录/到账/通知。工作簿验证到openpyxl保存重读层级。
- 数据包残余14笔资料不足与phone可选代码未发布分别记录,资料缺口见
remaining-data.md;普通QA/Redmine报告只列ID/数量,不复制姓名/证件/账号。phone规则在本地成功不等于线上已解除或所有100笔已成功。 - 本QA只写当前outputs的qa预检、测试脚本/日志和本记录;未写产品文件、受限PII、凭据、业务DB、浏览器、分支、commit/push/部署。生产修复由Ops独立授权执行,无再次生产探针。本地fixture库已销毁。
- 以上6条分层结果及37项复用,将一次逻辑批次写回#30并全文读回,收据单独记录journal与hash;此处不另创建issue或提前宣称写回成功。
新增QA证据:qa-incremental-sqlite-r1.log SHA 28803f933b03e326bbfc3808c195ac87890fb496fd90d3721b7a37af958a9cb8;qa_payment_phone_optional.py SHA 4d1866890f41b58bbacf518c3f54488a394d6705abad6c64e01d8b60d3b11334;原runner SHA 685017c91bb63547fc38f286c3935f8fb719a904f49a75045421b589ba7d8e4e。
RA Updated by Redmine Admin 14 days ago
#30 AOCI收尾补记(不新增测试结果)¶
AOCI收尾状态补记(不新增测试轮次)¶
原测试结果已在#30 journal306一次写入并全文读回,原报告SHA 516728e566237da181e4ddd4cfb0db7709a5d116c88dcee141ca12755ea53c48,原回写收据qa-writeback-receipt.json保留。上文authoring_required为当时状态,现由本补记替代,不改原用例结果或计数。
已消费Backend aoci-receipt.json及delivery附录:本次两条Entry一次Applied(applied=2、remaining=0、aligned=true),Verify/Check均exit0、structure_valid/governance_aligned=true;Guide complete=true、next_action=none、executable_targets=0。QA离线核对当前aoci.code.txt/.aoci/baseline.json与收据托管hash匹配,业务及格式后测试文件hash仍与验收候选一致,仅托管索引/基线变化,沿用既有5项QA和开发证据,无需重测。
本次治理维护已关闭;此前完整认知Attestation Schema缺口独立保留,不把治理对齐称为完整认知验证通过。Backend维护改动保留,QA未操作AOCI写入或产品源码。该补记只更新交付元数据,不新增Pass,不改变线上phone规则尚未部署、残余14笔资料缺口及SQLite验证边界。
RA Updated by Redmine Admin 14 days ago
#30 v1.20.11生产发布增量QA结果¶
2026-10-28,Asia/Shanghai;主任务01a181d7-ab0d-7940-a9ea-729f930f790b,Redmine NDB #30。用户明确允许commit/push及本次立即上线豁免,Operations唯一发布writer。Backend v1.20.11实际生产运行收据评审通过;生产容器合成纯校验smoke 8 Pass / 0 Fail。 本QA未重复生产版本、CI、数据库、业务API或浏览器探针,没有执行付款。
候选身份、集成与证据复用¶
- 最新生产基线
030f88e4675812268f300215abb673c60d2ddb92;source fixb7eca908ce7bc61117514ecb4b2a863e3cae26db。正常双父merged47e9d74ef24fd3417ce0cd5cacd8ce283a3b00e,正式release816afdc04c2b3f418c0798f0e195cd00c0207d8b,tagv1.20.11。Ops push收据确认remote main与正式tag,未push source或preview。 - QA已离线用本地Git对象核对相对生产基线的实际差异为获准7文件:两支付源码/测试、AOCI code索引/基线、api版本、.cz.toml、CHANGELOG;其他生产对象未混入本次差异。两支付文件正式blob实际SHA与QA一致:业务
0785bdea81286a9c1835b602e2e4b7c80c3aebf6266f00467bc1e6950db4d462,格式后测试0fac5c1a76f94a32abf82992a3dd379e7bbdc639bd73f33110f04ec521e8f023。 - 已有开发41项、QA独立增量5项及未重跑37项开发方法,沿#30 journal306及原
qa-review.md/日志复用,不新增相同Pass或再跑整套。两业务blob完全一致,版本、merge、AOCI窄条目/基线及metadata变化不改变相关支付逻辑/接口/schema/依赖。纯格式AST等价、AOCI窄收尾沿format/aoci收据及journal307;不把治理对齐当完整认知验证。 - 发布无模型、迁移或依赖变化,migrationDelta=0;不额外造迁移验证或备份门禁。本地SQLite原验证边界保持,不升级为PG锁并发实测。
构建、触发与真实运行的对应¶
- CNB
cnb-d6k-1k611he3k,release SHA/tag匹配,pipeline success;版本镜像push、production标签push及生产deploy trigger三阶段均success,staging两个阶段skipped。仅这些CI状态本身不足以证明实际运行。 - Ops随后在2026-10-28 18:44:30 +08:00核对精确生产Web服务:容器启动18:41:23,公开GET
/v1/versionHTTP200、version 1.20.11,容器内部api版本亦一致。 - 实际镜像摘要与CNB版本镜像/production别名摘要一致:
sha256:8c1fa9cc4a6862e51e1f16c928722531cb44a40d36f89408582feca1a856bd46。容器内实际业务/测试/api版本三源码SHA与正式候选一致;QA逐项比对运行/集成/CI原收据,未独立发新请求。 - QA已复算
production-receipt.json.evidence列出的7份源文件hash,全部一致;最终receipt嵌入runtime与原runtime-receipt完整相同。最终生产收据SHA9f8e8c046d29116c58f8a024e7e2f2f48b3595cb35fe20ee5edf3068e167ef64。
本次实际新增生产smoke逐条结果¶
以下由Ops在实际部署容器内调用validate_recipient_snapshot,使用SimpleNamespace/Decimal和内存合成字典,启用数据库连接/网络阻断;不是支付状态API、ORM写入、真实付款或页面验收。QA读取runtime-read.py核对编号与输入/断言,消费runtime-receipt.json原结果,无重新执行。
| 编号 | 合成输入/预期 | 实际 | 状态 |
|---|---|---|---|
| PROD-PHONE-1 | phone缺键,其他银联必填完整;允许且保留缺键 | 校验成功、输入/返回快照原形一致 | Pass |
| PROD-PHONE-2 | phone=null;允许且保留null | 校验成功、快照原形一致 | Pass |
| PROD-PHONE-3 | phone空串;允许且保留空串 | 校验成功、快照原形一致 | Pass |
| PROD-PHONE-4 | phone空白串;允许且不转换 | 校验成功、快照原形一致 | Pass |
| PROD-PHONE-5 | phone合成历史mask;允许且不升级/补造 | 校验成功、原mask保留 | Pass |
| PROD-PHONE-6 | phone合成非空值;允许且原值保留 | 校验成功、原值保留 | Pass |
| PROD-REQUIRED-1 | identify_code缺失;仍拒绝 | ValidationError | Pass |
| PROD-REQUIRED-2 | bank_country缺失;仍拒绝 | ValidationError | Pass |
8项为新增生产纯函数断言,不与原QA5或开发41相加称为生产业务流程通过。公开version、镜像/源码身份属于同一次运行核验的环境断言,不额外虚增业务用例数。
首次目标guard记录runtime-target-guard-attempt1.json为stage=host提前AssertionError、businessWrites=0,原失败保留;Ops执行结果说明先因资源含多个服务拒绝,随后限定精确ndb-server后只进行一次完整运行核验。该目标选择护栏失败不是支付功能Fail,也不被删除或冒称首次探测成功。
资料缺口与未测边界¶
- 此生产运行证据替代journal306/307及旧阶段文档中的“phone可选代码未部署”状态;phone可选校验已在生产源码及内存smoke确认。不表示已为任何真实成本开始/完成付款,也不保证原100笔全部能过其他校验。
- DATA-01已完成19行21字段生产资料修复,沿原独立回读及QA评审,不在本发布再次执行。仍14笔缺可靠身份证,其中6笔缺国家依据;6550/6596/6606/6639/6645虽已补国家仍缺身份证。发布不会取消这些必填或补造资料,缺口名单仍沿
remaining-data.md,本报告不复制PII。 - 真实支付状态API写入、生产fixture、银行导入/到账、通知、浏览器页面/登录均未执行;原本地真实路由/ORM与XLSX保存重读证据按其层级复用。员工手册变更为发布后跟进,不作为新发布前门禁。
- Ops收据:生产DB请求/业务写/fixture创建0、无付款通知、无新增备份,原备份服务未动;运行空间7已结束,Git/环境写停止。原数据修复是此前单独授权的事务,不能把本次发布0数据库写误说为整个任务从未生产修复。
- 当前checkout由Ops保留
bugfix/payment-phone-optional、source HEAD b7eca908…且干净;main/tag已发布。QA未切分支、取凭据、提交推送部署或修改源码,没有重复监控CNB/Coolify,也不修改共享root summary。
源文件与回写¶
发布源均在本release目录:integration-receipt.json、push-receipt.json、pipeline-status.json、cnb-stage-receipt.json、runtime-target-guard-attempt1.json、runtime-receipt.json、production-receipt.json、execution-result.md。Ops为唯一实际环境核验者;QA只消费源收据与本地对象。
本发布增量一次追加#30并全文读回,journal及当前报告hash见qa-writeback-receipt.json。原业务QA journal306、治理补记journal307及历史失败/缺口保留;不重复粘贴整套原结果或启动新验收。