Conversation
Organizers of a recurring meeting can now move or cancel one occurrence without touching the rest of the series. - BFF: PUT /api/meetings/:uid/occurrences/:occurrenceId proxies to the meeting-service ITX occurrence update, forwarding only start_time and duration (upstream rejects recurrence on a single occurrence) - Meeting card: Edit on a recurring meeting first asks for the scope — this occurrence opens a reschedule dialog, the series opens the editor - Join page: organizers get Reschedule and Cancel actions for the occurrence being shown; the page follows the occurrence to its new start time and re-reads the series timeline - Docs: describe the per-occurrence flow Closes #2804 Signed-off-by: Rashad <mrashad@contractor.linuxfoundation.org> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Essentials Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Recurring cards can bypass scope selection, and the reschedule dialog has several timezone correctness defects.
Review effort: Balanced
Findings: 3
Open (3)
What changed in this PR
Adds organizer controls to reschedule or cancel individual recurring-meeting occurrences.
Changes:
- Adds the occurrence-update BFF endpoint and shared contracts.
- Adds scope selection, rescheduling UI, and join-page actions.
- Adds unit tests and updates meeting documentation.
| File | Description |
|---|---|
packages/shared/src/interfaces/meeting.interface.ts |
Adds occurrence-update and edit-scope contracts. |
docs/user/meetings/manage-meetings/index.md |
Documents occurrence management. |
apps/lfx-one/src/server/services/meeting.service.ts |
Proxies occurrence updates upstream. |
apps/lfx-one/src/server/services/meeting.service.spec.ts |
Tests update proxy behavior. |
apps/lfx-one/src/server/routes/meetings.route.ts |
Registers the PUT route. |
apps/lfx-one/src/server/controllers/meeting.controller.ts |
Validates and handles updates. |
apps/lfx-one/src/server/controllers/meeting.controller.spec.ts |
Tests controller validation. |
apps/lfx-one/src/app/shared/services/meeting.service.ts |
Adds the client update method. |
apps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.ts |
Adds join-page occurrence actions. |
apps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.spec.ts |
Tests action gating and navigation. |
apps/lfx-one/src/app/modules/meetings/meeting-join/meeting-join.component.html |
Renders occurrence action buttons. |
apps/lfx-one/src/app/modules/meetings/components/reschedule-occurrence-dialog/reschedule-occurrence-dialog.component.ts |
Implements rescheduling behavior. |
apps/lfx-one/src/app/modules/meetings/components/reschedule-occurrence-dialog/reschedule-occurrence-dialog.component.spec.ts |
Tests rescheduling validation and errors. |
apps/lfx-one/src/app/modules/meetings/components/reschedule-occurrence-dialog/reschedule-occurrence-dialog.component.html |
Renders the rescheduling form. |
apps/lfx-one/src/app/modules/meetings/components/recurring-meeting-edit-options/recurring-meeting-edit-options.component.ts |
Models occurrence-versus-series scope. |
apps/lfx-one/src/app/modules/meetings/components/recurring-meeting-edit-options/recurring-meeting-edit-options.component.html |
Updates scope-selection UI. |
apps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.ts |
Integrates scope and reschedule dialogs. |
apps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.spec.ts |
Tests meeting-card scope flow. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const occurrence = meeting.recurrence ? (this.occurrence() ?? getCurrentOrNextOccurrence(meeting)) : null; | ||
| if (occurrence) { | ||
| this.showEditScopeModal(meeting, occurrence); | ||
| return; | ||
| } | ||
|
|
||
| this.composer.open({ | ||
| mode: 'edit', | ||
| meetingUid: meeting.id, | ||
| projectUid: meeting.project_uid, | ||
| }); | ||
| this.openSeriesEditor(meeting); |
| Currently {{ occurrence.start_time | meetingTime: occurrence.duration : 'date' }} · | ||
| {{ occurrence.start_time | meetingTime: occurrence.duration : 'time' }} |
| public readonly timezoneLabel: string = getLongTimezoneName(this.occurrence.start_time, this.timezone) || this.timezone; | ||
| public readonly minDuration = MIN_CUSTOM_DURATION; | ||
| public readonly maxDuration = MAX_CUSTOM_DURATION; | ||
| public readonly minDate: Date = new Date(); |

Closes #2804
Summary
Organizers of a recurring meeting can now reschedule or cancel one occurrence without touching the rest of the series. No upstream changes are needed: the meeting-service already exposes
PUT/DELETE /itx/meetings/{meeting_id}/occurrences/{occurrence_id}.Changes
PUT /api/meetings/:uid/occurrences/:occurrenceId. Validates a numeric occurrence id, a parseable futurestart_time, and an integerdurationof 5–480 minutes, then forwards onlystart_time+duration(upstream rejectsrecurrenceon a single-occurrence update).?occurrence=and re-reads the series timeline; after a cancel it falls through to the next occurrence.docs/user/meetings/manage-meetings/index.mdnow describes the scope choice and join-page actions (it previously said edits only applied to a single occurrence).Personas
Only affects organizers (Maintainer / ED / Board Member or Meeting Coordinator) of recurring meetings. Attendees see no change beyond the updated schedule.
Testing
yarn format:check,yarn lint,./check-headers.sh,yarn test(5,572 passing),yarn build— all green locally.Notes
Opened as a draft while the local full-branch review is still running; its findings will be pushed here before marking ready.