All 20 checks with why-it-matters prose, severity, and cross-references to related audits.
Serving stale availability data is a direct cause of double-bookings. When a customer books slot A, that change must be visible to every other client on the next calendar load — not after a session refresh or browser restart. Client-side caches without TTLs violate CWE-362 (concurrent resource access) and ISO 25010 functional correctness: two users see the same slot as open and both confirm. The downstream effect is a support ticket, a refund, and a damaged reputation. Booking platforms live and die by schedule integrity; a single double-booking erodes trust faster than any competitor can.
Why this severity: Critical because stale availability displayed to the user is the direct mechanical cause of double-bookings, which are unrecoverable without manual intervention and refunds.
booking-calendar-availability.calendar-display.data-freshnessSee full patternBuffer time enforced only in the UI is not enforced. Any client that posts directly to the booking API — a script, a browser extension, a race condition — bypasses the disabled slots entirely and books into the buffer window. This violates CWE-362 (race condition) and CWE-667 (improper locking), and the ISO 25010 functional-correctness attribute. The practical result: a host has back-to-back appointments with no travel or prep time, they run late, the second client has a bad experience, and a refund is likely. Server-side enforcement is the only enforcement that matters.
Why this severity: Critical because UI-only buffer checks are trivially bypassed with a direct API call, making double-booking into the buffer window mechanically possible without any exploit skills.
booking-calendar-availability.calendar-display.buffer-enforcementSee full patternStoring appointment datetimes without timezone information turns a scheduling platform into a time-bomb. A host in PST and a customer in EST reading the same `DATETIME 14:00` literal interpret it as different wall-clock times. This violates CWE-686 (wrong type used for value) and ISO 25010 functional correctness. The failure mode is invisible until someone misses an appointment and support has to reconstruct what actually happened. Once daylight saving time transitions enter the picture, the mismatches compound: a `DATETIME` column that was correct in January silently drifts by an hour in March.
Why this severity: Critical because timezone-naive storage causes silent appointment time mismatches that are invisible to both parties until a no-show occurs, with no automatic correction path.
booking-calendar-availability.calendar-display.utc-storageSee full patternColor is not a reliable communication channel. Roughly 8% of men have color vision deficiency, making red/green-only slot states indistinguishable. This violates WCAG 2.2 SC 1.4.1 (Use of Color) directly, and SC 1.4.3 (Contrast Minimum) compounds the problem when low-contrast grays are used for past/blocked states. The legal exposure under ADA Title III is real for booking platforms serving the public. Beyond compliance, a color-blind user who cannot distinguish booked from available slots will either book into a conflict or abandon the flow — both outcomes cost revenue.
Why this severity: High because color-only slot states exclude approximately 8% of male users from reliably distinguishing bookable slots, violating WCAG 2.2 SC 1.4.1 and creating legal exposure under ADA Title III.
booking-calendar-availability.calendar-display.visual-distinctionSee full patternA booking form that opens when a user clicks a booked slot violates WCAG 2.2 SC 4.1.3 (Status Messages) and creates a silent failure path: the form submits, the server rejects it, and the user has no idea why. Beyond accessibility, silent ignores of non-available slot clicks leave users wondering if the click registered at all — they repeat-click, get confused, and abandon. Assistive technology users cannot detect visually-implied disabled states; they rely on programmatic feedback. Two distinct messages (one for booked, one for blocked) are required because the corrective actions differ.
Why this severity: High because absent click feedback on unavailable slots produces silent failures that leave assistive technology users unable to determine why a booking attempt failed, violating WCAG 2.2 SC 4.1.3.
booking-calendar-availability.calendar-display.unavailable-feedbackSee full patternA booking calendar that requires horizontal scrolling at 320px fails WCAG 2.2 SC 1.4.10 (Reflow) and locks out users on low-end Android devices, which represent a disproportionate share of mobile traffic in emerging markets. Fixed-width calendar grids are one of the most common causes of horizontal overflow: a 7-column week grid with fixed column widths adds up to 700px or more on desktop, which is unreadable on mobile. Missing viewport meta tags compound this by preventing the browser from scaling correctly. The result is that mobile users see a broken, unreadable booking interface and leave.
Why this severity: Low because horizontal overflow is a usability defect rather than a data-integrity risk, but it directly excludes mobile users and violates WCAG 2.2 SC 1.4.10 (Reflow).
booking-calendar-availability.calendar-display.responsive-renderingSee full patternCalendar slots that are not reachable via Tab or Arrow keys exclude keyboard-only users and screen reader users entirely — the latter navigate by virtual cursor through focusable elements. This violates WCAG 2.2 SC 2.1.1 (Keyboard) and SC 2.4.7 (Focus Visible), and Section 508 2018 Refresh 502.3. Div-based slot grids without `tabIndex` or `role` attributes are the most common cause: they look interactive but are invisible to keyboard navigation. A user with motor impairment who cannot use a mouse literally cannot book an appointment.
Why this severity: Low because the failure locks out keyboard-only users but does not compromise data integrity — however it violates WCAG 2.2 SC 2.1.1 and Section 508 and constitutes an ADA compliance gap.
booking-calendar-availability.calendar-display.keyboard-navigationSee full patternA blank screen for 4 seconds while the availability API resolves is the leading cause of mobile booking abandonment. Synchronous data fetching on calendar pages blocks first paint, penalizes users on 3G connections (typical in mobile-first markets), and tanks Core Web Vitals LCP scores. ISO 25010 time-behaviour requires that interactive systems provide perceptible feedback within 1–2 seconds. Blocking fetches also mean that a slow or erroring availability API takes down the entire page instead of degrading gracefully to a skeleton.
Why this severity: Low because blocking load primarily affects mobile users on slow connections rather than corrupting data, but it is the dominant cause of booking page abandonment on 3G.
booking-calendar-availability.calendar-display.performance-load-timeSee full patternClickable past dates send doomed POST requests to the booking API, wasting backend cycles, polluting logs with 4xx errors, and surfacing generic server-side failures that erode user trust. Customers who manage to submit a past date hit a confusing rejection screen mid-flow, abandon the booking, and never return. This is a preventable user-experience regression that also inflates telemetry noise and masks real availability failures in your error-rate dashboards.
Why this severity: Low because server-side validation still blocks the booking, so the impact is UX friction and log pollution rather than data corruption or revenue loss.
booking-calendar-availability.calendar-display.past-date-protectionSee full patternDuration validation that exists only in the UI is bypassed by any direct API call. OWASP A03 (Injection) and CWE-20 (Improper Input Validation) both flag trust in client-supplied numeric fields. Without server-side bounds, an attacker or misbehaving client can create a 1-minute booking (flooding the schedule with noise) or a 48-hour booking (occupying a resource for two days). Both have direct revenue impact. Explicit named constants for min and max durations are required so the bounds are testable, auditable, and not silently scattered across the codebase.
Why this severity: High because absent server-side duration bounds allow direct API callers to create arbitrarily short or long bookings, causing resource monopolization and schedule flooding without any exploit skills.
booking-calendar-availability.availability-logic.duration-validationSee full patternSame-day cutoff rules that live only in the slot-filter query are display controls, not booking controls. A direct POST to the booking API bypasses the hidden slots entirely. OWASP A03 (Injection) and CWE-20 (Improper Input Validation) apply whenever a server accepts client-supplied timestamps without verifying them against business rules. Without server-side cutoff enforcement, a customer can schedule a same-day appointment that the host has no time to prepare for, or an automated client can flood the schedule with last-minute bookings.
Why this severity: High because the gap between UI slot-filtering and API validation means any direct API caller can book inside the cutoff window, bypassing the host's advance-notice requirement entirely.
booking-calendar-availability.availability-logic.same-day-cutoffSee full patternDisplaying all appointment times in a single server timezone (typically UTC or the business owner's zone) forces customers to do mental arithmetic and guarantees no-shows. A customer in EST booking a slot labeled '14:00 UTC' will arrive at 2 PM local time, six hours late. This directly destroys revenue per missed appointment, generates support tickets, and violates baseline WCAG 3.1.4 abbreviation expectations when timezone labels are absent. High-volume booking platforms lose thousands of dollars weekly to this single defect.
Why this severity: High because timezone display bugs produce silent no-shows that cost direct revenue per missed booking and damage customer relationships.
booking-calendar-availability.availability-logic.customer-timezone-displaySee full patternManual offset arithmetic like `date.getTime() + 5 * 3600000` hard-codes a fixed UTC offset and silently breaks twice a year during DST transitions. CWE-682 (Incorrect Calculation) and ISO 25010 functional correctness both flag this: New York is UTC-5 in January and UTC-4 in July — a hard-coded `-5` produces a one-hour appointment time error for every booking during EDT. IANA libraries carry the full historical and future timezone rule database; manual arithmetic carries none of it. A single DST-related booking error can generate dozens of no-shows before anyone notices the pattern.
Why this severity: High because manual offset arithmetic silently produces one-hour appointment time errors on every DST transition, affecting all bookings during a roughly five-month EDT window without any visible error.
booking-calendar-availability.availability-logic.iana-timezone-librarySee full patternWhen the calendar does not refresh after a successful booking, the just-booked slot still appears green and selectable. A second customer in the same session clicks it, hits a 409 conflict from the server, and sees a generic error. This creates double-booking races, duplicate conflict-handling work, and a confusing 'did my booking go through?' moment that drives support contacts. The defect also misleads the original user, who may refresh and fear their booking failed.
Why this severity: Low because server-side uniqueness constraints prevent actual double bookings; impact is confined to UX confusion and retry friction.
booking-calendar-availability.availability-logic.live-availability-updateSee full patternWhen the booking confirmation email says "2 PM EST" and the calendar block says "7 PM UTC", the customer has no reliable signal about when to show up. This ISO 25010 functional-correctness failure typically stems from one component reading the raw UTC value while another converts it — two code paths, two different timezone assumptions, same appointment. The damage is a no-show or a wrong-time arrival, followed by a refund request and a support ticket. Confirmation-calendar parity is not cosmetic: it is the contract the customer relies on to plan their day.
Why this severity: Low because the mismatch does not corrupt stored data, but it causes customers to appear at the wrong time, producing no-shows and direct refund liability.
booking-calendar-availability.availability-logic.confirmation-calendar-paritySee full patternAdvance booking limits that exist only as a UI filter are not limits at all. A direct POST to the booking API skips the date picker entirely. OWASP A03 (Injection) and CWE-20 (Improper Input Validation) apply to any business rule that can be bypassed by sending a raw HTTP request. Without a server-side ceiling, a misbehaving client can book a slot 5 years in the future, creating junk data in the schedule, blocking the resource for phantom appointments, and polluting analytics.
Why this severity: Low because far-future junk bookings are annoying and pollute analytics but do not expose sensitive data or create immediate revenue loss, making it lower urgency than buffer or duration violations.
booking-calendar-availability.availability-logic.advance-booking-limitsSee full patternDST transitions create two temporal anomalies that break naive slot generators: a spring-forward gap (2:00–2:59 AM does not exist) and a fall-back overlap (1:00–1:59 AM occurs twice). CWE-682 (Incorrect Calculation) and ISO 25010 functional correctness both apply. A slot generator that iterates wall-clock minutes without DST awareness will produce bookable slots at 2:30 AM on the spring transition — a time that literally does not exist in that timezone. When a customer confirms such a booking, the confirmation timestamp resolves to an ambiguous or invalid time, causing silent downstream errors in reminders, calendar exports, and host notifications.
Why this severity: Info because DST failures affect only two days per year in affected timezones, but on those days they can produce invalid appointment times that propagate silently through reminders and exports.
booking-calendar-availability.timezone.dst-handlingSee full patternStoring a host's Monday-through-Friday 9-to-5 availability as 260 individual database rows — one per workday — is an ISO 25010 functional-correctness failure masquerading as a schema decision. Pre-expanded rows mean adding a single exception (a vacation day) requires a DELETE and INSERT instead of an exception record. Querying a year's availability requires scanning hundreds of rows instead of parsing one RRULE string. Editing the recurring pattern requires a bulk UPDATE. The real business risk: a host who changes their hours sees stale slots appear because the expansion was done at write time, not at query time.
Why this severity: Low because pre-expanded storage causes maintenance debt and stale-schedule bugs rather than immediate data loss, but it blocks correct exception handling and makes schedule edits error-prone.
booking-calendar-availability.recurring.rule-based-storageSee full patternA recurring schedule exception that does not override the calendar in real time is an invisible lie. The host marks next Monday as closed; the customer sees open slots for next Monday; the booking confirms; the host is unavailable. This ISO 25010 functional-correctness failure occurs when the exception record is stored correctly but the slot generation query does not join against the exceptions table before returning availability. The result is phantom slots: the system thinks it is correctly managing exceptions, but customers book into them anyway.
Why this severity: Low because the failure requires a recurring-schedule-plus-exceptions setup to trigger, but when it does, it creates confirmed bookings on dates the host explicitly marked unavailable.
booking-calendar-availability.recurring.exception-handlingSee full patternWithout a scope prompt, editing a single weekly-recurring slot rewrites every past and future occurrence, corrupting historical schedules and silently changing appointments customers have already booked. Hosts lose the ability to handle one-off changes (vacation, a shifted single week) without breaking the entire series. This erodes trust in the scheduling tool, forces manual database fixes, and can cause calendar-invite mismatches where the host's system shows one time and the attendee's another.
Why this severity: Info because this is a capability gap rather than an active defect, but absence blocks common scheduling workflows and causes data churn when workarounds are used.
booking-calendar-availability.recurring.recurring-edit-scopeSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Calendar & Availability Audit