Учебное руководство
Главы руководства
На этой странице

Отчёт о переносе контента в Strapi

Состояние на 2 октября 2026 года. Учебный проект; автоматические UI-тесты не добавлялись.

Источник и объём

Снимок публичного API https://etnosportapi.npotau.ru получен 2026-10-02T14:31:58.056Z. SHA256: c7f25ab8b368cfa96ded5800ae70844f321ec998d87cbf2dadaa86df56822cfa. Снимок и подробные отчёты находятся в игнорируемом var/content-import/.

МодельДокументов
Новости94
События: отдельные появления в программе41
Информационные страницы5
FAQ15
Партнёры44
Настройки сайта1
Всего200

В Site перенесены 10 исторических отметок и 11 промослайдов. Исходные годы сохранены: новости включают 2026 год, программа относится к 22–24 августа 2025 года. Время окончания не придумано. Название и логотип оригинала загружаются через Media Library. Изображения хранятся в Garage S3. 21 новость и 4 события содержат iframe: встроенный плеер заменён безопасной ссылкой на исходное видео, каждое преобразование записано в warnings. Регистрация, SMS, аккаунты, тестовые контакты источника исключены по согласованному объёму.

Проверено локально

Первый импорт: 198 создано, 2 ошибки, 217 файлов. Причина двух ошибок — внешние VK-картинки галочек; они преобразованы в Unicode. Повтор: 2 создано, 198 пропущено, ошибок нет. Следующий повтор: 200 пропущено, новых документов и файлов нет. Ручные редакторские изменения default-import сохраняет; изменение существующих записей требует явного --update-existing. На стандартном Strapi выполнено 200 обновлений с чистым завершением после исправления ожидания post-commit callbacks. Прежние поля схем сохранены.

Независимое ревью выявило три ошибки: черновик после сбоя publish, неполные секции Site после ошибки страницы и отсутствие даты в новой редакторской новости. Все исправлены с RED→GREEN regression tests: атомарная публикация, проверка всех страниц перед Site и fallback на штатный publishedAt.

Production-сборки Next и Strapi собираются. Импортер проходит 16 Node tests; сайт/API — 17 Jest tests. Чистый Docker dry-run работает без подключения к CMS: 200 проверено, записей и файлов не создано, ошибок нет. Docker standalone сайт: /api/content-health возвращает 200 с counts 94/41/5/15/44; главная, история и детальная новость — 200; фото — 200 image/jpeg без пароля. При недоступной CMS readiness — 503, страница — явный отказ 500; JSON fallback отсутствует. Read token не найден в HTML/RSC и 21 browser static files. Read-only token отклоняет создание записи с HTTP 403. Проверены синтаксис deployment scripts, Compose configurations, TypeScript, lint, форматирование и относительные ссылки документации.

Production

Переключение выполнено. GitHub Actions run 37029814883: attempt 1 — checks/images и CMS-only подготовка; attempt 2 — повтор deploy job после проверенного импорта. Оба завершились успешно. Production release: 635e184e9bbffba5133cb8a50463193e0e460266. Предыдущий frontend: fc9c32445310540c0c950f6e8999d51bed739e72.

Холодная копия: /opt/gheilt/backups/content-20261002T160025Z, каталог 0700, все файлы 0600. Strapi dump — 205968 bytes; также сохранены оба тома Garage, прежние local uploads, environment и оба release refs. Scratch restore PostgreSQL успешен (прежних новостей было 0), Garage восстановлен в изолированной сети, тестовый PNG совпал побайтово. Scratch containers/network/volumes/DB удалены, исходные volumes сохранены.

Первый production запуск не получил доступа к snapshot и завершился до записи документов: host-файл 0600 принадлежал root, контейнер работает как node uid1000. Владелец snapshot исправлен, права 0600 сохранены; CMS восстановилась автоматически.

Успешный production импорт: 200 created, 0 updated, 0 skipped, 0 failed; 223 filesCreated, 24 filesReused. Повтор: 0 created, 0 updated, 200 skipped, 0 failed; 0 новых файлов. В Media Library осталось 223 файла. Все 223 оригинальных изображения доступны с публичного S3 origin с HTTP 200 и image MIME; все 11 промослайдов имеют media. Отчёты на VPS: content-import/import-report-20261002T160316Z.json и import-report-20261002T160456Z.json; локальные копии — var/content-import/production-{import,repeat}-report.json.

https://gheilt.mxsource.xyz/api/content-health возвращает ready и counts site1/news94/events41/pages5/faq15/partners44. Главная, news/events lists, news detail и все пять информационных страниц отвечают 200. Неизвестная новость — 404. tRPC news.list возвращает все 94 записи. PNG/JPEG через /api/media доступны без пароля с nosniff; SVG route отклоняется с 404. CMS /admin и Content API без Basic Auth — 401. Служебный read token не найден в production HTML/RSC и 21 static files; создание новости с этим token отклонено с 403. robots.txt запрещает обход всех путей, metadata и HTTP headers содержат noindex.

Ручная проверка редактора

Браузерная поверхность в сессии недоступна. Пользователю передан локальный сценарий Content Manager: draft → publish → edit/republish → unpublish. Подтверждение ещё не получено. Серверные проверки не заменяют эту ручную проверку интерфейса.

Эксплуатационные границы

Один VPS, один экземпляр Garage, без HA. Холодная копия на том же VPS защищает от ошибки миграции, но не от потери VPS; её нужно вынести наружу. Медиа публичны, в том числе файлы неопубликованных материалов; unpublish не удаляет файл. С 2026-10-04 внешний Basic Auth отключён, создан администратор Strapi; admin/API защищены средствами CMS. Результаты проверки выше относятся к состоянию на момент миграции. Откат frontend не откатывает CMS schema или БД.

Решения при выполнении плана

  • Работа выполнялась в отдельном Git worktree, чтобы незавершённый web не ушёл в main auto-deploy. Ошибка в изоляции могла бы преждевременно переключить сайт.
  • CMS сохранила свой TypeScript 5; target/lib ES2022 соответствует Node 24. Цена — отдельный compiler boundary и требование Node 24.
  • VK-картинки галочек заменены Unicode, без расширения whitelist на весь VK. Возможна небольшая разница в начертании символа.
  • Логотип и favicon из ранее извлечённого образца упакованы как вход импортера и загружены в CMS; frontend fallback отсутствует. Нужно отдельно обновлять эти исходные assets при замене образца.
  • Root .env загружается Next config через process.loadEnvFile: прежний Node launcher передавал недопустимый flag в дочерний NODE_OPTIONS. Изменение env требует перезапуска host Next.
  • Media proxy буферизует до 25 MiB вместо streaming, чтобы отклонить MIME/oversize до успешного ответа. Цена — память на buffers и копии при параллельных запросах.
  • CMS-only подготовка включается автоматически при CONTENT_READY=false, без дополнительного workflow mode. Оператор должен явно подтвердить импорт флагом; переключение выполнено повтором deploy job того же проверенного SHA.
  • Код deployment недостаточен для утверждения о готовности: на VPS фактически выполнены restore, import, повтор и public smoke. Без этих проверок production нельзя считать подтверждённым.
  • Ручной editor workflow остаётся неподтверждённым из-за недоступной браузерной поверхности и отсутствия ответа пользователя. Серверные tests не исключают дефекты редакторского UX.
  • Offsite backup/retention оставлены отдельной документированной операцией. Копия на том же VPS не спасает при его потере.

Независимое ревью: три Important исправлены; Critical и отложенных Minor нет.