fix: #3615951 The slot booking page is cached with one visitor's quantities in it and served to the next
Closes the disclosure in #3615951.
What was wrong
SlotBookingForm::buildForm() reads the visitor's basket into every quantity field and declared only yoyaku_booking_channel as cacheability. Nothing there names the visitor, so the dynamic page cache stored one render per route, language and channel and replayed it to the next anonymous visitor, whose stepper then reconciled their order against a quantity that was never theirs.
Core covers a form only for a visitor who has logged in. In FormBuilder::prepareForm() the form_token element, and the max-age = 0 that comes with it, is added on that condition alone, so an anonymous booking page carried no per-session element at all. That is the entire audience this page exists for.
What changed
SlotBookingFormdeclares thesessioncontext, and bounds the remaining counts with the collectedAvailabilityCacheTagsplusyoyaku.settings.availability_max_age— a lifetime rather than a booking tag, for the same reason the seat map uses one.AvailabilityCacheTagsis injected for it.CartFormhad the same hole with no#cacheline at all. It now declaressessionbefore it reads the basket: an empty cart is this visitor's answer as much as a full one, and the early return would otherwise leak a shared "your cart is empty".- Docs: the per-slot booking page's cacheability in
docs/calendar.md, the cart page's indocs/cart.md.
CalendarBookingForm was checked and needs nothing. It renders the calendar element and a submit button, and touches the cart only on submit, so user.permissions is the whole story there. The issue body claimed otherwise and is corrected.
No new translatable strings, so fr.po is unchanged.
Tests
Both new guards were seen to fail against the unfixed code before the fix landed:
SlotBookingFormTest::testThePrefilledFormNamesTheVisitorItWasBuiltFor— Failed asserting that an array contains 'session'.SlotBookingFormTest::testWhatIsLeftIsNotBelievedForever— Failed asserting that an array contains 'yoyaku_allotment_list'.CartFormCacheabilityTest::testTheCartNamesTheSessionEvenWhenEmpty— Failed asserting that an array contains 'session'.
Green afterwards on both SQLite and MySQL.
Still open, deliberately
The session context costs this page its shareability, which is what the availability document work bought for the seat map. Giving it back means filling the quantities and the counts in the browser, from the yoyaku_held stamp and a per-slot availability document, with the controls shipping disabled until that fill succeeds — and deleting the session context in the same commit rather than keeping it as a fallback. That is described in the issue and overlaps #3615940.