← Back to Gatherings

4.6.3 Gathering Schedules

Gathering schedules place activities in timed slots within an event. GatheringScheduledActivitiesTable stores the rows; GatheringScheduleService owns reusable add/edit/delete validation; GatheringsController exposes the corresponding actions.

Model expectations

A schedule row belongs to one gathering and references the selected gathering activity. It carries a start time, optional end time, has_end_time, display title, description, preregistration flag, and custom-activity flag. Venue/location context belongs to the parent gathering, not the scheduled-activity row. Times must fall within the rules enforced by the table/service and be interpreted using gathering timezone context.

Mutation path

  1. Load and authorize the parent gathering.
  2. Pass request data, gathering, and identity to GatheringScheduleService.
  3. Render service validation errors without losing field values or focus.
  4. Return the expected full-page or Turbo Frame response.

Do not save schedule rows directly from a plugin or Stimulus controller. The service keeps activity membership, timing, and auditing rules in one place.

GatheringCloneService::cloneSchedule() is the supported copy path when cloning an event.

Accessibility and verification

Use properly labeled date/time inputs and include the relevant timezone in visible help text. Announce add/edit/delete results when a frame updates. Test invalid ranges, cross-gathering activity IDs, authorization, clone behavior, timezone boundaries, keyboard operation, and tenant separation.