Packages

phoenix_kit

1.7.205
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib phoenix_kit email send_profiles.ex
Raw

lib/phoenix_kit/email/send_profiles.ex

defmodule PhoenixKit.Email.SendProfiles do
@moduledoc """
Context for newsletter send profiles ("Send Settings").
CRUD plus service-wide default management for `PhoenixKit.Email.SendProfile`.
"""
import Ecto.Query
alias PhoenixKit.Email.SendProfile
def list_send_profiles do
SendProfile
|> order_by([sp], asc: sp.name)
|> repo().all()
end
def get_send_profile!(uuid), do: repo().get!(SendProfile, uuid)
def get_send_profile(uuid), do: repo().get(SendProfile, uuid)
def create_send_profile(attrs) do
%SendProfile{}
|> SendProfile.changeset(attrs)
|> repo().insert()
end
def update_send_profile(%SendProfile{} = send_profile, attrs) do
send_profile
|> SendProfile.changeset(attrs)
|> repo().update()
end
def delete_send_profile(%SendProfile{} = send_profile), do: repo().delete(send_profile)
@doc """
Returns the service-wide default send profile, or `nil` if none is set.
"""
def get_default_send_profile do
# `enabled` is an operator kill-switch — a disabled profile must never be
# resolved for sending, not even when it is the default.
SendProfile
|> where([sp], sp.is_default == true and sp.enabled == true)
|> repo().one()
end
@doc """
Makes `send_profile` the service-wide default, clearing any previous
default in the same transaction. Bypasses the regular changeset
(raw `is_default` flips only) since no other field changes — the
partial unique index on `is_default` backstops concurrent races.
"""
def set_default_send_profile(%SendProfile{uuid: uuid}) do
repo().transaction(fn ->
SendProfile
|> where([sp], sp.is_default == true and sp.uuid != ^uuid)
|> repo().update_all(set: [is_default: false])
SendProfile
|> where([sp], sp.uuid == ^uuid)
|> repo().update_all(set: [is_default: true])
get_send_profile!(uuid)
end)
rescue
# Two concurrent "make default" clicks race on the partial unique index:
# each transaction's clear-step can't see the other's uncommitted set-step,
# so the loser's set-step trips the index and `update_all` RAISES — it
# bypasses changesets, so nothing translates the constraint into an error
# tuple. Normalize it: the LiveView's generic {:error, _} clause then shows
# "could not set default" instead of the whole view crashing. Anything
# other than exactly this constraint re-raises untouched.
e in Postgrex.Error ->
if e.postgres[:code] == :unique_violation and
e.postgres[:constraint] == "idx_email_send_profiles_default" do
{:error, :concurrent_default_change}
else
reraise e, __STACKTRACE__
end
end
defp repo, do: PhoenixKit.RepoHelper.repo()
end