PhoenixKit.Modules.Connections (phoenix_kit v1.7.71)

Copy Markdown View Source

Connections module for PhoenixKit - Social Relationships System.

Provides a complete social relationships system with two types of relationships:

  1. Follows - One-way relationships (User A follows User B, no consent needed)
  2. Connections - Two-way mutual relationships (both users must accept)

Plus blocking functionality to prevent unwanted interactions.

Public API

This is a PUBLIC API - all functions are available to parent applications for use in their own views, components, and logic.

Usage Examples

In a User Profile Page

alias PhoenixKit.Modules.Connections

# Get relationship for rendering follow/connect buttons
relationship = Connections.get_relationship(current_user, profile_user)

# Display counts
followers = Connections.followers_count(profile_user)
following = Connections.following_count(profile_user)
connections = Connections.connections_count(profile_user)

In a LiveView

def handle_event("follow", %{"user_uuid" => user_uuid}, socket) do
  target_user = get_user(user_uuid)

  case Connections.follow(socket.assigns.current_user, target_user) do
    {:ok, _follow} -> {:noreply, put_flash(socket, :info, "Now following!")}
    {:error, reason} -> {:noreply, put_flash(socket, :error, reason)}
  end
end

Business Rules

Following

  • Cannot follow yourself
  • Cannot follow if blocked (either direction)
  • Instant, no approval needed

Connections

  • Cannot connect with yourself
  • Cannot connect if blocked
  • Requires acceptance from recipient
  • If A requests B while B has pending request to A → auto-accept both

