> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getparable.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Data model

# Planning Center Groups Data Model

This document provides complete documentation of the Planning Center Groups data model in Parable, including all tables, fields, and relationships.

## Overview

The Groups module contains **18 entity tables** and **7 relationship tables** supporting small groups, classes, teams, group events, attendance tracking, enrollment management, and event RSVPs.

## Visual Data Model

<Tip>
  The diagram below shows the core entities and their relationships in the Groups module. Use it as a visual reference while exploring the detailed table definitions below.
</Tip>

### Core Entity Relationships

<Frame>
  <img src="https://mintcdn.com/parable/dIkTtcPi0zjaWA0V/diagrams/planning-center/groups-data-model-01.svg?fit=max&auto=format&n=dIkTtcPi0zjaWA0V&q=85&s=c55e879971237062bd68911347a35d01" alt="Groups module data model" width="3019" height="2717" data-path="diagrams/planning-center/groups-data-model-01.svg" />
</Frame>

[Open diagram in new tab →](/diagrams/planning-center/groups-data-model-01.svg)

### Key Relationships Explained

**Group Structure:**

* `GROUP_TYPE` categorizes groups (small groups, classes, teams, etc.)
* `GROUP`s are organized by type with flexible hierarchies
* `MEMBERSHIP`s link people to groups with roles (member, leader, owner)

**Enrollment Process:**

* `ENROLLMENT` tracks join requests and approvals
* Separate from `MEMBERSHIP` to handle pending/requested states
* Once approved, becomes an active `MEMBERSHIP`

**Event Management:**

* Groups host `EVENT`s (meetings, activities, gatherings)
* `ATTENDANCE` tracks who actually attended
* `RSVP`s track who plans to attend
* `EVENT_NOTE`s provide additional context

**Generic Relationship Pattern:**

* Location association via `groups_group_relationships` (relationship\_type: `location`)
* Campus linkage via `groups_group_relationships` (relationship\_type: `campus`)
* Resource assignments via `groups_group_relationships`

**Tagging System:**

* `TAG_GROUP`s organize related tags
* `TAG`s enable flexible categorization across groups
* Applied via relationship tables

## Query Requirements

### Schema Prefix

**IMPORTANT:** All tables in the Planning Center Groups module are in the `planning_center` schema. You MUST prefix all table names with `planning_center.` in your queries.

✅ CORRECT: `SELECT * FROM planning_center.groups_groups`
❌ INCORRECT: `SELECT * FROM groups_groups`

### Row Level Security (RLS)

This database uses Row Level Security (RLS) to automatically filter data based on:

* **tenant\_organization\_id**: You only see data for your current organization
* **system\_status**: You only see 'active' records by default

**DO NOT add these filters to your WHERE clause** - they are applied automatically:

* ❌ `WHERE tenant_organization_id = 1` (unnecessary)
* ❌ `WHERE system_status = 'active'` (unnecessary)

The RLS policies ensure you only access data you're authorized to see, making these filters redundant and potentially causing performance issues.

## Core Tables Overview

### Primary Entity Tables

* `groups_groups` - Small groups, classes, and teams
* `groups_people` - People who can join groups
* `groups_memberships` - Connections between people and groups
* `groups_events` - Group meetings and gatherings
* `groups_attendances` - Event attendance records
* `groups_rsvps` - Event RSVP responses from group members
* `groups_group_types` - Categories for organizing groups
* `groups_locations` - Physical meeting places
* `groups_enrollments` - Sign-up and registration management

### Supporting Entity Tables

* `groups_campuses` - Campus locations
* `groups_campus_groups` - Links between campuses and groups
* `groups_event_notes` - Notes for events
* `groups_group_applications` - Applications to join groups
* `groups_organizations` - Organization settings
* `groups_owners` - Group ownership information
* `groups_resources` - Group resources
* `groups_tags` - Labels for group characteristics
* `groups_tag_groups` - Tag groupings

### Relationship Tables

* `groups_group_relationships` - Links groups to other entities
* `groups_membership_relationships` - Links memberships to related entities
* `groups_event_relationships` - Links events to related entities
* `groups_attendance_relationships` - Links attendances to related entities
* `groups_rsvp_relationships` - Links RSVPs to events, groups, and people
* `groups_enrollment_relationships` - Links enrollments to related entities
* `groups_group_application_relationships` - Links applications to related entities

