Над репозиторием. Я делал следующим образом: пишу репозиторий, его интерфейс, затем через сервис контейнер привязываю интерфейс к реализации. Позже другой код-код-код, затем спустя некоторое время уже пишу слой кэша и всю логику кэширования. Кэширующий класс наследует тот же самый интерфейс и после написания подставляется в сервис-контейнер вместо текущей реализации. Можно кэширующий слой поставить еще выше, все от вашей архитектуры зависит (поэтому однозначного ответа тоже не будет), но ниже лично я смысла не вижу, может просто примеры не попадались, когда это требовалось. А архитектура в рамках ларавела четко не задана. Есть некие инструменты, описанные в документации, но вы можете строить архитектуру так, как вам кажется наиболее правильным. Я в свое время проникся статьей о гексагональной архитектуре и сейчас изложенные в ней принципы мне очень и очень нравятся (не сказать, что там что-то новое написали, просто разложили по полочкам внятно уже существующие вещи).