GameServer.Friends (GameServer v1.0.509)

Friends context - handles friend requests and relationships.

Basic semantics:

  • A single friendships row represents a directed request from requester -> target.
  • status: "pending" | "accepted" | "rejected" | "blocked"

  • When a user accepts a pending incoming request, that request becomes accepted. If a reverse pending request exists, it will be removed to avoid duplicate rows.
  • Listing friends returns the other user from rows with status accepted in either direction.

Usage

# Create a friend request (requester -> target)
{:ok, friendship} = GameServer.Friends.create_request(requester_id, target_id)

# Accept a pending incoming request (performed by the target)
{:ok, accepted} = GameServer.Friends.accept_friend_request(friendship.id, %GameServer.Accounts.User{id: target_id})

# List accepted friends for a user (paginated)
friends = GameServer.Friends.list_friends_for_user(user_id, page: 1, page_size: 25)

# Count accepted friends for a user
count = GameServer.Friends.count_friends_for_user(user_id)

# Remove a friendship (either direction)
{:ok, _} = GameServer.Friends.remove_friend(user_id, friend_id)

Summary

Functions

Accept a friend request (only the target may accept). Returns {:ok, friendship}.

Block an incoming request (only the target may block). Returns {:ok, friendship} with status "blocked".

Cancel an outgoing friend request (only the requester may cancel).

Count blocked friendships for a user (number of blocked rows where user is target).

Count accepted friends for a given user (distinct other user ids).

Count incoming pending friend requests for a user.

Count outgoing pending friend requests for a user.

Create a friend request from requester -> target. If a reverse pending request exists (target -> requester) it will be accepted instead. Returns {:ok, friendship} on success or {:error, reason}.

Get friendship between two users (ordered requester->target) if exists

Get friendship by id (returns nil when not found)

Get friendship by id

List blocked friendships for a user (Friendship structs where the user is the blocker / target).

List accepted friends for a given user id - returns list of User structs.

List accepted friendships for a user along with the other user and friendship id.

List incoming pending friend requests for a user (Friendship structs).

List outgoing pending friend requests for a user (Friendship structs).

Reject a friend request (only the target may reject). Returns {:ok, friendship}.

Remove a friendship (either direction) - only participating users may call this.

Unblock a previously-blocked friendship (only the user who blocked may unblock). Returns {:ok, :unblocked} on success.

Types

user_id()

@type user_id() :: integer()

Functions

accept_friend_request(friendship_id, user)

@spec accept_friend_request(integer(), GameServer.Accounts.User.t()) ::
  {:ok, GameServer.Friends.Friendship.t()} | {:error, term()}

Accept a friend request (only the target may accept). Returns {:ok, friendship}.

block_friend_request(friendship_id, user)

@spec block_friend_request(integer(), GameServer.Accounts.User.t()) ::
  {:ok, GameServer.Friends.Friendship.t()} | {:error, term()}

Block an incoming request (only the target may block). Returns {:ok, friendship} with status "blocked".

cancel_request(friendship_id, user)

@spec cancel_request(integer(), GameServer.Accounts.User.t()) ::
  {:ok, :cancelled} | {:error, :not_found | :not_authorized | term()}

Cancel an outgoing friend request (only the requester may cancel).

count_blocked_for_user(user_id)

@spec count_blocked_for_user(user_id() | GameServer.Accounts.User.t()) ::
  non_neg_integer()

Count blocked friendships for a user (number of blocked rows where user is target).

count_friends_for_user(user_id)

@spec count_friends_for_user(user_id() | GameServer.Accounts.User.t()) ::
  non_neg_integer()

Count accepted friends for a given user (distinct other user ids).

count_incoming_requests(user_id)

@spec count_incoming_requests(user_id() | GameServer.Accounts.User.t()) ::
  non_neg_integer()

Count incoming pending friend requests for a user.

count_outgoing_requests(user_id)

@spec count_outgoing_requests(user_id() | GameServer.Accounts.User.t()) ::
  non_neg_integer()

Count outgoing pending friend requests for a user.

create_request(requester_id, target_id)

@spec create_request(GameServer.Accounts.User.t() | user_id(), user_id()) ::
  {:ok, GameServer.Friends.Friendship.t()}
  | {:error,
     :cannot_friend_self
     | :blocked
     | :already_friends
     | :already_requested
     | term()}

Create a friend request from requester -> target. If a reverse pending request exists (target -> requester) it will be accepted instead. Returns {:ok, friendship} on success or {:error, reason}.

get_by_pair(requester_id, target_id)

@spec get_by_pair(user_id(), user_id()) :: GameServer.Friends.Friendship.t() | nil

Get friendship between two users (ordered requester->target) if exists

get_friendship(id)

@spec get_friendship(integer()) :: GameServer.Friends.Friendship.t() | nil

Get friendship by id (returns nil when not found)

get_friendship!(id)

@spec get_friendship!(integer()) :: GameServer.Friends.Friendship.t()

Get friendship by id

list_blocked_for_user(user_id, opts \\ [])

List blocked friendships for a user (Friendship structs where the user is the blocker / target).

list_friends_for_user(user_id, opts \\ [])

List accepted friends for a given user id - returns list of User structs.

Options

See GameServer.Types.pagination_opts/0 for available options.

list_friends_with_friendship(user_id, opts \\ [])

@spec list_friends_with_friendship(
  integer() | GameServer.Accounts.User.t(),
  GameServer.Types.pagination_opts()
) :: [%{friendship_id: integer(), user: GameServer.Accounts.User.t()}]

List accepted friendships for a user along with the other user and friendship id.

Returns a list of maps: %{friendship_id: integer(), user: %User{}}

list_incoming_requests(user_id, opts \\ [])

List incoming pending friend requests for a user (Friendship structs).

Options

See GameServer.Types.pagination_opts/0 for available options.

list_outgoing_requests(user_id, opts \\ [])

List outgoing pending friend requests for a user (Friendship structs).

Options

See GameServer.Types.pagination_opts/0 for available options.

reject_friend_request(friendship_id, user)

@spec reject_friend_request(integer(), GameServer.Accounts.User.t()) ::
  {:ok, GameServer.Friends.Friendship.t()} | {:error, term()}

Reject a friend request (only the target may reject). Returns {:ok, friendship}.

remove_friend(user_id, friend_id)

@spec remove_friend(integer(), integer()) ::
  {:ok, GameServer.Friends.Friendship.t()} | {:error, term()}

Remove a friendship (either direction) - only participating users may call this.

subscribe_user(user_id)

@spec subscribe_user(user_id()) :: :ok

unblock_friendship(friendship_id, user)

@spec unblock_friendship(integer(), GameServer.Accounts.User.t()) ::
  {:ok, :unblocked} | {:error, term()}

Unblock a previously-blocked friendship (only the user who blocked may unblock). Returns {:ok, :unblocked} on success.

unsubscribe_user(user_id)

@spec unsubscribe_user(user_id()) :: :ok