МенеджерСистемыВзаимодействия.УдалитьВыгрузкуДанных

Методы · DeleteDataDump

Удаляет выгрузку данных.

Синтаксис

УдалитьВыгрузкуДанных(<Идентификатор>)
Полное описание, параметры и ограничения

МенеджерСистемыВзаимодействия.УдалитьВыгрузкуДанных (CollaborationSystemManager.DeleteDataDump)

МенеджерСистемыВзаимодействия (CollaborationSystemManager)

УдалитьВыгрузкуДанных (DeleteDataDump)

Доступен, начиная с версии 8.3.22.

Синтаксис:
УдалитьВыгрузкуДанных(<Идентификатор>)
Параметры:

<Идентификатор> (обязательный)
Тип: ИдентификаторВыгрузкиДанныхСистемыВзаимодействия.
Идентификатор выгрузки данных.
Описание:

Удаляет выгрузку данных.

Доступность:

Сервер, толстый клиент, внешнее соединение.

См. также:
МенеджерСистемыВзаимодействия, метод УдалитьВыгрузкуДанныхАсинх

Использование в версии:

Доступен, начиная с версии 8.3.22.

Методическая информация

Практические примеры

Создать свою выгрузку взаимодействия, проверить готовность, восстановить две карточки и удалить только свой файл

Полный пульт отличает начало выгрузки/восстановления от окончания. Источник — ровно две собственные карточки полного подготовительного модуля, файлы/ID создаются самим пультом, mutation/delete допускаются только после свежего паспорта и точного собственного подтверждения.

Где и как запускать

Полный модуль управляемой формы УчебнаяВыгрузка85 собственного пустого УчебноеВзаимодействие85. Синхронные RPC и клиентское Ждать, все собственные проверки включены; серверный подготовительный модуль ниже создает конкретный источник.

Подготовка

  1. Только отдельная собственная VM, пустая учебная конфигурация УчебноеВзаимодействие858.5.1.1343, один UUID-пользователь Уч85Связь_, приложение УчебноеВзаимодействие85 и собственный сервер взаимодействия http://localhost:9094. Подготовьте их как в учебном модуле двух карточек, включенном ниже. Никакого рабочего абонента/совместного использования/интеграций/фона/персональных данных. Код не выполнялся и не создал резервных копий.

  2. В своем сервере вручную включите штатное локальное хранение выгрузок, разрешенное вашей серверной поставкой. Для файлового режима адрес будет путем на СЕРВЕРЕ ВЗАИМОДЕЙСТВИЯ, не сервере1С/клиенте. Для S3-ветви допустимо только отдельное локальное S3-совместимое хранилище http://localhost:9000/, без AWS/публичных бакетов. Это настройка вручную по документации вашего сервера; код не устанавливает хранилище и не подменяет его совместимость.

  3. Выдайте в этом новом стенде необходимые права администрирования данных/системы взаимодействия, настройки своего сервера/выгрузок. Никакое право не повышается кодом. Для положительного пути этой учебной партии выберите thin/thick управляемый клиент VM; наличие веб/mobile API не является проверкой этих клиентов.

  4. Создайте серверный общий модуль УчебноеВзаимодействие без Привилегированный, вставьте полный подготовительный модуль ниже. Вызовите его своей отдельной ручной командой с фразой СВОЕ ОБСУЖДЕНИЕ И ДВА СООБЩЕНИЯ. Он создаст собственный UUID-чат/две карточки и обновит второй текст до Проверка подтверждена:750. Сохраните показанный ключ только этого опыта; не подбирайте чужие чаты.

  5. Создайте другую внешнюю обработку УчебнаяВыгрузка85 с одной управляемой формой. Строки: Метка85 и Описание85 длиной200, IDВыгрузки85 и ПодтверждениеУдаления85 длиной100, ИсходныйКлюч85 длиной100, Режим85 длиной20, Фаза85 длиной30, Подтверждение85 длиной100, Статус85 длиной0. Булево НеизвестныйИсход85 и НачатоВосстановление85. Метка, описание, ID, фаза, флаги и статус только для просмотра/скрыты, не пользовательский выбор ID.

  6. Пять команд Создать85, Проверить85, Описание85, Восстановить85, Удалить85: общее действие ВыполнитьОперацию85. Назначьте ПриСозданииНаСервере/ПриОткрытии, вставьте весь основной модуль этой формы. Начальный список выгрузок своего приложения должен быть пуст — существующие выгрузки не переиспользуются и не удаляются.

  7. Введите только собственный ИсходныйКлюч85 из подготовительного опыта, выберите один режим Сервер или Ждать и фразу ТОЛЬКО СВОИ ДВЕ КАРТОЧКИ И ВЫГРУЗКА. Каждый режим изучайте на отдельном собственном свежем сервере/приложении. Сначала проверьте пустую фразу: никаких изменений. Создать85 начинает настоящую выгрузку только при вашем сознательном ручном запуске; файлы действительно появятся на вашем сервере, не здесь.

  8. После Создать85 нажимайте Проверить85 вручную с разумной паузой. Автотаймера/плотного цикла нет. Только статус Готово позволяет Описание85/Восстановить85/Удалить85. Восстановить85 сначала меняет собственный ответ750 на999, затем начинает восстановление именно своего снимка. Оно может перезаписать данные всего своего приложения, поэтому абсолютно все приложение и сервер должны быть только вашим учебным стендом.

  9. Если проверка восстановленного снимка нужна, дождитесь СтатусВосстановления=Успешно и свежего чтения исходных обеих карточек. Затем для необратимого удаления единственного собственного файла введите точный показанный IDВыгрузки85 в ПодтверждениеУдаления85. Возврата удаленного файла код не предлагает; сообщения/приложение этим методом не удаляются.

  10. При неизвестном результате пульт разрешает только чтение и не сбрасывает защитный флаг. Не повторяйте создание/правку/восстановление/удаление автоматически. При аварийном закрытии собственные метка/ID могут потеряться: это не повод подбирать старый файл. Автор не выполнял сеть/выгрузку/восстановление/удаление и не создавал архивов/резервных копий.

&НаКлиенте
Перем Выполняется85;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПроверитьСвоегоПользователя85();
    Если СистемаВзаимодействия.ПолучитьВыгрузкуДанных().Количество() <> 0 Тогда
        ВызватьИсключение "В выделенном своем приложении не должно быть прежних выгрузок";
    КонецЕсли;
    Метка85 = "Уч85Выгрузка_" + Строка(Новый УникальныйИдентификатор);
    Описание85 = Метка85 + " | Две собственные учебные карточки";
    IDВыгрузки85 = "";
    ИсходныйКлюч85 = "";
    Режим85 = "Сервер";
    Фаза85 = "Новая";
    Подтверждение85 = "";
    ПодтверждениеУдаления85 = "";
    НеизвестныйИсход85 = Ложь;
    НачатоВосстановление85 = Ложь;
    Статус85 = "Укажите точный свой UUID-ключ двух карточек, созданных этим учебным стендом";
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Выполняется85 = Ложь;
КонецПроцедуры

