Eu diria que mesmo em Java não é bem assim, você até tem o Spring, mas até onde eu entendo (que não é muito), o básico do básico, se divide em controller, service e repository, mas esses são só os esteriótipos do container de injeção de dependência dele, você pode fazer tudo funcionar só com controller e repository por exemplo. Se você for das antigas, o Java tinhas os Servelets e provavelmente você criaria um DAO também.

O ponto é que arquitetura não é algo relacionado a linguagem ou ecossistema, é algo que você aplica pois faz sentido organizar daquela forma, se você entende o que cada conceito significa, vai ser algo mais natural saber organizar o seu código sem se orientar pela maioria.

Se você aprendeu a separar em DTO, Repositories, e etc, organize assim também na suas aplicações Node que não vai ser lá um grande problema.

Como você pediu algumas sugestões, o meu apelo é que ao invés de se orientar pelos frameworks, ou confiar no jeito freestyle de alguém, você tente aprender sobre as arquiteturas de fato que já existem, e depois disso tirar suas próprias conclusões sobre como implementar no seu dia-a-dia. Uma série sensacional que aborda esse assunto é a do Herberto Graca: https://herbertograca.com/2017/07/03/the-software-architecture-chronicles/

Feito o aviso, minha recomendação é a arquitetura hexagonal, ela pode ser tão simples quanto implementar um spagetti code, e escalar tão complexa quanto uma implementação de DDD + Clean Architecture com Microsserviços. E como ela é bem simples, você pode usar qualquer padrão que você já conheça de outra arquitetura para organizar o seu código que provavelmente você consegue misturar bem as coisas

A ideia é bem simples, você pensa na sua aplicação, o que ela usa de fora (por exemplo o banco de dados), quem de fora usa ela (por exemplo o usuário num navegador web), e define interfaces para serem portas para cada um desses da aplicação, ai você implementa um adapter para essa porta, e depois instancia os objetos e passa cada adapter como dependência da sua aplicação (e ela como dependência dos adapters que usam ela), e pronto já tá implementado.

Um exemplo simples é uma aplicação web mesmo igual você sugeriu, você pode estruturar assim por exemplo:

  • app/
    • ports/
      • in/
        • FindPost.ts
        • ListPosts.ts
        • CreatePost.ts
        • UpdatePost.ts
        • DeletePost.ts
      • out/
        • PostRepository.ts
    • services/
      • PostService.ts
  • adapters/
    • in/
      • PostController.ts
      • PostServiceTest.ts
    • out/
      • PrismaPostRepository.ts

Ai PostService é uma classe que implementa as portas in, usa as portas out, e deve ser utilizada pelos adapters in como o PostController ou um teste automatizado PostServiceTest. As portas out são implementadas pelo PrismaPostRepository lá nos adapters de out.

Links que eu recomendo sobre o assunto: https://jmgarridopaz.github.io/content/articles.html https://youtu.be/fkr6CNoMwx4

Bem interessante essa arquitetura.