Blocking

  • Blocking removes any existing follow/connection between the users
  • Blocked user cannot follow, connect, or view profile
  • Blocking is one-way (A blocks B doesn't mean B blocks A)

Summary

Functions

Accepts a pending connection request.

Checks if user A has blocked user B.

Checks if user is blocked by other user.

Checks if two users can interact (neither has blocked the other).

Checks if two users are connected (mutual connection exists).

Returns the count of connections for a user.

Disables the Connections module.

Enables the Connections module.

Checks if the Connections module is enabled.

Creates a follow relationship.

Returns the count of followers for a user.

Checks if user A is following user B.

Returns the count of users that a user is following.

Returns the Connections module configuration.

Gets the full relationship status between two users in one call.

Returns statistics for the admin overview page.

Returns all users blocked by a user.

Returns all connections for a user.

Returns all followers of a user.

Returns all users that a user is following.

Returns pending incoming connection requests for a user.

Returns pending outgoing connection requests sent by a user.

Returns the count of pending incoming connection requests for a user.

Rejects a pending connection request.

Removes an existing connection between two users.

Sends a connection request from requester to recipient.

Removes a block.

Removes a follow relationship.

Functions

accept_connection(connection)

Accepts a pending connection request.

Parameters

  • connection_or_uuid - Connection struct or connection UUID

Returns

  • {:ok, %Connection{status: "accepted"}} - Request accepted
  • {:error, :not_found} - Connection not found
  • {:error, :not_pending} - Connection is not pending

block(blocker, blocked, reason \\ nil)

Blocks a user.

Blocking removes any existing follows and connections between the users.

Parameters

  • blocker - The user who is blocking
  • blocked - The user being blocked
  • reason - Optional reason for the block

Returns

  • {:ok, %Block{}} - Block created successfully
  • {:error, :self_block} - Cannot block yourself
  • {:error, :already_blocked} - User is already blocked

blocked?(blocker, blocked)

Checks if user A has blocked user B.

Examples

iex> Connections.blocked?(user_a, user_b)
true

blocked_by?(user, other)

Checks if user is blocked by other user.

Examples

iex> Connections.blocked_by?(user, other)
true

can_interact?(user_a, user_b)

Checks if two users can interact (neither has blocked the other).

Examples

iex> Connections.can_interact?(user_a, user_b)
true

connected?(user_a, user_b)

Checks if two users are connected (mutual connection exists).

Examples

iex> Connections.connected?(user_a, user_b)
true

connections_count(user)

Returns the count of connections for a user.

Examples

iex> Connections.connections_count(user)
50

disable_system()

Disables the Connections module.

enable_system()

Enables the Connections module.

enabled?()

Checks if the Connections module is enabled.

Examples

iex> PhoenixKit.Modules.Connections.enabled?()
true

follow(follower, followed)

Creates a follow relationship.

User A follows User B. No consent is required from User B.

Parameters

  • follower - The user who is following (struct with uuid/id, or integer/UUID string)
  • followed - The user being followed (struct with uuid/id, or integer/UUID string)

Returns

  • {:ok, %Follow{}} - Follow created successfully
  • {:error, :blocked} - Cannot follow due to block
  • {:error, :self_follow} - Cannot follow yourself
  • {:error, %Ecto.Changeset{}} - Validation error

Examples

iex> Connections.follow(current_user, target_user)
{:ok, %Follow{}}

iex> Connections.follow(user, user)
{:error, :self_follow}

followers_count(user)

Returns the count of followers for a user.

Examples

iex> Connections.followers_count(user)
42

following?(follower, followed)

Checks if user A is following user B.

Examples

iex> Connections.following?(user_a, user_b)
true

following_count(user)

Returns the count of users that a user is following.

Examples

iex> Connections.following_count(user)
100

get_config()

Returns the Connections module configuration.

Used by the Modules admin page to display module status and statistics.

Returns

A map containing:

  • :enabled - Whether the module is enabled
  • :follows_count - Total number of follows
  • :connections_count - Total number of accepted connections
  • :pending_count - Total number of pending connection requests
  • :blocks_count - Total number of blocks

Examples

iex> Connections.get_config()
%{
  enabled: true,
  follows_count: 100,
  connections_count: 50,
  pending_count: 5,
  blocks_count: 3
}

get_relationship(user_a, user_b)

Gets the full relationship status between two users in one call.

Parameters

  • user_a - First user
  • user_b - Second user

Returns

A map containing:

  • :following - Whether A follows B
  • :followed_by - Whether B follows A
  • :connected - Whether they have a mutual connection
  • :connection_pending - :sent, :received, or nil
  • :blocked - Whether A blocked B
  • :blocked_by - Whether B blocked A

Examples

iex> Connections.get_relationship(user_a, user_b)
%{
  following: true,
  followed_by: false,
  connected: false,
  connection_pending: :sent,
  blocked: false,
  blocked_by: false
}

get_stats()

Returns statistics for the admin overview page.

Returns

A map containing:

  • :follows - Total follows across all users
  • :connections - Total accepted connections
  • :pending - Total pending connection requests
  • :blocks - Total blocks

Examples

iex> Connections.get_stats()
%{follows: 100, connections: 50, pending: 5, blocks: 3}

list_blocked(user, opts \\ [])

Returns all users blocked by a user.

Options

  • :preload - Preload the blocked user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

list_connections(user, opts \\ [])

Returns all connections for a user.

Options

  • :preload - Preload the other user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

Examples

iex> Connections.list_connections(user)
[%Connection{requester: %User{}, recipient: %User{}}]

list_followers(user, opts \\ [])

Returns all followers of a user.

Options

  • :preload - Preload the follower user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

Examples

iex> Connections.list_followers(user)
[%Follow{follower: %User{}}]

list_following(user, opts \\ [])

Returns all users that a user is following.

Options

  • :preload - Preload the followed user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

Examples

iex> Connections.list_following(user)
[%Follow{followed: %User{}}]

list_pending_requests(user, opts \\ [])

Returns pending incoming connection requests for a user.

Options

  • :preload - Preload the requester user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

list_sent_requests(user, opts \\ [])

Returns pending outgoing connection requests sent by a user.

Options

  • :preload - Preload the recipient user (default: true)
  • :limit - Maximum number of results
  • :offset - Number of results to skip

pending_requests_count(user)

Returns the count of pending incoming connection requests for a user.

Examples

iex> Connections.pending_requests_count(user)
5

reject_connection(connection)

Rejects a pending connection request.

Parameters

  • connection_or_uuid - Connection struct or connection UUID

Returns

  • {:ok, %Connection{status: "rejected"}} - Request rejected
  • {:error, :not_found} - Connection not found
  • {:error, :not_pending} - Connection is not pending

remove_connection(user_a, user_b)

Removes an existing connection between two users.

Either user can remove the connection.

Parameters

  • user_a - First user
  • user_b - Second user

Returns

  • {:ok, %Connection{}} - Connection removed
  • {:error, :not_connected} - No connection exists

request_connection(requester, recipient)

Sends a connection request from requester to recipient.

If recipient already has a pending request to requester, both requests are automatically accepted.

Parameters

  • requester - The user sending the request
  • recipient - The user receiving the request

Returns

  • {:ok, %Connection{status: "pending"}} - Request sent
  • {:ok, %Connection{status: "accepted"}} - Auto-accepted (mutual request)
  • {:error, :blocked} - Cannot connect due to block
  • {:error, :self_connection} - Cannot connect with yourself
  • {:error, :already_connected} - Already connected
  • {:error, :pending_request} - Already has pending request

unblock(blocker, blocked)

Removes a block.

Parameters

  • blocker - The user who blocked
  • blocked - The user who was blocked

Returns

  • {:ok, %Block{}} - Block removed
  • {:error, :not_blocked} - No block exists

unfollow(follower, followed)

Removes a follow relationship.

Parameters

  • follower - The user who is following
  • followed - The user being followed

Returns

  • {:ok, %Follow{}} - Follow removed successfully
  • {:error, :not_following} - No follow relationship exists