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
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.
Core Entity Relationships
Open diagram in new tab →
Key Relationships Explained
Group Structure:
GROUP_TYPE categorizes groups (small groups, classes, teams, etc.)
GROUPs are organized by type with flexible hierarchies
MEMBERSHIPs 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
EVENTs (meetings, activities, gatherings)
ATTENDANCE tracks who actually attended
RSVPs track who plans to attend
EVENT_NOTEs 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_GROUPs organize related tags
TAGs 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 |
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
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
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
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
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
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
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
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
- Schema Qualification: Always use
planning_center. prefix for all table references
- Row Level Security: RLS automatically handles multi-tenancy and status filtering - do not add manual filters
- Monetary Values: Group event fees or donations stored in cents should be divided by 100.0 for display
- Archived Groups: Use
archived_at IS NULL or archived_at comparisons to control visibility instead of checking system_status
- Direct ID Columns: Core tables such as
groups_groups and groups_memberships expose direct IDs for performance-sensitive joins
Common Mistakes to Avoid
-
Missing Schema Prefix
- ❌
FROM groups_groups
- ✅
FROM planning_center.groups_groups
-
Adding Redundant RLS Filters
- ❌
WHERE tenant_organization_id = 1 AND system_status = 'active'
- ✅ Trust RLS to handle this automatically
-
Joining Without Schema
- ❌
JOIN groups_memberships m ON ...
- ✅
JOIN planning_center.groups_memberships m ON ...
-
Skipping Currency Conversion
- ❌
SELECT suggested_donation_cents as suggested_donation
- ✅
SELECT suggested_donation_cents / 100.0 as suggested_donation
-
Indexes: All tables have optimized indexes on:
- Primary keys and entity IDs
- Join columns and foreign keys
- Date columns for time-based queries
-
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