## Table Definitions

### groups\_groups

Small groups, classes, teams, and other group entities.

| Column                               | Type          | Description                                    |
| ------------------------------------ | ------------- | ---------------------------------------------- |
| `id`                                 | UUID          | Internal unique identifier                     |
| `group_id`                           | VARCHAR(64)   | Planning Center group ID                       |
| `archived_at`                        | TIMESTAMP     | When group was archived (NULL = active)        |
| `contact_email`                      | VARCHAR(255)  | Group contact email                            |
| `created_at`                         | TIMESTAMP     | When group was created                         |
| `description`                        | TEXT          | Group description                              |
| `events_visibility`                  | VARCHAR(255)  | Event visibility setting                       |
| `header_image`                       | JSONB         | Group header image data                        |
| `leaders_can_search_people_database` | BOOLEAN       | Leader permission setting                      |
| `location_type_preference`           | VARCHAR(255)  | 'physical', 'virtual', or 'hybrid'             |
| `memberships_count`                  | INTEGER       | Current member count                           |
| `name`                               | VARCHAR(255)  | Group name                                     |
| `public_church_center_web_url`       | VARCHAR(2048) | Public group URL                               |
| `schedule`                           | VARCHAR(255)  | Meeting schedule description                   |
| `virtual_location_url`               | VARCHAR(2048) | Online meeting URL                             |
| `tenant_organization_id`             | INTEGER       | Organization identifier                        |
| `system_status`                      | VARCHAR(50)   | Data status: 'active', 'transferring', 'stale' |
| `system_created_at`                  | TIMESTAMP     | When record was created in Parable             |
| `system_updated_at`                  | TIMESTAMP     | When record was last updated in Parable        |

### groups\_people

People who can participate in groups.

| Column                   | Type        | Description                             |
| ------------------------ | ----------- | --------------------------------------- |
| `id`                     | UUID        | Internal unique identifier              |
| `person_id`              | VARCHAR(64) | Planning Center person ID               |
| `permissions`            | VARCHAR(50) | Person's permission level               |
| `created_at`             | TIMESTAMP   | When person was added to Groups         |
| `tenant_organization_id` | INTEGER     | Organization identifier                 |
| `system_status`          | VARCHAR(50) | Data status                             |
| `system_created_at`      | TIMESTAMP   | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP   | When record was last updated in Parable |

### groups\_memberships

Connections between people and groups with roles.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `membership_id`          | VARCHAR(64)  | Planning Center membership ID           |
| `joined_at`              | TIMESTAMP    | When person joined group                |
| `role`                   | VARCHAR(255) | 'member' or 'leader'                    |
| `group_id`               | VARCHAR(64)  | Associated group ID (direct reference)  |
| `person_id`              | VARCHAR(64)  | Associated person ID (direct reference) |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

**Note**: This table uses direct ID columns for performance optimization.

### groups\_events

Group meetings, gatherings, and activities.

| Column                        | Type          | Description                             |
| ----------------------------- | ------------- | --------------------------------------- |
| `id`                          | UUID          | Internal unique identifier              |
| `event_id`                    | VARCHAR(64)   | Planning Center event ID                |
| `attendance_requests_enabled` | BOOLEAN       | Requesting attendance responses         |
| `automated_reminder_enabled`  | BOOLEAN       | Auto-reminders enabled                  |
| `canceled`                    | BOOLEAN       | Cancellation status                     |
| `canceled_at`                 | TIMESTAMP     | When event was canceled                 |
| `description`                 | TEXT          | Event description                       |
| `ends_at`                     | TIMESTAMP     | Event end time                          |
| `location_type_preference`    | VARCHAR(255)  | 'physical' or 'virtual'                 |
| `multi_day`                   | BOOLEAN       | Spans multiple days                     |
| `name`                        | VARCHAR(255)  | Event name                              |
| `reminders_sent`              | BOOLEAN       | Reminders have been sent                |
| `reminders_sent_at`           | TIMESTAMP     | When reminders were sent                |
| `repeating`                   | BOOLEAN       | Recurring event                         |
| `starts_at`                   | TIMESTAMP     | Event start time                        |
| `virtual_location_url`        | VARCHAR(2048) | Online meeting URL                      |
| `visitors_count`              | INTEGER       | Number of visitors                      |
| `tenant_organization_id`      | INTEGER       | Organization identifier                 |
| `system_status`               | VARCHAR(50)   | Data status                             |
| `system_created_at`           | TIMESTAMP     | When record was created in Parable      |
| `system_updated_at`           | TIMESTAMP     | When record was last updated in Parable |

