Files
ct-forms-portal/provisioning
Тимур Городецкий f9bed709ea feat: Provision-Lists.ps1 — фильтр -Lists для точечного добавления списков (#1)
Полный прогон на рабочем сайте перезаписывает варианты Choice живых списков
значениями из манифеста, а манифесты отстали от живых списков (#2). Новые
списки «Исключённые предложения» создаём точечно, не трогая остальные.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-27 11:23:58 +05:00
..

Провижионинг списков ct-forms-portal

Списки форм CT / OID / KPS воспроизводятся на боевом сайте портала /sites/sed из манифестов provisioning.json. Манифесты снимаются 1:1 с живых списков (Export-ListSchema.ps1), затем воспроизводятся на цели (Provision-Lists.ps1). Так схема всегда «под рукой» и одинаково создаётся на тесте и в бою (по аналогии с request-portal/provisioning).

Почему так, а не копия request-portal

  • Здесь литеральные имена списков (Сравнительная таблица, Позиции СТ ОИД…), а не конвенция «Форма N — данные/согласование». Скрипт request-portal на таких именах падал бы.
  • Поддержаны библиотеки документов (Коммерческие предложения*), а не только списки.
  • Одна форма (KPS) = много списков → манифест мультисписковый.

Коллизия имён KPS ↔ CT (важно!)

CT уже живёт на /sites/sed и владеет Сравнительная таблица, Позиции СТ, Оценка поставщиков, Критерии, Согласование СТ, библиотекой Коммерческие предложения. KPS раньше жил один на /sites/kps с теми же именами. При переезде на /sites/sed data-списки KPS получают суффикс КПС (зеркально суффиксу ОИД у OID):

Роль Было (на /sites/kps) Стало (на /sites/sed)
шапка Сравнительная таблица Сравнительная таблица КПС
позиции Позиции СТ Позиции СТ КПС
офферы Оценка поставщиков Оценка поставщиков КПС
критерии Критерии Критерии КПС
согласование Согласование СТ Согласование СТ КПС
библиотека КП Коммерческие предложения Коммерческие предложения КПС
без КП Не получены КП КПС Не получены КП КПС (уже уникально)
матрица Матрица согласования КПС Матрица согласования КПС (уже уникально)
справочник Поставщики Поставщики (ОБЩИЙ с CT)
справочник Курс Валют Курс Валют (ОБЩИЙ с CT)

Суффикс применяет Export автоматически (renameSuffix/renameExclude в sources.json), включая цели Lookup-колонок. Код уже приведён к новым именам:

  • forms/kps/services/KpsCtFormService.ts — карта LISTS;
  • components/config/kpsDocumentConfig.ts — siteUrl → /sites/sed, имена списков.

Общие справочники Поставщики, Курс Валют и Матрица согласования СТ создаёт манифест CT. OID тоже опирается на них (своей матрицы у OID нет). Поэтому провижионь вместе с CT (или все формы разом) — иначе Lookup'ы KPS/OID не найдут цель.

Что провижионинг НЕ делает (перенести отдельно!)

  • Данные справочников — содержимое Поставщики, Курс Валют, Матрица согласования *. Создаются только пустые списки с колонками.
  • Настройка Syntex на библиотеках Коммерческие предложения* (колонка file_content создаётся, но модель распознавания настраивается вручную).
  • URL потоков Power Automate (в коде сервисов) — указывают на прежнее окружение.
  • Единицы измерения (OID) живёт на /sites/stroy — внешний справочник, не трогаем.

Разовая подготовка (app-only, Sites.Selected)

Как в request-portal. Приложению нужен доступ и к /sites/sed, и к /sites/kps (последнее — только для экспорта схемы KPS с текущего сайта):

# один раз (если приложения ещё нет)
Register-PnPEntraIDApp -ApplicationName "PnP-Provisioning-Scoped" -Tenant "tnsukz.onmicrosoft.com" -SharePointApplicationPermissions "Sites.Selected" -Store CurrentUser

# админ выдаёт доступ к обоим сайтам
Grant-PnPAzureADAppSitePermission -AppId "<client-id>" -DisplayName "PnP-Provisioning-Scoped" -Permissions FullControl -Site "https://tnsukz.sharepoint.com/sites/sed"
Grant-PnPAzureADAppSitePermission -AppId "<client-id>" -DisplayName "PnP-Provisioning-Scoped" -Permissions Read       -Site "https://tnsukz.sharepoint.com/sites/kps"

Отпечаток сертификата:

Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.Subject -like "*PnP-Provisioning-Scoped*" } | Select-Object Subject, Thumbprint

Шаг 1. Снять схему с живых списков → манифесты

cd provisioning
./Export-ListSchema.ps1 `
  -ClientId "<client-id>" `
  -Tenant   "tnsukz.onmicrosoft.com" `
  -Thumbprint "<отпечаток>"

Создаст manifests/kps.provisioning.json, manifests/ct.provisioning.json, manifests/oid.provisioning.json. Только одна форма — флаг -Only kps.

Проверь манифесты глазами и закоммить в репозиторий — это и есть источник правды по схеме.

Шаг 2. Воспроизвести списки на /sites/sed

Сначала на тестовом сайте, потом на бою.

./Provision-Lists.ps1 `
  -SiteUrl  "https://tnsukz.sharepoint.com/sites/sed" `
  -ClientId "<client-id>" `
  -Tenant   "tnsukz.onmicrosoft.com" `
  -Thumbprint "<отпечаток>"

Идёт в два прохода: сначала все списки/библиотеки (чтобы Lookup нашли цель), потом колонки. Идемпотентно — повторный запуск ничего не ломает. -Only kps провижионит только KPS (но общие Поставщики/Курс Валют должны уже существовать).

Лог: [+] создано, [=] уже было, [~] обновлено, [!] предупреждение.

Формат манифеста

{
  "form": "kps",
  "targetSite": "https://tnsukz.sharepoint.com/sites/sed",
  "lists": [
    {
      "title": "Сравнительная таблица КПС",
      "template": "GenericList",      // или "DocumentLibrary"
      "shared": false,
      "columns": [
        { "internalName": "number", "title": "Номер СТ", "type": "Number" },
        { "internalName": "status", "title": "Статус", "type": "Choice", "choices": ["Черновик", "..."] },
        { "internalName": "winSupplier", "title": "Победитель", "type": "Lookup", "lookupList": "Поставщики", "lookupShowField": "Title" }
      ]
    }
  ]
}

Типы колонок: Text, Note, Number (+decimals), Choice (+choices, +multiChoice), DateTime (+dateOnly), Boolean, User (+userSelectionMode, +allowMultiple), Lookup (+lookupList, +lookupShowField, +allowMultiple).

Порядок миграции KPS (cutover)

  1. Экспорт (Шаг 1) → манифесты в репозитории.
  2. Провижн на /sites/sed (Шаг 2) → пустые списки … КПС + общие справочники.
  3. Перенести данные (справочники, а при необходимости — рабочие СТ) на новые списки.
  4. Задеплоить обновлённый ct-forms-portal (код уже смотрит на … КПС / /sites/sed).

До шага 4 старый kps-ct-form на /sites/kps продолжает работать — он не тронут.