Я usecase делаю "плоскими", без асинхронщины. Такие классы много легче писать по TDD, да и просто покрывать тестами. Интерактор - это по факту фасад над usecase, который берет на себя асинхронщину. Это его единственная ответственность.
Репозиторий - это гейт между бэком, локальным хранилищем и ядром (domain). UseCase обращается к repository, не задумываясь о том, откуда/куда брать/отдавать данные. Соответственно в слое domain у тебя интерфейс репозитория. Реализация репозитория - в слое репозиториев.
Репозиторий разруливает потоки данных. Если нет данных, обращается к интерфейсу remote storage. Если нужно кэшировать, сохраняет полученные с бэка в локальное хранилище (через интерфейсы локальных хранилищ). Если данные уже есть в локальном хранилище, берет их оттуда через интерфейсы локальных хранилищ. Соответственно в слое репозиториев нужно знать интерфейсы локальных и удаленных хранилищ. А вот их реализации создаются в слоях local и remote.
Что это дает? Если к примеру решили перейти на другую БД, переписывание модуля local не затронет модули remote и repository. Соответственно компилятору нет нужды перекомпилировать остальные модули.