Задача: Добавить admin resolver для массового обновления URI концептов в ЧПУ
Добавить admin resolver для массового обновления URI концептов в ЧПУ
Сделать безопасный админский bulk-resolver для миграции старых concept URI на человекопонятные slug с сохранением редиректов.
Цель
Добавить в haih-agent административный GraphQL resolver для массовой миграции старых концептов на человекопонятные URI (ЧПУ).
Сейчас в базе остается большое количество исторических концептов, у которых URI были созданы по старой схеме и не используют новый slugifyUri/человекочитаемый формат. Новая логика работает для создаваемых и изменяемых сущностей, но старые записи сами по себе не мигрируют.
Нужен централизованный административный инструмент, который позволит безопасно обновить такие URI массово.
Что должен делать resolver
Добавить admin-only mutation/resolver, который:
- Выбирает концепты, нуждающиеся в миграции URI.
- Для каждого вычисляет целевой URI по актуальным правилам
slugifyUri()и текущему имени/иерархии сущности. - Не меняет URI, если он уже соответствует актуальному формату.
- При изменении использует существующую общую логику смены URI (
processUriChangeили эквивалент), чтобы автоматически создавался301redirect со старого адреса на новый. - Не дублирует правила slugify/redirect локально внутри resolver — использовать общий код
haih-agent. - Возвращает понятный результат выполнения: сколько записей просмотрено, сколько изменено, сколько пропущено, сколько завершилось ошибкой.
Безопасность и управляемость
Resolver должен быть строго административным.
Желательно предусмотреть:
dryRun, чтобы сначала увидеть будущие изменения без записи в БД;limit/batch size для миграции частями;- возможность продолжить миграцию с cursor/offset либо другим устойчивым способом;
- фильтр только по концептам, где URI действительно требует изменения;
- логирование
oldUri -> newUri; - обнаружение конфликтов URI до записи;
- предсказуемое поведение, если два концепта после slugify претендуют на одинаковый URI;
- возможность безопасно повторно запустить resolver без повторного изменения уже мигрированных сущностей.
Конфликты URI
Отдельно определить стратегию для коллизий.
Нельзя молча перезаписывать существующий URI. Если вычисленный slug уже занят другим концептом, resolver должен либо:
- пропустить запись и вернуть collision в отчете;
- либо использовать заранее определенную детерминированную стратегию уникализации.
Стратегию необходимо явно зафиксировать в реализации.
Пример сценария
Было:
/concepts/cmt...
или другой исторический/технический URI.
Для концепта с названием:
TypeScript Generics
после миграции должно стать что-то вроде:
/concepts/typescript-generics
При этом старый адрес должен продолжить работать через 301 redirect.
SEO: зачем это нужно
Эта миграция важна не только для удобства URL, но и как часть общей SEO/GEO стратегии проектов на базе haih-agent.
1. Семантика прямо в URL
Технический адрес вроде:
/concepts/cmt7tulwi034wtj0qmz5n3s7h
не дает поисковой системе никакого дополнительного контекста о содержании страницы.
ЧПУ вроде:
/concepts/typescript-generics
содержит слова, совпадающие с темой документа. URL становится еще одним понятным сигналом наряду с title, description, headings и основным контентом.
2. Более понятный сниппет и доверие пользователя
Человекочитаемый URL легче воспринимается в SERP, ссылках и шаринге. Пользователь еще до перехода понимает, о чем страница, вместо набора технических ID.
Это потенциально улучшает качество клика и снижает ощущение "технической" или непрозрачной страницы.
3. Стабильная миграция без потери накопленных сигналов
Критически важно не просто заменить URL, а сохранить старые через 301.
301 позволяет поисковым системам понять, что документ переехал на новый постоянный адрес, и перенести накопленные сигналы старой страницы на новый URI вместо возникновения массовых 404.
4. Canonical и устранение дублей
После миграции человекочитаемый URI должен становиться canonical-адресом страницы.
Старые технические URL не должны индексироваться как отдельные дубли. Для них должен работать redirect на канонический ЧПУ.
5. Массовая миграция исторического контента
Без bulk-инструмента новый SEO-friendly механизм влияет только на новые и вручную отредактированные концепты. Большая часть уже накопленного контента останется на старых технических URI и не получит преимущества ЧПУ.
Admin resolver позволяет одномоментно или батчами привести исторический корпус к новой URL-модели.
6. База для downstream-проектов
Так как fi1osof.ru и другие проекты используют haih-agent как базис, resolver должен жить именно в haih-agent, а не реализовываться отдельно в каждом приложении.
Это даст единый механизм миграции URI для всех продуктов на этой платформе.
Критерии приемки
- Добавлен admin-only GraphQL resolver/mutation для массовой миграции URI концептов.
- Используется существующая общая логика
slugifyUriи смены URI, без дублирования алгоритмов. - Для измененного URI создается
301redirect со старого адреса. - Уже корректные ЧПУ не изменяются.
- Есть безопасная стратегия обработки URI collisions.
- Resolver можно запускать повторно без порчи уже мигрированных данных.
- Есть возможность выполнять миграцию батчами.
- Желательно реализован
dryRunс отчетом будущих изменений. - Результат resolver содержит статистику processed/updated/skipped/errors/collisions.
- Добавлены тесты на обычную миграцию, уже актуальный URI, collision, повторный запуск и создание redirect.
- После массовой миграции старые URL продолжают работать через 301, а новые ЧПУ могут использоваться как canonical URL.