frontend phase 15
This commit is contained in:
@@ -2,9 +2,12 @@ import { clientFetch } from '@/lib/api/client';
|
||||
import { unwrap, type ApiEnvelope } from '@/lib/api/types';
|
||||
import { ApiError } from '@/lib/api/errors';
|
||||
import type {
|
||||
AdminRefundResult,
|
||||
CancelBookingInput,
|
||||
CancellationPolicyPreview,
|
||||
InitiateRefundInput,
|
||||
RefundChannel,
|
||||
RefundPreview,
|
||||
RefundStatus,
|
||||
RefundSummary,
|
||||
RefundsApi,
|
||||
@@ -12,6 +15,7 @@ import type {
|
||||
|
||||
const BOOKINGS = '/api/v1/bookings';
|
||||
const REFUNDS = '/api/v1/refunds';
|
||||
const ADMIN_REFUNDS = '/api/v1/admin_refunds';
|
||||
|
||||
/**
|
||||
* The thin b11 customer refund payload (`GET refunds/{id}/status`) — the only refund shape the contract
|
||||
@@ -93,4 +97,52 @@ export const refundsClientApi: RefundsApi = {
|
||||
|
||||
getRefund: async (refundId: number) =>
|
||||
toSummary(unwrap(await clientFetch<ApiEnvelope<RefundStatusWire>>(`${REFUNDS}/${refundId}/status`))),
|
||||
|
||||
// REQ-035: refund preview endpoint. b11 computes the fee-leg decomposition only *on create* (there is no
|
||||
// read-only preview route), yet the admin console must disclose the split before initiating. Filed as a
|
||||
// proposed `GET api/v1/admin_refunds/preview?booking_id=&ticket_id=`; the mock serves it today.
|
||||
getRefundPreview: async (bookingId: number, ticketId: number | null) => {
|
||||
const params = new URLSearchParams({ booking_id: String(bookingId) });
|
||||
if (ticketId != null) params.set('ticket_id', String(ticketId));
|
||||
return unwrap(
|
||||
await clientFetch<ApiEnvelope<RefundPreview>>(`${ADMIN_REFUNDS}/preview?${params.toString()}`),
|
||||
);
|
||||
},
|
||||
|
||||
// Create + immediately execute a ticket-linked refund (b11 `POST api/v1/admin_refunds`). The response is
|
||||
// already `AdminRefundResult`-shaped (refundId/status/channel/decomposed legs/eta/clawbackId).
|
||||
initiateRefund: async (input: InitiateRefundInput) =>
|
||||
unwrap(
|
||||
await clientFetch<ApiEnvelope<AdminRefundResult>>(ADMIN_REFUNDS, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
bookingId: input.bookingId,
|
||||
ticketId: input.ticketId,
|
||||
refundPercentage: input.refundPercentage,
|
||||
refundChannel: input.refundChannel,
|
||||
reasonCategory: input.reasonCategory,
|
||||
reasonNotes: input.reasonNotes,
|
||||
}),
|
||||
}),
|
||||
),
|
||||
|
||||
// REQ-035: approve/reject a refund. b11 has no separate approve/reject step — `POST admin_refunds` both
|
||||
// creates and executes — so a failed-channel retry and an explicit rejection are proposed as
|
||||
// `POST api/v1/admin_refunds/{id}/approve` and `.../{id}/reject`; the mock serves both today.
|
||||
approveRefund: async (refundId: number) =>
|
||||
unwrap(
|
||||
await clientFetch<ApiEnvelope<AdminRefundResult>>(`${ADMIN_REFUNDS}/${refundId}/approve`, {
|
||||
method: 'POST',
|
||||
}),
|
||||
),
|
||||
|
||||
// REQ-035: see approveRefund. Reject records a reason and moves the refund to `rejected`.
|
||||
rejectRefund: async (refundId: number, reason: string) => {
|
||||
unwrap(
|
||||
await clientFetch<ApiEnvelope<true>>(`${ADMIN_REFUNDS}/${refundId}/reject`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ reason }),
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user