### groups\_attendances

Records of who attended which events.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `attendance_id`          | VARCHAR(64)  | Planning Center attendance ID           |
| `attended`               | BOOLEAN      | Whether person attended                 |
| `role`                   | VARCHAR(255) | Person's role at event                  |
| `person_id`              | VARCHAR(64)  | Associated person ID (direct reference) |
| `event_id`               | VARCHAR(64)  | Associated event ID (direct reference)  |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_rsvps

RSVP responses for group events, tracking whether people plan to attend.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `rsvp_id`                | VARCHAR(64)  | Planning Center RSVP ID                 |
| `response`               | VARCHAR(255) | RSVP response: 'yes', 'no', or 'maybe'  |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

**Note**: RSVPs are linked to Events, Groups, and People through the `groups_rsvp_relationships` table. Use relationship joins to access the event, group, or person associated with each RSVP.

### groups\_group\_types

Categories for organizing and configuring groups.

| Column                      | Type        | Description                              |
| --------------------------- | ----------- | ---------------------------------------- |
| `id`                        | UUID        | Internal unique identifier               |
| `group_type_id`             | VARCHAR(64) | Planning Center group type ID            |
| `church_center_visible`     | BOOLEAN     | Visible in Church Center                 |
| `church_center_map_visible` | BOOLEAN     | Show on Church Center map                |
| `color`                     | VARCHAR(32) | Display color                            |
| `default_group_settings`    | JSONB       | Default settings for groups of this type |
| `description`               | TEXT        | Type description                         |
| `name`                      | TEXT        | Type name                                |
| `position`                  | INTEGER     | Sort order                               |
| `tenant_organization_id`    | INTEGER     | Organization identifier                  |
| `system_status`             | VARCHAR(50) | Data status                              |
| `system_created_at`         | TIMESTAMP   | When record was created in Parable       |
| `system_updated_at`         | TIMESTAMP   | When record was last updated in Parable  |

### groups\_locations

Physical locations where groups meet.

| Column                   | Type             | Description                             |
| ------------------------ | ---------------- | --------------------------------------- |
| `id`                     | UUID             | Internal unique identifier              |
| `location_id`            | VARCHAR(64)      | Planning Center location ID             |
| `display_preference`     | VARCHAR(100)     | How to display location                 |
| `full_formatted_address` | VARCHAR(500)     | Complete address                        |
| `latitude`               | DOUBLE PRECISION | GPS latitude                            |
| `longitude`              | DOUBLE PRECISION | GPS longitude                           |
| `name`                   | VARCHAR(255)     | Location name                           |
| `radius`                 | INTEGER          | Coverage radius                         |
| `strategy`               | VARCHAR(100)     | Location strategy                       |
| `tenant_organization_id` | INTEGER          | Organization identifier                 |
| `system_status`          | VARCHAR(50)      | Data status                             |
| `system_created_at`      | TIMESTAMP        | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP        | When record was last updated in Parable |

### groups\_enrollments

Group enrollment and registration management.

| Column                   | Type        | Description                             |
| ------------------------ | ----------- | --------------------------------------- |
| `id`                     | UUID        | Internal unique identifier              |
| `enrollment_id`          | VARCHAR(64) | Planning Center enrollment ID           |
| `auto_closed`            | BOOLEAN     | Automatically closed                    |
| `auto_closed_reason`     | TEXT        | Why auto-closed                         |
| `date_limit`             | TEXT        | Enrollment deadline                     |
| `date_limit_reached`     | BOOLEAN     | Past deadline                           |
| `member_limit`           | INTEGER     | Maximum members allowed                 |
| `member_limit_reached`   | BOOLEAN     | At capacity                             |
| `status`                 | TEXT        | Enrollment status                       |
| `strategy`               | TEXT        | Enrollment strategy                     |
| `tenant_organization_id` | INTEGER     | Organization identifier                 |
| `system_status`          | VARCHAR(50) | Data status                             |
| `system_created_at`      | TIMESTAMP   | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP   | When record was last updated in Parable |

### groups\_tags