&НаКлиенте
Асинх Процедура ВыполнитьОперацию85(Команда)
    Если Выполняется85 Тогда
        ВызватьИсключение "Предыдущая операция пульта еще выполняется";
    КонецЕсли;
    Если Фаза85 = "Удалено" Тогда
        ВызватьИсключение "Опыт завершен. Новый пульт не подбирает прежние ID";
    КонецЕсли;
    Операция = Команда.Имя;
    Если Операция <> "Создать85" И Операция <> "Проверить85" И Операция <> "Описание85"
        И Операция <> "Восстановить85" И Операция <> "Удалить85" Тогда
        ВызватьИсключение "Неизвестная учебная операция выгрузки";
    КонецЕсли;
    Если НеизвестныйИсход85 И Операция <> "Проверить85" Тогда
        ВызватьИсключение "Исход записи неизвестен. Только чтение; повтор и удаление запрещены";
    КонецЕсли;
    Если Режим85 <> "Сервер" И Режим85 <> "Ждать" Тогда
        ВызватьИсключение "Нужен режим Сервер или Ждать";
    КонецЕсли;
    Если Подтверждение85 <> "ТОЛЬКО СВОИ ДВЕ КАРТОЧКИ И ВЫГРУЗКА" Тогда
        ВызватьИсключение "Подтвердите собственный выделенный сервер и данные";
    КонецЕсли;
    Выполняется85 = Истина;
    Попытка
        ПроверитьСвоиДанныеНаСервере85(Ложь);
        Если Операция = "Создать85" Тогда
            Если Фаза85 <> "Новая" Или IDВыгрузки85 <> "" Тогда
                ВызватьИсключение "Новая выгрузка уже могла быть создана";
            КонецЕсли;
            ПроверитьСвоиДанныеНаСервере85(Истина);
            Если Режим85 = "Ждать" Тогда
                Список = Ждать СистемаВзаимодействия.ПолучитьВыгрузкиДанныхАсинх();
                Если ТипЗнч(Список) <> Тип("Массив") Или Список.Количество() <> 0 Тогда
                    ВызватьИсключение "Перед созданием список выгрузок своего приложения должен быть пуст";
                КонецЕсли;
                НеизвестныйИсход85 = Истина;
                ИД = Ждать СистемаВзаимодействия.НачатьСозданиеВыгрузкиДанныхАсинх(Описание85);
            Иначе
                НеизвестныйИсход85 = Истина;
                ИД = СоздатьСвоюВыгрузкуНаСервере85();
            КонецЕсли;
            Если ТипЗнч(ИД) <> Тип("ИдентификаторВыгрузкиДанныхСистемыВзаимодействия") Тогда
                ВызватьИсключение "Создание могло начаться, но реальный ID не подтвержден";
            КонецЕсли;
            IDВыгрузки85 = Строка(ИД);
            Фаза85 = "Создание";
            НеизвестныйИсход85 = Ложь;
            Статус85 = "Получен только ID начатой своей выгрузки. Файл еще не объявляется готовым";
        Иначе
            Если IDВыгрузки85 = "" Тогда
                ВызватьИсключение "Нет полученного этим пультом собственного ID";
            КонецЕсли;
            ИД = Новый ИдентификаторВыгрузкиДанныхСистемыВзаимодействия(IDВыгрузки85);
            Если Режим85 = "Ждать" Тогда
                Факт = Ждать СистемаВзаимодействия.ПолучитьВыгрузкуДанныхАсинх(ИД);
            Иначе
                Факт = ПолучитьСвоюВыгрузкуНаСервере85(ИД);
            КонецЕсли;
            ПроверитьСвойПаспортВыгрузки85(Факт, ИД);
            Если Операция = "Проверить85" Тогда
                ПоказатьСвойСтатус85(Факт);
                Если Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Готово Тогда
                    Если Режим85 = "Ждать" Тогда
                        Адрес = Ждать СистемаВзаимодействия.ПолучитьАдресВыгрузкиДанныхАсинх(ИД);
                    Иначе
                        Адрес = ПолучитьСвойАдресНаСервере85(ИД);
                    КонецЕсли;
                    ПроверитьСвойАдрес85(Адрес, Факт.ДоступнаВыгрузка);
                    Если НачатоВосстановление85 И Факт.СтатусВосстановления = СтатусВосстановленияИзВыгрузкиДанныхСистемыВзаимодействия.Успешно Тогда
                        ПроверитьСвоиДанныеНаСервере85(Истина);
                        Фаза85 = "Восстановлено";
                        Статус85 = "Своя выгрузка сообщает Успешно и исходные две карточки прочитаны заново";
                    ИначеЕсли Не НачатоВосстановление85 Тогда
                        Фаза85 = "Готово";
                    КонецЕсли;
                КонецЕсли;
            Иначе
                Если Факт.Статус <> СтатусВыгрузкиДанныхСистемыВзаимодействия.Готово
                    Или Фаза85 <> "Готово" И Фаза85 <> "Восстановлено" Тогда
                    ВызватьИсключение "Мутация допускается только после ручной проверки готовности своего файла";
                КонецЕсли;
                Если Операция = "Описание85" Тогда
                    Если СтрНайти(Описание85, " | Описание подтверждено") <> 0 Тогда
                        ВызватьИсключение "Описание уже изменено этим опытом";
                    КонецЕсли;
                    НовоеОписание = Описание85 + " | Описание подтверждено";
                    НеизвестныйИсход85 = Истина;
                    Если Режим85 = "Ждать" Тогда
                        Результат = Ждать СистемаВзаимодействия.УстановитьОписаниеВыгрузкиДанныхАсинх(ИД, НовоеОписание);
                        Если Результат <> Неопределено Тогда
                            ВызватьИсключение "Native-результат изменения описания должен быть Неопределено";
                        КонецЕсли;
                        После = Ждать СистемаВзаимодействия.ПолучитьВыгрузкуДанныхАсинх(ИД);
                    Иначе
                        После = ИзменитьСвоеОписаниеНаСервере85(ИД, НовоеОписание);
                    КонецЕсли;
                    Если После.Идентификатор <> ИД Или После.Описание <> НовоеОписание Тогда
                        ВызватьИсключение "Новое описание собственной выгрузки не подтверждено";
                    КонецЕсли;
                    Описание85 = НовоеОписание;
                    НеизвестныйИсход85 = Ложь;
                    Статус85 = "Своё описание изменено API и отдельно прочитано, readonly свойство не назначалось";
                ИначеЕсли Операция = "Восстановить85" Тогда
                    Если НачатоВосстановление85 Тогда
                        ВызватьИсключение "Восстановление уже могло начаться. Повтор запрещен";
                    КонецЕсли;
                    НеизвестныйИсход85 = Истина;
                    НачатоВосстановление85 = Истина;
                    ИзменитьТолькоСвоюКарточкуПередВосстановлением85();
                    Если Режим85 = "Ждать" Тогда
                        Результат = Ждать СистемаВзаимодействия.НачатьВосстановлениеИзВыгрузкиДанныхАсинх(ИД);
                        Если Результат <> Неопределено Тогда
                            ВызватьИсключение "Начало восстановления обещанием должно дать Неопределено";
                        КонецЕсли;
                    Иначе
                        НачатьСвоеВосстановлениеНаСервере85(ИД);
                    КонецЕсли;
                    Фаза85 = "Восстановление";
                    НеизвестныйИсход85 = Ложь;
                    Статус85 = "Восстановление только начато. Нажимайте Проверить85 вручную до подтвержденного статуса и двух исходных карточек";
                Иначе
                    Если ПодтверждениеУдаления85 <> IDВыгрузки85 Тогда
                        ВызватьИсключение "Для необратимого удаления введите только точный свой ID выгрузки";
                    КонецЕсли;
                    Если НачатоВосстановление85 И Фаза85 <> "Восстановлено" Тогда
                        ВызватьИсключение "Нельзя удалять файл, пока свой опыт восстановления не подтвержден";
                    КонецЕсли;
                    НеизвестныйИсход85 = Истина;
                    Если Режим85 = "Ждать" Тогда
                        Результат = Ждать СистемаВзаимодействия.УдалитьВыгрузкуДанныхАсинх(ИД);
                        Если Результат <> Неопределено Тогда
                            ВызватьИсключение "Native-результат удаления должен быть Неопределено";
                        КонецЕсли;
                        Остаток = Ждать СистемаВзаимодействия.ПолучитьВыгрузкиДанныхАсинх();
                    Иначе
                        Остаток = УдалитьТолькоСвоюВыгрузкуНаСервере85(ИД);
                    КонецЕсли;
                    Если ТипЗнч(Остаток) <> Тип("Массив") Или Остаток.Количество() <> 0 Тогда
                        ВызватьИсключение "Отсутствие своего файла в изначально пустом списке не подтверждено";
                    КонецЕсли;
                    Фаза85 = "Удалено";
                    НеизвестныйИсход85 = Ложь;
                    Статус85 = "Свой единственный файл выгрузки удален. Сообщения и приложение не удалялись";
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    Исключение
        Выполняется85 = Ложь;
        Статус85 = "Операция не подтверждена. Сохраните только свою метку/ID и проверьте свой сервер вручную; повторных записей нет";
        ВызватьИсключение "Учебная операция прервана без вывода адреса файла, ключей и чужих текстов";
    КонецПопытки;
    Выполняется85 = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвойПаспортВыгрузки85(Факт, ИД)
    Если ТипЗнч(Факт) <> Тип("ВыгрузкаДанныхСистемыВзаимодействия")
        Или Факт.Идентификатор <> ИД Или Факт.Описание <> Описание85
        Или ТипЗнч(Факт.ДатаСоздания) <> Тип("Дата") Или Факт.ДатаСоздания = Дата(1, 1, 1)
        Или ТипЗнч(Факт.ДоступнаВыгрузка) <> Тип("Булево") Тогда
        ВызватьИсключение "Полный паспорт своей выгрузки не совпал";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьСвойСтатус85(Факт)
    Если Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Ошибка
        Или Факт.СтатусВосстановления = СтатусВосстановленияИзВыгрузкиДанныхСистемыВзаимодействия.Ошибка Тогда
        ВызватьИсключение "Сервер сообщил ошибку своего файла или восстановления";
    КонецЕсли;
    Если Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Создание Тогда
        Статус85 = "Создание еще выполняется. Готовности нет";
    ИначеЕсли Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Загрузка Тогда
        ВызватьИсключение "В этом опыте загрузка чужого файла не начиналась";
    ИначеЕсли Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Восстановление Тогда
        Если Не НачатоВосстановление85 Тогда
            ВызватьИсключение "Неожиданное восстановление вне своего опыта";
        КонецЕсли;
        Статус85 = "Свое восстановление еще выполняется. Неопределено не означает, что оно никогда не начиналось";
    ИначеЕсли Факт.Статус = СтатусВыгрузкиДанныхСистемыВзаимодействия.Готово Тогда
        Статус85 = "Свой файл готов по статусу. Готовность не заменяет проверку результата восстановления";
    Иначе
        ВызватьИсключение "Неизвестный статус не выдается за готовность";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвойАдрес85(Адрес, ДоступноСкачивание)
    Если ТипЗнч(Адрес) <> Тип("Строка") Или Не ЗначениеЗаполнено(Адрес) Тогда
        ВызватьИсключение "Адрес своего готового файла не получен";
    КонецЕсли;
    Если ДоступноСкачивание Тогда
        Если Лев(Адрес, СтрДлина("http://localhost:9000/")) <> "http://localhost:9000/" Тогда
            ВызватьИсключение "S3-ссылка должна вести только в собственное локальное хранилище";
        КонецЕсли;
        Статус85 = Статус85 + " | Получена ограниченная по времени ссылка только на свой localhost S3; скачивание не выполнено";
    Иначе
        Если Лев(Адрес, 7) = "http://" Или Лев(Адрес, 8) = "https://" Тогда
            ВызватьИсключение "При файловом хранении ожидается путь на сервере взаимодействия, не публичный URL";
        КонецЕсли;
        Статус85 = Статус85 + " | Получен путь на сервере взаимодействия, не путь клиента/сервера1С; файл не открывался";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СоздатьСвоюВыгрузкуНаСервере85()
    ПроверитьСвоиДанныеНаСервере85(Истина);
    Если СистемаВзаимодействия.ПолучитьВыгрузкуДанных().Количество() <> 0 Тогда
        ВызватьИсключение "Начальный список должен быть пустым";
    КонецЕсли;
    Возврат СистемаВзаимодействия.НачатьСозданиеВыгрузкиДанных(Описание85);
