Resolve bookable times from member availability

FeatureMediaService
Shipped
August 25, 2026 at 8:22 PM UTC
Author
Kamo
Commit
6c8ba10

Availability is now computed rather than stored. MemberAvailabilityService owns the arithmetic: expand each presenter's declared windows over the type's booking horizon, subtract the webinars they are already presenting and everything on their calendar, apply any child-org narrowing, then keep the start times a webinar of that length still fits inside. Overlap between a window and a calendar event is legal on write and only ever subtracts on read. That is what lets a member declare standing hours once and never revisit them when a meeting lands inside — the meeting removes its own part of the window and nothing else. Candidate start times come off the DECLARED window, not off the free remainder. Stepping from each surviving fragment would turn a clean 9:00 / 9:30 / 10:00 grid into 10:15 / 10:45 for the rest of the morning because of one 15-minute call; generating the grid from the window the member drew and keeping only what still fits means the 10:00 disappears and 10:30 stays put. There is now ONE implementation. The public booking page and the signed-in scheduler each had their own copy of this, with different rules, so a visitor and a member could be shown different times for the same webinar. Both booking paths now also require the requested period to be inside declared availability. Before, that was true by construction because the caller picked one of the type's own dated rows; with an absolute instant on the wire, nothing stopped a request naming three in the morning on a day nobody had offered. /types/{id}/slots/available is replaced by /types/{id}/bookable-times. The public endpoint keeps its path and its availableTimes key, and drops the slots half — it reported a local date and a bare wall-clock time with no zone, which an anonymous browser had no way to resolve into anything it could act on. 30 tests cover the interval arithmetic and the expansion, including the timezone, date-line, daylight-saving and past-midnight cases. 280 pass.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing