Analysis and implementation plan: - Scope: petsitter messages request-flow summary card for booking_request_pending threads. - Root cause: the shared request-flow summary contract reduced the summary card to View details + primary CTA, so the destructive decline action was stripped from the inline petsitter booking-request card. - Implementation: expose a targeted summary secondary action for petsitter booking_request_pending and render it on the inline RequestFlowStateCard while leaving footer-banner behavior unchanged. - Regression tests added before implementation: contract-level coverage for summary actions and rendered-card coverage for Accept + Decline + View details. - Risks checked: avoid broadening quote-decision flows and avoid changing footer action ordering.
Standalone QA Hub
Issue #50
/at/petsitter/messages · 2026-03-10 13:11:03
Screenshot
Stored at legacy-import/issues/167/1772783991776-d4088f45-932b-4915-b624-cd462931301a.png
Metadata
Selector candidates
[
{
"matches": 8,
"score": 76,
"selector": "div.bg-white.border.border-\\[\\#E3EDF7\\]",
"strategy": "class"
},
{
"matches": 77,
"score": 60,
"selector": "div:nth-of-type(1)",
"strategy": "nth-of-type"
},
{
"matches": 52,
"score": 58,
"selector": "div \u003e div \u003e div \u003e div \u003e div \u003e div:nth-of-type(1)",
"strategy": "ancestor-path"
}
]
Target fingerprint
{
"ancestorPath": [
"div",
"div",
"div",
"div",
"div",
"div"
],
"ariaLabel": null,
"className": "bg-white border border-[#E3EDF7] rounded-2xl p-5 w-full max-w-[500px] shadow-[0_1px_2px_rgba(0,0,0,0.04)]",
"href": null,
"id": null,
"name": null,
"role": null,
"tagName": "div",
"textSample": "MAE wants to book with you 🐶 Pet Boarding • 6 mars – 8 mars MAE has sent a booking request with the agreed dates and pr"
}
Secondary signal
{
"hasFiberInstance": true,
"reactComponentStack": [
"div",
"sa",
"eO",
"su",
"Content",
"o",
"I",
"U",
"x",
"c",
"f",
"T"
],
"reactOwnerStack": [],
"source": "react-fiber"
}
Layout evidence
bbox:
{
"bottom": 944,
"height": 309,
"left": 17,
"right": 517,
"top": 635,
"width": 500,
"x": 17,
"y": 635
}
viewport:
{
"height": 1112,
"width": 916
}
scroll:
{
"x": 0,
"y": 0
}
screenshotMarks:
[]
DOM excerpt
<div class="bg-white border border-[#E3EDF7] rounded-2xl p-5 w-full max-w-[500px] shadow-[0_1px_2px_rgba(0,0,0,0.04)]"><div class="flex items-start gap-4 mb-4"><div class="w-10 h-10 rounded-full flex items-center justify-center shrink-0 mt-1 bg-[#E9F4FD] text-[#7fbce6]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 384 512" class="text-base" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M64 0C28.7 0 0 28.7 0 64L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-288-128 0c-17.7 0-32-14.3-32-32L224 0 64 0zM256 0l0 128 128 0L256 0zM80 64l64 0c8.8 0 16 7.2 16 16s-7.2 16-16 16L80 96c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64l64 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-64 0c-8.8 0-16-7.2-16-16s7.2-16 16-16zm16 96l192 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32L96 352c-17.7 0-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32zm0 32l0 64 192 0 0-64L96 256zM240 416l64 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-64 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"></path></svg></div><div class="flex-1"><h3 class="text-[#1F2937] text-lg font-semibold leading-tight mb-1">MAE wants to book with you 🐶</h3><p class="text-[#6B7280] text-sm mb-2">Pet Boarding • 6 mars – 8 mars</p><p class="text-[#6B7280] text-sm leading-relaxed mb-3">MAE has sent a booking request with the agreed dates and price. Accept to allow the owner to complete the payment and confirm the booking.</p><p class="text-[#1F2937] text-base font-bold">You'll receive 26,00 € after completion</p></div></div><div class="flex flex-col items-center gap-3 mt-2"><button data-slot="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive has-[>svg]:px-4 w-full bg-[#7fbce6] text-white h-11 px-4 rounded-xl text-[15px] font-medium transition-colors shadow-sm hover:bg-[#6ca8d1]" type="button" data-sentry-element="Comp" data-sentry-component="Button" data-sentry-source-file="button.tsx">Accept booking</button><button type="button" class="text-[#6B7280] text-sm font-medium hover:text-[#7fbce6] hover:underline transition-colors pb-1" data-sentry-component="InlineLinkAction" data-sentry-source-file="RequestFlowStateCard.tsx">See details</button></div></div>
Thread
Completed: - Fix shipped in the request-flow summary contract and inline RequestFlowStateCard so petsitter booking_request_pending cards now show Accept + Decline + View details. - Regression tests run and passing: - pnpm vitest run tests/unit/booking/request-flow-contract.test.ts - pnpm vitest run tests/unit/request-flow/request-flow-state-card-model-render.test.tsx - Visual inspection artifacts: - /home/tarasowski/Coding/projects/holidog-3002/artifacts/qa-167-visual-fixed.png - /home/tarasowski/Coding/projects/holidog-3002/artifacts/qa-167-petsitter-messages-page.png - Note: the live seeded messages route in the devtools session stalled on Loading conversations after selection, so the acceptance screenshot was captured from a browser render harness built from the real RequestFlowStateCard component with booking_request_pending props.
Visual inspection attachment: fixed request-flow card showing Accept + Decline + View details.
qa-167-visual-fixed.png
Supporting capture from the petsitter messages page during validation.
qa-167-petsitter-messages-page.png