Hosting: state the reservation grace window where it matters - #1439
Conversation
PR Summary by QodoHosting: surface reservation grace window in API and UI messaging
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
1.
|
Code Review by Qodo
1. Env var not restored
|
The expiry lifecycle already existed end to end (the sweep reclaims unpaid reservations after ABANDONED_TENANT_GRACE_DAYS, the name frees after quarantine and a reclaim overwrites the draft config), but nothing user-facing said so: an owner had no way to know their customized reservation is held for a limited window. The window resolves through one shared reservationGraceDays() in the subscription service, used by the sweep's config and now surfaced in GET /v1/payments/methods, so the number quoted to users cannot drift from the number the sweep enforces. The signup payment step states it for fresh reservations (renewals are not reservations and stay silent), and the manage panel's awaiting-payment entry states it next to the resume link. Silent when an older service omits the field. Part of #1415
fd0f2ec to
ec4829e
Compare
Review finding: the notice keyed on a null renewal baseline, which is also the state for expired and suspended tenants, so an owner renewing an expired blog was told their name would be released after the window, which is false: the sweep only reclaims inactive rows with no payments. An explicit fresh-reservation flag is now set by each entry into the payment step (fresh create and resume true, the 409 renewal path false), pinned by a renewal spec. The window strings switch to count based plurals so a one-day window does not read as 1 days.
Closes #1415. Stacked on #1438 (base retargets to develop when that merges).
Investigating this issue showed the expiry lifecycle already exists end to end: the payment listener's sweep reclaims unpaid (inactive) reservations after
ABANDONED_TENANT_GRACE_DAYS(fail-safe 7), the name frees after the re-registration quarantine, a reclaim overwrites the abandoned draft config and the?resume=deep link is the return door, with the checkout grace-clock refresh protecting actively-paid reservations. What was missing is the messaging half: nothing user-facing said the reservation and its saved look are held for a limited window.reservationGraceDays()resolver in the subscription service now feeds both the sweep's configuration and a newreservation.graceDaysfield onGET /v1/payments/methods, so the number quoted to users cannot drift from the number the sweep enforces.Tests: API methods endpoint pins the fail-safe 7 and a configured value; web specs pin the notice on the payment step for a fresh reservation and its absence without the field. Hosting API 417 tests, apps/web 2622, typechecks green.