КонецФункции

&НаСервере
Функция ПолучитьСвоюВыгрузкуНаСервере85(ИД)
    ПроверитьСвоиДанныеНаСервере85(Ложь);
    Возврат СистемаВзаимодействия.ПолучитьВыгрузкуДанных(ИД);
КонецФункции

&НаСервере
Функция ПолучитьСвойАдресНаСервере85(ИД)
    ПроверитьСвоюГотовуюВыгрузкуНаСервере85(ИД);
    Возврат СистемаВзаимодействия.ПолучитьАдресВыгрузкиДанных(ИД);
КонецФункции

&НаСервере
Функция ИзменитьСвоеОписаниеНаСервере85(ИД, НовоеОписание)
    ПроверитьСвоюГотовуюВыгрузкуНаСервере85(ИД);
    Если НовоеОписание <> Описание85 + " | Описание подтверждено" Тогда
        ВызватьИсключение "Нет собственного ожидаемого описания";
    КонецЕсли;
    СистемаВзаимодействия.УстановитьОписаниеВыгрузкиДанных(ИД, НовоеОписание);
    Возврат СистемаВзаимодействия.ПолучитьВыгрузкуДанных(ИД);
КонецФункции

&НаСервере
Процедура НачатьСвоеВосстановлениеНаСервере85(ИД)
    ПроверитьСвоюГотовуюВыгрузкуНаСервере85(ИД);
    СистемаВзаимодействия.НачатьВосстановлениеИзВыгрузкиДанных(ИД);
КонецПроцедуры

&НаСервере
Функция УдалитьТолькоСвоюВыгрузкуНаСервере85(ИД)
    ПроверитьСвоюГотовуюВыгрузкуНаСервере85(ИД);
    Если ПодтверждениеУдаления85 <> IDВыгрузки85 Или Строка(ИД) <> IDВыгрузки85 Тогда
        ВызватьИсключение "Точный свой ID удаления не подтвержден";
    КонецЕсли;
    СистемаВзаимодействия.УдалитьВыгрузкуДанных(ИД);
    Возврат СистемаВзаимодействия.ПолучитьВыгрузкуДанных();
