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.