5.6 KiB
booking-requests — the money-free pre-payment request
Client seam
client/src/services/bookingRequests/·USE_BOOKING_REQUESTS_MOCK = false(real) · 7 server ops Last verified: 2026-07-30 against commitd3ec723and swagger.v1.json (2026-07-29).
Stage one of the booking flow: the customer asks, the nurse answers, and no money exists yet. A
booking_requests row becomes a bookings row only on payment capture — see
bookings.md and payment.md.
Features/Booking(singular, this domain) andFeatures/Bookings(plural, the post-payment engine) are different server areas, not a rename.
Endpoints
| Method | Path | Caller | Verdict |
|---|---|---|---|
| POST | /api/v1/booking_requests/create |
customer | wired |
| GET | /api/v1/booking_requests/list |
both | wired · paginated · role-scoped |
| GET | /api/v1/booking_requests/get/{id} |
both | wired |
| POST | /api/v1/booking_requests/accept/{id} |
nurse | wired |
| POST | /api/v1/booking_requests/reject/{id} |
nurse | wired |
| POST | /api/v1/booking_requests/cancel/{id} |
customer | wired |
| GET | /api/v1/booking_requests/checkout_summary/{id} |
customer | wired — but read by the payment domain, not this one |
All [Authorize]. No phantoms.
checkout_summary is the C6 money read (gross / commission / VAT breakdown, REQ-016 delivered). It lives
on this controller because the request is what gets paid for, and is documented in
payment.md where it is consumed.
The lifecycle
pending_nurse_response ──accept──▸ accepted_awaiting_payment ──capture──▸ converted
│ │
├──reject──▸ rejected_by_nurse └──window lapses──▸ payment_deadline_expired
├──deadline──▸ expired_no_response
└──customer──▸ cancelled_by_customer
Forward-only. A backward or sideways transition is a clean 409, never a 500. Two deadlines are
server-owned and config-driven (booking_request_response_deadline_minutes,
payment_window_minutes in admin.md):
- the nurse's response window →
expired_no_response - the customer's payment window after acceptance →
payment_deadline_expired
POST /api/v1/admin_booking_requests/expire is the ops one-shot for both; the in-process scheduler runs
it unattended. See admin.md.
Shape rules the JSON does not express
- Stage-one disclosure is deliberately partial. Before payment the nurse sees only unencrypted
customerNotesand a city/district-coarse masked address. Encrypted care instructions and the full address are unreadable until the booking is confirmed. This is a hard server rule, not a UI choice. - The countdown is server-frozen.
CountdownTimerrenders a deadline the server sent; the client never computes an expiry from a local clock. variantPriceis onBookingRequestDto(REQ-013, delivered) so the customer sees the price they are committing to without a second variant fetch. It is a digit string.- The inbox list item carries
variantLabel+patientAge(REQ-014, delivered).
The two list shapes, exactly
Confirmed field-by-field against the live swagger, because three in-repo comments disagree about this:
BookingRequestListItemDto (list) |
BookingRequestDto (detail) |
|
|---|---|---|
variantLabel |
yes | yes |
patientAge |
yes | — (patientName instead) |
variantPrice · variantPriceUnit |
no | yes |
| address / notes | customerNotes only |
full masked address block |
nurseRejectionReason |
— | yes, free text |
Two consequences:
client/src/services/bookingRequests/types.tsis behind the wire. It marksvariantLabelas "client-augmented …undefinedon the real path", but the server serves it. Widening the client type is safe and would let the real inbox card render its decision-first headline today.- REQ-050 is partly stale. It states the list DTO carries neither field, "confirmed against
services/bookingRequests/types.ts" — i.e. confirmed against the client type, not the wire. What the wire genuinely lacks isvariantPrice/variantPriceUniton the list row and thestatus=answeredgroup filter. requiredCaregiverGenderis never defaulted or dropped.anyis an explicit choice, distinct from absent.- The address the request references is snapshotted at create time; later edits to the saved address do not rewrite it.
Enums
| Vocabulary | Values |
|---|---|
BookingRequestStatus |
pending_nurse_response accepted_awaiting_payment converted rejected_by_nurse expired_no_response payment_deadline_expired cancelled_by_customer |
RequiredCaregiverGender |
male female any |
RequestRole (client-side list filter) |
customer nurse |
Verified identical to Baya.Domain/Entities/Booking/BookingRequestStatus.cs. REQ-015 confirmed these
serialise as the exact snake_case codes.
Open REQs
| REQ | Status | Effect |
|---|---|---|
| REQ-044 | open | No structured nurseRejectionReasonCode — the wire carries free-text nurseRejectionReason. The client runs a keyword heuristic over it, documented in-code as a known approximation |
| REQ-050 | open, narrower than filed | The list row already has variantLabel; it lacks variantPrice/variantPriceUnit. The status=answered group filter is genuinely absent, so the «پاسخداده» tab fires three page-1 queries and concatenates — an unpaged workaround a nurse with many answered requests will hit |