What does this PR do?
Adds the ability to invite team members as optional guests on calendar invites for team event types.
The use case: you want a teammate — a shadow, observer, backup — to get the calendar invite, but you don’t want their availability to block the booking. Think CC’ing someone on a meeting.
Fixes #18947
/claim #18947
How it works end-to-end
- New M2M relation between
EventType and User via _optional_guest_team_members join table
- UI toggle in Advanced settings → “Invite team members as optional guests” with a multi-select picker
- All 6 calendar integrations handled natively:
- Google →
optional: true, responseStatus: needsAction
- Exchange 2013/2016/generic →
OptionalAttendees.Add()
- Feishu/Lark →
is_optional: true
- Email dedup so optional guests aren’t duplicated if they’re already attendees
- Optional guests are excluded from availability conflict checks entirely
What I considered
- Previous PRs (#22651, #22127) had stale code and merge conflicts — wrote this from scratch using current patterns
- Each calendar service uses its native optional attendee mechanism rather than hacking around it
- Prisma implicit M2M since we just need user IDs with no extra metadata
Mandatory Tasks (DO NOT REMOVE)
- I have self-reviewed the code (A decent size PR without self-review might be rejected).
- I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A — no docs change needed.
- I confirm automated tests are in place that prove my fix is effective or that my feature works.
How should this be tested?
- Create/edit a team event type → Advanced tab
- Toggle on “Invite team members as optional guests” → pick 1-2 members → Save
- Book the event from the public page
- Check the calendar invite — selected members should show as optional attendees
- Verify non-team event types don’t show the toggle
Edge cases worth checking
- Toggle on → select members → toggle off → should clear selection on save
- Select a member who’s also a host → should not be duplicated (dedup logic)
- Exchange calendars → member should be in OptionalAttendees, not RequiredAttendees
| Calendar |
What to verify |
| Google |
optional: true, responseStatus: needsAction |
| Exchange |
Member in OptionalAttendees collection |
| Feishu/Lark |
is_optional: true on attendee |