Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Бізнес-логіка й контролери». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Контролер має бути тонким - приймати вхідні дані, викликати потрібний сервіс/use-case і формувати відповідь; уся бізнес-логіка виноситься нижче по шарах: сервіси (Application layer), доменний шар, репозиторії, валідація схем, авторизація/політики, мапери/DTO, а кросс-нарізні речі (auth, логування, rate-limit) - у middleware/інфраструктуру. **Ключове:** інтеграції та побічні ефекти (зовнішні API, e-mail/SMS, черги) також виносяться в інфраструктурний шар і викликаються з use-cases, а не напряму з контролера.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняКоротко: **контролер має бути тонким** - отримувати вхідні дані, викликати потрібний "use-case/сервіс" і формувати відповідь. **Уся бізнес-логіка виноситься нижче по шарах.** Ось куди саме: ## Куди виносити логіку 1. **Сервіси / Use-cases (Application layer)** - Що тут: оркестрація сценаріїв, транзакції, виклики репозиторіїв, інтеграції, доменні перевірки високого рівня. - Контролер → `userService.createUser(dto)` → результат/виняток. - Іменування за діями: `CreateUser`, `ChangeEmail`, `PlaceOrder`. 2. **Домений шар (Domain layer)** - **Entities/Value Objects** з інваріантами й бізнес-правилами (без залежностей від Express/БД). - Приклад: `User.changeEmail()` валідує правило "не можна змінювати e-mail частіше N разів". 3. **Репозиторії / DAO (Data access layer)** - Інкапсулюють доступ до БД/ORM (Prisma, Sequelize, TypeORM), зберігають **лише** CRUD і прості вибірки. - Інтерфейси в домені, реалізації - в інфраструктурі. 4. **Валідація схем (Validation layer)** - Схеми вводу/виводу: `zod/joi/express-validator`. - Запускати до контролера (middleware) чи в use-case (якщо залежить від доменних правил). - Контролер лишається чистим від дерев if/else. 5. **Авторизація/політики (Policy/ACL)** - Правила доступу: `canUpdateProfile(user, target)`. - Тримати окремо від контролера (policy-функції чи Casbin/Oso). 6. **Мапери/DTO і форматування** - Перетворення між шарами: запит → DTO → доменна сутність → DTO → відповідь. - Прибирає витік деталей БД/ORM назовні. 7. **Крос-нарізні речі - в middleware/інфраструктуру** - Автентифікація, логування, трейсинг, rate-limit, кеш, CSRF, CORS - **не в контролері**. 8. **Інтеграції та побічні ефекти** - Клієнти зовнішніх API, e-mail/SMS, черги/задачі (BullMQ/RabbitMQ), кеш (Redis) - в інфраструктурному шарі, викликаються з use-cases. ## Приклад структури ```javascript src/ app.ts routes/ users.ts controllers/ users.controller.ts application/ # use-cases / services users/ create-user.usecase.ts change-email.usecase.ts domain/ users/ user.entity.ts email.vo.ts user.errors.ts user.repo.ts # інтерфейс репозиторію infrastructure/ db/ prisma/ user.prisma-repo.ts # реалізація репозиторію http/ mailer.client.ts queues/ events.publisher.ts shared/ validation/ user.dto.ts (zod/joi) mapping/ user.mapper.ts policies/ user.policies.ts ```Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.