An interface that returns Eloquent models has abstracted nothing

A repository interface returning ORM models and accepting query builders has renamed the ORM rather than abstracted it, and swapping the implementation is still impossible.

// in the domain, knowing nothing about storage
interface Orders
{
    public function ofCustomer(CustomerId $id): OrderCollection;
    public function save(Order $order): void;
}

// in infrastructure, knowing everything about it
final class EloquentOrders implements Orders
{
    public function ofCustomer(CustomerId $id): OrderCollection
    {
        $rows = OrderRow::where('customer_id', $id->value())->get();

        return OrderCollection::fromRows($rows);
    }
}

Named methods rather than a generic findBy are what carry the meaning, and they also mean each query is written once instead of assembled at every call site. The honest cost is a mapping layer between rows and domain objects, which is real work and the reason most projects skip this. It pays where the domain logic is complicated enough to be worth testing without a database, and does not where the application is forms over tables.