sojorn/go-backend/internal/database/migrations/20260204000002_circle_privacy.up.sql
Patrick Britton 61165000a9 Implement social graph, circle privacy, and data export system
Backend Infrastructure:
- Add circle_members table and is_in_circle() SQL function
- Implement GetFollowers/GetFollowing with pagination and trust scores
- Add complete circle management (add/remove/list members)
- Create comprehensive data export for GDPR compliance

API Endpoints:
- GET /users/:id/followers - List user's followers
- GET /users/:id/following - List users they follow
- POST /users/circle/:id - Add to close friends circle
- DELETE /users/circle/:id - Remove from circle
- GET /users/circle/members - List circle members
- GET /users/me/export - Export all user data as JSON

Note: Circle visibility enforcement in feed queries needs manual completion in post_repository.go GetFeed(), GetPostsByAuthor(), and GetPostByID() methods.
2026-02-04 16:19:05 -06:00

27 lines
1.1 KiB
PL/PgSQL

-- Circle (Close Friends) Privacy Feature
-- Allows users to share posts only with a specific inner circle
CREATE TABLE IF NOT EXISTS public.circle_members (
user_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
member_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (user_id, member_id),
-- Prevent self-addition
CHECK (user_id != member_id)
);
-- Index for fast circle membership checks
CREATE INDEX IF NOT EXISTS idx_circle_members_user_id ON public.circle_members(user_id);
CREATE INDEX IF NOT EXISTS idx_circle_members_member_id ON public.circle_members(member_id);
-- Helper function to check if a user is in another user's circle
CREATE OR REPLACE FUNCTION public.is_in_circle(circle_owner_id UUID, potential_member_id UUID)
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1 FROM public.circle_members
WHERE user_id = circle_owner_id AND member_id = potential_member_id
);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER STABLE;