Skip to content

Calendar ​

The Calendar module is GCM's central record of when things happen. It covers one-off events (a Christmas concert, a leaders' retreat), recurring weekly services, member birthdays pulled from the directory, and the meeting templates that drive every attendance roster.

Calendar month view

Events vs meetings ​

These two concepts are often confused because both show up on the calendar grid. They're stored separately and serve different jobs:

EventMeeting
Where it livesevents tablemeetings table
PurposeA specific occurrence (date + time + place)A recurring template that drives attendance (e.g. "Sunday Service")
Configured inCalendar β†’ Add eventSettings β†’ Meetings
RecurrenceRRULE on the event itselfImplicit β€” every time you mark attendance, you pick a meeting
ScopeOptional org-unit filterRequired scope_level (org / branch / center / cell)

A useful rule of thumb: if it has a published flyer, it's an event. If it's "what we do every Sunday at 10am," it's a meeting.

See Meetings & scope levels for the meeting model, Creating an event for one-off events.

What the calendar shows ​

The month grid surfaces three layers on top of each other:

  • Events β€” colour-coded dots, with hover-card preview.
  • Birthdays β€” a cake icon, pulled live from the member directory.
  • Recurring expansions β€” a single weekly event renders as 4 or 5 dots in a month, computed in the browser from the RRULE string.

The right-hand day panel lists everything happening on the selected date. The Upcoming tab flips to a chronological list of the next twenty events from today forward.

See Calendar views & day detail for the navigation patterns.

How recurrence works ​

GCM stores recurrence using the iCalendar RRULE standard (RFC 5545). When you pick "Weekly on Mon, Wed, Fri until Dec 31" in the event form, that's saved as:

FREQ=WEEKLY;BYDAY=MO,WE,FR;UNTIL=20261231T235959Z

Two extra fields cover the gaps:

  • exception_dates β€” a string array of dates to skip (e.g. cancel one specific Sunday).
  • recurrence_end_date β€” a redundant end-date column for fast SQL filtering.

For backward compatibility there's also a legacy recurrence_rule text column accepting weekly / monthly / yearly. New events always write both β€” the RRULE is authoritative.

See Recurring patterns & RRULE for the full picker spec.

Exceptions ​

The exception_dates array handles the simple case ("just skip this date"). For richer overrides β€” change the title for one occurrence, move start time by an hour, cancel only this date β€” there's an event_exceptions table:

sql
event_exceptions(
  event_id, exception_date,
  is_cancelled, override_title,
  override_start_time, override_end_time,
  override_location
)

This lets you turn a regular Sunday Service into a "Christmas Eve Service" without forking the whole recurring event. See Event exceptions.

Reminders ​

Each org has one event_reminder_config row that controls when and how reminders go out. The offsets are stored as hours-before, so [24, 1] means "24 hours before and one hour before." Channels are chosen by slug β€” email, sms, whatsapp, push β€” and tracked per-occurrence in event_reminders_sent to prevent double-sending recurring events.

See Event reminders.

Scope & branches ​

Events can be filtered to a single org unit (branch, center, cell) via org_unit_id. A null value means all branches see it β€” useful for org-wide announcements like Christmas.

The branch filter in the calendar toolbar applies a SQL OR org_unit_id IS NULL so global events stay visible while branch-specific ones are scoped. Users whose role doesn't span all branches only see the dropdown options they're assigned to.

Permissions ​

ActionAdminPastorShepherdMember
View calendaryesyesyesyes
Create eventyesyesyesno
Edit eventyesyesown org-unitno
Delete eventyesyesown org-unitno
Configure meetingsyesyesnono
Configure remindersyesnonono

The permission keys are events.view, events.create, events.edit, events.delete. Members can always see the calendar but can't add to it unless explicitly granted events.create.

Next steps ​

  1. Create an event β€” your first one-off date.
  2. Meetings & scope levels β€” set up Sunday Service.
  3. Recurring patterns & RRULE β€” beyond simple weekly.
  4. Event exceptions β€” when one occurrence differs.
  5. Event reminders β€” automated nudges by email / SMS / WhatsApp.
  6. Calendar views & day detail β€” month grid vs upcoming list.
  7. Linking events to attendance β€” how the calendar feeds the check-in station.