I use the following pattern…
# context
def list_users(queries \\ & &1) do
from(User)
|> queries.()
|> Repo.all()
end
# controller
Accounts.list_users(fn query ->
query
|> Accounts.include_user_profile()
|> Accounts.filter_non_executive_users()
|> Accounts.filter_users_by_company(company)
|> Accounts.order_users_by_first_name()
end)
All of the needed queries are publicly exposed from the context. This is very explicit, dependency-free, and dead simple to find the call sites where you might be using a specific query.
I previously experimented with a more dynamic method via a package, but found it to be a little more difficult to maintain and more magic than needed. That dynamic method is wrapped up in the TokenOperator package. There is a good bit of discussion on some of the things you mention in the thread for TokenOperator and another for the QueryBuilder package.