КонецФункции

&НаСервере
Процедура ПроверитьСвоюГотовуюВыгрузкуНаСервере85(ИД)
    ПроверитьСвоиДанныеНаСервере85(Ложь);
    Если Строка(ИД) <> IDВыгрузки85 Или IDВыгрузки85 = "" Тогда
        ВызватьИсключение "Не тот реальный ID, который создал собственный пульт";
    КонецЕсли;
    Факт = СистемаВзаимодействия.ПолучитьВыгрузкуДанных(ИД);
    Если Факт.Идентификатор <> ИД Или Факт.Описание <> Описание85
        Или Факт.Статус <> СтатусВыгрузкиДанныхСистемыВзаимодействия.Готово Тогда
        ВызватьИсключение "Свой готовый файл не подтвержден свежим чтением";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПроверитьСвоиДанныеНаСервере85(ИсходныйТекст)
    Пользователь = ПроверитьСвоегоПользователя85();
    Если Лев(ИсходныйКлюч85, СтрДлина("Уч85Обсуждение_")) <> "Уч85Обсуждение_" Тогда
        ВызватьИсключение "Укажите свой ключ, созданный полным учебным модулем двух карточек";
    КонецЕсли;
    UUIDКлюча = Новый УникальныйИдентификатор(Сред(ИсходныйКлюч85, СтрДлина("Уч85Обсуждение_") + 1));
    Если ИсходныйКлюч85 <> "Уч85Обсуждение_" + Строка(UUIDКлюча) Тогда
        ВызватьИсключение "Нужен канонический собственный UUID-ключ";
    КонецЕсли;
    Обсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(ИсходныйКлюч85);
    Если Обсуждение = Неопределено Или Обсуждение.Ключ <> ИсходныйКлюч85
        Или Обсуждение.Заголовок <> ИсходныйКлюч85 + " | Проверка карточки книги"
        Или Обсуждение.Интеграция <> Неопределено Или Обсуждение.КонтекстОбсуждения <> Неопределено
        Или Обсуждение.ВнешнийИдентификатор <> ""
        Или Обсуждение.Участники.Количество() <> 1 Или Не Обсуждение.Участники.Содержит(Пользователь.Идентификатор) Тогда
        ВызватьИсключение "Источник не является собственным закрытым учебным обсуждением";
    КонецЕсли;
    Отбор = Новый ОтборСообщенийСистемыВзаимодействия;
    Отбор.Обсуждение = Обсуждение.Идентификатор;
    Отбор.Количество = 3;
    Список = СистемаВзаимодействия.ПолучитьСообщения(Отбор);
    Если Список.Количество() <> 2 Тогда
        ВызватьИсключение "Источник должен содержать ровно две собственные учебные карточки";
    КонецЕсли;
    Первая = Неопределено;
    Вторая = Неопределено;
    Для Каждого Карточка Из Список Цикл
        Если Карточка.Обсуждение <> Обсуждение.Идентификатор Или Карточка.Автор <> Пользователь.Идентификатор
            Или Карточка.Данные <> ИсходныйКлюч85 + "|Книга|3|250" Или Карточка.ФорматДанныхСтроки <> "text/plain"
            Или Карточка.Вложения.Количество() <> 0 Или Карточка.Действия.Количество() <> 0 Тогда
            ВызватьИсключение "Паспорт одной из собственных карточек неверен";
        КонецЕсли;
        Если Карточка.ИсходноеСообщение = Неопределено Тогда
            Если Первая <> Неопределено Или Строка(Карточка.Текст) <> ИсходныйКлюч85 + " | Книга: количество 3, цена 250" Тогда
                ВызватьИсключение "Первая собственная карточка не подтверждена";
            КонецЕсли;
            Первая = Карточка;
        Иначе
            Если Вторая <> Неопределено Тогда
                ВызватьИсключение "Лишний ответ не допускается";
            КонецЕсли;
            Текст = Строка(Карточка.Текст);
            Если Текст <> ИсходныйКлюч85 + " | Проверка подтверждена: 750"
                И (ИсходныйТекст Или Текст <> ИсходныйКлюч85 + " | После выгрузки: 999") Тогда
                ВызватьИсключение "Второй собственный текст не совпал с подготовленным опытом";
            КонецЕсли;
            Вторая = Карточка;
        КонецЕсли;
    КонецЦикла;
    Если Первая = Неопределено Или Вторая = Неопределено Или Вторая.ИсходноеСообщение <> Первая.Идентификатор Тогда
        ВызватьИсключение "Связь собственного ответа не подтверждена";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ИзменитьТолькоСвоюКарточкуПередВосстановлением85()
    ПроверитьСвоиДанныеНаСервере85(Истина);
    Обсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(ИсходныйКлюч85);
    Отбор = Новый ОтборСообщенийСистемыВзаимодействия;
    Отбор.Обсуждение = Обсуждение.Идентификатор;
    Отбор.Количество = 3;
    Для Каждого Карточка Из СистемаВзаимодействия.ПолучитьСообщения(Отбор) Цикл
        Если Карточка.ИсходноеСообщение <> Неопределено Тогда
            Карточка.Текст = Новый ФорматированнаяСтрока(ИсходныйКлюч85 + " | После выгрузки: 999");
            Карточка.Записать();
            ПроверитьСвоиДанныеНаСервере85(Ложь);
            ПровереннаяКарточка = СистемаВзаимодействия.ПолучитьСообщение(Карточка.Идентификатор);
            Если ПровереннаяКарточка.Идентификатор <> Карточка.Идентификатор
                Или Строка(ПровереннаяКарточка.Текст) <> ИсходныйКлюч85 + " | После выгрузки: 999" Тогда
                ВызватьИсключение "Собственная новая карточка999 не подтверждена перед началом восстановления";
            КонецЕсли;
            Возврат;
        КонецЕсли;
    КонецЦикла;
    ВызватьИсключение "Своя карточка для изменения не найдена";
КонецПроцедуры

