docs(tools/sp): грабли поискового индекса и прав на элементах
Проверено на тенанте 2026-08-28, при разборе «перевести отчёт по вакансиям на Search или нет»: 1. Часть полей индекс не отдаёт ВООБЩЕ, хотя значения в списках есть (OpenReason/OpenReasonDetails, CandidateName/HireDate/ReplacedEmployee, Ticket). Рядом в тех же списках PositionOWSTEXT, RequestStatusOWSCHCS, SelectionRequestIdOWSNMBR и др. отдаются нормально — то есть дело не в типе колонки и не в задержке crawl. Добавлена таблица с тем, какие имена уже перепробованы, чтобы не ходить по кругу. 2. Отличить «managed property нет» от «есть, но пусто» через SelectProperties нельзя — на несуществующее имя молча приходит null. Отличается сортировкой: SortList по несуществующему свойству падает 400/500. 3. Права у заявок портала разорваны на КАЖДОМ элементе (HasUniqueRoleAssignments = true), поэтому под своей учёткой в списке видно 2 элемента из 19 — не баг и не кэш браузера. App-only это не трогает. Отсюда же: ItemCount списка считает всё, /items — только доступное вам. Заодно исправлено утверждение «Search под app-only обычно ничего не отдаёт» — на сертификате CN=PnP-SharePoint-Sync отдаёт, и postquery, и кастомные managed properties. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+37
-4
@@ -13,10 +13,14 @@
|
||||
пользователь вводит его в браузере сам, дальше CLI for Microsoft 365 держит токен у
|
||||
себя. Ни пароля, ни client secret в репозитории и в командах нет.
|
||||
|
||||
**Работаем от имени пользователя, а не приложения.** Это не удобство, а требование:
|
||||
SharePoint Search REST (`/_api/search/query`) под app-only-токеном обычно не отдаёт
|
||||
ничего, ему нужен пользовательский контекст. А Search — главное, что здесь измеряют.
|
||||
Побочный плюс: видно ровно то же, что видит пользователь в портале.
|
||||
**Работаем от имени пользователя, а не приложения.** Главное, что это даёт: видно
|
||||
ровно то же, что видит пользователь в портале, — а у заявок портала это принципиально,
|
||||
потому что права разорваны НА КАЖДОМ элементе (см. «Грабли» ниже).
|
||||
|
||||
Раньше здесь было написано, что Search под app-only-токеном «обычно не отдаёт ничего».
|
||||
Проверено 2026-08-28 на сертификате `CN=PnP-SharePoint-Sync` (тот же, что у бэкенда
|
||||
`tnsu-approval-route`): **отдаёт** — и `postquery`, и кастомные managed properties.
|
||||
Так что app-only Search как таковой рабочий; ограничения у него другие, см. «Грабли».
|
||||
|
||||
## Разовая подготовка
|
||||
|
||||
@@ -96,3 +100,32 @@ claims-логине частей будет четыре. Разбирать с
|
||||
партиций и в query-строке упирается в предел длины URL. Форма тела взята один в один
|
||||
из PnPjs (`@pnp/sp/search/query.js`): `{ request: { ...query } }`, массивы плоские,
|
||||
`odata=nometadata`. Иначе инструмент мерил бы не то, что портал.
|
||||
|
||||
**Часть полей индекс не отдаёт ВООБЩЕ, хотя значения в списках есть** (проверено
|
||||
2026-08-28 поштучным сравнением Search и REST на одних и тех же элементах):
|
||||
|
||||
| Список | Поле | Пробовали имена |
|
||||
| --- | --- | --- |
|
||||
| Заявка на подбор | `OpenReason`, `OpenReasonDetails` | `…OWSCHCS`, `…OWSMTXT`, `…OWSTEXT`, с префиксом `TansuSite` |
|
||||
| Прием на работу | `CandidateName`, `HireDate`, `ReplacedEmployee` | `…OWSTEXT`, `…OWSDATE`, с префиксом `TansuSite` |
|
||||
| — согласование | `Ticket` (Lookup) | `TicketOWSTEXT`, `TicketOWSLKID`, `TicketId`, `Ticket` |
|
||||
|
||||
Отличить «managed property нет вовсе» от «есть, но у строк пусто» через
|
||||
`SelectProperties` НЕЛЬЗЯ — на несуществующее имя ответ молча приходит с `null`.
|
||||
Отличается сортировкой: `SortList` по несуществующему свойству падает ошибкой
|
||||
400/500, по существующему — работает.
|
||||
|
||||
При этом рядом в тех же списках нормально отдаются `PositionOWSTEXT`,
|
||||
`RequestStatusOWSCHCS`, `SelectionRequestIdOWSNMBR`, `SelectionRequestListIdOWSTEXT`,
|
||||
`SubmitDateOWSDATE`, `TansuSiteApproverOWSUSER` — то есть это не про тип колонки и не
|
||||
про задержку crawl (у свежесозданных элементов рабочие поля появляются, а эти нет).
|
||||
Из-за этого отчёт по вакансиям в `tnsu-approval-route` остался на items REST по
|
||||
партициям, а не на Search — подробный расчёт в doc-комментарии `VacancyReportService`.
|
||||
|
||||
**Права разорваны на КАЖДОМ элементе.** У заявок портала
|
||||
`HasUniqueRoleAssignments = true` поштучно: доступ выдан только участникам заявки плюс
|
||||
общему админу. Поэтому под своей учёткой в списке видно 2 элемента из 19 — и это не
|
||||
баг и не кэш браузера, а модель доступа. App-only токен (сертификат) это не трогает и
|
||||
читает всё. Если сравниваете «сколько элементов в списке», обязательно фиксируйте, под
|
||||
кем смотрите: `ItemCount` в метаданных списка считает ВСЁ, а `/items` — только
|
||||
доступное вам.
|
||||
|
||||
Reference in New Issue
Block a user