4 242 товара, 73 категории, 4 поставщика с автоматической синхронизацией, AI-генерация описаний и SEO-тегов, поиск с устойчивостью к ошибкам, автоматическая конвертация изображений в WebP, и всё это работает на Django 4.2 с PostgreSQL. Это не учебный проект и не MVP. Это живой продакшен-магазин airstep.com.ua, который ежедневно обслуживает реальных покупателей.
В этом кейсе мы расскажем, как команда Artbrain построила полноценную e-commerce платформу с нуля: от кастомной CMS-админки до zero-downtime деплоя. Разберём технические решения, которые сделали этот проект быстрым, удобным для менеджера и масштабируемым для бизнеса.
Задача: почему не Shopify, WooCommerce или Prom.ua
Первый вопрос, который задаёт бизнес: «А зачем нужна кастомная разработка, если есть готовые платформы?» В случае Airstep ответ был очевиден:
Работа с несколькими поставщиками одновременно. Airstep не производитель, а ритейлер. Товары поступают от 4 разных поставщиков, у каждого свой XML-фид, своя структура данных и свои правила ценообразования. Ни одна коробочная платформа не поддерживает такой сценарий из коробки. Нужна кастомная логика синхронизации, сопоставления категорий и автоматической наценки.
Контроль над админкой. Стандартные админки e-commerce платформ рассчитаны на один магазин с одним складом. Когда у вас 4 242 товара от 4 поставщиков и нужно массово генерировать описания через AI, конвертировать изображения и синхронизировать остатки, нужен совсем другой интерфейс. Мы построили CMS-админку, которая позволяет менеджеру управлять всем каталогом из одного места.
Скорость и SEO. Магазин на Django даёт полный контроль над HTML, CSS и серверной логикой. Мы можем оптимизировать каждый байт: от Core Web Vitals до структурированных данных. На Shopify или WooCommerce такой уровень контроля невозможен.
Это тот случай, когда кастомная разработка интернет-магазина не прихоть, а бизнес-необходимость. Подробнее о том, почему мы выбираем Django, мы писали в отдельной статье.
Архитектура проекта: что под капотом
Технологический стек: Django 4.2 (LTS) на бэкенде, PostgreSQL как основная база данных, Meilisearch для поиска, vanilla JavaScript на фронтенде (без React, осознанный выбор в пользу скорости), Nginx + Gunicorn в продакшене.
Архитектура построена по принципу «минимум зависимостей, максимум контроля». Мы не используем Django REST Framework для фронтенда магазина. Он работает на серверном рендеринге с минимальным JavaScript для интерактивных элементов (корзина, поиск, фильтры). Это даёт молниеносный First Contentful Paint и отличные показатели Core Web Vitals.
Синхронизация с 4 поставщиками: главный вызов проекта
Это сердце всей системы. Четыре поставщика, Villomi, Vzutik, Sollorini и Lor, каждый имеет собственный XML/YML-фид с товарами. Данные обновляются ежедневно. Задача: автоматически загружать фиды, разбирать товары, загружать изображения, рассчитывать цены с наценкой и обновлять каталог.
Каждый поставщик реализован как отдельная Django management command. Это позволяет запускать синхронизацию вручную через админку (кнопки «Villomi», «Vzutik», «Sollorini», «Lor» на скриншоте) и автоматически через cron.
Как работает пайплайн синхронизации
- Загрузка XML-фида от поставщика
- Парсинг товаров: извлекаем название, артикул, цену, размеры, цвета, материалы, изображения
- Очистка названий: regex удаляет бренды поставщиков и артикулы из заголовков, поскольку покупатель не должен видеть внутренние коды
- Автоматическая наценка: для каждого поставщика настраивается процент наценки через админку
- Сопоставление категорий: категории поставщика автоматически сопоставляются с категориями магазина
- Загрузка и конвертация изображений: фотографии с URL поставщика загружаются, конвертируются в WebP и сохраняются локально
- Обновление или создание товаров: если товар уже существует (по sync ID), обновляются цена, наличие и размеры; если новый, он создаётся
- Управление наличием: товары, которых больше нет в фиде, автоматически снимаются с публикации
Защита от дублей и процессов-зомби
Один из подводных камней: что произойдёт, если менеджер нажмёт кнопку синхронизации, когда предыдущая ещё не завершилась? Или если cron-задача запустится параллельно с ручным запуском?
Мы реализовали систему PID-файлов. При старте синхронизация создаёт PID-файл с ID процесса. Перед запуском новой проверяется, существует ли PID-файл и жив ли процесс (через /proc/[pid]/status). Если процесс жив, API возвращает 409 Conflict. Если PID-файл существует, но процесс мёртв (зомби), файл удаляется и новая синхронизация запускается нормально.
AI-модуль: генерация описаний и SEO-тегов
Одна из самых интересных фич проекта. В админку встроен AI-модуль на базе Claude API, который умеет:
- Генерировать описания товаров: на основе названия, материала, цвета и категории AI создаёт уникальное HTML-описание с ключевыми словами для SEO
- Генерировать метатеги: title и description для каждого товара, оптимизированные под поисковые запросы
- Автоматически переводить: контент генерируется на украинском с возможностью автоматического перевода на английский
- Пакетная обработка: можно выбрать сотни товаров и прогнать их через AI за один раз (кнопки «AI опис» и «AI SEO» на скриншоте каталога)
Всё логируется в ProductActivityLog: для каждой AI-генерации сохраняется дифф (что было до и что стало после). Менеджер всегда может отменить изменения.
Админка: всё под контролем менеджера
CMS-админка построена полностью кастомно. Это не стандартная Django Admin, а собственный интерфейс с продуманным UX. На скриншоте карточки товара видны ключевые элементы:
- Двуязычность: переключатель «Українська / English» для всех текстовых полей
- AI-генерация: кнопка «AI опис» генерирует описание товара одним кликом
- Визуальный выбор размеров: интерактивная сетка размеров вместо текстового поля
- Характеристики: цвет, материал, внутренняя отделка с возможностью добавления новых
- Прозрачное ценообразование: видны цена поставщика, наценка и акционная цена. Менеджер видит всю картину
- Привязка к поставщику: ID, артикул поставщика, ссылка на товар в системе поставщика
В каталоге (на первом скриншоте) видны дерево категорий слева, список товаров с фотографиями, ценами и статусами наличия. Панель инструментов вверху содержит кнопки синхронизации каждого поставщика отдельно или всех вместе, пакетный AI, конвертацию в WebP и экспорт в Google Merchant Feed.
Поиск на Meilisearch: мгновенный и устойчивый к ошибкам
Стандартный SQL-поиск (LIKE или Full Text Search в PostgreSQL) не подходит для e-commerce. Покупатель пишет «крросівки» вместо «кроссовки», «замшеві чиревики» вместо «замшевые черевики», и ничего не находит. Это потерянные продажи.
Мы интегрировали Meilisearch, поисковый движок со встроенной устойчивостью к ошибкам. Как это работает:
- Typo tolerance: «крросівки» находит «кроссовки», «чиревики» находит «черевики»
- Instant search: результаты появляются во время ввода текста, с debounce 200 мс
- Фасетная фильтрация: поиск сразу показывает количество товаров по категориям
- AbortController: если пользователь продолжает вводить текст, предыдущий запрос автоматически отменяется (ресурсы не расходуются)
- Rate limiting: 120 запросов в минуту с одного IP (защита от злоупотреблений)
Автоматический пайплайн изображений
Изображения, самая большая проблема любого магазина. 4 000+ товаров, по 3–5 фотографий на каждый, это десятки тысяч файлов. У поставщиков фотографии в JPEG разного качества и размера. Покупателям нужны оптимизированные WebP для быстрой загрузки.
Мы построили полностью автоматический пайплайн:
- Загрузка: фотография скачивается по URL поставщика
- Ресайз: максимум 1920×1920 пикселей, LANCZOS-ресемплинг (через Pillow)
- Конвертация в WebP: quality 85%, оптимальный баланс размера и качества
- Запись в БД: пути сразу сохраняются как .webp, никакого рассинхрона между файлами и записями
Есть также пакетная конвертация: кнопка «WebP» в админке конвертирует все изображения, которые ещё не в WebP. Используется пагинация по курсору, чтобы не перегружать память при обработке тысяч файлов.
Умная фильтрация каталога
Фильтрация отличает хороший магазин от плохого. В Airstep реализованы:
- 13 цветовых групп с украинскими названиями и ключевыми словами. Например, группа «бежевый» включает слова «бежев», «айвор», «кремов», «молочн», «капучін». Это означает, что товар «Черевики кольору капучіно» автоматически попадёт в фильтр «бежевый»
- Сезонный буст: демисезонные товары (весна-осень) поднимаются выше в выдаче, потому что подходят более широкой аудитории
- Фильтрация по цене с округлением до 100 грн (удобнее для пользователя)
- Оптимизация на уровне БД: вся логика фильтрации работает через Django
Case/Whenисключительно на стороне PostgreSQL, без загрузки товаров в Python
Витрина магазина: что видит покупатель
Фронтенд магазина построен на серверном рендеринге Django templates с минимальным JavaScript (vanilla JS, без фреймворков). Это даёт:
- Молниеносный First Contentful Paint
- Полный контроль над SEO и структурированными данными
- Минимальный размер страницы
- Полную адаптивность для мобильных устройств
Корзина реализована на localStorage и работает даже офлайн. Когда покупатель начинает оформление, но не завершает его, данные (телефон, имя, email, сумма) сохраняются в AbandonedCart. Менеджер видит брошенные корзины в админке и может связаться с клиентом.
Также есть Availability Notifications: если товара нет в наличии, покупатель может подписаться на уведомления. Когда товар появляется после синхронизации, клиент получает сообщение.
Безопасность: CSP, HSTS и санитизация контента
Безопасность в e-commerce не опция, а обязанность. Мы реализовали:
- Content Security Policy (CSP): вайтлист разрешённых доменов для скриптов, стилей и изображений. Защита от XSS-атак
- HSTS на год: браузер запоминает, что сайт работает только через HTTPS
- Защита от clickjacking:
frame-ancestors 'none', сайт невозможно встроить в iframe - Permissions Policy: отключены геолокация, камера и микрофон, они магазину не нужны
- HTML-санитизация через Bleach: разные правила для пользовательского контента (отзывы) с более жёсткими ограничениями и для админского (описания товаров) с более широкими
CSS-пайплайн и оптимизация фронтенда
9 CSS-модулей проходят через пайплайн: PostCSS → autoprefixer → PurgeCSS → минификация. Результат:
- Dev: ~143 KB → Prod: ~107 KB (минус 25%)
- PurgeCSS удаляет неиспользуемые стили, но с safelist на regex для динамических классов (swiper-*, animate__*, pc-*)
- JS-минификация через terser
- Nginx gzip_static: предварительно сжатые .gz-файлы раздаются без затрат CPU на сжатие в реальном времени
- 30-дневный immutable-кэш для статики с версионными хешами для cache busting
Zero-downtime деплой
Магазин должен быть доступен 24/7, любая пауза в работе означает потерянные заказы. Мы настроили:
- Systemd + Gunicorn с graceful reload (HUP signal): новые воркеры запускаются, старые завершают текущие запросы
- Автоматический перезапуск при сбоях: задержка 5 секунд, до 10 перезапусков за 5 минут
- OOM protection: OOMScoreAdjust=-500, ядро Linux будет убивать Gunicorn в последнюю очередь
- Nginx раздаёт статику напрямую, не нагружая Django
Аналитика без Google Analytics
Вместо стороннего трекинга мы построили собственную систему аналитики:
- SearchQuery: логирование поисковых запросов с нормализацией. Менеджер видит, что ищут покупатели, и может отмечать «популярные» запросы для отображения на главной
- ProductActivityLog: аудит всех изменений товаров с JSON-диффами (кто, когда и что изменил)
- AnalyticsEvent: события view, search, add-to-cart, purchase. Этого достаточно для понимания воронки без сторонних скриптов, которые замедляют сайт
IndexNow: мгновенная индексация изменений
При создании или обновлении товара система автоматически отправляет запрос Bing, Yandex и другим поисковикам через IndexNow API. Пакетная отправка до 10 000 URL за один запрос. Реализовано на чистом urllib.request, без внешних зависимостей. Подобный подход мы используем и в других наших проектах.
Ключевые результаты
После запуска платформы Airstep получил:
Автоматизация вместо ручной работы. Раньше менеджер вручную добавлял товары, загружал фотографии и писал описания. Теперь синхронизация с 4 поставщиками происходит автоматически. AI генерирует описания. Изображения конвертируются сами. Менеджер занимается бизнесом, а не рутиной.
4 242 товара в каталоге. Из них 3 842 в наличии. 73 категории. Всё синхронизируется ежедневно без участия человека.
Мгновенный поиск. Покупатели находят товары даже с ошибками в запросе. Конверсия поиска значительно выше, чем при стандартном SQL-поиске.
Прозрачное ценообразование. Менеджер видит цену поставщика, наценку и акции, всё в одном интерфейсе. Никаких таблиц в Excel.
Zero-downtime. Обновление кода, синхронизация и AI-генерация работают без остановки магазина.
Посмотреть страницу проекта с техническими деталями можно в нашем портфолио: кейс Airstep.
Вывод: когда нужна кастомная e-commerce платформа
Готовые платформы закрывают типовые задачи. Но есть ситуации, когда они не подходят:
- Несколько поставщиков с разными форматами данных и правилами ценообразования
- Потребность в AI-автоматизации: генерация контента, переводы и SEO-оптимизация для тысяч товаров
- Специфическая бизнес-логика: наценки по поставщикам, abandoned cart recovery, availability notifications
- Полный контроль над SEO: структурированные данные, Core Web Vitals и метатеги для каждого товара
- Масштабирование без ограничений платформы: никаких лимитов на товары, категории или API-запросы
Если вы узнали свою ситуацию, оставьте заявку. Мы проведём бесплатную консультацию, проанализируем ваш бизнес и честно скажем, нужна ли вам кастомная разработка или можно обойтись готовым решением. Рассчитать ориентировочную стоимость можно через наш онлайн-калькулятор.
Нужен интернет-магазин с нестандартным функционалом? Заказать разработку интернет-магазина под ключ: от $2 500, срок 4–8 недель.
Подробнее о наших услугах разработки под ключ и реализованных проектах.
Частые вопросы
Сколько времени занимает разработка интернет-магазина с нуля?
Зависит от сложности. Базовый магазин – 4-6 недель. Магазин с кастомной CMS, синхронизацией поставщиков и AI-функциями (как в кейсе Airstep) – 2-3 месяца. В Artbrain первый рабочий прототип показываем спустя 2 недели.
Что такое AI-описание товаров и зачем это нужно?
AI генерирует уникальные описания товаров на основе характеристик, фотографий и данных поставщика. Это решает проблему дубликатов контента (когда у всех магазинов одинаковые описания от поставщика). Уникальные описания улучшают SEO и помогают Google различать ваш магазин среди конкурентов.
Как работает синхронизация с поставщиками?
Система автоматически получает каталоги от поставщиков (через API, XML-фиды или парсинг), обновляет цены, остатки и характеристики. В кейсе Airstep мы синхронизировали 4 поставщика и 6700+ товаров в реальном времени. Это устраняет ручную работу и ошибки.
