Манифесты отстают от живых списков, когда колонки добавляют руками или кодом, и пересоздание по ним ломает функции. Скрипт только читает и показывает, чего нет в манифесте, чего нет на сайте и где отличаются тип, варианты или лукап. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
10 KiB
Провижионинг списков 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 (но общие Поставщики/Курс Валют должны уже существовать).
Лог: [+] создано, [=] уже было, [~] обновлено, [!] предупреждение.
Сверка манифестов с живыми списками
Манифест отстаёт, когда колонки добавляют руками или кодом. Перед провижинингом на рабочем сайте и после ручных правок списков — сверка (только чтение):
./Compare-Manifests.ps1 `
-SiteUrl "https://tnsukz.sharepoint.com/sites/sed" `
-ClientId "<client-id>" `
-Tenant "tnsukz.onmicrosoft.com" `
-CertificatePath "<путь к .pfx>" -CertificatePassword "<пароль>"
- есть в манифесте, нет в живом (создаст Provision-Lists.ps1), + есть в живом, нет в
манифесте (при пересоздании пропадёт — дописать в манифест), ~ отличаются тип, варианты или лукап.
Добавить новый список на рабочий сайт
Полный прогон Provision-Lists.ps1 синхронизирует варианты Choice у ВСЕХ живых списков с
манифестами. Новый список добавляй точечно — -Lists "Название": остальные списки не трогаются.
Формат манифеста
{
"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) → манифесты в репозитории.
- Провижн на
/sites/sed(Шаг 2) → пустые списки… КПС+ общие справочники. - Перенести данные (справочники, а при необходимости — рабочие СТ) на новые списки.
- Задеплоить обновлённый
ct-forms-portal(код уже смотрит на… КПС//sites/sed).
До шага 4 старый kps-ct-form на /sites/kps продолжает работать — он не тронут.