Перейти к основному содержимому

План унификации 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, wp2app. 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 — PHP src/Modules/StudioSync/, клиент STUDIO_SYNC_REST_BASE, CLI wp 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

Полный 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

Правило для оставшихся A platform: выкинуть /module/ и заменить префикс wp2platformwp2. Для B platform — wp2/{slug}/v1. Для D — wp2/{slug}/v1. Остальные плагины: {plugin-id}/{slug}/v1 как в таблице.

Studio Sync уже на каноне (wp2/studio-sync/v1) — строка в таблице для сверки, не задача фазы 2.

СемьяСейчасЦель
Site Managerwp2/site-manager/v1wp2/site-manager/v1
Site Duplicatorwp2/site-duplicator/v1wp2/site-duplicator/v1
Post Duplicatorwp2/post-duplicator/v1wp2/post-duplicator/v1
Multi Networkwp2/multi-network/v1wp2/multi-network/v1
Media Converterwp2/media-converter/v1wp2/media-converter/v1
Subtitles & Timecodeswp2/media-subtitles-timecodes/v1wp2/media-subtitles-timecodes/v1
Enable Media Replacewp2/enable-media-replace/v1wp2/enable-media-replace/v1
Studio Syncwp2/studio-sync/v1уже канон — не трогать
Passwordlesswp2/passwordless/v1wp2/passwordless/v1
Magic Linkswp2/magic-links/v1wp2/magic-links/v1
Media Playbackwp2/media-playback/v1wp2/media-playback/v1
Licensewp2/license/v1/…wp2/license/v1
Sections Folderwp2/sections-folder/v1/…wp2/sections-folder/v1
Elementor Style Presetswp2/elementor-style-presets/v1/…wp2/elementor-style-presets/v1
Local Syncwp2/local-sync/v1wp2/local-sync/v1
Static Builderwp2lms/static-builder/v1wp2lms/static-builder/v1
Turbowp2lms/turbo/v1wp2lms/turbo/v1
Embed Packages канонwp2lms-pro/embed-packages/v1без смены
Embed Packages aliaswp2platform/module/embed-packages/v1удалить регистрацию; канон только wp2lms-pro/embed-packages/v1
Tutor AIwp2tutor/v1 + /ai-chatwp2tutor/ai/v1
Tutor Embeddingwp2tutor/v1 + /embedding/…wp2tutor/embedding/v1
Tutor RAGwp2tutor/v1 + /rag-chunks/…wp2tutor/rag/v1
Formswp2tutor/v1 + /wp2tutor-form/form/…wp2tutor-forms/form/v1
Forms i18nwp2tutor/v1 + /wp2tutor-form/i18n/…wp2tutor-forms/i18n/v1
Bot Telegram / VK / Deep Chatwp2tutor/v1 + /telegram|vk|deepchat/…wp2tutor-bot/telegram/v1, …/vk/v1, …/deepchat/v1
wp2app Auth / Content / AIwp2app/v1wp2app/auth/v1, wp2app/content/v1, wp2app/ai-chat/v1

Полные URL (где route не «тот же суффикс»)

Семьи A platform: {route} как в инвентаре, NS wp2/{slug}/v1. Ниже — B, D, tutor, forms, bot, app. Studio Sync в таблицу URL не входит: уже wp2/studio-sync/v1.

Префикс везде /wp-json/.

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

METHODСейчасЦель
GETwp2/license/v1/productswp2/license/v1/products
POSTwp2/license/v1/{product_id}/activatewp2/license/v1/{product_id}/activate
POST…/deactivatewp2/license/v1/{product_id}/deactivate
GET…/statuswp2/license/v1/{product_id}/status
GET…/datawp2/license/v1/{product_id}/data

Sections Folder

METHODСейчасЦель
GETwp2/sections-folder/v1/sidebarwp2/sections-folder/v1/sidebar
PUT…/reorderwp2/sections-folder/v1/reorder
PUT…/assignwp2/sections-folder/v1/assign
PATCH…/sections/{id}wp2/sections-folder/v1/sections/{id}

Elementor Style Presets

METHODСейчасЦель
GET / POSTwp2/elementor-style-presets/v1/presetswp2/elementor-style-presets/v1/presets
GET / PATCH…/presets/{id}wp2/elementor-style-presets/v1/presets/{id}

Local Sync

METHODСейчасЦель
GETwp2/local-sync/v1/projectswp2/local-sync/v1/projects
POST…/syncwp2/local-sync/v1/sync
POST…/validatewp2/local-sync/v1/validate

CLI (pages-cli / local-sync), если дергает REST или печатает NS — тот же канон.

Static Builder (суффикс тот же)

