defmodule GameServer.Leaderboards do @moduledoc ~S""" The Leaderboards context. Provides server-authoritative leaderboard management. Scores can only be submitted via server-side code — there is no public API for score submission. ## Usage # Create a leaderboard {:ok, lb} = Leaderboards.create_leaderboard(%{ slug: "weekly_kills", title: "Weekly Kills", sort_order: :desc, operator: :incr }) # Submit score (server-only): resolve the active leaderboard first and submit by integer ID leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills") {:ok, record} = Leaderboards.submit_score(leaderboard.id, user_id, 10) # List records with rank (use integer leaderboard id) records = Leaderboards.list_records(leaderboard.id, page: 1, limit: 25) # Get user's record (use integer leaderboard id) {:ok, record} = Leaderboards.get_user_record(leaderboard.id, user_id) **Note:** This is an SDK stub. Calling these functions will raise an error. The actual implementation runs on the GameServer. """ @doc ~S""" Returns a changeset for a leaderboard (used in forms). """ @spec change_leaderboard(GameServer.Leaderboards.Leaderboard.t()) :: Ecto.Changeset.t() def change_leaderboard(_leaderboard) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.change_leaderboard/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Returns a changeset for a leaderboard (used in forms). """ @spec change_leaderboard(GameServer.Leaderboards.Leaderboard.t(), map()) :: Ecto.Changeset.t() def change_leaderboard(_leaderboard, _attrs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.change_leaderboard/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Returns a changeset for a record (used in admin forms). """ @spec change_record(GameServer.Leaderboards.Record.t()) :: Ecto.Changeset.t() def change_record(_record) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.change_record/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Returns a changeset for a record (used in admin forms). """ @spec change_record(GameServer.Leaderboards.Record.t(), map()) :: Ecto.Changeset.t() def change_record(_record, _attrs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.change_record/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Count all leaderboard records across all leaderboards. """ @spec count_all_records() :: non_neg_integer() def count_all_records() do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> 0 _ -> raise "GameServer.Leaderboards.count_all_records/0 is a stub - only available at runtime on GameServer" end end @doc ~S""" Counts unique leaderboard slugs. """ @spec count_leaderboard_groups() :: non_neg_integer() def count_leaderboard_groups() do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> 0 _ -> raise "GameServer.Leaderboards.count_leaderboard_groups/0 is a stub - only available at runtime on GameServer" end end @doc ~S""" Counts leaderboards matching the given filters. Accepts the same filter options as `list_leaderboards/1`. """ @spec count_leaderboards() :: non_neg_integer() def count_leaderboards() do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> 0 _ -> raise "GameServer.Leaderboards.count_leaderboards/0 is a stub - only available at runtime on GameServer" end end @doc ~S""" Counts leaderboards matching the given filters. Accepts the same filter options as `list_leaderboards/1`. """ @spec count_leaderboards(keyword()) :: non_neg_integer() def count_leaderboards(_opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> 0 _ -> raise "GameServer.Leaderboards.count_leaderboards/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Counts records for a leaderboard. """ @spec count_records(integer()) :: non_neg_integer() def count_records(_leaderboard_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> 0 _ -> raise "GameServer.Leaderboards.count_records/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Creates a new leaderboard. ## Attributes See `t:GameServer.Types.leaderboard_create_attrs/0` for available fields. ## Examples iex> create_leaderboard(%{slug: "my_lb", title: "My Leaderboard"}) {:ok, %Leaderboard{}} iex> create_leaderboard(%{slug: "", title: ""}) {:error, %Ecto.Changeset{}} """ @spec create_leaderboard(GameServer.Types.leaderboard_create_attrs()) :: {:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()} def create_leaderboard(_attrs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.create_leaderboard/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Deletes a leaderboard and all its records. """ @spec delete_leaderboard(GameServer.Leaderboards.Leaderboard.t()) :: {:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()} def delete_leaderboard(_leaderboard) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.delete_leaderboard/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Deletes a record. """ @spec delete_record(GameServer.Leaderboards.Record.t()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, Ecto.Changeset.t()} def delete_record(_record) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.delete_record/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Deletes a user's record from a leaderboard. Accepts either leaderboard ID (integer) or slug (string). """ @spec delete_user_record(integer() | String.t(), integer()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, :not_found} def delete_user_record(_id_or_slug, _user_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.delete_user_record/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Ends a leaderboard by setting `ends_at` to the current time. """ @spec end_leaderboard(GameServer.Leaderboards.Leaderboard.t() | integer() | String.t()) :: {:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t() | :not_found} def end_leaderboard(_leaderboard) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.end_leaderboard/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets the currently active leaderboard with the given slug. Returns `nil` if no active leaderboard exists. An active leaderboard is one that: - Has not ended (`ends_at` is nil or in the future) - Has started (`starts_at` is nil or in the past) If multiple active leaderboards exist with the same slug, returns the most recently created one. """ @spec get_active_leaderboard_by_slug(String.t()) :: GameServer.Leaderboards.Leaderboard.t() | nil def get_active_leaderboard_by_slug(_slug) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]} _ -> raise "GameServer.Leaderboards.get_active_leaderboard_by_slug/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a single record by leaderboard ID and label. """ @spec get_label_record(integer(), String.t()) :: GameServer.Leaderboards.Record.t() | nil def get_label_record(_leaderboard_id, _label) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]} _ -> raise "GameServer.Leaderboards.get_label_record/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a leaderboard by its integer ID. ## Examples iex> get_leaderboard(123) %Leaderboard{id: 123} iex> get_leaderboard(999) nil """ @spec get_leaderboard(integer() | String.t()) :: GameServer.Leaderboards.Leaderboard.t() | nil def get_leaderboard(_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]} _ -> raise "GameServer.Leaderboards.get_leaderboard/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a leaderboard by its integer ID. Raises if not found. """ @spec get_leaderboard!(integer()) :: GameServer.Leaderboards.Leaderboard.t() def get_leaderboard!(_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.get_leaderboard!/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a single record by leaderboard ID and user ID. """ @spec get_record(integer(), integer()) :: GameServer.Leaderboards.Record.t() | nil def get_record(_leaderboard_id, _user_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]} _ -> raise "GameServer.Leaderboards.get_record/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a record by its integer ID. Raises if not found. Intended for internal/admin usage. """ @spec get_record!(integer()) :: GameServer.Leaderboards.Record.t() def get_record!(_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> nil _ -> raise "GameServer.Leaderboards.get_record!/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Gets a user's record with their rank. Returns `{:ok, record_with_rank}` or `{:error, :not_found}`. """ @spec get_user_record(integer(), integer()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, :not_found} def get_user_record(_leaderboard_id, _user_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.get_user_record/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists unique leaderboard slugs with summary info. Returns a list of maps with: - `:slug` - the leaderboard slug - `:title` - title from the latest leaderboard - `:description` - description from the latest leaderboard - `:active_id` - ID of the currently active leaderboard (or nil) - `:latest_id` - ID of the most recent leaderboard - `:season_count` - total number of leaderboards with this slug """ @spec list_leaderboard_groups() :: [map()] def list_leaderboard_groups() do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> %{} _ -> raise "GameServer.Leaderboards.list_leaderboard_groups/0 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists unique leaderboard slugs with summary info. Returns a list of maps with: - `:slug` - the leaderboard slug - `:title` - title from the latest leaderboard - `:description` - description from the latest leaderboard - `:active_id` - ID of the currently active leaderboard (or nil) - `:latest_id` - ID of the most recent leaderboard - `:season_count` - total number of leaderboards with this slug """ @spec list_leaderboard_groups(keyword()) :: [map()] def list_leaderboard_groups(_opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> %{} _ -> raise "GameServer.Leaderboards.list_leaderboard_groups/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists leaderboards with optional filters. ## Options * `:slug` - Filter by slug (returns all seasons of that leaderboard) * `:active` - If `true`, only active leaderboards. If `false`, only ended. * `:order_by` - Order by field: `:ends_at` or `:inserted_at` (default) * `:starts_after` - Only leaderboards that started after this DateTime * `:starts_before` - Only leaderboards that started before this DateTime * `:ends_after` - Only leaderboards that end after this DateTime * `:ends_before` - Only leaderboards that end before this DateTime * `:page` - Page number (default 1) * `:page_size` - Page size (default 25) ## Examples iex> list_leaderboards(active: true) [%Leaderboard{}, ...] iex> list_leaderboards(slug: "weekly_kills") [%Leaderboard{}, ...] iex> list_leaderboards(starts_after: ~U[2025-01-01 00:00:00Z]) [%Leaderboard{}, ...] """ @spec list_leaderboards() :: [GameServer.Leaderboards.Leaderboard.t()] def list_leaderboards() do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_leaderboards/0 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists leaderboards with optional filters. ## Options * `:slug` - Filter by slug (returns all seasons of that leaderboard) * `:active` - If `true`, only active leaderboards. If `false`, only ended. * `:order_by` - Order by field: `:ends_at` or `:inserted_at` (default) * `:starts_after` - Only leaderboards that started after this DateTime * `:starts_before` - Only leaderboards that started before this DateTime * `:ends_after` - Only leaderboards that end after this DateTime * `:ends_before` - Only leaderboards that end before this DateTime * `:page` - Page number (default 1) * `:page_size` - Page size (default 25) ## Examples iex> list_leaderboards(active: true) [%Leaderboard{}, ...] iex> list_leaderboards(slug: "weekly_kills") [%Leaderboard{}, ...] iex> list_leaderboards(starts_after: ~U[2025-01-01 00:00:00Z]) [%Leaderboard{}, ...] """ @spec list_leaderboards(keyword()) :: [GameServer.Leaderboards.Leaderboard.t()] def list_leaderboards(_opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_leaderboards/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists all leaderboards with the given slug (all seasons), ordered by end date. """ @spec list_leaderboards_by_slug(String.t()) :: [GameServer.Leaderboards.Leaderboard.t()] def list_leaderboards_by_slug(_slug) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_leaderboards_by_slug/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists all leaderboards with the given slug (all seasons), ordered by end date. """ @spec list_leaderboards_by_slug( String.t(), keyword() ) :: [GameServer.Leaderboards.Leaderboard.t()] def list_leaderboards_by_slug(_slug, _opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_leaderboards_by_slug/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists records for a leaderboard, ordered by rank. ## Options See `t:GameServer.Types.pagination_opts/0` for available options. Returns records with `rank` field populated. """ @spec list_records(integer()) :: [GameServer.Leaderboards.Record.t()] def list_records(_leaderboard_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_records/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists records for a leaderboard, ordered by rank. ## Options See `t:GameServer.Types.pagination_opts/0` for available options. Returns records with `rank` field populated. """ @spec list_records(integer(), GameServer.Types.pagination_opts()) :: [ GameServer.Leaderboards.Record.t() ] def list_records(_leaderboard_id, _opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_records/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists records around a specific user (centered on their position). Returns records above and below the user's rank. ## Options * `:limit` - Total number of records to return (default 11, centered on user) """ @spec list_records_around_user(integer(), integer()) :: [GameServer.Leaderboards.Record.t()] def list_records_around_user(_leaderboard_id, _user_id) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_records_around_user/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Lists records around a specific user (centered on their position). Returns records above and below the user's rank. ## Options * `:limit` - Total number of records to return (default 11, centered on user) """ @spec list_records_around_user(integer(), integer(), keyword()) :: [GameServer.Leaderboards.Record.t()] def list_records_around_user(_leaderboard_id, _user_id, _opts) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> [] _ -> raise "GameServer.Leaderboards.list_records_around_user/3 is a stub - only available at runtime on GameServer" end end @doc ~S""" Resolves multiple slugs to their currently active leaderboards in a single query. Returns a map of `slug => %Leaderboard{}` for each slug that has an active leaderboard. Slugs with no active leaderboard are omitted from the result. ## Examples iex> resolve_slugs(["weekly_kills", "monthly_score", "nonexistent"]) %{ "weekly_kills" => %Leaderboard{id: 1, slug: "weekly_kills", ...}, "monthly_score" => %Leaderboard{id: 5, slug: "monthly_score", ...} } """ @spec resolve_slugs([String.t()]) :: %{required(String.t()) => GameServer.Leaderboards.Leaderboard.t()} def resolve_slugs(_slugs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> "" _ -> raise "GameServer.Leaderboards.resolve_slugs/1 is a stub - only available at runtime on GameServer" end end @doc ~S""" Submit a score for a label-based (non-user) record. Works just like `submit_score/4` but uses a string label instead of a user ID. This is useful for statistics, rankings by category, etc. ## Examples iex> submit_label_score(leaderboard_id, "English", 42) {:ok, %Record{label: "English", score: 42}} """ @spec submit_label_score(integer(), String.t(), integer(), map()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, term()} def submit_label_score(_leaderboard_id, _label, _score, _metadata) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.submit_label_score/4 is a stub - only available at runtime on GameServer" end end @doc ~S""" Submits a score for a user on a leaderboard. This is a server-only function — there is no public API for score submission. The score is processed according to the leaderboard's operator: * `:set` — Always replace with new score * `:best` — Only update if new score is better (respects sort_order) * `:incr` — Add to existing score * `:decr` — Subtract from existing score To submit to a leaderboard by slug, first get the active leaderboard ID: leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills") Leaderboards.submit_score(leaderboard.id, user_id, 10) ## Examples iex> submit_score(123, user_id, 10) {:ok, %Record{score: 10}} iex> submit_score(123, user_id, 5, %{weapon: "sword"}) {:ok, %Record{score: 15, metadata: %{weapon: "sword"}}} """ @spec submit_score(integer(), integer(), integer()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, term()} def submit_score(_leaderboard_id, _user_id, _score) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.submit_score/3 is a stub - only available at runtime on GameServer" end end @doc ~S""" Submits a score for a user on a leaderboard. This is a server-only function — there is no public API for score submission. The score is processed according to the leaderboard's operator: * `:set` — Always replace with new score * `:best` — Only update if new score is better (respects sort_order) * `:incr` — Add to existing score * `:decr` — Subtract from existing score To submit to a leaderboard by slug, first get the active leaderboard ID: leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills") Leaderboards.submit_score(leaderboard.id, user_id, 10) ## Examples iex> submit_score(123, user_id, 10) {:ok, %Record{score: 10}} iex> submit_score(123, user_id, 5, %{weapon: "sword"}) {:ok, %Record{score: 15, metadata: %{weapon: "sword"}}} """ @spec submit_score(integer(), integer(), integer(), map()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, term()} def submit_score(_leaderboard_id, _user_id, _score, _metadata) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.submit_score/4 is a stub - only available at runtime on GameServer" end end @doc ~S""" Updates an existing leaderboard. Note: `slug`, `sort_order`, and `operator` cannot be changed after creation. ## Attributes See `t:GameServer.Types.leaderboard_update_attrs/0` for available fields. """ @spec update_leaderboard( GameServer.Leaderboards.Leaderboard.t(), GameServer.Types.leaderboard_update_attrs() ) :: {:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()} def update_leaderboard(_leaderboard, _attrs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.update_leaderboard/2 is a stub - only available at runtime on GameServer" end end @doc ~S""" Updates an existing record. Intended for internal/admin usage. """ @spec update_record(GameServer.Leaderboards.Record.t(), map()) :: {:ok, GameServer.Leaderboards.Record.t()} | {:error, Ecto.Changeset.t()} def update_record(_record, _attrs) do case Application.get_env(:game_server_sdk, :stub_mode, :raise) do :placeholder -> {:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}} _ -> raise "GameServer.Leaderboards.update_record/2 is a stub - only available at runtime on GameServer" end end end