&НаСервере
Функция ПроверитьСвоегоПользователя85()
    ПроверитьСвойПустойСтенд();
    Если ПривилегированныйРежим() Тогда
        ВызватьИсключение "Входной привилегированный режим не допускается";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен единственный собственный учебный пользователь";
    КонецЕсли;
    Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
        Или Лев(Текущий.Имя, СтрДлина("Уч85Связь_")) <> "Уч85Связь_" Тогда
        ВызватьИсключение "Учебный пользователь не подтвержден";
    КонецЕсли;
    UUIDМетки = Новый УникальныйИдентификатор(Сред(Текущий.Имя, СтрДлина("Уч85Связь_") + 1));
    Если Текущий.Имя <> "Уч85Связь_" + Строка(UUIDМетки)
        Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
        ВызватьИсключение "Имя должно содержать собственный канонический ненулевой UUID";
    КонецЕсли;
    Если Не СистемаВзаимодействия.ИнформационнаяБазаЗарегистрирована()
        Или Не СистемаВзаимодействия.ИспользованиеДоступно() Тогда
        ВызватьИсключение "Вручную подготовьте регистрацию собственной учебной базы";
    КонецЕсли;
    Если СистемаВзаимодействия.АдресСервера() <> "http://localhost:9094" Тогда
        ВызватьИсключение "Разрешен только отдельно подготовленный сервер localhost:9094 в своей VM";
    КонецЕсли;
    Версия = СистемаВзаимодействия.ВерсияСервера();
    Если ТипЗнч(Версия) <> Тип("Строка") Или Не ЗначениеЗаполнено(Версия) Тогда
        ВызватьИсключение "Версия своего сервера не получена";
    КонецЕсли;
    ИД = СистемаВзаимодействия.ИдентификаторТекущегоПользователя();
    Если ТипЗнч(ИД) <> Тип("ИдентификаторПользователяСистемыВзаимодействия") Тогда
        ВызватьИсключение "Не получен реальный идентификатор собственного участника";
    КонецЕсли;
    Если СистемаВзаимодействия.ПолучитьИдентификаторПользователя(Текущий.УникальныйИдентификатор) <> ИД
        Или СистемаВзаимодействия.ПолучитьИдентификаторПользователяИнформационнойБазы(ИД) <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Двустороннее соответствие своей учетной записи неверно";
    КонецЕсли;
    Пользователь = СистемаВзаимодействия.ПолучитьПользователя(ИД);
    Если Пользователь.Идентификатор <> ИД Или Пользователь.Имя <> Текущий.Имя
        Или Пользователь.ПолноеИмя <> Текущий.ПолноеИмя
        Или Пользователь.ИдентификаторПользователяИнформационнойБазы <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Паспорт своего пользователя не совпал с информационной базой";
    КонецЕсли;
    Если Пользователь.Внешний Или Пользователь.Заблокирован
        Или Пользователь.ТипВнешнейСистемы <> ""
        Или Пользователь.ИдентификаторПользователяВнешнейСистемы <> Неопределено
        Или Пользователь.АдресЭлектроннойПочты <> ""
        Или Пользователь.АдресЭлектроннойПочтыДляАутентификации <> ""
        Или Пользователь.НомерТелефона <> ""
        Или Пользователь.КлючСопоставления <> "" Тогда
        ВызватьИсключение "Нужен чистый внутренний пользователь без персональных контактов и объединений";
    КонецЕсли;
    Если Пользователь.АдминистраторАбонента <> СистемаВзаимодействия.ТекущийПользовательЯвляетсяАдминистраторомАбонента() Тогда
        ВызватьИсключение "Признак администратора абонента не согласован";
    КонецЕсли;
    ВсеПользователи = СистемаВзаимодействия.СтандартныеПользователи.ВсеПользователиПриложения;
    Если ИД = ВсеПользователи Или ИД = Новый ИдентификаторПользователяСистемыВзаимодействия Тогда
        ВызватьИсключение "Стандартный адресат и Никого не оповещать не являются своей учетной записью";
    КонецЕсли;
    ВосстановленныйИД = Новый ИдентификаторПользователяСистемыВзаимодействия(Строка(ИД));
    Если СистемаВзаимодействия.ПолучитьПользователя(ВосстановленныйИД).Идентификатор <> ИД Тогда
        ВызватьИсключение "Восстановленный из строки реальный ID не подтвержден сервером";
    КонецЕсли;
    Приложение = СистемаВзаимодействия.ПолучитьПриложение(СистемаВзаимодействия.ИдентификаторТекущегоПриложения());
    Если Приложение.Идентификатор <> СистемаВзаимодействия.ИдентификаторТекущегоПриложения()
        Или Приложение.Наименование <> "УчебноеВзаимодействие85" Тогда
        ВызватьИсключение "Нужно свое приложение с точным учебным наименованием";
    КонецЕсли;
    Возврат Пользователь;
КонецФункции

&НаСервере
Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
Полный серверный подготовительный модуль УчебноеВзаимодействие: создать собственный чат/две карточки

Общий модуль УчебноеВзаимодействие: полный серверный модуль

Серверный общий модуль своей отдельной CF УчебноеВзаимодействие85; собственный localhost сервер, один UUID-пользователь и две реальные собственные карточки. Не вызывается при авторстве.

