FastStack

Кейсы разработки, интеграций и автоматизации

Практические задачи из production-проектов: разработка и модернизация веб-систем, API, интеграции, производительность, инфраструктура, автоматизация и техническое SEO.

УслугиКейсыО насКонтакты
FastStack
УслугиКейсыО насКонтакты
  1. Главная
  2. /Кейсы

Практический опыт

Production-кейс FINIST

Ниже подробно разобран один большой production-проект: от разработки корпоративного сайта и развития товарного каталога до React/TypeScript-интерфейсов, файлового сервиса, видеоплатформы, API, deployment, серверной инфраструктуры и технического SEO.

Production-кейс

FINIST — развитие корпоративного сайта и каталога профессионального оборудования

Проект начался с разработки сайта для завода FINIST вместо старой файловой системы и постепенно вырос в большой production-контур: WooCommerce-каталог, сложные карточки оборудования, React- и TypeScript-интерфейсы, собственные таблицы, файловый сервис, видеоплатформа, API, SEO-инфраструктура, автоматизация deployment и обслуживание сервера.

От старого сайта к единой production-системе

Старый сайт представлял собой накопившуюся файловую структуру с отдельными каталогами CSS, JavaScript, изображений, мобильной версии, загрузок, рассылки, PDF-библиотеки и сторонних компонентов. Новый сайт был разработан с нуля на WordPress и WooCommerce. После запуска работа продолжилась уже как развитие единой системы: каталога оборудования, карточек товаров, внутренних сервисов, API, видео, SEO и серверной инфраструктуры.

Содержание кейса

Что сделано в проекте

  1. 1.Карточка товара и frontend
  2. 2.Таблицы характеристик
  3. 3.ACF, варианты и миграции
  4. 4.API и кэширование
  5. 5.Файловый сервис disk.f-inox.ru
  6. 6.Видеоплатформа
  7. 7.Каталог и URL
  8. 8.Техническое SEO
  9. 9.Deployment и сервер

Подробно

Задачи, поиск решений и результат

1.

Карточка товара и frontend

1.1

Перестройка frontend-архитектуры карточки товара

Проблема

Карточка товара со временем объединила PHP-разметку, inline-JavaScript, DOM-контроллеры и React-компоненты. Несколько частей страницы могли независимо управлять галереей, активным изображением, вариантами, вкладками и состоянием интерфейса.

Поиск

Проведена трассировка ProductPage.tsx, PHP-шаблонов и клиентских обработчиков. Найдены устаревшие контроллеры, параллельные точки инициализации и дублирующая логика управления интерфейсом.

Решение

Карточка разделена на специализированные TypeScript/React-модули: ProductPrimaryGalleryController, ProductVariantsController, ProductAdaptiveTables, ProductAdditionalInformation, ProductTabsController, ProductStickyCards и ProductSupplementaryGalleries. Общая DOM-логика вынесена в отдельные utility и controller-модули.

Результат

Удалены WCTabsController, openAdditionalInformation, tablepress-adaptive.client и другие промежуточные реализации. Карточка получила единый типизированный frontend-контур, TypeScript-ошибки устранены.

1.2

Галерея товара и визуальные варианты

Проблема

Изображение товара должно было зависеть от выбранных материалов и декоративных вариантов, но не от всех WooCommerce-атрибутов. Например, изменение размера не должно менять фотографию.

Поиск

Разобраны product media, ACF-варианты, WooCommerce-атрибуты и существующие связи между миниатюрами и основным изображением.

Решение

Галерея и варианты разделены на независимые контроллеры. Для сложных вариантов предусмотрена модель базового изображения и дополнительных визуальных слоёв. Логика thumbnails и дополнительных галерей вынесена в отдельные модули.

Результат

Визуальное состояние товара управляется только теми параметрами, которые действительно меняют внешний вид, а размер и другие невизуальные атрибуты не вмешиваются в галерею.

2.

Таблицы характеристик

2.1

Собственная система таблиц вместо TablePress

Проблема

