The "revenue-earning" configuration I've rolled out time and time again looks almost-unfailingly like this:
| Javascript | JQuery, Moment.js, etc | |
| "Presentation" | JSON/AJAX | HTML/LESS |
| Controllers | Play (Reactive, Async) | |
| Services | Play - RESTful API calls | Mondrian |
| Persistence | MongoDB (via ReactiveMongo) | |
Yep. Decidedly unsexy, and yes, occasionally the javascript can get a bit funky and coupled to the HTML, but it works and with careful attention to the principles of Single Responsibility and Least Surprise, a "vertical slice" through the functionality would look like:
| Javascript | /assets/js/author.js | |
| "Presentation" | /views/html/author/author.scala.html /assets/css/author.less |
|
| Controllers | /controllers/AuthorController.scala | |
| Services | /models/Author.scala /services/AuthorService.scala |
|
| Persistence | [Authors collection in MongoDB] | |
... where no source file is more than 200 lines of code. Nothing too controversial there, I think you'd agree.