Чистая архитектура: как не превратить проект в спагетти
Следующий шаг
Открой бота или продолжай маршрут внутри раздела.
Статья -> план в ИИ
Отправь ссылку на эту статью в любой ИИ и получи план внедрения под свой проект.
Прочитай эту статью: https://vibecode.morecil.ru/ru/server-i-logika/chistaya-arhitectura/
Работай в контексте моего текущего проекта.
Сделай план внедрения под мой стек:
1) что изменить
2) в каких файлах
3) риски и типичные ошибки
4) как проверить, что всё работает
Если есть варианты, дай "быстрый" и "production-ready". Как использовать
- Скопируй этот промпт и отправь в чат с ИИ.
- Прикрепи проект или открой папку репозитория в ИИ-инструменте.
- Попроси изменения по файлам, риски и короткий чеклист проверки.
Если ты вайбкодишь уже пару месяцев, то наверняка сталкивался с этой классической картиной:
Начинаешь простой пет-проект — «да ладно, всего пару эндпоинтов». Через неделю у тебя 12 файлов в одной папке src/, функции на 300 строк, импорты через 5 папок вверх, а при попытке добавить новую фичу ИИ выдаёт «я не понимаю контекст всего проекта».
В итоге код превращается в спагетти, ты тратишь часы на рефакторинг вместо того, чтобы двигаться дальше, а проект хочется просто удалить и начать заново.
Я прошёл через это раз 15. А потом начал использовать чистую архитектуру (Clean Architecture) и всё изменилось. Теперь даже большие приложения (боты с платежами, SaaS-тулы, внутренние сервисы) остаются читаемыми, легко масштабируются и — самое главное — ИИ понимает, что куда писать.
Сегодня разберём по полочкам, что это такое, почему это must-have для вайбкодера в 2026 году и как заставить Claude / Cursor / Codex генерировать код сразу по чистой архитектуре.
Что такое чистая архитектура простыми словами
Представь дом:
- Ядро дома (Entities / Domain) — стены, фундамент, несущие конструкции. Это бизнес-правила, которые никогда не меняются (пользователь, заказ, платеж).
- Этаж выше (Use Cases / Application) — комнаты и мебель. Это конкретные действия: «создать заказ», «отправить уведомление».
- Ещё выше (Adapters / Interface) — окна и двери. Это как код общается с внешним миром: контроллеры, репозитории, внешние API.
- Снаружи (Frameworks & Drivers) — крыша, сад, забор. База данных, фреймворк (FastAPI, Express), Telegram Bot API и т.д.
Главное правило (Dependency Rule): стрелки зависимостей идут только внутрь. Внешние слои знают про внутренние, но внутренние — никогда не знают про внешние.
То есть твой домен не знает, что у тебя PostgreSQL или MongoDB. Он просто говорит «мне нужен репозиторий пользователей» — и всё.
Почему это идеально именно для вайбкодеров
ИИ лучше понимает задачу
Когда ты говоришь модели «напиши функцию регистрации», она видит чёткую структуру и не лепит всё в один файл.Легко добавлять и менять
Хочешь поменять базу с Supabase на Prisma? Меняешь только Infrastructure слой. Домен и Use Cases остаются нетронутыми.Тесты пишутся сами собой
Use Cases — это чистые функции. Их можно тестировать без запуска сервера.Проект не превращается в монолит
Даже если сейчас ты делаешь пет-проект на 3 файла, через месяц он вырастет до 50 — и ты не утонешь.Легко подключать новые ИИ-агенты
Cline, OpenCode, Pencil — все они сразу понимают, куда класть новый код.
Практическая структура папок (мой шаблон 2026 года)
Вот как выглядит мой типичный проект:
src/
├── domain/ # Ядро — никогда не меняется
│ ├── entities/ # User, Order, Payment
│ ├── value-objects/ # Email, Money, UUID
│ └── exceptions/ # DomainError, ValidationError
│
├── application/ # Бизнес-логика
│ ├── use-cases/ # CreateUser, ProcessOrder, SendNotification
│ ├── dto/ # CreateUserDto, OrderResponseDto
│ └── ports/ # Интерфейсы репозиториев и внешних сервисов
│
├── infrastructure/ # Конкретные реализации
│ ├── persistence/ # Репозитории (Prisma, Supabase)
│ ├── external/ # Telegram, Stripe, Email
│ └── config/ # env, database connection
│
├── presentation/ # API, контроллеры, боты
│ ├── http/ # FastAPI routers или Next.js API routes
│ ├── telegram/ # Handlers бота
│ └── webhooks/ # Stripe webhooks и т.д.
│
├── common/ # Утилиты, guards, decorators
└── main.ts / app.py # Точка входа
Как заставить ИИ писать по чистой архитектуре (готовые промпты)
Промпт №1 — создание нового проекта с нуля
Ты эксперт по чистой архитектуре (Uncle Bob).
Создай структуру проекта на TypeScript + FastAPI (или Next.js App Router) по правилам Clean Architecture.
Слои:
- domain (entities, value objects, exceptions)
- application (use-cases, dto, ports)
- infrastructure (persistence, external services)
- presentation (controllers/handlers)
Задача: [опиши свою задачу, например "бот-магазин с оплатой через ЮKassa"]
Сначала выведи полную структуру папок.
Потом создай все необходимые файлы с заглушками.
В каждом use-case добавь комментарии с Dependency Inversion.
Промпт №2 — рефакторинг существующего спагетти-кода
У меня есть проект в стиле "всё в одном файле". Переведи его на чистую архитектуру.
Вот текущая структура: [вставь tree]
Сохрани всю логику, но раздели по слоям:
domain → application → infrastructure → presentation
Сначала покажи новую структуру папок, потом поэтапно перепиши каждый слой.
Реальный пример: Use Case «Создать заказ»
domain/entities/order.ts
export class Order {
constructor(
public readonly id: string,
public readonly userId: string,
public readonly items: OrderItem[],
public readonly total: Money,
public readonly status: OrderStatus = 'pending'
) {}
confirm() {
if (this.status !== 'pending') throw new DomainError('Order already confirmed');
// бизнес-правило
}
}
application/use-cases/create-order.ts
export class CreateOrderUseCase {
constructor(
private readonly orderRepo: OrderRepositoryPort,
private readonly paymentService: PaymentPort
) {}
async execute(dto: CreateOrderDto): Promise<OrderResponseDto> {
const order = new Order(/* ... */);
await this.orderRepo.save(order);
await this.paymentService.createPayment(order);
return OrderMapper.toResponse(order);
}
}
infrastructure/persistence/prisma-order-repo.ts
export class PrismaOrderRepository implements OrderRepositoryPort {
async save(order: Order) { /* prisma magic */ }
}
Видишь? Use Case не знает про Prisma. Он знает только про интерфейс OrderRepositoryPort.
Как внедрять постепенно (даже в старом проекте)
- Начни с одного Use Case (самого важного).
- Выдели Entities и Value Objects.
- Создай Ports (интерфейсы).
- Реализуй их в Infrastructure.
- Подключи через Dependency Injection (в FastAPI — Depends, в NestJS — @Injectable).
Через 2–3 таких Use Case весь проект начнёт «сам» проситься в чистую архитектуру.
Частые ошибки вайбкодеров и как их избежать
- Импорт домена в контроллер → нарушение Dependency Rule
- Бизнес-логика в репозитории → репозиторий должен только сохранять/читать
- Прямые вызовы внешних сервисов из Use Case → выноси в Ports
- Большие Use Cases → один Use Case = одно действие
Итог: чистая архитектура — это не про «правильность», а про скорость и спокойствие
Когда проект построен правильно, ты перестаёшь бояться добавлять новые фичи. ИИ начинает работать как настоящий senior-разработчик, потому что понимает границы ответственности. А ты — как архитектор, который просто даёт задачи.
Я теперь каждый новый проект начинаю именно так. Даже если это «простой бот на 100 строк» — через неделю он всё равно вырастет, и структура спасёт меня от переписывания.