Процедура ВыполнитьПример(Подтверждение = "") Экспорт
    Пользователь = ПроверитьСвоегоПользователя85();
    Если Подтверждение <> "СВОЕ ОБСУЖДЕНИЕ И ДВА СООБЩЕНИЯ" Тогда
        ВызватьИсключение "Сначала прочитайте подготовку. Обсуждение не создано";
    КонецЕсли;
    ИДПользователя = Пользователь.Идентификатор;
    Ключ = "Уч85Обсуждение_" + Строка(Новый УникальныйИдентификатор);
    Сообщить("Собственный кандидат ключа: " + Ключ);
    Если СистемаВзаимодействия.ПолучитьОбсуждение(Ключ) <> Неопределено Тогда
        ВызватьИсключение "Коллизия ключа: существующее обсуждение не меняется";
    КонецЕсли;
    Выбор = Новый КоллекцияИдентификаторовПользователейСистемыВзаимодействия;
    Выбор.Добавить(ИДПользователя);
    Если Выбор.Количество() <> 1 Или Не Выбор.Содержит(ИДПользователя) Тогда
        ВызватьИсключение "Состав своего участника не собран";
    КонецЕсли;
    Выбор.Удалить(ИДПользователя);
    Если Выбор.Количество() <> 0 Или Выбор.Содержит(ИДПользователя) Тогда
        ВызватьИсключение "Удаление из локального подбора не подтверждено";
    КонецЕсли;
    Выбор.Добавить(ИДПользователя);
    Выбор.Очистить();
    Если Выбор.Количество() <> 0 Тогда
        ВызватьИсключение "Локальный подбор не очищен";
    КонецЕсли;
    Выбор.Добавить(ИДПользователя);
    Обсуждение = СистемаВзаимодействия.СоздатьОбсуждение();
    Обсуждение.Ключ = Ключ;
    Обсуждение.Заголовок = Ключ + " | Проверка карточки книги";
    Обсуждение.Групповое = Истина;
    Обсуждение.Отображаемое = Истина;
    Обсуждение.ТолькоПросмотр = Ложь;
    Обсуждение.КонтекстОбсуждения = Неопределено;
    Обсуждение.Интеграция = Неопределено;
    Обсуждение.ВнешнийИдентификатор = "";
    Для Каждого Участник Из Выбор Цикл
        Обсуждение.Участники.Добавить(Участник);
    КонецЦикла;
    Обсуждение.Записать();
    ИДОбсуждения = Обсуждение.Идентификатор;
    Если ТипЗнч(ИДОбсуждения) <> Тип("ИдентификаторОбсужденияСистемыВзаимодействия") Тогда
        ВызватьИсключение "Запись могла произойти, но реальный ID обсуждения не получен";
    КонецЕсли;
    Сообщить("Свой ID обсуждения: " + Строка(ИДОбсуждения));
    Восстановленное = Новый ИдентификаторОбсужденияСистемыВзаимодействия(Строка(ИДОбсуждения));
    ПроверитьСвоеОбсуждение85(Восстановленное, Ключ, ИДПользователя);
    Отбор = Новый ОтборОбсужденийСистемыВзаимодействия;
    Отбор.Ключ = Ключ;
    Отбор.Групповое = Истина;
    Отбор.Отображаемое = Истина;
    Отбор.КонтекстноеОбсуждение = Ложь;
    Отбор.КонтекстОбсуждения = Неопределено;
    Отбор.ТекущийПользовательЯвляетсяУчастником = Истина;
    Отбор.Количество = 2;
    Отбор.НаправлениеСортировки = НаправлениеСортировки.Возр;
    Отбор.ДатаНачала = Неопределено;
    Отбор.ВнешнийИдентификатор = "";
    Если Отбор.Интеграция <> Неопределено Тогда
        ВызватьИсключение "Новый отбор не должен выбирать внешнюю интеграцию";
    КонецЕсли;
    Список = СистемаВзаимодействия.ПолучитьОбсуждения(Отбор);
    Если Список.Количество() <> 1 Или Список[0].Идентификатор <> ИДОбсуждения Тогда
        ВызватьИсключение "Точный отбор собственного обсуждения не совпал";
    КонецЕсли;
    СистемаВзаимодействия.УстановитьРежимНаблюдения(ИДОбсуждения, Ложь, ИДПользователя);
    СистемаВзаимодействия.УстановитьОтображениеОповещенийОбсуждения(ИДОбсуждения,
        ОтображениеОповещенийСистемыВзаимодействия.НеБеспокоить, ИДПользователя);
    Если СистемаВзаимодействия.ПолучитьРежимНаблюдения(ИДОбсуждения, ИДПользователя)
        Или СистемаВзаимодействия.ПолучитьОтображениеОповещенийОбсуждения(ИДОбсуждения, ИДПользователя)
        <> ОтображениеОповещенийСистемыВзаимодействия.НеБеспокоить Тогда
        ВызватьИсключение "Собственные настройки оповещений не подтверждены";
    КонецЕсли;
    ПроверитьСвоеОбсуждение85(ИДОбсуждения, Ключ, ИДПользователя);
    ОтборДоЗаписи = Новый ОтборСообщенийСистемыВзаимодействия;
    ОтборДоЗаписи.Обсуждение = ИДОбсуждения;
    ОтборДоЗаписи.Количество = 2;
    ОтборДоЗаписи.НаправлениеСортировки = НаправлениеСортировки.Возр;
    ОтборДоЗаписи.После = Неопределено;
    Если СистемаВзаимодействия.ПолучитьСообщения(ОтборДоЗаписи).Количество() <> 0 Тогда
        ВызватьИсключение "Перед первой своей записью обсуждение должно быть пусто";
    КонецЕсли;
    Исходное = СистемаВзаимодействия.СоздатьСообщение(ИДОбсуждения);
    Исходное.Текст = Новый ФорматированнаяСтрока(Ключ + " | Книга: количество 3, цена 250");
    Исходное.Данные = Ключ + "|Книга|3|250";
    Исходное.ФорматДанныхСтроки = "text/plain";
    Исходное.Получатели.Добавить(Новый ИдентификаторПользователяСистемыВзаимодействия);
    ПроверитьСвойЧерновик85(Исходное);
    Исходное.Записать();
    ИДИсходного = Исходное.Идентификатор;
    Сообщить("Свой ID первого сообщения: " + Строка(ИДИсходного));
    ПервыйФакт = СистемаВзаимодействия.ПолучитьСообщение(
        Новый ИдентификаторСообщенияСистемыВзаимодействия(Строка(ИДИсходного)));
    ПроверитьСвоеСообщение85(ПервыйФакт, ИДИсходного, ИДОбсуждения, ИДПользователя, Ключ,
        Ключ + " | Книга: количество 3, цена 250", Неопределено);
    ПроверитьСвоеОбсуждение85(ИДОбсуждения, Ключ, ИДПользователя);
    ДоВторойЗаписи = СистемаВзаимодействия.ПолучитьСообщения(ОтборДоЗаписи);
    Если ДоВторойЗаписи.Количество() <> 1 Или ДоВторойЗаписи[0].Идентификатор <> ИДИсходного Тогда
        ВызватьИсключение "Перед второй своей записью ожидается только подтвержденное первое сообщение";
    КонецЕсли;
    Второе = СистемаВзаимодействия.СоздатьСообщение(ИДОбсуждения);
    Второе.Текст = Новый ФорматированнаяСтрока(Ключ + " | Проверка: сумма 750");
    Второе.Данные = Ключ + "|Книга|3|250";
    Второе.ФорматДанныхСтроки = "text/plain";
    Второе.ИсходноеСообщение = ИДИсходного;
    Второе.Получатели.Добавить(Новый ИдентификаторПользователяСистемыВзаимодействия);
    ПроверитьСвойЧерновик85(Второе);
    Второе.Записать();
    ИДВторого = Второе.Идентификатор;
    Сообщить("Свой ID второго сообщения: " + Строка(ИДВторого));
    ВторойФакт = СистемаВзаимодействия.ПолучитьСообщение(ИДВторого);
    ПроверитьСвоеСообщение85(ВторойФакт, ИДВторого, ИДОбсуждения, ИДПользователя, Ключ,
        Ключ + " | Проверка: сумма 750", ИДИсходного);
    ПроверитьСвойСписок85(ИДОбсуждения, ИДИсходного, ИДВторого);
    ПроверитьСвоеОбсуждение85(ИДОбсуждения, Ключ, ИДПользователя);
    ВторойФакт = СистемаВзаимодействия.ПолучитьСообщение(ИДВторого);
    ПроверитьСвоеСообщение85(ВторойФакт, ИДВторого, ИДОбсуждения, ИДПользователя, Ключ,
        Ключ + " | Проверка: сумма 750", ИДИсходного);
    ВторойФакт.Текст = Новый ФорматированнаяСтрока(Ключ + " | Проверка подтверждена: 750");
    ВторойФакт.Записать();
    ПроверитьСвоеСообщение85(СистемаВзаимодействия.ПолучитьСообщение(ИДВторого),
        ИДВторого, ИДОбсуждения, ИДПользователя, Ключ,
        Ключ + " | Проверка подтверждена: 750", ИДИсходного);
    Сообщить("Два своих сообщения сохранены, отобраны и одно обновлено. Удаление не выполняется автоматически");
КонецПроцедуры

Процедура ПроверитьСвойЧерновик85(Сообщение)
    Если Сообщение.Вложения.Количество() <> 0 Или Сообщение.Действия.Количество() <> 0
        Или Сообщение.ПанельКнопок.РядыКнопок.Количество() <> 0
        Или Сообщение.ЗначенияПодстановокШаблонаСообщения.Количество() <> 0
        Или Сообщение.ШаблонСообщения <> Неопределено Тогда
        ВызватьИсключение "Новый собственный черновик содержит неподготовленные вложения или шаблон";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвоеОбсуждение85(Идентификатор, Ключ, Участник)
    Факт = СистемаВзаимодействия.ПолучитьОбсуждение(Идентификатор);
    Если Факт.Идентификатор <> Идентификатор Или Факт.Ключ <> Ключ
        Или Факт.Заголовок <> Ключ + " | Проверка карточки книги"
        Или Не Факт.Групповое Или Не Факт.Отображаемое Или Факт.ТолькоПросмотр
        Или Факт.КонтекстОбсуждения <> Неопределено Или Факт.Интеграция <> Неопределено
        Или Факт.ВнешнийИдентификатор <> ""
        Или Факт.Участники.Количество() <> 1 Или Не Факт.Участники.Содержит(Участник) Тогда
        ВызватьИсключение "Полный собственный паспорт обсуждения изменен или не совпал";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвоеСообщение85(Факт, Идентификатор, Обсуждение, Автор, Ключ, Текст, Исходное)
    Если Факт.Идентификатор <> Идентификатор Или Факт.Обсуждение <> Обсуждение
        Или Факт.Автор <> Автор Или Строка(Факт.Текст) <> Текст
        Или Факт.Данные <> Ключ + "|Книга|3|250" Или Факт.ФорматДанныхСтроки <> "text/plain"
        Или Факт.ИсходноеСообщение <> Исходное Или ТипЗнч(Факт.Дата) <> Тип("Дата")
        Или Факт.Дата = Дата(1, 1, 1) Тогда
        ВызватьИсключение "Полное собственное сообщение не подтверждено. Чужое содержимое не выводится";
    КонецЕсли;
    ПроверитьСвойЧерновик85(Факт);
