Редактор сервисов и AI
Создание HTML/CSS/JavaScript сервиса, предпросмотр, черновики и публикация в веб-версии.
В Администрирование → Сервисы можно подключить приложение по URL или создать встроенный сервис из HTML, CSS и JavaScript. Раздел находится между Панели MotionCode и Автоматизации. В общих параметрах вкладки «Сервисы» больше нет.
Два способа подключения
По ссылке на сервер — прежний сценарий: название, URL, иконка, полномочие и список сотрудников. Приложение размещается на вашем сервере.
HTML, CSS и JavaScript — код хранится на бэкенде Synchra24 и запускается в изолированном фрейме веб-версии. Отдельный сервер приложения не нужен. Суммарный сериализованный JSON с исходниками ограничен 5 МиБ, максимум 100 активных встроенных сервисов на компанию. Для этого этапа исходники хранятся в PostgreSQL; загрузка ZIP и установка сторонних npm-пакетов не поддерживаются. React с JSX доступен во вкладке JavaScript.
Для управления сервисами нужна лицензия Приложения и право admin_edit_provider_services. Для AI также нужна лицензия AI-ассистент. Доступ к опубликованному сервису определяется полномочием и выбранными сотрудниками, как у сервиса по ссылке.
Редактор
Создайте встроенный сервис и заполните плашку параметров: название, иконку, полномочие для запуска и список сотрудников с доступом. Кнопка выбора сотрудников открывает стандартное окно поиска и множественного выбора, как у сервиса по ссылке. Пустой список не ограничивает доступ конкретными сотрудниками; заданное полномочие продолжает проверяться. Иконки и правила полномочия совпадают с сервисами по ссылке; пустое полномочие оставляет доступ без дополнительного требования к роли. После сохранения эти настройки меняются кнопкой настройки сервиса. Затем откройте вкладки:
- HTML — содержимое страницы, например
<main><h1>Остатки</h1><pre id="stock"></pre></main>; - CSS — стили. Переменные
--background,--text,--muted,--accentпомогают поддерживать светлую и тёмную тему; - JavaScript — обычный JS или React с JSX. Код запускается после HTML; JSX подготавливается к запуску автоматически.
Редакторы поддерживают подсветку, отступы и сворачивание блоков. SDK @synchra24/app встроен. Уже доступны synchra, SynchraApp и SERVICE_TOKEN; токены пользователя и компании в код не передаются.
Кнопка Загрузить код из файлов (папка рядом с форматированием кода) позволяет выбрать один или несколько файлов: .html / .htm, .css, .js / .jsx / .mjs. Их содержимое в UTF-8 заменяет код соответствующих вкладок; остальные вкладки сохраняются. Можно выбрать только один файл каждого типа. Все файлы проверяются до замены кода; при ошибке или превышении общего лимита исходников 5 МиБ редактор остаётся без изменений. Для HTML используйте содержимое страницы, а JavaScript и CSS загружайте отдельно. Загрузка не сохраняет и не публикует сервис: проверьте предпросмотр, затем сохраните черновик. Файлы .jsx загружаются во вкладку JavaScript и выполняются с поддержкой React и JSX.
Кнопка Экспортировать код в ZIP справа в верхней панели скачивает текущие исходники из редактора, включая несохранённые правки. В архив входят index.html, style.css и script.js; имя архива соответствует названию сервиса. JavaScript сохраняется без преобразования, включая JSX. Это исходники для редактора: экспорт не добавляет ключ сервиса, SDK или встроенные библиотеки движка. Экспорт не сохраняет и не публикует сервис.
Кнопка Форматировать в панели каждого редактора расставляет отступы и выравнивает HTML, CSS или JavaScript. При ошибке синтаксиса исходный текст сохраняется, а редактор показывает причину. Форматирование не сохраняет и не публикует сервис автоматически.
try {
const artifact = await synchra.getArtifact('warehouse.stock');
document.querySelector('#stock').textContent = JSON.stringify(artifact.value, null, 2);
} catch (error) {
document.querySelector('#stock').textContent = error.message;
}
В текущем веб-мосте доступны получение артефактов, контекст компании, проверка интеграции и чтение темы. Камера, геопозиция, выбор файлов и другие мобильные методы в этом веб-режиме недоступны. Чтение артефактов сохраняет ограничения API: нужна лицензия API и право управления интеграциями. Не используйте fetch или CDN: сетевые запросы фрейма заблокированы. Изображения можно включать как data:.
React и JSX
React и ReactDOM входят в веб-версию и доступны в предпросмотре и опубликованном сервисе. Новый сервис содержит React-пример с чтением артефакта. В HTML укажите контейнер:
<div id="root"></div>
Во вкладке JavaScript можно писать JSX, функциональные компоненты и хуки:
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
function App() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Нажатий: {count}</button>;
}
createRoot(document.getElementById('root')).render(<App />);
Допустимы импорты из react, react-dom/client, lodash и dayjs, а также глобальные React и ReactDOM. Явно вызывайте createRoot(...).render(...): компонент не монтируется автоматически. synchra.getArtifact() работает из обработчиков и эффектов; отображайте загрузку и обрабатывайте ошибки. Другие сторонние модули, TypeScript, CDN и сетевые запросы не поддерживаются. React-приложение выполняется в том же sandbox, без доступа к авторизации основного сайта. В лимит 5 МиБ входят исходники сервиса; встроенные React, Lodash, Day.js и SDK не учитываются.
Кнопка форматирования работает с JSX. Ошибки подготовки кода показываются в панели логов; исходник остаётся в редакторе. Обычные сервисы на JavaScript продолжают работать.
Кнопка ⓘ в верхней панели рядом с AI-помощником и обновлением открывает README библиотеки @synchra24/app с GitHub в окне документации. Заголовки, списки, таблицы и примеры кода отображаются в формате Markdown. Можно открыть оригинал на GitHub; при ошибке доступна повторная загрузка. Документация загружается через веб-сервер с кэшированием на час.
Lodash и Day.js
Библиотеки встроены в движок: доступны без CDN и установки пакетов в предпросмотре и опубликованном сервисе. Можно использовать глобальные _ и dayjs либо импорты:
import _ from 'lodash';
import debounce from 'lodash/debounce';
import dayjs from 'dayjs';
const groups = _.groupBy(items, 'status');
const date = dayjs('13.10.2026', 'DD.MM.YYYY', true);
if (date.isValid()) console.log(date.format('DD.MM.YYYY'));
const moscowTime = dayjs.utc('2026-10-13T09:00:00Z').tz('Europe/Moscow');
Day.js использует русскую локаль по умолчанию; английская также встроена (dayjs.locale('en') или dayjs(value).locale('en')). Следующие плагины уже подключены через dayjs.extend, повторная настройка не нужна:
| Плагины | Возможности |
|---|---|
utc, timezone |
UTC и явное преобразование часовых поясов |
customParseFormat, localizedFormat |
Разбор заданного формата, строгая проверка и локализованный вывод дат |
relativeTime, duration |
Относительное время и длительности |
isBetween, isSameOrBefore, isSameOrAfter, minMax |
Диапазоны, сравнение, минимальная и максимальная дата |
isoWeek |
Недели по ISO |
Импорты dayjs/plugin/<name> разрешены для перечисленных плагинов, локали — dayjs/locale/ru и dayjs/locale/en. Для lodash доступны основной модуль и методы через lodash/<method>. Не используйте неуказанные плагины или другие локали: они не входят в движок. Часовой пояс задавайте явно по сценарию сервиса; время браузера может отличаться от времени компании.
Проверка моста и ключ сервиса
При старте проверяйте await synchra.isSynchraIntegrated() перед запросами контекста, артефактов и другими действиями через мост. До завершения проверки кнопки таких действий должны быть отключены. При false покажите сообщение о недоступном мосте и не выполняйте запросы: SDK возвращает false также при отклонённом ключе сервиса.
Движок автоматически передаёт SERVICE_TOKEN — ключ текущего сервиса — и создаёт synchra как new SynchraApp(SERVICE_TOKEN). Используйте готовый экземпляр. Не прописывайте реальный ключ в исходниках, не выводите его в логи и не заменяйте токеном пользователя или компании. Для внешнего приложения по URL ключ указывается при создании экземпляра SDK согласно документации библиотеки; для встроенного сервиса это уже делает движок.
const integrated = await synchra.isSynchraIntegrated();
if (!integrated) {
// Покажите сообщение и оставьте действия моста отключёнными.
return;
}
const artifact = await synchra.getArtifact('warehouse.stock');
// Отобразите artifact.value с обработкой загрузки, пустых данных и ошибок.
Пример выше — тело асинхронной функции. Стартовый React-шаблон проверяет мост в useEffect, хранит результат проверки и разрешает загрузку только при true. Эти же правила входят в инструкции AI-помощнику.
Предпросмотр эмулирует мост, передаёт тестовый ключ preview-service и возвращает успешный результат проверки для него. Проверка ключа выполняется при каждом вызове. Чтение артефактов возвращает только содержимое вкладки «Тестовые артефакты». Тестовый ключ не предоставляет доступ к реальным данным компании. Специально отключать проверку интеграции для предпросмотра не нужно.
Предпросмотр
Предпросмотр отображает сервис в области 393 × 852 CSS-пикселя, соответствующей экрану iPhone. Рядом находится панель JavaScript-логов: вывод console.log, console.info, console.warn, console.error, console.debug, а также ошибки выполнения и необработанные отклонения Promise. Панель хранит последние 300 сообщений; их можно очистить кнопкой или вызовом console.clear(). Обновление предпросмотра перезапускает сервис и очищает логи. На узком экране панель располагается ниже телефона.
Предпросмотр запускает код в sandbox без доступа к cookies и хранилищу основного сайта. Он использует тестовые артефакты, а не данные компании. На отдельной вкладке Тестовые артефакты редактор поддерживает подсветку JSON, отступы, сворачивание блоков и кнопку форматирования. При ошибке синтаксиса появляется сообщение. Введите JSON-объект, в котором ключ — имя артефакта, а значение — его содержимое:
{"warehouse.stock":{"items":[{"sku":"A01","quantity":12}]}}
Кнопка Обновить предпросмотр находится в верхней панели редактора, рядом с AI-помощником. Нажмите её или используйте Ctrl+S (Cmd+S на Mac), когда курсор в редакторе HTML, CSS, JavaScript или тестовых артефактов. Предпросмотр перезапускается с текущими исходниками и тестовыми данными; черновик при этом не сохраняется и не публикуется. Ошибки выполнения выводятся рядом с предпросмотром. Значения внешних данных выводите через textContent, избегайте вставки непроверенного HTML.
AI-помощник
Кнопка со звёздочками открывает помощника. Например: «Покажи остатки из warehouse.stock, добавь поиск и выдели товары, которых мало». Агент получает текущий код, правила веб-моста и пример использования SDK, основанный на app_example. Исходный пример на React служит справочником возможностей; в редакторе агент генерирует HTML/CSS/JavaScript, включая React с JSX.
AI возвращает предложение и краткое описание. Посмотрите предложенный код и нажмите Применить к черновику. Затем проверьте предпросмотр, сохраните и опубликуйте. Генерация сама не меняет рабочую версию и не предоставляет дополнительных прав пользователю.
Предложенный код показан в отдельных вкладках HTML, CSS и JavaScript с подсветкой и автоматическим форматированием. Его можно поправить в редакторе и отформатировать кнопкой. Повторный запрос дорабатывает предложенный вариант. Кнопка Применить к черновику переносит код в основной редактор; до применения текущие исходники не меняются.
Для генерации кода через резервную модель DeepSeek включён режим обдумывания. Он может занимать больше времени; основная модель остаётся YandexGPT. Предложение по-прежнему нужно проверить в предпросмотре.
Черновик и публикация
Кнопки Открыть, Сохранить черновик и Опубликовать находятся под редактором. Сообщения об успехе, ошибках и несохранённых изменениях отображаются цветной плашкой между редактором и кнопками. Публикация доступна только для сохранённого текущего кода; после правок сначала сохраните черновик.
Сохранить черновик создаёт сервис или сохраняет следующую редакцию исходников. Опубликовать делает текущий сохранённый черновик рабочим. При несохранённых изменениях публикация заблокирована.
До первой публикации сервис не отображается в списке доступных приложений сотрудников. Последующие изменения черновика не затрагивают опубликованную страницу. Кнопка Открыть открывает опубликованный вариант в веб-версии. Если другой администратор уже изменил черновик, сохранение со старым номером редакции отклоняется; перечитайте сервис.
На этом этапе хранятся текущий черновик и последняя публикация, без архива прошлых публикаций. Настройки доступа и название меняются кнопкой настройки. Удаление использует прежний механизм удаления сервиса.
API и размещение
Обычный API использует Bearer-токен пользователя и X-Provider-Token своей компании:
| Метод | Путь | Назначение |
|---|---|---|
| POST | /api/v1/providers/integrations/hosted-services |
Создать встроенный сервис с name, source: {html, css, js}, необязательными icon, permission, allowed_users. |
| GET | /api/v1/providers/integrations/hosted-services/{service_id} |
Прочитать черновик и номера редакций. |
| POST | /api/v1/providers/integrations/hosted-services/{service_id}/save |
Сохранить source с ожидаемым revision. |
| POST | /api/v1/providers/integrations/hosted-services/{service_id}/publish |
Опубликовать сохранённый черновик с ожидаемым revision. |
| GET | /api/v1/providers/integrations/hosted-services/{service_id}/published |
Прочитать публикацию с проверкой доступа сотрудника. |
| POST | /api/v1/ai/services/generate |
Предложить код по prompt и текущему source. |
Ответы в общей оболочке API. Объект сервиса содержит service, source, revision, published_revision. Конфликт редакции — 409; отсутствие публикации — 404; отсутствие права или лицензии — 403.
Таблица hosted_service_sources создаётся при старте сервиса провайдеров. HOSTED_SERVICE_WEB_URL задаёт адрес веб-версии для генерируемых ссылок; по умолчанию — https://app.synchra24.com. Для локального стенда можно указать http://localhost:3000.
В мобильном приложении опубликованный сервис открывается без отдельного входа в веб-версию. WebView передаёт ключ сервиса и ID компании в заголовках; страница использует существующий native bridge, чтобы получить публикацию авторизованным API-запросом приложения. Заголовки сами по себе не предоставляют доступ к исходникам или данным. Авторизация пользователя и компании остаётся в приложении; API проверяет лицензию, полномочие сервиса и ограничения по сотрудникам. Вызовы контекста и чтения артефактов также идут через native bridge. Обычное открытие ссылки в браузере продолжает требовать веб-авторизацию. Офлайн-кэширование встроенных сервисов пока не реализовано. Внешние сервисы по URL продолжают работать по прежней схеме.