Labels for categorizing and filtering groups.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `tag_id`                 | VARCHAR(64)  | Planning Center tag ID                  |
| `name`                   | VARCHAR(255) | Tag name                                |
| `position`               | INTEGER      | Sort order                              |
| `tag_group_id`           | VARCHAR(64)  | Parent tag group (direct reference)     |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_tag\_groups

Groupings for organizing tags.

| Column                     | Type         | Description                             |
| -------------------------- | ------------ | --------------------------------------- |
| `id`                       | UUID         | Internal unique identifier              |
| `tag_group_id`             | VARCHAR(64)  | Planning Center tag group ID            |
| `display_publicly`         | BOOLEAN      | Show publicly                           |
| `facet`                    | VARCHAR(255) | Facet type                              |
| `multiple_options_enabled` | BOOLEAN      | Allow multiple selections               |
| `name`                     | VARCHAR(255) | Group name                              |
| `position`                 | INTEGER      | Sort order                              |
| `tenant_organization_id`   | INTEGER      | Organization identifier                 |
| `system_status`            | VARCHAR(50)  | Data status                             |
| `system_created_at`        | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`        | TIMESTAMP    | When record was last updated in Parable |

### groups\_campuses

Campus locations for multi-site organizations.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `campus_id`              | VARCHAR(64)  | Planning Center campus ID               |
| `name`                   | VARCHAR(255) | Campus name                             |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_group\_applications

Applications to join groups requiring approval.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `group_application_id`   | VARCHAR(64)  | Planning Center application ID          |
| `applied_at`             | TIMESTAMP    | When application was submitted          |
| `message`                | TEXT         | Application message                     |
| `status`                 | VARCHAR(100) | Application status                      |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_event\_notes

Notes and annotations for events.

| Column                   | Type        | Description                             |
| ------------------------ | ----------- | --------------------------------------- |
| `id`                     | UUID        | Internal unique identifier              |
| `event_note_id`          | VARCHAR(64) | Planning Center event note ID           |
| `event_id`               | VARCHAR(64) | Associated event ID (direct reference)  |
| `body`                   | TEXT        | Note content                            |
| `annotatable_id`         | VARCHAR(64) | ID of annotated entity                  |
| `owner_id`               | VARCHAR(64) | Note owner ID                           |
| `tenant_organization_id` | INTEGER     | Organization identifier                 |
| `system_status`          | VARCHAR(50) | Data status                             |
| `system_created_at`      | TIMESTAMP   | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP   | When record was last updated in Parable |

### groups\_organizations

Organization configuration and settings.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `organization_id`        | VARCHAR(64)  | Planning Center organization ID         |
| `name`                   | VARCHAR(255) | Organization name                       |
| `time_zone`              | VARCHAR(255) | Organization time zone                  |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_owners

Group ownership and management information.

| Column                   | Type          | Description                             |
| ------------------------ | ------------- | --------------------------------------- |
| `id`                     | UUID          | Internal unique identifier              |
| `owner_id`               | VARCHAR(64)   | Planning Center owner ID                |
| `avatar_url`             | VARCHAR(2048) | Owner avatar image URL                  |
| `first_name`             | VARCHAR(255)  | Owner first name                        |
| `last_name`              | VARCHAR(255)  | Owner last name                         |
| `tenant_organization_id` | INTEGER       | Organization identifier                 |
| `system_status`          | VARCHAR(50)   | Data status                             |
| `system_created_at`      | TIMESTAMP     | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP     | When record was last updated in Parable |

### groups\_resources

Resources associated with group types.

| Column                   | Type         | Description                             |
| ------------------------ | ------------ | --------------------------------------- |
| `id`                     | UUID         | Internal unique identifier              |
| `resource_id`            | VARCHAR(64)  | Planning Center resource ID             |
| `group_type_id`          | VARCHAR(64)  | Associated group type ID                |
| `description`            | VARCHAR(255) | Resource description                    |
| `last_updated`           | TIMESTAMP    | When resource was last updated          |
| `name`                   | VARCHAR(255) | Resource name                           |
| `type`                   | VARCHAR(50)  | Resource type                           |
| `visibility`             | VARCHAR(50)  | Resource visibility                     |
| `created_by_id`          | VARCHAR(64)  | Creator ID                              |
| `tenant_organization_id` | INTEGER      | Organization identifier                 |
| `system_status`          | VARCHAR(50)  | Data status                             |
| `system_created_at`      | TIMESTAMP    | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP    | When record was last updated in Parable |

### groups\_campus\_groups

Links between campuses and groups.

| Column                   | Type        | Description                             |
| ------------------------ | ----------- | --------------------------------------- |
| `id`                     | UUID        | Internal unique identifier              |
| `group_id`               | VARCHAR(64) | Associated group ID (direct reference)  |
| `campus_id`              | VARCHAR(64) | Associated campus ID (direct reference) |
| `tenant_organization_id` | INTEGER     | Organization identifier                 |
| `system_status`          | VARCHAR(50) | Data status                             |
| `system_created_at`      | TIMESTAMP   | When record was created in Parable      |
| `system_updated_at`      | TIMESTAMP   | When record was last updated in Parable |

## Relationship Tables

### groups\_group\_relationships

Links groups to related entities like types, locations, and tags.

| Column                   | Type        | Description                |
| ------------------------ | ----------- | -------------------------- |
| `id`                     | UUID        | Internal unique identifier |
| `group_id`               | VARCHAR(64) | Group ID                   |
| `relationship_type`      | VARCHAR(50) | Type of relationship       |
| `relationship_id`        | VARCHAR(64) | ID of related entity       |
| `tenant_organization_id` | INTEGER     | Organization identifier    |
| `system_status`          | VARCHAR(50) | Data status                |
| `system_created_at`      | TIMESTAMP   | When created               |
| `system_updated_at`      | TIMESTAMP   | Last update                |

Common relationship types:

* `GroupType` - Links to groups\_group\_types
* `Location` - Links to groups\_locations
* `Tag` - Links to groups\_tags
* `Enrollment` - Links to groups\_enrollments
* `Campus` - Links to groups\_campuses

### groups\_membership\_relationships

Links memberships to additional related entities.

| Column                   | Type        | Description                |
| ------------------------ | ----------- | -------------------------- |
| `id`                     | UUID        | Internal unique identifier |
| `membership_id`          | VARCHAR(64) | Membership ID              |
| `relationship_type`      | VARCHAR(50) | Type of relationship       |
| `relationship_id`        | VARCHAR(64) | ID of related entity       |
| `tenant_organization_id` | INTEGER     | Organization identifier    |
| `system_status`          | VARCHAR(50) | Data status                |
| `system_created_at`      | TIMESTAMP   | When created               |
| `system_updated_at`      | TIMESTAMP   | Last update                |

### groups\_event\_relationships

Links events to groups and locations.

| Column                   | Type        | Description                |
| ------------------------ | ----------- | -------------------------- |
| `id`                     | UUID        | Internal unique identifier |
| `event_id`               | VARCHAR(64) | Event ID                   |
| `relationship_type`      | VARCHAR(50) | Type of relationship       |
| `relationship_id`        | VARCHAR(64) | ID of related entity       |
| `tenant_organization_id` | INTEGER     | Organization identifier    |
| `system_status`          | VARCHAR(50) | Data status                |
| `system_created_at`      | TIMESTAMP   | When created               |
| `system_updated_at`      | TIMESTAMP   | Last update                |

Common relationship types:

* `Group` - Links to groups\_groups
* `Location` - Links to groups\_locations

### groups\_attendance\_relationships

Links attendance records to events and people.

| Column                   | Type        | Description                |
| ------------------------ | ----------- | -------------------------- |
| `id`                     | UUID        | Internal unique identifier |
| `attendance_id`          | VARCHAR(64) | Attendance ID              |
| `relationship_type`      | VARCHAR(50) | Type of relationship       |
| `relationship_id`        | VARCHAR(64) | ID of related entity       |
| `tenant_organization_id` | INTEGER     | Organization identifier    |
| `system_status`          | VARCHAR(50) | Data status                |
| `system_created_at`      | TIMESTAMP   | When created               |
| `system_updated_at`      | TIMESTAMP   | Last update                |

Common relationship types:

* `Event` - Links to groups\_events
* `Person` - Links to groups\_people

### groups\_rsvp\_relationships

Links RSVPs to their associated events, groups, and people.

| Column                   | Type         | Description                |
| ------------------------ | ------------ | -------------------------- |
| `id`                     | UUID         | Internal unique identifier |
| `rsvp_id`                | VARCHAR(64)  | RSVP ID                    |
| `relationship_type`      | VARCHAR(255) | Type of relationship       |
| `relationship_id`        | VARCHAR(64)  | ID of related entity       |
| `tenant_organization_id` | INTEGER      | Organization identifier    |
| `system_status`          | VARCHAR(50)  | Data status                |
| `system_created_at`      | TIMESTAMP    | When created               |
| `system_updated_at`      | TIMESTAMP    | Last update                |

Common relationship types:

* `Event` - Links to groups\_events
* `Group` - Links to groups\_groups
* `Person` - Links to groups\_people

### groups\_enrollment\_relationships

Links enrollments to related entities.

| Column                   | Type        | Description                |
| ------------------------ | ----------- | -------------------------- |
| `id`                     | UUID        | Internal unique identifier |
| `enrollment_id`          | VARCHAR(64) | Enrollment ID              |
| `relationship_type`      | VARCHAR(50) | Type of relationship       |
| `relationship_id`        | VARCHAR(64) | ID of related entity       |
| `tenant_organization_id` | INTEGER     | Organization identifier    |
| `system_status`          | VARCHAR(50) | Data status                |
| `system_created_at`      | TIMESTAMP   | When created               |
| `system_updated_at`      | TIMESTAMP   | Last update                |

## System Fields

All tables include these system fields for data management:

* `tenant_organization_id` - Multi-tenant organization identifier
* `system_status` - Data lifecycle status:
  * `transferring` - Being imported from Planning Center
  * `active` - Current active data
  * `stale` - Marked for removal
* `system_created_at` - When record was created in Parable
* `system_updated_at` - When record was last updated in Parable

## Common Query Patterns

### Finding a Person's Groups

```sql theme={null}
SELECT
    g.name as group_name,
    g.description,
    m.role,
    m.joined_at