КонецПроцедуры

Процедура ПроверитьСвойСписок85(Обсуждение, Первый, Второй)
    Отбор = Новый ОтборСообщенийСистемыВзаимодействия;
    Отбор.Обсуждение = Обсуждение;
    Отбор.Количество = 3;
    Отбор.НаправлениеСортировки = НаправлениеСортировки.Возр;
    Отбор.После = Неопределено;
    Список = СистемаВзаимодействия.ПолучитьСообщения(Отбор);
    Если Список.Количество() <> 2 Тогда
        ВызватьИсключение "В собственном обсуждении должно быть ровно два собственных сообщения";
    КонецЕсли;
    Для Каждого СтрокаСообщения Из Список Цикл
        Если СтрокаСообщения.Обсуждение <> Обсуждение
            Или СтрокаСообщения.Идентификатор <> Первый И СтрокаСообщения.Идентификатор <> Второй Тогда
            ВызватьИсключение "В список попало неподтвержденное сообщение";
        КонецЕсли;
    КонецЦикла;
    Отбор.После = Второй;
    Если СистемаВзаимодействия.ПолучитьСообщения(Отбор).Количество() <> 0 Тогда
        ВызватьИсключение "После второго собственного сообщения не ожидаются записи";
    КонецЕсли;
КонецПроцедуры

Функция ПроверитьСвоегоПользователя85()
    ПроверитьСвойПустойСтенд();
    Если ПривилегированныйРежим() Тогда
        ВызватьИсключение "Входной привилегированный режим не допускается";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователи.Количество() <> 1 Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен единственный собственный учебный пользователь";
    КонецЕсли;
    Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
        Или Лев(Текущий.Имя, СтрДлина("Уч85Связь_")) <> "Уч85Связь_" Тогда
        ВызватьИсключение "Учебный пользователь не подтвержден";
    КонецЕсли;
    UUIDМетки = Новый УникальныйИдентификатор(Сред(Текущий.Имя, СтрДлина("Уч85Связь_") + 1));
    Если Текущий.Имя <> "Уч85Связь_" + Строка(UUIDМетки)
        Или UUIDМетки = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000") Тогда
        ВызватьИсключение "Имя должно содержать собственный канонический ненулевой UUID";
    КонецЕсли;
    Если Не СистемаВзаимодействия.ИнформационнаяБазаЗарегистрирована()
        Или Не СистемаВзаимодействия.ИспользованиеДоступно() Тогда
        ВызватьИсключение "Вручную подготовьте регистрацию собственной учебной базы";
    КонецЕсли;
    Если СистемаВзаимодействия.АдресСервера() <> "http://localhost:9094" Тогда
        ВызватьИсключение "Разрешен только отдельно подготовленный сервер localhost:9094 в своей VM";
    КонецЕсли;
    Версия = СистемаВзаимодействия.ВерсияСервера();
    Если ТипЗнч(Версия) <> Тип("Строка") Или Не ЗначениеЗаполнено(Версия) Тогда
        ВызватьИсключение "Версия своего сервера не получена";
    КонецЕсли;
    ИД = СистемаВзаимодействия.ИдентификаторТекущегоПользователя();
    Если ТипЗнч(ИД) <> Тип("ИдентификаторПользователяСистемыВзаимодействия") Тогда
        ВызватьИсключение "Не получен реальный идентификатор собственного участника";
    КонецЕсли;
    Если СистемаВзаимодействия.ПолучитьИдентификаторПользователя(Текущий.УникальныйИдентификатор) <> ИД
        Или СистемаВзаимодействия.ПолучитьИдентификаторПользователяИнформационнойБазы(ИД) <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Двустороннее соответствие своей учетной записи неверно";
    КонецЕсли;
    Пользователь = СистемаВзаимодействия.ПолучитьПользователя(ИД);
    Если Пользователь.Идентификатор <> ИД Или Пользователь.Имя <> Текущий.Имя
        Или Пользователь.ПолноеИмя <> Текущий.ПолноеИмя
        Или Пользователь.ИдентификаторПользователяИнформационнойБазы <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Паспорт своего пользователя не совпал с информационной базой";
    КонецЕсли;
    Если Пользователь.Внешний Или Пользователь.Заблокирован
        Или Пользователь.ТипВнешнейСистемы <> ""
        Или Пользователь.ИдентификаторПользователяВнешнейСистемы <> Неопределено
        Или Пользователь.АдресЭлектроннойПочты <> ""
        Или Пользователь.АдресЭлектроннойПочтыДляАутентификации <> ""
        Или Пользователь.НомерТелефона <> ""
        Или Пользователь.КлючСопоставления <> "" Тогда
        ВызватьИсключение "Нужен чистый внутренний пользователь без персональных контактов и объединений";
    КонецЕсли;
    Если Пользователь.АдминистраторАбонента <> СистемаВзаимодействия.ТекущийПользовательЯвляетсяАдминистраторомАбонента() Тогда
        ВызватьИсключение "Признак администратора абонента не согласован";
    КонецЕсли;
    ВсеПользователи = СистемаВзаимодействия.СтандартныеПользователи.ВсеПользователиПриложения;
    Если ИД = ВсеПользователи Или ИД = Новый ИдентификаторПользователяСистемыВзаимодействия Тогда
        ВызватьИсключение "Стандартный адресат и Никого не оповещать не являются своей учетной записью";
    КонецЕсли;
    ВосстановленныйИД = Новый ИдентификаторПользователяСистемыВзаимодействия(Строка(ИД));
    Если СистемаВзаимодействия.ПолучитьПользователя(ВосстановленныйИД).Идентификатор <> ИД Тогда
        ВызватьИсключение "Восстановленный из строки реальный ID не подтвержден сервером";
    КонецЕсли;
    Приложение = СистемаВзаимодействия.ПолучитьПриложение(СистемаВзаимодействия.ИдентификаторТекущегоПриложения());
    Если Приложение.Идентификатор <> СистемаВзаимодействия.ИдентификаторТекущегоПриложения()
        Или Приложение.Наименование <> "УчебноеВзаимодействие85" Тогда
        ВызватьИсключение "Нужно свое приложение с точным учебным наименованием";
    КонецЕсли;
    Возврат Пользователь;