wp2lms/static-builder/v1/{pages,builds,…}wp2lms/static-builder/v1/{тот же route}. CLI bin/static-builder/* перевести вместе со скиллом 10.

Turbo

METHODСейчасЦель
POSTwp2lms/turbo/v1/xapi-actor/sessionwp2lms/turbo/v1/xapi-actor/session
POSTwp2lms/turbo/v1/gravity-forms/submitwp2lms/turbo/v1/gravity-forms/submit
POSTwp2lms/turbo/v1/dsh/expandwp2lms/turbo/v1/dsh/expand
GETwp2lms/turbo/v1/static/{id}wp2lms/turbo/v1/static/{id}

Tutor

METHODСейчасЦель
GET / POSTwp2tutor/v1/ai-chatwp2tutor/ai/v1/chat
POSTwp2tutor/v1/embedding/syncwp2tutor/embedding/v1/sync
POST…/embedding/statuseswp2tutor/embedding/v1/statuses
POST…/embedding/diagnosticswp2tutor/embedding/v1/diagnostics
GET / POSTwp2tutor/v1/rag-chunks/datatableswp2tutor/rag/v1/datatables
GET…/rag-chunks/chunk/{id_chunk}wp2tutor/rag/v1/chunk/{id_chunk}

Forms

METHODСейчасЦель
POSTwp2tutor/v1/wp2tutor-form/form/updateDefinitionwp2tutor-forms/form/v1/updateDefinition
POST…/updateShortcodewp2tutor-forms/form/v1/updateShortcode
POST…/updateStyleswp2tutor-forms/form/v1/updateStyles
POST…/updateL10nwp2tutor-forms/form/v1/updateL10n
POST…/updateRunnerwp2tutor-forms/form/v1/updateRunner
GET…/getRunnerDatawp2tutor-forms/form/v1/getRunnerData
GETwp2tutor/v1/wp2tutor-form/i18n/localewp2tutor-forms/i18n/v1/locale
GET…/i18n/translationwp2tutor-forms/i18n/v1/translation

Bot

METHODСейчасЦель
POSTwp2tutor/v1/telegram/webhook/{bot_id}wp2tutor-bot/telegram/v1/webhook/{bot_id}
POSTwp2tutor/v1/vk/callback/{channel_id}wp2tutor-bot/vk/v1/callback/{channel_id}
POST / OPTIONSwp2tutor/v1/deepchat/chat/{channel_id}wp2tutor-bot/deepchat/v1/chat/{channel_id}

wp2app

METHODСейчасЦель
GETwp2app/v1/mewp2app/auth/v1/me
POSTwp2app/v1/loginwp2app/auth/v1/login
POSTwp2app/v1/logoutwp2app/auth/v1/logout
GETwp2app/v1/noncewp2app/auth/v1/nonce
POSTwp2app/v1/lost-passwordwp2app/auth/v1/lost-password
POSTwp2app/v1/reset-passwordwp2app/auth/v1/reset-password
GETwp2app/v1/contentwp2app/content/v1 (query path как сейчас)
GETwp2app/v1/content/{id}wp2app/content/v1/{id}
POST / OPTIONSwp2app/v1/ai-chat/chatwp2app/ai-chat/v1/chat

Studio Sync — не в scope

Переименование WP2 Sync → Studio Sync и канон wp2/studio-sync/v1 уже сделаны. Этот план их не повторяет и не меняет slug на studio.

Playground-bundle в wp2studio — зеркало platform, обновлять сборкой.

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, wp2app, bot) ставят строку {product}/{slug}/v1 по таблице.

Совместимость

Нет. Старый REST URL, CLI-имя и OpenAPI-path удаляются в том же изменении, что появляется канон. Коды WP_Error в этом эпике не переименовывать (это не URL).

Клиент и сервер одной семьи выкладываются вместе. Не выкладывать плагин с новым NS, пока скилл / SPA / админка этой семьи не переведены. Webhook бота: сменить URL в кабинете Telegram/VK при выкладке.

Клиенты (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 Linksonepix/wp2app/assets/src/auth/AuthContext.tsx; PrivateSiteExemption.php; RestLockdown.php
Local Sync.agents/skills/09-local-sync, 06-page-builder; PHP Local Sync REST already
Turboonepix/wp2lms/src/Modules/Turbo/**; бандлы Pulse/MOS, если хардкодят wp2lms/turbo/v1
Formsbuilder JS / rest_url в wp2tutor-forms; фильтр wp2tutor/rest_controllers
Bot + Deep Chatрегистрация webhook URL в админке каналов; wp2app ChatProxy wp2tutor/v1/deepchat
wp2appRestAuthController, ClassicContentController, ChatProxyController, UrlHelper boot restUrl
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

  • В 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 нет.
  • Вызывать из prebuild wp2-site как сейчас.
  • Не парсить OpenAPI из PHP как единственный канон.

Тесты (DoD семьи)

  • PHPUnit / REST: канон отвечает.
  • Старый URL этой семьи — 404 (негативный тест).
  • Forms/bot: нет регистрации на wp2tutor/v1.

Порядок работ

Клиент и PHP одной семьи — один релиз (связанные MR мержатся вместе).

  1. Инфра: RestController (product, slug); audit только канон.
  2. Удалить alias Embed Packages; канон wp2lms-pro/embed-packages/v1 не трогать.
  3. Остальные A platform + Static Builder: platform → wp2/{slug}/v1 (не wp2platform/…); Static Builder → wp2lms/static-builder/v1. Сразу клиенты (скиллы 10 / HLS / Whisper, passwordless, админки). Studio Sync пропускаем.
  4. B platform: License, Sections Folder, Presets.
  5. Local Sync + скилл 09 + CLI.
  6. Turbo + бандлы Pulse/MOS.
  7. Tutor: ai / embedding / rag.
  8. Forms: свой product, развязка wp2tutor/rest_controllers.
  9. wp2app: auth / content / ai-chat.
  10. 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 (уже был канон).