FROM planning_center.groups_memberships m
JOIN planning_center.groups_groups g
    ON m.group_id = g.group_id
WHERE m.person_id = 'PERSON_ID'
    AND g.archived_at IS NULL
ORDER BY m.joined_at DESC;
```

### Getting Group Members with Roles

```sql theme={null}
SELECT
    g.name as group_name,
    p.first_name,
    p.last_name,
    m.role,
    m.joined_at
FROM planning_center.groups_groups g
JOIN planning_center.groups_memberships m
    ON g.group_id = m.group_id
JOIN planning_center.groups_people p
    ON m.person_id = p.person_id
WHERE g.group_id = 'GROUP_ID'
ORDER BY m.role DESC, m.joined_at;
```

### Finding Events for a Group

```sql theme={null}
SELECT
    e.name as event_name,
    e.starts_at,
    e.ends_at,
    e.location_type_preference,
    e.canceled
FROM planning_center.groups_events e
JOIN planning_center.groups_event_relationships er
    ON e.event_id = er.event_id
    AND er.relationship_type = 'Group'
WHERE er.relationship_id = 'GROUP_ID'
    AND e.starts_at >= CURRENT_DATE
ORDER BY e.starts_at;
```

### Tracking Event Attendance

```sql theme={null}
SELECT
    e.name as event_name,
    e.starts_at,
    COUNT(CASE WHEN a.attended = true THEN 1 END) as attended_count,
    COUNT(DISTINCT ar.relationship_id) as total_invited
