feat: add join confirmation and mail templating
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Simon 2026-03-09 18:15:12 +01:00
parent 3672ef0d03
commit 6385fbc831
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2
24 changed files with 585 additions and 53 deletions

View file

@ -0,0 +1,56 @@
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
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).
case Ash.read(query, domain: Mv.Membership, authorize?: false) do
{:ok, requests} ->
count = delete_expired_requests(requests)
Mix.shell().info("Deleted #{count} expired join request(s).")
count
{:error, error} ->
Mix.raise("Failed to list expired join requests: #{inspect(error)}")
end
end
defp delete_expired_requests(requests) do
Enum.reduce_while(requests, 0, fn request, acc ->
case Ash.destroy(request, domain: Mv.Membership, authorize?: false) do
:ok -> {:cont, acc + 1}
{:error, _} -> {:halt, acc}
end
end)
end
end