раздел «Отчёты» в боковом меню — скачивание отчёта по вакансиям #17

Merged
gorbenko.pavel merged 5 commits from report into main 2026-08-31 11:00:19 +00:00
Collaborator

Пункт меню виден только заданному списку почт (Тришина, Городецкий,
Горбенко) — группы HR в SharePoint пока нет, добавили TODO завести
проверку по ней отдельно (reportsAccess.ts). Скрыт из меню совсем, а
не показан неактивным, и прямой переход по ?rpnav=reports у остальных
редиректит на «Новую заявку».

Раздел — форма периода (С/По) и кнопка «Скачать xlsx», дергает
GET api/reports/vacancies через тот же AadHttpClient, что и остальные
вызовы approval-route API. Имя файла собирается на фронте по формату
бэкенда (VacancyReportWorkbook.FileName), а не читается из
Content-Disposition — approval-route не объявляет заголовок в
Access-Control-Expose-Headers, браузер бы его не отдал.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

Пункт меню виден только заданному списку почт (Тришина, Городецкий, Горбенко) — группы HR в SharePoint пока нет, добавили TODO завести проверку по ней отдельно (reportsAccess.ts). Скрыт из меню совсем, а не показан неактивным, и прямой переход по ?rpnav=reports у остальных редиректит на «Новую заявку». Раздел — форма периода (С/По) и кнопка «Скачать xlsx», дергает GET api/reports/vacancies через тот же AadHttpClient, что и остальные вызовы approval-route API. Имя файла собирается на фронте по формату бэкенда (VacancyReportWorkbook.FileName), а не читается из Content-Disposition — approval-route не объявляет заголовок в Access-Control-Expose-Headers, браузер бы его не отдал. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
gorbenko.pavel added 1 commit 2026-08-28 06:46:08 +00:00
Пункт меню виден только заданному списку почт (Тришина, Городецкий,
Горбенко) — группы HR в SharePoint пока нет, добавили TODO завести
проверку по ней отдельно (reportsAccess.ts). Скрыт из меню совсем, а
не показан неактивным, и прямой переход по ?rpnav=reports у остальных
редиректит на «Новую заявку».

Раздел — форма периода (С/По) и кнопка «Скачать xlsx», дергает
GET api/reports/vacancies через тот же AadHttpClient, что и остальные
вызовы approval-route API. Имя файла собирается на фронте по формату
бэкенда (VacancyReportWorkbook.FileName), а не читается из
Content-Disposition — approval-route не объявляет заголовок в
Access-Control-Expose-Headers, браузер бы его не отдал.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
gorbenko.pavel added 4 commits 2026-08-31 10:03:43 +00:00
Проверено на тенанте 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>
Причина найдена: одноимённые колонки в разных списках — разные поля со своими
crawled property, автосозданное managed property привязано к одному из них.
Добавлена таблица, показывающая, что PositionOWSTEXT отдаёт значения в одном
списке и молчит в другом, — иначе картина выглядит бессмыслицей.

Исправлено неверное утверждение из предыдущего коммита: проверять существование
managed property через SortList нельзя. Sortable — независимый от Retrievable
флаг, у автосозданных ows_* обычно выключен; SortList падает 400/500 и на
заведомо живом PositionOWSTEXT. Рабочий способ — сверка Search с REST, её делает
`sp-write props`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Колонка OpenReason/OpenReasonDetails называлась одинаково с полями в других
списках сайта, из-за чего Search индексировал managed property только у ОДНОГО
из них — не у этого (см. sp-write props/field, разбирались 2026-08-28/29 в
tnsu-approval-route). Переименование снимает коллизию: VacancyOpenReasonOWSMTXT/
VacancyOpenReasonDetailsOWSTEXT теперь индексируются нормально, проверено.

Данные из старых колонок на живом сайте уже перенесены отдельным скриптом
(migrate-openreason.sh, разово, вне репозитория). provisioning.json обновлён на
новые internalName — он только добавляет колонки, никогда не удаляет, так что
старые OpenReason/OpenReasonDetails на сайте провижининг сам не уберёт.

load.ts/submit.ts менять не пришлось — оба читают/пишут поля по ключам
IFormData обобщённо.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Те же три поля internalName делит форма «Реферальная программа» — Search
индексировал managed property только у одного из двух списков (см. sp-write
sitefield/field: разные Id при одинаковом имени). Тот же приём, что для
VacancyOpenReason в RecruitingSelection: переименовать в уникальное имя,
данные перенести.

  CandidateName     -> HireCandidateName
  HireDate          -> HireHireDate
  ReplacedEmployee  -> HireReplacedEmployee

На этот раз — genuine столбцы САЙТА (createsitefield + linksitefield в
sp-write), а не просто колонки списка: так задумано и в самом провижинере
(Ensure-SiteColumn — простые типы должны быть общим эталоном), просто на
практике это не всегда соблюдается (Position тоже разъехался по Id между
списками). Проверено: Id столбца на сайте и на списке совпадают.

Данные на живом сайте перенесены отдельным скриптом (migrate-hire-fields.sh,
разово, вне репозитория) — все 37 элементов, сверено на трёх.

Задело WorkplaceSetup/prefill.ts — оно читает CandidateName/HireDate ИЗ
загруженной заявки на приём для кросс-форменного предзаполнения. Referral
(та же коллизия, другая форма) НЕ трогал.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gorbenko.pavel merged commit ddce6b4f25 into main 2026-08-31 11:00:19 +00:00
gorbenko.pavel deleted branch report 2026-08-31 11:00:19 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: timur.gorodetskiy/request-portal#17