How to filter using a code interface

I tried this. I went down this path for a while for the purposes of learning, but this code lives outside of the resource and I would want the code interface to expose a single function to anything outside of the resource.

# outside of the resource
Red.Practice.Card
|> Ash.Query.for_read(:next, %{}, actor: user)
|> Red.Practice.read_one!()

The above is valid code and returns a result, but it does not filter by actor automatically.

Which made me think I still need to filter by actor in the filter expression, but I do not know how to access the actor there.

I tried this, which is invalid: filter expr(retry_at < now() and user_id == ^context.actor)

The prepare function had an after_action which ran after we already queried DB results belonging to other users, so it felt too late to start filtering there.

I also tried the following to see if I can add the filter in a before_action which was valid code, but the before_action never ran:

# inside the action
prepare fn query, context ->
        Ash.Query.before_action(query, fn
          query, results ->
            dbg("before action")
            dbg(query)
            {:ok, results}
        end)

        Ash.Query.after_action(query, fn
          query, [] ->
            dbg("No cards found with retry_at < now")
            Red.Practice.Card.oldest_untried_card()

          _query, results ->
            dbg("A card was found with retry_at < now")
            {:ok, results}
        end)
      end

I am okay with just passing the user_id as an argument to the code interface. It would be used like this from outside of the resource: Red.Practice.Card.next(user.id).

I will probably never create a JSON or GraphQL Api for this app. But I suspect that if I do, I would need to find a way to just use the auth context and not pass in an argument here.

But if @zachdaniel or anyone else is willing to keep helping me find the even-more-better way to do this, I’m open to keep trying things.