План унификации REST URL (фаза 2)
Статус: фаза 2 выполнена. PHP, OpenAPI, скиллы и клиенты на каноне {product}/{slug}/v1. Dual-register / alias / rewrite нет. Старый URL — 404. Таблицы ниже — исторический mapping old → new.
Эта страница была планом работ. Namespace в PHP в фазе 1 не менялись; фаза 2 сменила URL без dual-route.
Вход: инвентарь ручек (текущие URL).
Единая схема
Заголовок раздела «Единая схема»Все REST всех продуктов — одна форма:
{product}/{slug}/v1| Часть | Значение |
|---|---|
{product} |
REST-префикс продукта. Плагины: wp2lms, wp2lms-pro, wp2tutor, wp2tutor-forms, wp2tutor-bot. WP2 Platform — исключение: в URL не wp2platform, а wp2. Plugin id / репозиторий остаются wp2platform. |
{slug} |
идентификатор модуля (в ядре плагина или в аддоне — без разницы) |
v1 |
версия REST этой семьи |
Отдельного шаблона «ядро = {product}/v1» нет. Новый модуль регистрирует только {product}/{slug}/v1. {product} = REST-префикс владельца (для platform это wp2, не id плагина).
Запрещено в новом коде:
{product}/module/{slug}/v1{product}/v1без сегмента модуля- REST-префикс
wp2platform/…(только снимаемый старый код) - чужой корень (
wp2lms-local-sync,wp2turbo, общиеwp2tutor/v1у forms/bot)
Старые адреса не поддерживаем: нет dual-register, нет deprecated alias в OpenAPI, нет rewrite в nginx, нет «срока снятия». В одном изменении PHP регистрирует только канон, клиенты (Studio, скиллы, SPA, CLI, админки) переезжают вместе. Старый URL — 404.
Эталон формы {product}/{slug}/v1 уже в коде:
- Embed Packages
wp2lms-pro/embed-packages/v1 - Studio Sync
wp2/studio-sync/v1— PHPsrc/Modules/StudioSync/, клиентSTUDIO_SYNC_REST_BASE, CLIwp studio-sync. Не переделывать (в т.ч. не сводить кwp2/studio/v1).
Media Playback сейчас wp2/media-playback/v1 — в фазе 2 на wp2/media-playback/v1. Dual-register Embed Packages (wp2platform/module/embed-packages/v1) снимаем.
Состав path: slug только в namespace
Заголовок раздела «Состав path: slug только в namespace»Полный URL: /wp-json/{product}/{slug}/v1{route}.
{slug} не повторять в {route}. Если сейчас slug сидит в route (wp2/license/v1/products), после переезда он уходит в namespace, route начинается со следующего сегмента (/products).
| Было | Стало |
|---|---|
{product}/module/{slug}/v1{route} |
{product}/{slug}/v1{route} — тот же {route} |
{product}/v1/{slug}{route} |
{product}/{slug}/v1{route} |
чужой корень {legacy}/v1{route} |
{product}/{slug}/v1{route} |
Исключение только если {route} после вырезания slug стал бы пустым: тогда канон — GET|POST …/{product}/{slug}/v1 (корень модуля) или явный короткий resource (/chat). Ниже для каждой такой семьи выбран один вариант, без «или».
blog_id и прочие query не входят в namespace; остаются query, как сейчас.
Namespace old → new
Заголовок раздела «Namespace old → new»Правило для оставшихся A platform: выкинуть /module/ и заменить префикс wp2platform → wp2. Для B platform — wp2/{slug}/v1. Для D — wp2/{slug}/v1. Остальные плагины: {plugin-id}/{slug}/v1 как в таблице.
Studio Sync уже на каноне (wp2/studio-sync/v1) — строка в таблице для сверки, не задача фазы 2.
| Семья | Сейчас | Цель |
|---|---|---|
| Site Manager | wp2/site-manager/v1 |
wp2/site-manager/v1 |
| Site Duplicator | wp2/site-duplicator/v1 |
wp2/site-duplicator/v1 |
| Post Duplicator | wp2/post-duplicator/v1 |
wp2/post-duplicator/v1 |
| Multi Network | wp2/multi-network/v1 |
wp2/multi-network/v1 |
| Media Converter | wp2/media-converter/v1 |
wp2/media-converter/v1 |
| Subtitles & Timecodes | wp2/media-subtitles-timecodes/v1 |
wp2/media-subtitles-timecodes/v1 |
| Enable Media Replace | wp2/enable-media-replace/v1 |
wp2/enable-media-replace/v1 |
| Studio Sync | wp2/studio-sync/v1 |
уже канон — не трогать |
| Passwordless | wp2/passwordless/v1 |
wp2/passwordless/v1 |
| Magic Links | wp2/magic-links/v1 |
wp2/magic-links/v1 |
| Media Playback | wp2/media-playback/v1 |
wp2/media-playback/v1 |
| License | wp2/license/v1/… |
wp2/license/v1 |
| Course Manager | wp2/course-manager/v1/… |
wp2/course-manager/v1 |
| Elementor Style Presets | wp2/elementor-style-presets/v1/… |
wp2/elementor-style-presets/v1 |
| Local Sync | wp2/local-sync/v1 |
wp2/local-sync/v1 |
| Static Builder | wp2lms/static-builder/v1 |
wp2lms/static-builder/v1 |
| Turbo | wp2lms/turbo/v1 |
wp2lms/turbo/v1 |
| Embed Packages канон | wp2lms-pro/embed-packages/v1 |
без смены |
| Embed Packages alias | wp2platform/module/embed-packages/v1 |
удалить регистрацию; канон только wp2lms-pro/embed-packages/v1 |
| Tutor AI | wp2tutor/v1 + /ai-chat |
wp2tutor/ai/v1 |
| Tutor Embedding | wp2tutor/v1 + /embedding/… |
wp2tutor/embedding/v1 |
| Tutor RAG | wp2tutor/v1 + /rag-chunks/… |
wp2tutor/rag/v1 |
| Forms | wp2tutor/v1 + /wp2tutor-form/form/… |
wp2tutor-forms/form/v1 |
| Forms i18n | wp2tutor/v1 + /wp2tutor-form/i18n/… |
wp2tutor-forms/i18n/v1 |
| Bot Telegram / VK / Deep Chat | wp2tutor/v1 + /telegram|vk|deepchat/… |
wp2tutor-bot/telegram/v1, …/vk/v1, …/deepchat/v1 |
Полные URL (где route не «тот же суффикс»)
Заголовок раздела «Полные URL (где route не «тот же суффикс»)»Семьи A platform: {route} как в инвентаре, NS wp2/{slug}/v1. Ниже — B, D, tutor, forms, bot. Studio Sync в таблицу URL не входит: уже wp2/studio-sync/v1.
Префикс везде /wp-json/.
Studio Sync — готово, вне работ фазы 2
Заголовок раздела «Studio Sync — готово, вне работ фазы 2»Код: onepix/wp2platform/src/Modules/StudioSync/ (AbstractRestController → namespace wp2/studio-sync/v1). OpenAPI: те же path в wp2platform-modules.yaml. Клиент: onepix/wp2studio/electron/runtime/core/constants.ts (STUDIO_SYNC_REST_BASE). CLI: wp studio-sync.
Не делать: повторный rename, wp2/studio/v1, dual-register со старым wp2platform/module/wp2sync/v1.
License
Заголовок раздела «License»| METHOD | Сейчас | Цель |
|---|---|---|
| GET | wp2/license/v1/products |
wp2/license/v1/products |
| POST | wp2/license/v1/{product_id}/activate |
wp2/license/v1/{product_id}/activate |
| POST | …/deactivate |
wp2/license/v1/{product_id}/deactivate |
| GET | …/status |
wp2/license/v1/{product_id}/status |
| GET | …/data |
wp2/license/v1/{product_id}/data |
Course Manager
Заголовок раздела «Course Manager»| METHOD | Сейчас | Цель |
|---|---|---|
| GET | wp2/course-manager/v1/sidebar |
wp2/course-manager/v1/sidebar |
| PUT | …/reorder |
wp2/course-manager/v1/reorder |
| PUT | …/assign |
wp2/course-manager/v1/assign |
| PATCH | …/sections/{id} |
wp2/course-manager/v1/sections/{id} |
Elementor Style Presets
Заголовок раздела «Elementor Style Presets»| METHOD | Сейчас | Цель |
|---|---|---|
| GET / POST | wp2/elementor-style-presets/v1/presets |
wp2/elementor-style-presets/v1/presets |
| GET / PATCH | …/presets/{id} |
wp2/elementor-style-presets/v1/presets/{id} |
Local Sync
Заголовок раздела «Local Sync»| METHOD | Сейчас | Цель |
|---|---|---|
| GET | wp2/local-sync/v1/projects |
wp2/local-sync/v1/projects |
| POST | …/sync |
wp2/local-sync/v1/sync |
| POST | …/validate |
wp2/local-sync/v1/validate |
CLI (pages-cli / local-sync), если дергает REST или печатает NS — тот же канон.
Static Builder (суффикс тот же)
Заголовок раздела «Static Builder (суффикс тот же)»wp2lms/static-builder/v1/{pages,builds,…} → wp2lms/static-builder/v1/{тот же route}. CLI bin/static-builder/* перевести вместе со скиллом 10.
| METHOD | Сейчас | Цель |
|---|---|---|
| POST | wp2lms/turbo/v1/xapi-actor/session |
wp2lms/turbo/v1/xapi-actor/session |
| POST | wp2lms/turbo/v1/gravity-forms/submit |
wp2lms/turbo/v1/gravity-forms/submit |
| POST | wp2lms/turbo/v1/dsh/expand |
wp2lms/turbo/v1/dsh/expand |
| GET | wp2lms/turbo/v1/static/{id} |
wp2lms/turbo/v1/static/{id} |
| METHOD | Сейчас | Цель |
|---|---|---|
| GET / POST | wp2tutor/v1/ai-chat |
wp2tutor/ai/v1/chat |
| POST | wp2tutor/v1/embedding/sync |
wp2tutor/embedding/v1/sync |
| POST | …/embedding/statuses |
wp2tutor/embedding/v1/statuses |
| POST | …/embedding/diagnostics |
wp2tutor/embedding/v1/diagnostics |
| GET / POST | wp2tutor/v1/rag-chunks/datatables |
wp2tutor/rag/v1/datatables |
| GET | …/rag-chunks/chunk/{id_chunk} |
wp2tutor/rag/v1/chunk/{id_chunk} |
| METHOD | Сейчас | Цель |
|---|---|---|
| POST | wp2tutor/v1/wp2tutor-form/form/updateDefinition |
wp2tutor-forms/form/v1/updateDefinition |
| POST | …/updateShortcode |
wp2tutor-forms/form/v1/updateShortcode |
| POST | …/updateStyles |
wp2tutor-forms/form/v1/updateStyles |
| POST | …/updateL10n |
wp2tutor-forms/form/v1/updateL10n |
| POST | …/updateRunner |
wp2tutor-forms/form/v1/updateRunner |
| GET | …/getRunnerData |
wp2tutor-forms/form/v1/getRunnerData |
| GET | wp2tutor/v1/wp2tutor-form/i18n/locale |
wp2tutor-forms/i18n/v1/locale |
| GET | …/i18n/translation |
wp2tutor-forms/i18n/v1/translation |
| METHOD | Сейчас | Цель |
|---|---|---|
| POST | wp2tutor/v1/telegram/webhook/{bot_id} |
wp2tutor-bot/telegram/v1/webhook/{bot_id} |
| POST | wp2tutor/v1/vk/callback/{channel_id} |
wp2tutor-bot/vk/v1/callback/{channel_id} |
| POST / OPTIONS | wp2tutor/v1/deepchat/chat/{channel_id} |
wp2tutor-bot/deepchat/v1/chat/{channel_id} |
Studio Sync — не в scope
Заголовок раздела «Studio Sync — не в scope»Переименование WP2 Sync → Studio Sync и канон wp2/studio-sync/v1 уже сделаны. Этот план их не повторяет и не меняет slug на studio.
Playground-bundle в wp2studio — зеркало platform, обновлять сборкой.
RestController (wordpress-core)
Заголовок раздела «RestController (wordpress-core)»Сейчас: __construct($app_name) → namespace {app_name}/v1, route_path = namespace + rest_base. Это как раз запрещённый шаблон B.
Цель:
namespace = {product}/{slug}/v{n}rest_base = resource внутри модуля (не дубль slug)Конструктор: product + slug (оба non-empty). License: ('wp2', 'license') — REST-префикс wp2, плагин по-прежнему wp2platform. rest_base не дублирует slug.
Один namespace на контроллер — канон. Старый {app_name}/v1 не регистрировать.
Одноаргументный конструктор не сохранять: наследники (platform, tutor, forms) переезжают в том же изменении, что core.
Модули без этого base (Studio Sync уже на wp2/studio-sync/v1, Local Sync, Static Builder, Turbo, bot) ставят строку {product}/{slug}/v1 по таблице.
Совместимость
Заголовок раздела «Совместимость»Нет. Старый REST URL, CLI-имя и OpenAPI-path удаляются в том же изменении, что появляется канон. Коды WP_Error в этом эпике не переименовывать (это не URL).
Клиент и сервер одной семьи выкладываются вместе. Не выкладывать плагин с новым NS, пока скилл / SPA / админка этой семьи не переведены. Webhook бота: сменить URL в кабинете Telegram/VK при выкладке.
Клиенты (grep при каждом семействе)
Заголовок раздела «Клиенты (grep при каждом семействе)»| Семья | Где править |
|---|---|
| Studio Sync | не трогать — уже wp2/studio-sync/v1 |
| Static Builder | .agents/skills/10-static-builder; onepix/wp2lms/bin/static-builder/* |
| Media Converter / subtitles | .agents/skills/media-hls-encode, media-whisper-tracks (_common.py NS) |
| Passwordless / Magic Links | onepix/wp2platform/src/Modules/PasswordlessLogin; onepix/wp2platform/src/Modules/MagicLinks |
| Local Sync | .agents/skills/09-local-sync, 06-page-builder; PHP Local Sync REST already |
| Turbo | onepix/wp2lms/src/Modules/Turbo/**; бандлы Pulse/MOS, если хардкодят wp2lms/turbo/v1 |
| Forms | builder JS / rest_url в wp2tutor-forms; фильтр wp2tutor/rest_controllers |
| Bot + Deep Chat | регистрация webhook URL в админке каналов |
| License / Sections / Presets | админ JS/PHP get_rest_url() / rest_url() в тех модулях |
| Embed Packages alias | агенты/доки, кто ещё бьёт в wp2platform/module/embed-packages |
| Site Manager и пр. A | админки соответствующих модулей (rest_url / DualRest) |
Вне scope по-прежнему: AnalogWP, /wp/v2/*, AJAX. В scope фазы 2: WP-CLI тех же семей — сразу новые имена, без alias старых команд.
Публичные webhooks бота: при выкладке оператор обязан сменить URL в Telegram/VK. Старый path не отвечает.
Аудит audit:openapi
Заголовок раздела «Аудит audit:openapi»- В PHP и YAML только канон
{product}/{slug}/v1. - Fail, если PHP-ручка нет в YAML, или в YAML/PHP остался
/module/, голый{product}/v1, REST-префиксwp2platform/,wp2lms-local-sync,wp2turbo, alias embed-packages, общийwp2tutor/v1у forms/bot. NAMESPACE_ALIASв сканере не считать нормой: второго NS нет.- Вызывать из
prebuildwp2-site как сейчас. - Не парсить OpenAPI из PHP как единственный канон.
Тесты (DoD семьи)
Заголовок раздела «Тесты (DoD семьи)»- PHPUnit / REST: канон отвечает.
- Старый URL этой семьи — 404 (негативный тест).
- Forms/bot: нет регистрации на
wp2tutor/v1.
Порядок работ
Заголовок раздела «Порядок работ»Клиент и PHP одной семьи — один релиз (связанные MR мержатся вместе).
- Инфра: RestController
(product, slug); audit только канон. - Удалить alias Embed Packages; канон
wp2lms-pro/embed-packages/v1не трогать. - Остальные A platform + Static Builder: platform →
wp2/{slug}/v1(неwp2platform/…); Static Builder →wp2lms/static-builder/v1. Сразу клиенты (скиллы 10 / HLS / Whisper, passwordless, админки). Studio Sync пропускаем. - B platform: License, Course Manager, Presets.
- Local Sync + скилл 09 + CLI.
- Turbo + бандлы Pulse/MOS.
- Tutor:
ai/embedding/rag. - Forms: свой product, развязка
wp2tutor/rest_controllers. - Bot: новые webhook URL; смена в кабинетах каналов в той же выкладке.
Первый код: шаги 2–3. Studio Sync в очередь не ставить.
Критерии готовности семьи
Заголовок раздела «Критерии готовности семьи»- Канон строго
{product}/{slug}/v1, route без дубля slug, URL как в таблицах выше. - В PHP и OpenAPI только канон: platform —
wp2/{slug}/v1, остальные плагины —{plugin-id}/{slug}/v1. Нет/module/, нет голого{product}/v1, нет REST-префиксаwp2platform/. npm run audit:openapiзелёный.- Клиенты из grep-таблицы и CLI переведены в том же изменении.
- Тесты DoD зелёные, включая 404 на старый URL.
- В
onepix/нет обращений к старому path (кроме негативных тестов). Playground-зеркало — сборкой, не руками.
Фаза 2 выполнена (шаги 1–10). Studio Sync по-прежнему вне scope (уже был канон).