FROM planning_center.groups_events e
LEFT JOIN planning_center.groups_attendance_relationships ar
    ON e.event_id = ar.relationship_id
    AND ar.relationship_type = 'Event'
LEFT JOIN planning_center.groups_attendances a
    ON ar.attendance_id = a.attendance_id
GROUP BY e.event_id, e.name, e.starts_at
ORDER BY e.starts_at DESC;
```

### Event RSVPs Summary

```sql theme={null}
SELECT
    e.name as event_name,
    e.starts_at,
    COUNT(CASE WHEN r.response = 'yes' THEN 1 END) as yes_count,
    COUNT(CASE WHEN r.response = 'no' THEN 1 END) as no_count,
    COUNT(CASE WHEN r.response = 'maybe' THEN 1 END) as maybe_count,
    COUNT(*) as total_rsvps
FROM planning_center.groups_events e
JOIN planning_center.groups_rsvp_relationships er
    ON e.event_id = er.relationship_id
    AND er.relationship_type = 'Event'
JOIN planning_center.groups_rsvps r
    ON er.rsvp_id = r.rsvp_id
WHERE e.starts_at >= CURRENT_DATE
GROUP BY e.event_id, e.name, e.starts_at
ORDER BY e.starts_at;
```

### Finding RSVPs for a Person

```sql theme={null}
SELECT
    e.name as event_name,
    e.starts_at,
    g.name as group_name,
    r.response