Технические характеристики товаров хранились и выводились через TablePress. Для адаптации его HTML под карточку товара постепенно возник отдельный JavaScript-контур, жёстко связанный с DOM-разметкой стороннего плагина.

Поиск

Проведён аудит массива таблиц и их связей с товарами. Найдены повторно используемые таблицы, нестандартные структуры, HTML внутри ячеек и особые случаи, которые нельзя было переносить простым копированием.

Решение

Разработана собственная подсистема данных таблиц и новый frontend-контур ProductAdaptiveTables с отдельными модулями подготовки данных и управления адаптивным представлением. Логика таблиц была отделена от runtime-разметки TablePress.

Результат

Карточка товара перестала зависеть от TablePress как от frontend-движка. Данные таблиц и их интерактивное представление стали контролироваться собственным кодом.

2.2

Адаптация больших таблиц под мобильные экраны

Проблема

Обычная широкая таблица характеристик плохо читается на телефоне: горизонтальный скролл скрывает связь между названием параметра и значением.

Поиск

Проверялись реальные таблицы с различным количеством колонок, заголовков и значений, а также существующее поведение TablePress на узких экранах.

Решение

Разработано отдельное адаптивное представление таблиц с преобразованием данных для мобильного интерфейса вместо простого уменьшения исходной HTML-таблицы.

Результат

Один набор данных используется и на desktop, и на мобильных устройствах, но представляется в форме, подходящей конкретной ширине экрана.

3.

ACF, варианты и миграции

3.1

Переход к глобальным группам вариантов ACF

Проблема

Одинаковые цвета, материалы и варианты повторялись непосредственно в разных товарах. Это создавало дубли данных и риск расхождения одинаковых вариантов между карточками.

Поиск

Проверена фактическая структура ACF-полей и повторяющихся наборов вариантов.

Решение

Вместо локального хранения одинаковых данных созданы шесть глобальных групп вариантов, которые могут подключаться к разным товарам.

Результат

Общие варианты получили единую точку редактирования и могут переиспользоваться без копирования данных между товарами.

3.2

Контролируемая миграция вариантов и изображений

Проблема

Старые связи между вариантами и изображениями нельзя было безопасно перенести массовой заменой: часть записей имела неоднозначные соответствия.

Поиск

Миграция запускалась сначала в dry-run с подсчётом групп, связей и элементов без однозначного соответствия. Для отдельных товаров обнаруживались как полностью сопоставленные наборы, так и несопоставленные изображения.

Решение

Автоматически переносились только однозначные соответствия. Неопределённые элементы выводились отдельно для ручной проверки.

Результат

Миграция не уничтожала спорные данные и позволяла отделять автоматические преобразования от случаев, требующих решения человеком.

3.3

Диагностика предполагаемой потери товарных связей

Проблема

После изменений появилась версия, что часть вариантов или товарных связей могла массово исчезнуть из базы.

Поиск

Вместо восстановления всей базы были сопоставлены несколько резервных копий и конкретные таблицы связей. Различия локализовывались по отдельным товарам и term relations.

Решение

Использовано дифференциальное сравнение данных между резервными копиями, а не откат production целиком.

Результат

Версия о массовой потере данных была исключена, а фактическое изменение удалось локализовать до конкретной связи.

3.4

Поиск ошибки lazy-loading изображений вариантов

Проблема

В ACF были заполнены изображения и существовали реальные attachment-файлы, но frontend продолжал показывать серые placeholders.

Поиск

Проверены ACF-поля, attachment ID, физические URL и HTML, формируемый PHP. Сервер корректно отдавал placeholder с data-атрибутом для ленивой загрузки, однако соответствующий клиентский обработчик обнаружен не был.

Решение

Проблема была отделена от данных и локализована на уровне клиентской логики.

Результат

Было доказано, что ACF и media-данные исправны, поэтому дальнейшее исправление не требовало вмешательства в базу или повторной загрузки изображений.

4.

API и кэширование

4.1

Отдельный API-контур каталога

Проблема

Frontend требовал данные каталога без полной загрузки WordPress-страницы. При этом часть исторического API вручную собирала URL и могла расходиться с реальными WordPress permalink.

Поиск

