Quando usarlo
Oggi il cliente che annulla in ritardo riceve
late_cancellation_refund_percent dell'importo pagato, fino all'inizio
dell'appuntamento. Questo playbook aggiunge una finestra per servizio (per
esempio le ultime 4 ore) in cui il rimborso scende a zero.
Regole da rispettare
- Le migration sono append-only: non modificare
202610060001_booking_domain.sql, aggiungi un nuovo file. - La decisione sul rimborso è pura e vive in
refundForCancellation;workflows.tsla applica e non deve calcolare importi da solo. - Le cancellazioni dello staff rimborsano sempre per intero.
- Un rimborso già deciso (
refundTargetCents) non diminuisce mai.
Passi
- Crea
supabase/migrations/<YYYYMMDDHHMM>_service_no_refund_window.sqlcon un timestamp successivo a tutte le migration esistenti:
Il defaultalter table public.services add column no_refund_hours integer not null default 0 check (no_refund_hours between 0 and 720), add constraint services_no_refund_within_free_window check (no_refund_hours <= free_cancellation_hours);0mantiene il comportamento attuale per i servizi esistenti. - In
src/lib/booking/policy.ts:- aggiungi
noRefundHoursaBookingPolicy; - aggiungi
"no_refund_window"aRefundReason; - in
refundForCancellation, per un cliente a cui mancano meno dinoRefundHoursall'inizio, imposta il motivono_refund_windowe il target0. Lascia al suo posto ilMath.maxconrefundTargetCents.
- aggiungi
- In
src/lib/booking/repository.tsaggiungino_refund_hoursaServiceRow, al pickservicediBookingDetails, aSERVICE_COLUMNS, alla selectservices(...)diBOOKING_DETAILSe atoPolicy. - Nell'area admin aggiungi il campo
noRefundHoursal form dei servizi insrc/app/admin/catalog/page.tsxeno_refund_hours: integer(formData, "noRefundHours", 0)all'insert insrc/app/admin/actions.ts. I vincoli CHECK validano il valore. - Spiega la finestra al cliente nel riquadro delle cancellazioni di
src/app/book/[serviceId]/page.tsx, solo quandono_refund_hours > 0. - In
test/policy.test.tsaggiunginoRefundHoursalla policy condivisa e verifica che:- dentro la finestra non ci sia rimborso, con motivo
no_refund_window; - fra le due soglie valga ancora la percentuale tardiva;
- lo staff rimborsi comunque per intero dentro la finestra;
- un target di rimborso precedente non venga ridotto.
- dentro la finestra non ci sia rimborso, con motivo
Completato quando
- i comandi di verifica passano;
- la migration si applica su un progetto Supabase con servizi esistenti;
- i servizi creati prima della modifica si comportano esattamente come prima.
