mitgliederverwaltung/lib/mix/tasks/join_requests.cleanup_expired.ex
Simon 5deb102e45
All checks were successful
continuous-integration/drone/push Build is passing
refactor: adress review comments
2026-03-09 18:54:40 +01:00

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