Проведена трассировка /api/catalog/. Установлено, что данные формируются отдельным PHP-кодом и прямыми запросами к базе, а не только стандартными WordPress-функциями.

Решение

API стал рассматриваться как самостоятельный слой. Ошибки URL исправляются в точке их формирования, а не маскируются глобальными rewrite или дополнительными редиректами.

Результат

Удалось отделить ошибки WordPress permalink от ошибок собственного API и локализовать источник устаревших AJAX-ссылок.

4.2

BFF и HTTP-кэширование данных

Проблема

Некоторым frontend-блокам требовались данные WordPress, но прямое выполнение одинаковых тяжёлых запросов на каждый запрос страницы было избыточным.

Поиск

Проверены реальные запросы главной страницы и кейсов, частота обновления данных и возможность условного HTTP-кэширования.

Решение

Создан PHP BFF, включая /api/cases.php. Добавлены серверный TTL-кэш, ETag и Last-Modified.

Результат

Frontend получил стабильный API-контракт, а повторные запросы могут обслуживаться без повторного полного формирования данных.

4.3

Исправление логики фильтров кейсов

Проблема

При выборе одного фильтра система могла неправильно вычислять доступные значения других фильтров.

Поиск

Разобрана логика selected и available для каждого селектора и влияние текущего выбранного значения на расчёт остальных.

Решение

При вычислении available текущий фильтр исключается из набора ограничений, а остальные активные фильтры продолжают учитываться.

Результат

API снова формирует корректные наборы доступных значений без взаимного блокирования фильтров.

5.

Файловый сервис disk.f-inox.ru

5.1

Разработка внутреннего файлового сервиса disk.f-inox.ru

Проблема

Для рабочих файлов требовался отдельный удобный интерфейс вместо прямого доступа сотрудников к файловой системе сервера или использования WordPress media library.

Поиск

Определены операции, необходимые для повседневной работы: просмотр каталогов, поиск, загрузка, скачивание, создание папок, переименование, перемещение, удаление и восстановление.

Решение

Создан отдельный проект disk.finox на React Router SSR, React 19, TypeScript, Tailwind CSS 4 и Vite с PHP 8.5 backend. Файловая система используется как источник истины, серверные операции сосредоточены в backend/Storage.php и API.

Результат

Получен самостоятельный веб-файловый менеджер с навигацией, поиском, плиточным представлением, загрузкой и скачиванием, созданием каталогов, переименованием, перемещением, корзиной и восстановлением.

5.2

Безопасность файлового сервиса

Проблема

Веб-доступ к filesystem создаёт риск path traversal, выхода через symlink, обращения к системным именам и выполнения потенциально опасных операций напрямую через API.

Поиск

Проверялись серверные пути для чтения, загрузки, переименования, перемещения и удаления. Ограничения frontend не рассматривались как защита.

Решение

Проверки путей и разрешённых операций выполняются на backend. Опасные переходы и системные области изолируются на серверном уровне.

Результат

Безопасность файловых операций не зависит от поведения браузера и проверяется непосредственно перед работой с filesystem.

5.3

Поиск и работа с файлами в disk.finox

Проблема

Обычная навигация по вложенным папкам становится неудобной при большом количестве файлов.

Поиск

Определены сценарии поиска по имени и типу объекта, а также необходимость отличать каталоги от файлов в результатах.

Решение

В файловый сервис добавлен поиск по хранилищу с отдельным представлением найденных папок и файлов.

Результат

Пользователь может находить нужные объекты без последовательного открытия всей структуры каталогов.

6.

Видеоплатформа

6.1

Собственная видеоплатформа внутри FINIST

Проблема

Обычные WordPress attachments не покрывали требования к публичной видеотеке, вертикальным видео, состояниям public/unlisted/private, связям с товарами и кейсами и отдельному playback-контуру.

Поиск

Разобраны существующие видео, metadata, физическое хранение файлов, статусы публикации, URL и требования к дальнейшему воспроизведению.

Решение

Создан отдельный video runtime с таблицей wp_videos, страницами /video/, /video/{id}/ и /shorts/{id}/, source-хранилищем finist-library/video и отдельной playback-структурой.

