feat(admin): build the last two screens, and pin spacing with a test
The cancellation policy page showed only the tenant policy, so nothing said which services opt out of it. Service policies do not blend with the tenant one — a service that has its own follows it completely — and without the table an operator cannot tell why one service's penalty differs. It lists them with a link to each service. The waitlist had the matches endpoint and no way to reach it. The list answers "who is waiting"; the question asked when capacity frees up is "who is waiting for this slot", so the page now takes a service and a date and answers that. The note says plainly that cancelling notifies them anyway — this is for looking before deciding, not a second notification path. Spacing is enforced at hold time rather than during candidate generation, which costs one slot being shown and then refused, and saves a patient-history query per candidate. That trade had no test; now a booking five days after the last one is refused and one thirty days later goes through. Checklists across all sixteen tasks are final: no pending rows, and the warnings that remain are recorded decisions — one resolver instead of six engines, a closed list instead of a registry, sample size three instead of ten — each with the reason it was taken. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,26 @@ export function useCancelAppointment() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* درخواستهایی که با یک زمان مشخص میخوانند — ابزار لحظهٔ آزاد شدن ظرفیت.
|
||||
*
|
||||
* جدا از فهرست است چون سؤال متفاوتی میپرسد: نه «چه کسی منتظر است» بلکه «چه کسی
|
||||
* برای **این** وقت منتظر است».
|
||||
*/
|
||||
export function useWaitlistMatches(params: { serviceUuid: string; start: number; branchUuid?: string }) {
|
||||
const query = useQuery({
|
||||
queryKey: ['waitlist-matches', params],
|
||||
queryFn: () =>
|
||||
api.get<ApiResponse<WaitlistEntry[]>>(
|
||||
`/api/v1/waitlist/matches?service_uuid=${params.serviceUuid}&start=${params.start}` +
|
||||
(params.branchUuid ? `&branch_uuid=${params.branchUuid}` : ''),
|
||||
),
|
||||
enabled: !!params.serviceUuid && params.start > 0,
|
||||
});
|
||||
|
||||
return { matches: Array.isArray(query.data?.data) ? query.data.data : [], loading: query.isFetching };
|
||||
}
|
||||
|
||||
export function useWaitlist(status?: string) {
|
||||
const qc = useQueryClient();
|
||||
const key = [...WAITLIST_KEY, status ?? ''];
|
||||
|
||||
Reference in New Issue
Block a user