КонецФункции

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Разбор по шагам

  1. Главный guard подтверждает свой единственный UUID-пользователь/точный localhost/точное приложение. Подготовительный ключ должен быть каноническим UUID, а чат — без контекста/интеграции/внешних привязок, с одним собственным участником. Ровно две карточки имеют свой автор/данные/MIME/точные исходные тексты и настоящую связь ответа.

  2. Безаргументный ПолучитьВыгрузкуДанных() в серверном модуле возвращает Массив списка. Это отдельная native-перегрузка от ПолучитьВыгрузкуДанных(ИД), которая возвращает один объект. Exporter-суффикс #&^@^%&*^#1 не является BSL именем и нигде в коде не вызывается.

  3. Создать85 проверяет отсутствие прежних файлов и устанавливает НеизвестныйИсход до начала. Синхронная ветвь возвращает настоящий ID; Ждать НачатьСозданиеВыгрузкиДанныхАсинх тоже возвращает ID при НАЧАЛЕ создания. Ни возврат native-вызова, ни выполнение обещания не означают готового файла.

  4. IDВыгрузки85 содержит только Строка ID, реально возвращенного созданием. Для дальнейших команд конструктор получает именно эту строку; она не создается из произвольного UUID/чужого ввода. Get по ID проверяет настоящий объект, тот же ID, свою точную Описание, серверную дату в часовом поясе сеанса и тип ДоступнаВыгрузка.

  5. Проверить85 читает status без автоматического повторения. Создание/Восстановление — ожидание, Ошибка — отказ, Загрузка — неожиданный чужой для этого опыта путь, Готово — только готовность файла. СтатусВосстановления=Неопределено может означать неначатый ИЛИ незавершенный процесс, поэтому его нельзя использовать как доказательство отсутствия восстановления.

  6. GetAddress вызывается только для готового своего ID. ДоступнаВыгрузка=true требует точную локальную S3-ссылку; false допускает только полученный серверный файловый путь, не публичный URL. Сам адрес/подписанный query не выводятся в журналы или интерфейс, HTTP/file операции не выполняются. Получение адреса — не скачивание и не проверка содержимого файла.

  7. Описание85 меняет описание только своим API УстановитьОписаниеВыгрузкиДанных, не присваиванием readonly свойства. После native-ответа получаются fresh ID/Описание; новое значение формируется только из собственной метки. Promise setter заканчивается Неопределено, а не Булево успеха.

  8. Восстановить85 свежо подтверждает собственные исходные карточки и меняет только свой второй текст750 на999. НачатоВосстановление и возможная запись отмечены заранее. Затем синхронный begin или Ждать BeginRestore начинают восстановление своего ID, но не объявляют окончания; promise-result=Неопределено.

  9. Проверить85 после begin требует одновременно Готово, СтатусВосстановления=Успешно и fresh проверку двух исходных карточек750/их данных/автора/связи ответа. Одно enumУспешно не заменяет содержательную проверку; ошибка/неизвестное состояние не дают разрешения удалить файл.

  10. Удалить85 требует свежую готовую свою выгрузку, известное состояние и точное повторное подтверждение своего ID. Для серверной ветви guard повторяется на сервере, для Ждать результат Неопределено отдельно проверяется. После удаления свежий список в изначально пустом приложении должен быть пуст. Catch не пытается восстановить удаленный файл.

  11. В catch снимается только флаг выполняющейся команды, но НеизвестныйИсход не снимается. Программа не пишет повторно, не удаляет/откатывает в обработчике ошибки и не выводит адреса/ключи/чужие тексты. Ручная сверка допустима только по собственным метке/ID на своем отдельном сервере.

Как проверить результат

  1. До создания и без фразы нет записей. Непустой прежний список, другой участник/автор/данные или третья карточка должны остановить опыт до начала выгрузки.

  2. После Создать85 показан только фактический ID начатого процесса, не обещание готовности. Попытка изменить/восстановить/удалить до ручного подтверждения Готово должна отказать.

  3. Проверить85 показывает собственные состояния без плотного polling. Readonly дата/ID/описание/ДоступнаВыгрузка/статусы читаются, не назначаются. Полученный серверный путь не принимается за файл клиента1С.

  4. После изменения описания fresh Get подтверждает тот же свой ID и точное новое описание. После beginrestore возврат метода не показывает восстановление.

  5. Положительный результат восстановления требует свежей исходной карточки750 вместо999, исходных данных и связи с первой карточкой, плюс nativeУспешно. Неопределено/Ошибка/неожиданный процесс не считаются успехом.

  6. Без точного подтверждения ID удаление не вызывается. После подтвержденного удаления список пуст, фаза Удалено, дальнейшие операции запрещены. Потерянный ответ не разрешает повторное удаление автоматически.

Ожидаемый результат

Реальный собственный цикл выгрузки/готовности/описания/начала восстановления/проверки двух карточек/удаления дан для server и Ждать. Готовность файла, готовность обещания и подтвержденное восстановление данных различаются; неизвестный результат остается неизвестным.

На что обратить внимание

  1. Файлы выгрузок содержат данные системы взаимодействия, а не файл конфигурации или .dt базы1С. Снимок/восстановление может затронуть все приложение: только выделенная собственная VM/сервер/абонент/приложение без персональных сведений.

  2. Native синхронные методы доступны server/thick/external, promise-методы — client/external по конкретной странице; не переносите Ждать-код на сервер. НачатьСоздание и НачатьВосстановление завершают свою функцию при старте процесса, не при готовности.

  3. ПолучитьВыгрузкуДанных имеет две разные перегрузки: ноль аргументов=Массив списка, реальный ID=один объект. Exporter synthetic suffix — только канонический ключ карточки, не имя метода встроенного языка.

  4. В экспортированном plain-пункте нулевая signature.params/returnTypeDefinition=Массив расходятся с ошибочно обогащенными syntaxText/описанием одного объекта. У sentinel-пункта один обязательный ID и returnTypeDefinition одного объекта. Урок привязан по точным установленным GetDataDumps6305.html и GetDataDump6307.html, не по этому ошибочному тексту exporter; источники/карточки не переписаны.

  5. ID из строки не проверяется конструктором. Его происхождение, exactметка/описание и fresh native-объект проверяются отдельно. Системные статусы и даты не устанавливаются вручную; readonly Описание изменяется только выделенным методом менеджера.

  6. S3-ссылка ограничена по времени и может содержать секретный токен; не публикуйте ее. ДоступнаВыгрузка относится к S3-скачиванию, не к общему статусу готовности. File-путь относится именно к серверу взаимодействия и не обязан существовать на клиенте/сервере1С.

  7. СтатусВосстановления=Неопределено не отличает никогда не начатое восстановление от еще не завершенного. Пульт хранит собственный флаг начала, проверяет основной статус и реальные собственные исходные карточки; при потере формы история ожидания может потеряться.

  8. НеизвестныйИсход после потенциальной записи не очищается чтением и не заменяется сообщением успеха. Восстановление/удаление не атомарны с предварительным чтением; параллельные клиенты/боты/другие администраторы запрещены подготовкой. Нет автоматического undo, retry или восстановления удаленного файла.

  9. Реальные действия автором не выполнялись: server/S3/files не использовались, backup/archive не создан, сеть/данные/права не менялись. Статическая проверка API8.5.1.1343 и кода не равна проверке сервера или восстановлению. RuntimeVerifiedScenarios=0.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.