Результат

Видео перестало быть просто вложением WordPress и стало самостоятельным типом контента со своими URL, состояниями публикации, playback-данными и связями.

6.2

Вертикальный видеопросмотр

Проблема

При ленте коротких видео одновременная работа нескольких плееров создаёт лишнюю нагрузку и конфликтующее воспроизведение.

Поиск

Проверено поведение плееров при свайпе между вертикальными видео.

Решение

Интерфейс построен так, чтобы активным оставался только текущий плеер.

Результат

Пользователь получает вертикальную ленту с управляемым переключением видео без одновременного воспроизведения всего списка.

6.3

Связи между товарами, кейсами и видео

Проблема

Если связи между тремя типами контента редактировать независимо в каждом месте, данные постепенно начинают расходиться.

Поиск

Рассмотрены варианты хранения связей и стоимость обратного поиска по большому каталогу.

Решение

Точкой истины выбран товар. Остальные представления читают связанные данные от него, а для обратного направления предусматривается индекс или кэш.

Результат

Сформирована единая модель связей вместо нескольких независимых наборов отношений.

6.4

SEO и статусы видеоконтента

Проблема

Public, unlisted и private видео требуют разного поведения не только во frontend, но и для поисковых систем.

Поиск

Проверялись detail-страницы, HTTP-состояния, canonical и SEO-разметка для разных статусов.

Решение

Public-видео могут индексироваться и получают собственные detail-страницы, unlisted закрываются от индексации, private не выдаётся как публичная страница.

Результат

Статус видео управляет одновременно доступностью контента и его поисковым поведением.

6.5

SEO-переименование видеотеки

Проблема

Исторические названия части роликов плохо подходили для самостоятельных страниц и поисковых title.

Поиск

Автоматический аудит сопоставил 96 видео. Из них 66 изменений были определены как безопасные, а 30 потребовали дополнительной проверки.

Решение

Автоматическое изменение применялось только к однозначным случаям.

Результат

На первом проходе изменено 66 названий, после дополнительной проверки — ещё 3. Спорные варианты не были изменены автоматически.

6.6

Перенос видеотеки в единое хранилище

Проблема

Видео, posters и служебные файлы исторически находились в нескольких каталогах, тогда как новый runtime требовал единой схемы хранения.

Поиск

Сопоставлены production-пути старой видеотеки и структура нового video runtime.

Решение

Определён единый корень wp-content/uploads/finist-library и отдельные области для source и playback. Старые данные не удалялись до проверки миграции.

Результат

Код получил одну предсказуемую структуру хранения вместо набора исторических директорий.

6.7

Транскрипты и возобновляемая обработка видео

Проблема

Длительная обработка видеотеки не должна начинаться заново после остановки процесса.

Поиск

Проверена полнота локального набора видео и metadata-файлов.

Решение

Для обработки используется сохраняемое состояние с transcript, status, checksum, engine, model, language и временем обработки.

Результат

Процесс обработки можно продолжать после остановки, а состояние каждого файла проверяется по metadata.

7.

Каталог и URL

7.1

Перестройка структуры товарного каталога

Проблема

Товары могли находиться одновременно в промежуточных и конечных категориях, из-за чего дерево каталога, навигация и SEO-структура становились неоднозначными.

Поиск

Проведён аудит связей product_cat и наличия товаров непосредственно у родительских узлов.

Решение

Зафиксировано правило: товары относятся к конечным категориям дерева, а промежуточные категории используются как навигационные узлы.

Результат

Прямые товарные связи у промежуточных родителей были устранены, структура каталога стала однозначнее.

7.2

Корректная пагинация категорий

Проблема

URL вида ?catalog_page=2 мог возвращать HTTP 200 даже для категории, где второй страницы фактически не существовало.

Поиск

Сопоставлялись фактическое количество элементов категории и HTTP-ответы для catalog_page.

Решение

Добавлена проверка реального количества страниц. catalog_page=N разрешается только в существующем диапазоне, а catalog_page=1 считается лишним параметром.

