refinement phase 4

This commit is contained in:
hamid
2026-07-13 12:29:00 +03:30
parent 314763f764
commit 64f6aa45c9
27 changed files with 308 additions and 243 deletions
@@ -12,43 +12,27 @@ import type {
const BASE = '/api/v1/booking_requests';
/**
* The b8 wire `BookingRequestDto` — identical to our app DTO minus the client-augmented `variantPrice`
* (REQ-013: the contract returns `variantLabel` + `variantPriceUnit` but no price) and `bookingId`
* (REQ-017: a `converted` request gives no way to reach the booking it became).
*/
type BookingRequestWireDto = Omit<BookingRequestDto, 'variantPrice' | 'bookingId'>;
/** Map the wire DTO to the app DTO, defaulting the not-yet-contracted fields to `null`. */
function toDto(wire: BookingRequestWireDto): BookingRequestDto {
return { ...wire, variantPrice: null, bookingId: null };
}
/**
* Real HTTP implementation of the `BookingRequestsApi` seam (b8 contract
* `dev/contracts/domains/booking-requests.md`). Routes are action-style + snake_case; ids for
* accept/reject/cancel/get come from the **route**, never the body; JSON bodies/fields are camelCase and
* `clientFetch` returns the raw envelope, so we `unwrap()`. Mutations use POST.
*
* NOT the primary implementation this phase (`USE_BOOKING_REQUESTS_MOCK = true`): every input id (nurse,
* patient, address) comes from a mock-primary upstream domain today, and the DTO omits `variantPrice`
* (REQ-013). This client maps everything b8 provides — the `context` arg (a mock-only display aid) is
* ignored here, and the nurse-view masking is done server-side (so `role` is ignored too). Selected once
* the upstream domains are live and REQ-013 lands (a single config flip; no hook/component change).
* PRIMARY once `USE_BOOKING_REQUESTS_MOCK = false` (refinement-phase-4; REQ-013/014/017 delivered): the
* DTO now carries `variantPrice` + `nurseAvatarUrl` (REQ-013) + `bookingId` (REQ-017), and the list item
* carries `variantLabel` + `patientAge` (REQ-014), so the wire maps 1:1 to the app DTO. The `context` arg
* (a mock-only display aid) is ignored here, and the nurse-view masking is done server-side.
*/
export const bookingRequestsClientApi: BookingRequestsApi = {
create: async (payload: CreateBookingRequestPayload) =>
toDto(
unwrap(
await clientFetch<ApiEnvelope<BookingRequestWireDto>>(`${BASE}/create`, {
method: 'POST',
body: JSON.stringify(payload),
}),
),
unwrap(
await clientFetch<ApiEnvelope<BookingRequestDto>>(`${BASE}/create`, {
method: 'POST',
body: JSON.stringify(payload),
}),
),
get: async (id: number) =>
toDto(unwrap(await clientFetch<ApiEnvelope<BookingRequestWireDto>>(`${BASE}/get/${id}`))),
get: async (id: number) => unwrap(await clientFetch<ApiEnvelope<BookingRequestDto>>(`${BASE}/get/${id}`)),
list: async (params: BookingRequestListParams): Promise<Paginated<BookingRequestListItem>> => {
const query = new URLSearchParams();
@@ -62,22 +46,16 @@ export const bookingRequestsClientApi: BookingRequestsApi = {
},
accept: async (id: number) =>
toDto(
unwrap(await clientFetch<ApiEnvelope<BookingRequestWireDto>>(`${BASE}/accept/${id}`, { method: 'POST' })),
),
unwrap(await clientFetch<ApiEnvelope<BookingRequestDto>>(`${BASE}/accept/${id}`, { method: 'POST' })),
reject: async (id: number, payload: RejectBookingRequestPayload) =>
toDto(
unwrap(
await clientFetch<ApiEnvelope<BookingRequestWireDto>>(`${BASE}/reject/${id}`, {
method: 'POST',
body: JSON.stringify(payload),
}),
),
unwrap(
await clientFetch<ApiEnvelope<BookingRequestDto>>(`${BASE}/reject/${id}`, {
method: 'POST',
body: JSON.stringify(payload),
}),
),
cancel: async (id: number) =>
toDto(
unwrap(await clientFetch<ApiEnvelope<BookingRequestWireDto>>(`${BASE}/cancel/${id}`, { method: 'POST' })),
),
unwrap(await clientFetch<ApiEnvelope<BookingRequestDto>>(`${BASE}/cancel/${id}`, { method: 'POST' })),
};
@@ -11,7 +11,7 @@
* (REQ-013). Flip to `false` once the upstream domains are live and REQ-013 lands — no hook/component
* change (see `dev/shared-working-context/reports/frontend-phase-7-report.md`).
*/
export const USE_BOOKING_REQUESTS_MOCK = true;
export const USE_BOOKING_REQUESTS_MOCK = false;
/**
* The customer's C5 and the nurse inbox **poll** while a request is non-terminal so a transition