Search
Project
General
Profile
Sign in
Register
Home
Projects
Help
Search
:
NDB
All Projects
NDB
Overview
Activity
Issues
News
Download (19.4 KB)
QA验收 #1
» http-integration-results.json
Redmine Admin
, 10/06/2026 04:31 PM
{
"run"
:
"2026-10-07 isolated real HTTP"
,
"ports"
:
{
"postgres"
:
56488
,
"backend"
:
18000
,
"bff"
:
13000
,
"notificationMock"
:
13001
},
"fixture"
:
{
"meetings"
:
{
"A_started"
:
1
,
"B1_minutes_attend"
:
2
,
"B2_attend_minutes"
:
3
,
"D_paid_no_contract"
:
4
},
"contact_id"
:
2
,
"contract_count"
:
0
},
"checks"
:
[
{
"id"
:
"HTTP-001"
,
"name"
:
"Real NDB+BFF channel readiness"
,
"precondition"
:
"Dedicated ports/databases"
,
"action"
:
"GET /health/ready"
,
"expected"
:
"NDB signed ping and PG both up"
,
"at"
:
"2026-10-06T16:29:26.804Z"
,
"actual"
:
{
"status"
:
"ok"
,
"channelDb"
:
"up"
,
"ndb"
:
"up"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-002"
,
"name"
:
"Synthetic zero-contract empty baseline"
,
"precondition"
:
"Fresh migration and seed"
,
"action"
:
"Read isolated ORM snapshot"
,
"expected"
:
"0 Registration, 0 Tasks, 0 Contracts"
,
"at"
:
"2026-10-06T16:29:26.804Z"
,
"actual"
:
{
"registrations"
:
[],
"tasks"
:
[],
"contract_count"
:
0
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-003"
,
"name"
:
"Anonymous minutes write denied"
,
"precondition"
:
"No JWT"
,
"action"
:
"PUT A minutes"
,
"expected"
:
"401 UNAUTHENTICATED, no mutation"
,
"at"
:
"2026-10-06T16:29:27.556Z"
,
"actual"
:
{
"status"
:
401
,
"data"
:
{
"error"
:
{
"code"
:
"UNAUTHENTICATED"
,
"message"
:
"请先登录"
},
"requestId"
:
"6def3d9e-6172-415e-863e-151132724f73"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-004"
,
"name"
:
"Unbound synthetic JWT denied"
,
"precondition"
:
"User lacks phone/contact"
,
"action"
:
"PUT A minutes"
,
"expected"
:
"403 CONTACT_NOT_BOUND"
,
"at"
:
"2026-10-06T16:29:27.558Z"
,
"actual"
:
{
"status"
:
403
,
"data"
:
{
"error"
:
{
"code"
:
"CONTACT_NOT_BOUND"
,
"message"
:
"请先绑定客户联系人"
},
"requestId"
:
"682e586e-8537-4a7a-95e8-eafc68a29d72"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-005"
,
"name"
:
"Legacy subscription is not reservation"
,
"precondition"
:
"Only old channel subscription seeded"
,
"action"
:
"GET A minutes"
,
"expected"
:
"JSON null, no NDB Task"
,
"at"
:
"2026-10-06T16:29:27.567Z"
,
"actual"
:
{
"reservation"
:
null
,
"taskCount"
:
0
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-006"
,
"name"
:
"A started free minutes-only created"
,
"precondition"
:
"A started,0h,no contract"
,
"action"
:
"PUT A minutes"
,
"expected"
:
"reserved+unified Registration/Task"
,
"at"
:
"2026-10-06T16:29:28.357Z"
,
"actual"
:
{
"id"
:
"1"
,
"meetingId"
:
"1"
,
"clientContactId"
:
"2"
,
"taskId"
:
"1"
,
"status"
:
"reserved"
,
"createdAt"
:
"2026-10-07T00:29:28.409211"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-007"
,
"name"
:
"A same-key retry reuses ids"
,
"precondition"
:
"A reserved"
,
"action"
:
"Repeat PUT same key"
,
"expected"
:
"Same registration/task ids"
,
"at"
:
"2026-10-06T16:29:28.414Z"
,
"actual"
:
{
"id"
:
"1"
,
"meetingId"
:
"1"
,
"clientContactId"
:
"2"
,
"taskId"
:
"1"
,
"status"
:
"reserved"
,
"createdAt"
:
"2026-10-07T00:29:28.409211"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-008"
,
"name"
:
"A authoritative GET preserves server naive microseconds"
,
"precondition"
:
"A reserved after replay"
,
"action"
:
"GET A minutes"
,
"expected"
:
"same ids and exact createdAt string"
,
"at"
:
"2026-10-06T16:29:28.452Z"
,
"actual"
:
{
"id"
:
"1"
,
"meetingId"
:
"1"
,
"clientContactId"
:
"2"
,
"taskId"
:
"1"
,
"status"
:
"reserved"
,
"createdAt"
:
"2026-10-07T00:29:28.409211"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-009"
,
"name"
:
"A concurrent natural retries on real PG"
,
"precondition"
:
"A reserved; threaded real Backend"
,
"action"
:
"6 parallel PUT with distinct keys"
,
"expected"
:
"All same ids and only one Task"
,
"at"
:
"2026-10-06T16:29:28.487Z"
,
"actual"
:
{
"responses"
:
6
,
"registrationId"
:
"1"
,
"taskId"
:
"1"
,
"taskCount"
:
1
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-010"
,
"name"
:
"A minutes-only has no attendance projection"
,
"precondition"
:
"A minutes requested only"
,
"action"
:
"GET A registration"
,
"expected"
:
"JSON null"
,
"at"
:
"2026-10-06T16:29:29.352Z"
,
"actual"
:
null
,
"status"
:
"Pass"
},
{
"id"
:
"HTTP-011"
,
"name"
:
"A absent myMeetings and present myMinutes"
,
"precondition"
:
"A minutes-only"
,
"action"
:
"GET both lists"
,
"expected"
:
"Attendance empty; minutes contains A"
,
"at"
:
"2026-10-06T16:29:29.394Z"
,
"actual"
:
{
"myMeetings"
:
0
,
"myMinutes"
:
1
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-012"
,
"name"
:
"A minutes-only cannot obtain join link"
,
"precondition"
:
"A already started"
,
"action"
:
"GET A join-link"
,
"expected"
:
"visible=false,joinUrl=null"
,
"at"
:
"2026-10-06T16:29:29.483Z"
,
"actual"
:
{
"visible"
:
false
,
"joinUrl"
:
null
,
"reason"
:
"REGISTRATION_REQUIRED"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-013"
,
"name"
:
"A cannot add attendance after start"
,
"precondition"
:
"A started,minutes-only"
,
"action"
:
"POST A registration"
,
"expected"
:
"MEETING_NOT_OPEN without new Task"
,
"at"
:
"2026-10-06T16:29:29.527Z"
,
"actual"
:
{
"status"
:
409
,
"data"
:
{
"error"
:
{
"code"
:
"MEETING_NOT_OPEN"
,
"message"
:
"会议当前不可报名"
},
"requestId"
:
"5f775969-8e2c-48fe-bd92-b16e7b15eb49"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-014"
,
"name"
:
"B1 minutes first while not started"
,
"precondition"
:
"B1 future,0h"
,
"action"
:
"PUT B1 minutes"
,
"expected"
:
"reserved"
,
"at"
:
"2026-10-06T16:29:30.361Z"
,
"actual"
:
{
"id"
:
"2"
,
"meetingId"
:
"2"
,
"clientContactId"
:
"2"
,
"taskId"
:
"2"
,
"status"
:
"reserved"
,
"createdAt"
:
"2026-10-07T00:29:30.412283"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-015"
,
"name"
:
"B1 then attendance shares Registration/Task"
,
"precondition"
:
"B1 minutes first"
,
"action"
:
"POST B1 registration + isolated snapshot"
,
"expected"
:
"same id/task, both flags"
,
"at"
:
"2026-10-06T16:29:30.416Z"
,
"actual"
:
{
"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"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-016"
,
"name"
:
"B1 future join link withheld"
,
"precondition"
:
"B1 both intents before start"
,
"action"
:
"GET join-link"
,
"expected"
:
"visible=false"
,
"at"
:
"2026-10-06T16:29:31.223Z"
,
"actual"
:
{
"visible"
:
false
,
"joinUrl"
:
null
,
"reason"
:
"MEETING_NOT_OPEN"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-017"
,
"name"
:
"B2 attendance first while not started"
,
"precondition"
:
"B2 future,0h"
,
"action"
:
"POST B2 registration"
,
"expected"
:
"confirmed"
,
"at"
:
"2026-10-06T16:29:31.254Z"
,
"actual"
:
{
"id"
:
"3"
,
"meetingId"
:
"3"
,
"status"
:
"confirmed"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-018"
,
"name"
:
"B2 then minutes shares Registration/Task"
,
"precondition"
:
"B2 attend first"
,
"action"
:
"PUT B2 minutes + snapshot"
,
"expected"
:
"same id,task, both flags"
,
"at"
:
"2026-10-06T16:29:31.301Z"
,
"actual"
:
{
"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"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-019"
,
"name"
:
"Both intentions appear in separate lists"
,
"precondition"
:
"A minutes-only,B1/B2 both"
,
"action"
:
"GET both my lists"
,
"expected"
:
"myMeetings=2,myMinutes=3"
,
"at"
:
"2026-10-06T16:29:32.908Z"
,
"actual"
:
{
"myMeetings"
:
2
,
"myMinutes"
:
3
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-020"
,
"name"
:
"Future B1 cancel keeps minutes and Task"
,
"precondition"
:
"B1 future,both"
,
"action"
:
"DELETE registration"
,
"expected"
:
"cancelled;same reserved minutes and ongoing Task"
,
"at"
:
"2026-10-06T16:29:32.989Z"
,
"actual"
:
{
"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"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-021"
,
"name"
:
"Future B1 reattend reuses id/Task"
,
"precondition"
:
"B1 cancelled but future"
,
"action"
:
"POST registration fresh key"
,
"expected"
:
"confirmed,same ids,3 Tasks total"
,
"at"
:
"2026-10-06T16:29:33.910Z"
,
"actual"
:
{
"id"
:
"2"
,
"meetingId"
:
"2"
,
"status"
:
"confirmed"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-022"
,
"name"
:
"Advance only isolated B fixtures to started"
,
"precondition"
:
"B1/B2 future registration complete"
,
"action"
:
"Guarded synthetic ORM time update"
,
"expected"
:
"Only B1/B2 updated"
,
"at"
:
"2026-10-06T16:29:34.732Z"
,
"actual"
:
{
"advanced"
:
[
2
,
3
]
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-023"
,
"name"
:
"Started attendee B1 obtains link"
,
"precondition"
:
"B1 advanced,confirmed"
,
"action"
:
"GET join-link"
,
"expected"
:
"visible=true synthetic invalid-domain link"
,
"at"
:
"2026-10-06T16:29:35.508Z"
,
"actual"
:
{
"visible"
:
true
,
"joinUrl"
:
"https://qa-meeting.example.invalid/join/B1_minutes_attend"
,
"reason"
:
null
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-024"
,
"name"
:
"Started attendee B2 obtains link"
,
"precondition"
:
"B2 advanced,confirmed"
,
"action"
:
"GET join-link"
,
"expected"
:
"visible=true"
,
"at"
:
"2026-10-06T16:29:35.550Z"
,
"actual"
:
{
"visible"
:
true
,
"joinUrl"
:
"https://qa-meeting.example.invalid/join/B2_attend_minutes"
,
"reason"
:
null
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-025"
,
"name"
:
"Started B1 cancel preserves minutes Task"
,
"precondition"
:
"B1 started,both"
,
"action"
:
"DELETE registration + snapshot"
,
"expected"
:
"cancelled and minutes same ids/ongoing Task"
,
"at"
:
"2026-10-06T16:29:35.586Z"
,
"actual"
:
{
"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"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-026"
,
"name"
:
"Cancelled started B1 loses link"
,
"precondition"
:
"B1 cancelled,minutes retained"
,
"action"
:
"GET join-link"
,
"expected"
:
"visible=false,no link"
,
"at"
:
"2026-10-06T16:29:36.486Z"
,
"actual"
:
{
"visible"
:
false
,
"joinUrl"
:
null
,
"reason"
:
"REGISTRATION_REQUIRED"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-027"
,
"name"
:
"Started B1 cannot restore attendance"
,
"precondition"
:
"B1 cancelled after start"
,
"action"
:
"POST attend fresh key"
,
"expected"
:
"MEETING_NOT_OPEN,no extra Task"
,
"at"
:
"2026-10-06T16:29:36.520Z"
,
"actual"
:
{
"status"
:
409
,
"data"
:
{
"error"
:
{
"code"
:
"MEETING_NOT_OPEN"
,
"message"
:
"会议当前不可报名"
},
"requestId"
:
"f261e04e-d31e-4dbc-ae31-145be5e9c02f"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-028"
,
"name"
:
"Started B1 repeated minutes retained"
,
"precondition"
:
"B1 cancelled attendee,minutes active"
,
"action"
:
"PUT minutes fresh key"
,
"expected"
:
"same reserved id/task"
,
"at"
:
"2026-10-06T16:29:37.344Z"
,
"actual"
:
{
"id"
:
"2"
,
"meetingId"
:
"2"
,
"clientContactId"
:
"2"
,
"taskId"
:
"2"
,
"status"
:
"reserved"
,
"createdAt"
:
"2026-10-07T00:29:30.412283"
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-029"
,
"name"
:
"Started B2 cancel preserves same minutes Task"
,
"precondition"
:
"B2 opposite order"
,
"action"
:
"DELETE registration"
,
"expected"
:
"cancelled,same minutes id/task"
,
"at"
:
"2026-10-06T16:29:37.390Z"
,
"actual"
:
{
"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"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-030"
,
"name"
:
"All free Tasks remain zero and unique"
,
"precondition"
:
"A/B1/B2 complete"
,
"action"
:
"Read isolated snapshot"
,
"expected"
:
"3 registrations,3 unique Tasks,0 contracts,all prices0"
,
"at"
:
"2026-10-06T16:29:37.464Z"
,
"actual"
:
{
"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
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-031"
,
"name"
:
"Synthetic paid no contract rejects without mutation"
,
"precondition"
:
"D synthetic1h,no contracts"
,
"action"
:
"PUT D minutes"
,
"expected"
:
"NO_ACTIVE_CONTRACT,still3 Tasks"
,
"at"
:
"2026-10-06T16:29:38.248Z"
,
"actual"
:
{
"status"
:
409
,
"data"
:
{
"error"
:
{
"code"
:
"NO_ACTIVE_CONTRACT"
,
"message"
:
"当前客户暂无有效合同,请联系客户经理开通后再报名"
},
"requestId"
:
"e5e32c49-8b3e-48f0-ad21-a43a50da7cde"
}
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-032"
,
"name"
:
"Real PG refusal outbox durable and deduplicated"
,
"precondition"
:
"D denied"
,
"action"
:
"Repeat rejection+PG SELECT"
,
"expected"
:
"one pending row,not reservation"
,
"at"
:
"2026-10-06T16:29:39.079Z"
,
"actual"
:
[
{
"meeting_id"
:
"4"
,
"state"
:
"pending"
,
"attempts"
:
0
,
"accepted_at"
:
null
}
],
"status"
:
"Pass"
},
{
"id"
:
"HTTP-033"
,
"name"
:
"Refusal persists across real BFF restart and mock acceptance"
,
"precondition"
:
"Outbox stored in real PG"
,
"action"
:
"Stop/restart BFF; bootstrap dispatch to mock13001"
,
"expected"
:
"same row accepted once;no real email"
,
"at"
:
"2026-10-06T16:29:39.132Z"
,
"actual"
:
{
"outbox"
:
{
"state"
:
"accepted"
,
"attempts"
:
1
,
"accepted_at"
:
"2026-10-06T16:29:39.777Z"
},
"mockRequests"
:
1
,
"realEmails"
:
0
},
"status"
:
"Pass"
},
{
"id"
:
"HTTP-034"
,
"name"
:
"Accepted refusal never becomes successful reservation"
,
"precondition"
:
"D notice accepted by mock"
,
"action"
:
"GET D minutes;GET myMinutes;snapshot"
,
"expected"
:
"null,D absent,3 Tasks"
,
"at"
:
"2026-10-06T16:29:39.930Z"
,
"actual"
:
{
"reservation"
:
null
,
"myMinutes"
:
3
,
"taskCount"
:
3
},
"status"
:
"Pass"
}
],
"summary"
:
{
"executed"
:
34
,
"pass"
:
34
,
"fail"
:
0
},
"cleanup"
:
{
"services"
:
[
{
"role"
:
"Backend"
,
"pid"
:
53599
,
"exitCode"
:
null
,
"signal"
:
"SIGTERM"
},
{
"role"
:
"BFF"
,
"pid"
:
53601
,
"exitCode"
:
null
,
"signal"
:
"SIGTERM"
},
{
"role"
:
"BFF"
,
"pid"
:
53625
,
"exitCode"
:
null
,
"signal"
:
"SIGTERM"
}
],
"container"
:
"ndb-qa-minutes-http-20261007-56488"
,
"containerStopped"
:
true
},
"boundaries"
:
{
"realWechatLogin"
:
false
,
"miniUI"
:
false
,
"realEmails"
:
0
,
"sharedBusinessDbWrites"
:
0
},
"mockNotifications"
:
[
{
"path"
:
"/v1/notifications"
,
"key"
:
"minutes-no-contract-e0cdd570c83130ab69bfbdce67ee9d375a6b100c05156ebbc74abe0630fb5929"
,
"body"
:
{
"metadata"
:
{
"source"
:
"mp-conference-minutes-no-contract"
},
"deliveries"
:
[
{
"channel"
:
"email"
,
"to"
:
{
"emails"
:
[
"qa-staff@example.invalid"
]
},
"subject"
:
"纪要预约因无有效合同被拒绝"
,
"content"
:
{
"kind"
:
"normal"
,
"contentType"
:
"text"
,
"body"
:
"会议ID:4
\n
客户联系人ID:2
\n
渠道用户ID:qa-http-bound-user
\n
拒绝原因:NO_ACTIVE_CONTRACT
\n
预约未成功,请工作人员核实合同。"
}
}
]
}
}
]
}
« Previous
1
…
47
48
49
50
51
…
78
Next »
(49-49/78)
Loading...