Результат

Несуществующие страницы пагинации перестали создавать отдельные HTTP 200 и индексируемые пустые URL.

7.3

Миграция старых URL

Проблема

После изменения структуры каталога и контента в поиске и внешних ссылках продолжали существовать старые адреса.

Поиск

Сопоставлялись старые URL, текущие permalink, canonical и реальные HTTP-ответы для товаров, категорий, кейсов и других типов контента.

Решение

Однозначные случаи переведены на 301, а для разных типов сущностей используются разные правила вместо одного глобального redirect.

Результат

Старые адреса переводятся на актуальную структуру без создания произвольных перенаправлений для неоднозначных случаев.

7.4

Аудит внутренних ссылок после миграций

Проблема

Даже при правильных 301 внутренние ссылки сайта могли продолжать вести сначала на старый адрес.

Поиск

Выполнен обход публичных страниц с проверкой конечных HTTP-статусов внутренних ссылок.

Решение

301, реальные 404 и внешние ограничения разбирались отдельно. Исправлялись конкретные источники ссылок, а не применялся массовый search-replace по всей базе.

Результат

Получен проверяемый список внутренних ссылок, которые действительно требовали изменения.

8.

Техническое SEO

8.1

Очистка SEO-метаданных категорий

Проблема

SEO title и description хранились в нескольких исторических местах и могли расходиться с тем, что реально выводилось на странице.

Поиск

Сравнивались termmeta, Yoast taxonomy metadata, WordPress-данные и итоговый HTML.

Решение

Дублирующие значения удалялись, а конечной контрольной точкой считался фактический HTML страницы.

Результат

Устранён слой конфликтующих SEO-значений, из-за которого административные данные и frontend могли показывать разные title.

8.2

Разбор массовых проблем Google Search Console

Проблема

Большой список URL в Search Console выглядел как множество независимых ошибок.

Поиск

URL были сгруппированы по структуре и фактическому поведению.

Решение

Исправления выполнялись по системным причинам, а не отдельным URL.

Результат

Сотни URL были сведены к ограниченному числу классов проблем, для которых можно было исправлять общее правило.

8.3

Контроль индексации технических PDF

Проблема

PDF с документацией должны быть доступны посетителям, но не должны формировать самостоятельный массив поисковых страниц.

Поиск

Проверялись HTTP-доступность файлов и управляющие SEO-заголовки.

Решение

PDF оставлены доступными по HTTP, но исключены из индексации через X-Robots-Tag.

Результат

Технические документы доступны пользователю без необходимости индексировать каждый PDF как отдельную поисковую страницу.

8.4

Аудит непубличного контента

Проблема

Draft, private и pending записи не должны случайно попадать в sitemap или открываться извне.

Поиск

Одновременно проверялись статус записи, sitemap и внешний HTTP-ответ.

Решение

Контроль публикации выполняется по фактической доступности, а не только по полю post_status.

Результат

Непубличные материалы исключены из sitemap и не выдаются как обычные публичные страницы.

9.

Deployment и сервер

9.1

Разработка быстрого безопасного deployment-скрипта

Проблема

Обычная синхронизация всего WordPress-проекта либо выполняла лишнюю работу, либо требовала вручную решать, какие файлы можно обновлять, удалять или оставлять на production. Дополнительный риск создавали uploads, WordPress core, сторонние плагины, runtime-файлы, права доступа и возможные изменения непосредственно на сервере.

Поиск

Deployment был переработан вокруг предварительной разведки без записи. Скрипт отдельно читает локальное состояние, production-список и server preflight, затем классифицирует файлы на local-only, common и server-only. Для общих файлов сравниваются size и mtime, отдельно проверяются более новые server-файлы, права, владельцы и лишние объекты. SSH-соединение переиспользуется через multiplexing, а metadata production проверяется параллельно через xargs -P32.

Решение

Создан единый guarded deployment-скрипт, который сам анализирует состояние проекта и выбирает минимально необходимый сценарий. Если изменился только dist, используется отдельный быстрый путь. Для остальных изменений выполняется полный защищённый сценарий. Перед потенциально опасными действиями работают safety-gates, а системные области, uploads, WordPress core и сторонние плагины исключены из автоматической синхронизации.

