Skip to content

feat: Instant Book: Added strategy where busy intervals are retrieved from calendar feed#434

Merged
tuj merged 20 commits into
release/3.0.0from
feature/instantbook-busy-from-feed
May 27, 2026
Merged

feat: Instant Book: Added strategy where busy intervals are retrieved from calendar feed#434
tuj merged 20 commits into
release/3.0.0from
feature/instantbook-busy-from-feed

Conversation

@tuj

@tuj tuj commented May 6, 2026

Copy link
Copy Markdown
Contributor

NB! Builds on #433

Link to issue

#436

Link to ticket

https://leantime.itkdev.dk/#/tickets/showTicket/7208

Description

  • Added strategy to "Instant Book" where busy intervals are retrieved from calendar feed.
  • Fixed instant booking template error handling.
  • Fixed bugs when fetching intervals.
  • Fixed calendar test issue following change to 10 min default update interval.

Checklist

  • My code is covered by test cases.
  • My code passes our test (all our tests).
  • My code passes our static analysis suite.
  • My code passes our continuous integration process.

@tuj tuj self-assigned this May 6, 2026
@tuj tuj added enhancement New feature or request backlog Future fixes and improvements labels May 6, 2026
@tuj tuj changed the title Added strategy where busy intervals are retrieved from calendar feed Instant Book: Added strategy where busy intervals are retrieved from calendar feed May 6, 2026
@tuj tuj added version 3 Issues related to the release of version 3 and removed backlog Future fixes and improvements labels May 7, 2026
@tuj
tuj requested a review from turegjorup May 7, 2026 12:03
@tuj tuj changed the title Instant Book: Added strategy where busy intervals are retrieved from calendar feed feat: Instant Book: Added strategy where busy intervals are retrieved from calendar feed May 8, 2026
Base automatically changed from feature/instantbook-cleanup to release/3.0.0 May 21, 2026 10:58
turegjorup and others added 5 commits May 27, 2026 10:26
Bad values now throw InvalidArgumentException (→ 500) on first instantiation
instead of NotAcceptableException (→ 406) at action time. The match default
arm is dropped as unreachable given the constructor guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Null feed, null feed source, and non-calendar feed type on the slide are
admin-fixable data issues, not Accept-header negotiation failures. Replaced
NotAcceptableException with Symfony's UnprocessableEntityHttpException so
they surface as 422 without a custom exception class or yaml mapping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The resources used here are not configured to block conflicting bookings at
the Graph API level — a POST that conflicts will simply succeed rather than
return 409. The pre-check is the actual safeguard; the 409 catch is just a
backstop for resources whose AutomateProcessing setting does reject conflicts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The cache wrapping getBusyIntervals() used a fixed key, so concurrent
requests with different watched resources or time windows could read each
other's data — a second slide would see the first slide's resources and
report unbooked rooms as free for up to 15 minutes.

Extracted the cached path into getBusyIntervalsCached() and built the key
from the sorted resource set plus from/to at minute precision.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extracted the live-Graph pre-check from quickBook() into assertSlotFree() so
the conflict-throw branch can be exercised without standing up the full
quickBook plumbing (spam-protect cache, validateResourceAccess, getToken).

Added two tests: a busy schedule overlapping the requested window must throw
ConflictException; an empty schedule must pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@turegjorup

Copy link
Copy Markdown
Contributor

Local review follow-up

Worked through the review findings on this branch. Five commits pushed on top of the original head (7b4318b3..3b9f1e64).

Fixed

Concern Resolution Commit
406 (Not Acceptable) for INSTANT_BOOK_BUSY_INTERVALS_SOURCE misconfig Constructor guard throws \InvalidArgumentException → 500; default arm dropped as unreachable ca263e37
406 for slide-config errors (null feed / null source / non-calendar type) Symfony\…\UnprocessableEntityHttpException → 422 (admin-fixable data state, not Accept-header negotiation) 557fc4fb
Pre-booking Graph call looked like wasted overhead Comment rewritten: the resources here are not configured to block conflicts at the Graph API level — a conflicting POST would silently succeed — so the pre-check is required for correctness, not an optimisation. The 409 catch is a backstop for resources that do reject conflicts a7ac945e
CACHE_KEY_BUSY_INTERVALS_PREFIX was a fixed key — different slides could read each other's data for up to 15 min Extracted to getBusyIntervalsCached(); key now built from sorted resource set + from/to at minute precision 91d028ed
No test coverage for the new conflict pre-check Extracted to assertSlotFree(); added tests for busy → ConflictException and empty → pass 3b9f1e64

Verified safe (no change needed)

  • Frontend apiUrl removal in calendar-single-booking.jsx — verified the change is a bug fix, not a regression. slide["@id"] is an absolute path (/v2/slides/<ulid>) per API Platform's default url_generation_strategy = 1 (ABSOLUTE_PATH); confirmed by existing test assertions in LayoutsTest.php. The previous ${apiUrl}${slide["@id"]}/action produced broken URLs because apiUrl came from localStorage populated with configData.apiEndpoint, which ClientConfigController does not actually return — so apiUrl was the literal string "undefined" in any non-fallback config.

Out of scope / FYI

  • KobaFeedType timestamp shape — dropped; the feed type is @deprecated, defensive code not warranted.
  • Polling cadence 5s → 60s — UX choice, documented in CHANGELOG.
  • phpunit.xml.dist disabledweak — minor scope creep; could be mentioned in the description or split if you want cleaner history.

Tooling: validated via task coding-standards:php:check, task code-analysis, task test:api -- tests/Interactive/InstantBookTest.php after each change. All clean.

@tuj
tuj merged commit a0b3c89 into release/3.0.0 May 27, 2026
21 checks passed
@tuj
tuj deleted the feature/instantbook-busy-from-feed branch May 27, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request version 3 Issues related to the release of version 3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants