Connections module for PhoenixKit - Social Relationships System.
Provides a complete social relationships system with two types of relationships:
- Follows - One-way relationships (User A follows User B, no consent needed)
- 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
endBusiness 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.
Blocks a user.
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
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
Blocks a user.
Blocking removes any existing follows and connections between the users.
Parameters
blocker- The user who is blockingblocked- The user being blockedreason- Optional reason for the block
Returns
{:ok, %Block{}}- Block created successfully{:error, :self_block}- Cannot block yourself{:error, :already_blocked}- User is already blocked
Checks if user A has blocked user B.
Examples
iex> Connections.blocked?(user_a, user_b)
true
Checks if user is blocked by other user.
Examples
iex> Connections.blocked_by?(user, other)
true
Checks if two users can interact (neither has blocked the other).
Examples
iex> Connections.can_interact?(user_a, user_b)
true
Checks if two users are connected (mutual connection exists).
Examples
iex> Connections.connected?(user_a, user_b)
true
Returns the count of connections for a user.
Examples
iex> Connections.connections_count(user)
50
Disables the Connections module.
Enables the Connections module.
Checks if the Connections module is enabled.
Examples
iex> PhoenixKit.Modules.Connections.enabled?()
true
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}
Returns the count of followers for a user.
Examples
iex> Connections.followers_count(user)
42
Checks if user A is following user B.
Examples
iex> Connections.following?(user_a, user_b)
true
Returns the count of users that a user is following.
Examples
iex> Connections.following_count(user)
100
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
}
Gets the full relationship status between two users in one call.
Parameters
user_a- First useruser_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, ornil: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
}
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}
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
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{}}]
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{}}]
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{}}]
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
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
Returns the count of pending incoming connection requests for a user.
Examples
iex> Connections.pending_requests_count(user)
5
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
Removes an existing connection between two users.
Either user can remove the connection.
Parameters
user_a- First useruser_b- Second user
Returns
{:ok, %Connection{}}- Connection removed{:error, :not_connected}- No connection exists
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 requestrecipient- 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
Removes a block.
Parameters
blocker- The user who blockedblocked- The user who was blocked
Returns
{:ok, %Block{}}- Block removed{:error, :not_blocked}- No block exists
Removes a follow relationship.
Parameters
follower- The user who is followingfollowed- The user being followed
Returns
{:ok, %Follow{}}- Follow removed successfully{:error, :not_following}- No follow relationship exists