Результат

Deploy быстро принимает решение по фактическому состоянию local и production. Если изменений нет, он завершается без записи. Если изменился только dist, выполняется короткая authoritative-синхронизация. При полном deploy включается maintenance, проверяется HTTP 503, синхронизируются только разрешённые области, корректируются права, очищаются кэши и выполняется health-check HTTP 200. При ошибке после начала записи сайт остаётся в maintenance.

9.2

Оптимизация VPS по фактической нагрузке

Проблема

Сервер был выделен с запасом ресурсов, но реальные измерения не подтверждали необходимость исходной конфигурации.

Поиск

Измерялись load average, использование памяти, PHP-FPM и MariaDB.

Решение

Конфигурация VPS была уменьшена с 4 CPU / 4 GB до 2 CPU / 2 GB. PHP-FPM pm.max_children снижен с 24 до 6, а innodb_buffer_pool_size MariaDB установлен в 64 MB.

Результат

Production продолжил работать на меньшем объёме ресурсов без необходимости оплачивать неиспользуемый запас.

9.3

Аудит медиахранилища

Проблема

Uploads занимал значительный объём, а количество производных изображений заметно превышало количество исходных media attachments.

Поиск

Проверялись attachment-записи, наличие физических файлов, thumbnails и потенциальные orphan-файлы.

Решение

Перед очисткой данные разделены на реальные вложения, отсутствующие файлы, производные изображения и потенциальные orphan.

Результат

Получена количественная карта медиахранилища, позволяющая выполнять очистку адресно вместо удаления файлов по приблизительным признакам.

9.4

Патч несовместимости Yoast SEO с текущей версией PHP

Проблема

Yoast SEO генерировал Deprecated warning при использовании null в качестве ключа cache.

Поиск

Проблема локализована до memoizer-классов и обращения к indexable->id, который в отдельных случаях был null.

Решение

Для cache key добавлен fallback на spl_object_id(), а исправление оформлено отдельным повторяемым patch-инструментом.

Результат

Предупреждения устранены, PHP syntax check проходит, а повторный запуск патча определяет уже исправленное состояние.

9.5

Защита административного входа WordPress

Проблема

Стандартные WordPress endpoints авторизации постоянно доступны автоматическим попыткам входа.

Поиск

Проверены маршруты входа и требования к административному доступу.

Решение

Создан MU-модуль Finist Auth Guard с отдельным маршрутом входа, rate limit и whitelist для административного контура.

Результат

Публичный WordPress-вход отделён от рабочего административного доступа, а автоматические попытки ограничиваются до обработки защищённой части системы.

Итог

FINIST вырос из разработки нового корпоративного сайта в комплексную production-систему. Работа охватила не только WordPress и WooCommerce, но и собственные React/TypeScript-интерфейсы, таблицы товаров, файловый сервис, видеоплатформу, API, миграции данных, deployment, серверную инфраструктуру и техническое SEO. Общий принцип работы оставался одинаковым: сначала определить фактическое состояние системы и доказать источник проблемы измеримыми данными, затем изменить минимально необходимый слой и проверить результат на уровне frontend, HTTP, базы данных или сервера.

Есть похожая задача?

Опишите проект, текущее состояние и требуемый результат. Можно начать без готового технического задания.

Обсудить задачу
FastStack

Внедрение AI и ИИ-автоматизации в существующие бизнес-системы, разработка AI-сервисов, интеграции с CRM, 1С, API и веб-инфраструктурой.

Обсудить AI-задачу

AI-решения

Внедрение AIРазработка AI-системAI-поиск и RAGAI-подбор товаровАвтоматизация КП

Веб-разработка

Сайты и веб-системыИнтернет-магазиныWordPress и WooCommerceВеб-приложенияAPI и интеграцииПоддержка и сервер

FastStack

КейсыО проектеКонтактыОбсудить AI-проект
© 2026 FastStack
Политика конфиденциальностиПолитика обработки персональных данных