FROM planning_center.groups_rsvps r
JOIN planning_center.groups_rsvp_relationships er
    ON r.rsvp_id = er.rsvp_id
    AND er.relationship_type = 'Event'
JOIN planning_center.groups_events e
    ON er.relationship_id = e.event_id
JOIN planning_center.groups_rsvp_relationships gr
    ON r.rsvp_id = gr.rsvp_id
    AND gr.relationship_type = 'Group'
JOIN planning_center.groups_groups g
    ON gr.relationship_id = g.group_id
JOIN planning_center.groups_rsvp_relationships pr
    ON r.rsvp_id = pr.rsvp_id
    AND pr.relationship_type = 'Person'
WHERE pr.relationship_id = 'PERSON_ID'
    AND e.starts_at >= CURRENT_DATE
ORDER BY e.starts_at;
```

### Groups by Type

```sql theme={null}
SELECT
    gt.name as group_type,
    COUNT(DISTINCT g.group_id) as group_count,
    SUM(g.memberships_count) as total_members
FROM planning_center.groups_group_types gt
LEFT JOIN planning_center.groups_group_relationships gr
    ON gt.group_type_id = gr.relationship_id
    AND gr.relationship_type = 'GroupType'
LEFT JOIN planning_center.groups_groups g
    ON gr.group_id = g.group_id
    AND g.archived_at IS NULL
GROUP BY gt.group_type_id, gt.name
ORDER BY gt.position;
```

## Data Integrity Rules

1. **Schema Qualification**: Always use `planning_center.` prefix for all table references
2. **Row Level Security**: RLS automatically handles multi-tenancy and status filtering - do not add manual filters
3. **Monetary Values**: Group event fees or donations stored in cents should be divided by 100.0 for display
4. **Archived Groups**: Use `archived_at IS NULL` or `archived_at` comparisons to control visibility instead of checking `system_status`
5. **Direct ID Columns**: Core tables such as `groups_groups` and `groups_memberships` expose direct IDs for performance-sensitive joins

## Common Mistakes to Avoid

1. **Missing Schema Prefix**
   * ❌ `FROM groups_groups`
   * ✅ `FROM planning_center.groups_groups`

2. **Adding Redundant RLS Filters**
   * ❌ `WHERE tenant_organization_id = 1 AND system_status = 'active'`
   * ✅ Trust RLS to handle this automatically

3. **Joining Without Schema**
   * ❌ `JOIN groups_memberships m ON ...`
   * ✅ `JOIN planning_center.groups_memberships m ON ...`

4. **Skipping Currency Conversion**
   * ❌ `SELECT suggested_donation_cents as suggested_donation`
   * ✅ `SELECT suggested_donation_cents / 100.0 as suggested_donation`

## Performance Considerations

1. **Indexes**: All tables have optimized indexes on:
   * Primary keys and entity IDs
   * Join columns and foreign keys
   * Date columns for time-based queries

2. **Query Optimization**:
   * Always use the `planning_center.` schema prefix
   * RLS handles tenant and status filtering automatically
   * Filter archived groups or attendance flags when relevant
   * Consider CTEs for complex multi-join queries
   * Use direct ID columns when available instead of relationship tables

## Data Types and Conventions

### Location Preferences

* `physical` - In-person meetings
* `virtual` - Online meetings
* `hybrid` - Both in-person and online

### Roles

* `member` - Regular group member
* `leader` - Group leader with additional permissions

### RSVP Responses

* `yes` - Person plans to attend
* `no` - Person will not attend
* `maybe` - Person is undecided

### Application Status

* `pending` - Awaiting review
* `approved` - Accepted into group
* `rejected` - Not accepted

## Next Steps

* Return to [Overview](/planning-center/groups/overview) for high-level understanding
* Review [Basic Queries](/planning-center/groups/basic-queries) for simple examples
* Check [Advanced Queries](/planning-center/groups/advanced-queries) for complex analysis
* See [Reporting Examples](/planning-center/groups/reporting-examples) for production-ready reports
