Skip to main content

circle_feed_state

Overview

The circle_feed_state table extends the slow-feed pacing system to individual circles. Each row tracks when a user last checked a specific circle's feed and their current batch size. Rows are automatically created when a user joins a circle and deleted when they leave.

Relevant Invariants

  • Invariant #12: "Slowness Is Baked In" -- Circle-level pacing prevents binge reading within any single circle

Schema

-- From 20260131_circle_feed_state.sql
CREATE TABLE circle_feed_state (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
circle_id UUID NOT NULL REFERENCES circles(id) ON DELETE CASCADE,
last_checked_at TIMESTAMPTZ DEFAULT NOW(),
current_batch_size INTEGER DEFAULT 5,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, circle_id)
);

Columns

ColumnTypeNullableDefaultDescription
iduuidNogen_random_uuid()Primary key
user_iduuidNo--User whose state this tracks
circle_iduuidNo--Circle this state applies to
last_checked_attimestamptzNoNOW()When user last viewed this circle feed
current_batch_sizeintegerNo5Number of posts to show in current batch
created_attimestamptzNoNOW()Row creation timestamp
updated_attimestamptzNoNOW()Last update timestamp

RLS Policies

-- SELECT/UPDATE: Users can manage their own circle feed state
CREATE POLICY "Users can manage own circle feed state"
ON circle_feed_state FOR ALL
USING (auth.uid() = user_id);

Triggers

-- Auto-create feed state when user joins a circle
CREATE TRIGGER create_circle_feed_state_on_join
AFTER INSERT ON circle_members
FOR EACH ROW EXECUTE FUNCTION create_circle_feed_state();

-- Auto-delete feed state when user leaves a circle
CREATE TRIGGER delete_circle_feed_state_on_leave
AFTER DELETE ON circle_members
FOR EACH ROW EXECUTE FUNCTION delete_circle_feed_state();

Last updated: 2026-02-07