75 lines
2 KiB
Elixir
75 lines
2 KiB
Elixir
defmodule Mix.Tasks.JoinRequests.CleanupExpired do
|
|
@moduledoc """
|
|
Hard-deletes JoinRequests in status `pending_confirmation` whose confirmation link has expired.
|
|
|
|
Retention: records with `confirmation_token_expires_at` older than now are deleted.
|
|
Intended for cron or Oban (e.g. every hour). See docs/onboarding-join-concept.md.
|
|
|
|
## Usage
|
|
|
|
mix join_requests.cleanup_expired
|
|
|
|
## Examples
|
|
|
|
$ mix join_requests.cleanup_expired
|
|
Deleted 3 expired join request(s).
|
|
"""
|
|
use Mix.Task
|
|
|
|
require Ash.Query
|
|
require Logger
|
|
|
|
alias Mv.Membership.JoinRequest
|
|
|
|
@shortdoc "Deletes join requests in pending_confirmation with expired confirmation token"
|
|
|
|
@impl Mix.Task
|
|
def run(_args) do
|
|
Mix.Task.run("app.start")
|
|
|
|
now = DateTime.utc_now()
|
|
|
|
query =
|
|
JoinRequest
|
|
|> Ash.Query.filter(status == :pending_confirmation)
|
|
|> Ash.Query.filter(confirmation_token_expires_at < ^now)
|
|
|
|
# Bypass authorization: cleanup is a system maintenance task (cron/Oban).
|
|
# Use bulk_destroy so the data layer can delete in one pass when supported.
|
|
opts = [domain: Mv.Membership, authorize?: false]
|
|
|
|
count =
|
|
case Ash.count(query, opts) do
|
|
{:ok, n} -> n
|
|
{:error, _} -> 0
|
|
end
|
|
|
|
do_run(query, opts, count)
|
|
end
|
|
|
|
defp do_run(_query, _opts, 0) do
|
|
Mix.shell().info("No expired join requests to delete.")
|
|
0
|
|
end
|
|
|
|
defp do_run(query, opts, count) do
|
|
case Ash.bulk_destroy(query, :destroy, %{}, opts) do
|
|
%{status: status, errors: errors} when status in [:success, :partial_success] ->
|
|
maybe_log_errors(errors)
|
|
Mix.shell().info("Deleted #{count} expired join request(s).")
|
|
count
|
|
|
|
%{status: :error, errors: errors} ->
|
|
Mix.raise("Failed to delete expired join requests: #{inspect(errors)}")
|
|
end
|
|
end
|
|
|
|
defp maybe_log_errors(nil), do: :ok
|
|
defp maybe_log_errors([]), do: :ok
|
|
|
|
defp maybe_log_errors(errors) do
|
|
Logger.warning(
|
|
"Join requests cleanup: #{length(errors)} error(s) while deleting expired requests: #{inspect(errors)}"
|
|
)
|
|
end
|
|
end
|