4 242 товари (дані на березень 2026, зараз понад 6 700), 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-адмінку, яка дозволяє менеджеру керувати всім каталогом з одного місця.
На Shopify чи WooCommerce такий рівень контролю неможливий.
Це саме той випадок, коли кастомна розробка інтернет-магазину – не примха, а бізнес-необхідність. Детальніше про те, чому ми обираємо Django, ми писали в окремій статті.
Архітектура проекту: що під капотом
Архітектура побудована за принципом «мінімум залежностей, максимум контролю». Ми не використовуємо 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. Покупець пише «крросівки» замість «кросівки», «замшеві чиревики» замість «замшеві черевики» – і нічого не знаходить. Це втрачені продажі.
Як це працює:
- Typo tolerance – «крросівки» знаходить «кросівки», «чиревики» знаходить «черевики»
- Instant search – результати з'являються під час набору тексту, з debounce 200мс
- Фасетна фільтрація – пошук одразу показує кількість товарів по категоріях
- AbortController – якщо користувач продовжує набирати текст, попередній запит автоматично скасовується (не витрачає ресурси)
- Rate limiting – 120 запитів на хвилину з одного IP (захист від зловживань)
Автоматичний пайплайн зображень
Зображення – це найбільша проблема будь-якого магазину. 4 000+ товарів, по 3-5 фото на кожен – це десятки тисяч файлів. У постачальників фото в JPEG різної якості та розміру. Покупцям потрібні оптимізовані WebP для швидкого завантаження.
Ми побудували повністю автоматичний пайплайн:
- Завантаження – фото скачується з URL постачальника
- Конвертація в 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 – відключена геолокація, камера, мікрофон (не потрібні магазину)
CSS-пайплайн та оптимізація фронтенду
9 CSS-модулів проходять через пайплайн: PostCSS → autoprefixer → PurgeCSS → мініфікація. Результат:
- Dev: ~143 KB → Prod: ~107 KB (мінус 25%)
- PurgeCSS видаляє невикористані стилі, але з safelist на regex для динамічних класів (swiper-*, animate__*, pc-*)
- Nginx gzip_static – пре-стиснуті .gz файли роздаються без витрат CPU на стиснення в реальному часі
- 30-денний immutable кеш для статики – з версійними хешами для cache busting
Zero-downtime деплой
Магазин має бути доступний 24/7 – будь-яка перерва в роботі це втрачені замовлення. Ми налаштували:
- Systemd + Gunicorn з graceful reload (HUP signal) – нові воркери стартують, старі завершують поточні запити
- Auto-restart при крашах – затримка 5 секунд, до 10 рестартів за 5 хвилин
- OOM protection – OOMScoreAdjust=-500, ядро Linux буде вбивати Gunicorn в останню чергу
- Nginx роздає статику напряму, не навантажуючи Django
Аналітика без Google Analytics
Замість стороннього трекінгу ми побудували власну систему аналітики:
- SearchQuery – логування пошукових запитів з нормалізацією. Менеджер бачить, що шукають покупці, і може відмічати «популярні» запити для відображення на головній
- ProductActivityLog – аудит всіх змін товарів з JSON-діффами (хто, коли, що змінив)
- AnalyticsEvent – події view, search, add-to-cart, purchase. Достатньо для розуміння воронки без сторонніх скриптів, які сповільнюють сайт
IndexNow: миттєва індексація змін
Батчева відправка до 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+ товарів в реальному часі. Це усуває ручну роботу та помилки.
