circle_members
Overview
The circle_members table tracks which users belong to which circles and their role within each circle. Roles include 'admin' (the circle owner) and 'member'. Membership changes trigger automatic creation or deletion of circle_feed_state rows.
Schema
-- From 20260131_circles_schema.sql
CREATE TABLE circle_members (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
circle_id UUID NOT NULL REFERENCES circles(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
role TEXT DEFAULT 'member' CHECK (role IN ('admin', 'member')),
joined_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(circle_id, user_id)
);
Columns
| Column | Type | Nullable | Default | Description |
|---|---|---|---|---|
id | uuid | No | gen_random_uuid() | Primary key |
circle_id | uuid | No | -- | Circle reference, cascades on delete |
user_id | uuid | No | -- | Member user reference, cascades on delete |
role | text | No | 'member' | Role: admin or member |
joined_at | timestamptz | No | NOW() | When user joined the circle |
RLS Policies
-- SELECT: Circle members can view other members
CREATE POLICY "Circle members can view membership"
ON circle_members FOR SELECT
USING (is_circle_member(auth.uid(), circle_id));
-- INSERT: Circle admin can add members
CREATE POLICY "Circle admin can add members"
ON circle_members FOR INSERT
WITH CHECK (is_circle_admin(auth.uid(), circle_id));
-- DELETE: Admin can remove members, members can leave
CREATE POLICY "Admin can remove or member can leave"
ON circle_members FOR DELETE
USING (
is_circle_admin(auth.uid(), circle_id) OR auth.uid() = user_id
);
Related
- circles -- Parent circle
- circle_feed_state -- Auto-created on membership join
- profiles -- Member user
Last updated: 2026-02-07