Skip to main content

blocks

Overview

The blocks table implements user blocking. When a block is active, the blocked user completely disappears -- they see a 404-style response, not a "you have been blocked" message. This design prevents the block from becoming a form of communication.

Enhanced in the block_enhancement migration to add search hiding and profile view prevention.

Relevant Invariants

  • Invariant #5: "Repair Over Punishment" -- Blocking is a last resort; the system favors de-escalation first
  • Invariant #14: "Privacy Is Infrastructure" -- Block causes complete disappearance, not a visible status

Schema

-- Pre-existing table with additions from 20260205_block_enhancement.sql
CREATE TABLE blocks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
blocker_id UUID REFERENCES auth.users(id) NOT NULL,
blocked_id UUID REFERENCES auth.users(id) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
-- Block enhancement (20260205_block_enhancement.sql)
hide_from_search BOOLEAN DEFAULT TRUE,
prevent_profile_view BOOLEAN DEFAULT TRUE,
UNIQUE(blocker_id, blocked_id)
);

Columns

ColumnTypeNullableDefaultDescription
iduuidNouuid_generate_v4()Primary key
blocker_iduuidNo--User who initiated the block
blocked_iduuidNo--User being blocked
created_attimestamptzNoNOW()When block was created
hide_from_searchbooleanNoTRUEHide blocked user from search results
prevent_profile_viewbooleanNoTRUEPrevent blocked user from viewing blocker profile

RLS Policies

-- SELECT: Users can see their own blocks
CREATE POLICY "Users can view own blocks"
ON blocks FOR SELECT
USING (auth.uid() = blocker_id);

-- INSERT: Users can block others
CREATE POLICY "Users can create blocks"
ON blocks FOR INSERT
WITH CHECK (auth.uid() = blocker_id);

-- DELETE: Users can unblock
CREATE POLICY "Users can remove blocks"
ON blocks FOR DELETE
USING (auth.uid() = blocker_id);
  • profiles -- Both parties in the block
  • friendships -- Blocking removes any existing friendship

Last updated: 2026-02-07