b868e8012d
One web part replaces the separate stroy-bot-* web parts. The section and its parameters live in the page query string (?page=objects&projectId=5), so links can be copied, opened in a new tab and the browser Back button works. - shared config: site/Dataverse/API addresses, list and table names - HTTP layer behind IHttpClient so repositories can be unit-tested - ui-kit AppLayout + Sidebar, placeholder for sections not ported yet - migration checklist with every feature of the old web parts - design tokens mirrored from ui-kit instead of 8 copies Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
214 lines
20 KiB
Markdown
214 lines
20 KiB
Markdown
# Чек-лист миграции StroyBot → монорепо
|
||
|
||
Каждый раздел считается перенесённым только когда все пункты проверены в workbench.
|
||
Пишущие операции (создание / правка / удаление / импорт) проверяем **только на тестовом проекте «ТЕСТ StroyBot»**.
|
||
|
||
Правила переноса:
|
||
- Запросы, поля, фильтры, права и тексты переносятся **1:1** из исходного репозитория.
|
||
- Известные баги переносятся как есть (помечены 🐞) — исправляем позже отдельными коммитами.
|
||
- Старые страницы и web parts не трогаем, поддержка старых URL не нужна.
|
||
|
||
Легенда: `[ ]` — не проверено, `[x]` — проверено в workbench.
|
||
|
||
---
|
||
|
||
## 0. Общее (оболочка)
|
||
|
||
- [ ] Одна web part, разделы переключаются через `?page=…`, проект — через `?projectId=…`
|
||
- [ ] Кнопки «назад/вперёд» браузера переключают разделы
|
||
- [ ] Ссылку на любой раздел можно скопировать и открыть в новой вкладке
|
||
- [ ] Выбранный проект сохраняется между перезагрузками (`sessionStorage`, ключ `stroybot_selected_project`)
|
||
- [ ] Шрифты Inter и Lora подгружаются (раньше грузили report-list и assigner)
|
||
- [ ] `webApiPermissionRequests` в одном пакете: `api.tnsu.kz` (`9232d9e2-…`, `Reports.Read` и `user_impersonation`) + Dataverse `https://tansu.crm5.dynamics.com` (`user_impersonation`)
|
||
|
||
**Сознательные изменения (не функционал, а настройка):**
|
||
- Настройки property pane из 8 web parts сведены в одну группу «Подключение». Имена списков больше не настраиваются в property pane — они в константах.
|
||
- `worksPageUrl` (objects → works) больше не нужен: переход внутри приложения.
|
||
|
||
---
|
||
|
||
## 1. Главная (stroy-bot-main)
|
||
|
||
### Выбор проекта
|
||
- [ ] Поле «Проект:», плейсхолдер «Выберите проект», иконка поиска
|
||
- [ ] Список грузится при первом фокусе, «Загрузка проектов…»
|
||
- [ ] При фокусе текст выделяется
|
||
- [ ] Фильтр по Title (без учёта регистра, подстрока), максимум **7** результатов
|
||
- [ ] У каждого — бейдж статуса, «Без статуса» если пусто
|
||
- [ ] Сообщения: «Нет доступных проектов», «Проекты не найдены», «Ошибка загрузки. Попробуйте ещё раз.»
|
||
- [ ] Клик вне / Esc — закрыть и вернуть выбранное название (или очистить)
|
||
- [ ] Бейдж статуса рядом с полем: текущий — зелёный, завершен/завершён — серый, архивный — золотой, иначе — нейтральный
|
||
- [ ] Сортировка по алфавиту, затем до 7 недавно активных (из Dataverse `cree9_reports`) — наверх
|
||
- [ ] Права из «Доступы»: `read | edit0 | aproove`, `canEdit` = OR по `edit0`
|
||
- [ ] Подсказка «Выберите проект, чтобы активировать ссылки ниже»
|
||
|
||
### Разделы проекта
|
||
- [ ] Объекты / «Объекты по проекту»
|
||
- [ ] Отчёты по проекту / «Просмотр отчётности»
|
||
- [ ] Отправить отчёт / «Отправка отчёта по проекту»
|
||
- [ ] Загрузить работы из сметы / «Импорт работ в систему»
|
||
- [ ] Архив проекта / «Библиотека документов» → `{SITE}/Shared Documents/Архив/{Title}` (внешняя ссылка, новая вкладка)
|
||
- [ ] Ресурсы проекта / «Профессии и компании»
|
||
- [ ] Без выбранного проекта карточки неактивны
|
||
- [ ] Статус «архивный» — неактивно всё, кроме Архива; экспорт тоже неактивен
|
||
- [ ] Статус «завершен/завершён» — неактивно «Отправить отчёт»
|
||
- [ ] `canEdit = false` — неактивно «Отправить отчёт»
|
||
|
||
### Экспорт данных «Выгрузить за период»
|
||
- [ ] Кнопка «?» — поповер с 3 строками (день / Пн–Вс / произвольный), закрытие по клику мимо
|
||
- [ ] Поля «Начало» и «Конец» видны только при выбранном проекте
|
||
- [ ] «Укажите период для активации ссылки», пока даты не заданы
|
||
- [ ] Ошибка «Дата начала не может быть позже даты конца», кнопка неактивна
|
||
- [ ] Бейдж: «Ежедневный отчёт» (`daily`) / «Еженедельный отчёт» (Пн–Вс, `weekly`) / «Отчёт за период» (`period`)
|
||
- [ ] «Выгрузить» → спиннер «Формируется…» → файл `{prefix}_{from}_{to}.xlsx`
|
||
- [ ] Запрос `GET https://api.tnsu.kz/Report/StroyBot?start=…&end=…&projectId=…` (unix UTC 00:00:00 / 23:59:59)
|
||
- [ ] Ошибки: «Ошибка API: {status} {statusText}» / «Ошибка при загрузке отчёта»
|
||
|
||
🐞 Лишний запрос к «Доступы» без фильтра по пользователю.
|
||
|
||
---
|
||
|
||
## 2. Объекты (stroy-bot-objects) — `?page=objects&projectId=`
|
||
|
||
- [ ] Шапка «Объекты проекта» + название проекта («Загрузка...» / «Ошибка»)
|
||
- [ ] «Добавить объект» (только `canEdit`), «Экспорт» → «Экспортируется...» → `objects-{projectId}.xlsx` (`GET https://api.tnsu.kz/Report/ProjectObjects?projectId=`)
|
||
- [ ] Без projectId — «Вы не выбрали проект»; «Проект с ID={id} не найден»; «Ошибка: …»
|
||
- [ ] Пусто — «Объекты не найдены» + «+ Добавить объект» (если `canEdit`)
|
||
- [ ] Тулбар «{N} объектов» (рекурсивно), «Развернуть», «Свернуть»
|
||
- [ ] Дерево: отступ, иконка папки/файла, счётчик детей, шеврон, клик по строке — выделить + раскрыть
|
||
- [ ] Раскрытые узлы сохраняются между перезагрузками в рамках сессии
|
||
- [ ] Уровни: 0 — Объект-пятно, 1 — Раздел, 2 — Вид работ (не глубже 3 уровней)
|
||
- [ ] Контекстное меню (⋮ и правый клик, только `canEdit`): Добавить объект (не на уровне 2), Редактировать, Работы, Удалить
|
||
- [ ] Модалка: «Название *» (обязательно, Enter — сохранить), «Родительский объект» (select только при правке Раздела: узлы уровня 0, сортировка ru, без себя и потомков), «Проект» (read-only)
|
||
- [ ] Заголовки модалки: «Добавить Объект-пятно / Раздел / Вид работ», «Редактировать …», «— (корневой)»
|
||
- [ ] Удаление: подтверждение с числом дочерних, «Это действие нельзя отменить.»
|
||
- [ ] Drag & drop (только `canEdit`): до / внутрь / после, запрет на себя и потомков, ошибка «Не удалось переместить: …»
|
||
- [ ] «Работы» → раздел Работы с `objectId`
|
||
- [ ] После любой операции дерево перезагружается
|
||
- [ ] Список «Объекты»: `Title`, `project` (текст = название проекта), `parent` (self-lookup)
|
||
- [ ] Права: «Доступы» `projectId`/`userId` → `edit0`
|
||
|
||
🐞 Перетаскивание меняет только родителя, порядок не сохраняется. 🐞 Удаление узла не удаляет детей.
|
||
|
||
---
|
||
|
||
## 3. Работы (stroy-bot-works) — `?page=works&projectId=&objectId=`
|
||
|
||
- [ ] Шапка с названием проекта
|
||
- [ ] «Добавить работу» (только `canEdit`)
|
||
- [ ] Таблица-дерево: #, Наименование, Ед. изм., Проектный объём (ru-RU, 3 знака), Дата (`dd.mm.yy`, «start – finish» / одна / «—»)
|
||
- [ ] Родители свёрнуты по умолчанию, шеврон «Свернуть/Развернуть», нумерация по видимым строкам
|
||
- [ ] «Загрузка данных...», «Работы не найдены» (+ кнопка), ошибки Dataverse
|
||
- [ ] Меню строки ⋮ (`canEdit`): Добавить дочернюю, Редактировать, Удалить
|
||
- [ ] Модалка: НАИМЕНОВАНИЕ *, ЕД. ИЗМ. (список «Единицы измерения», с пагинацией; текущее значение не из списка — добавить наверх), ПРОЕКТНЫЙ ОБЪЁМ (шаг 0.001), РОДИТЕЛЬСКАЯ РАБОТА (без себя и потомков), ОБЪЕКТ (read-only), ДАТА НАЧАЛА / ОКОНЧАНИЯ
|
||
- [ ] «Сохранить и добавить еще» (в режиме добавления: модалка остаётся, родитель сохраняется)
|
||
- [ ] Подтверждение удаления «Подтвердите удаление»
|
||
- [ ] Dataverse `cree9_tables`, фильтр `cree9_objectid eq '{objectId}'`; без objectId — все работы
|
||
- [ ] Навигационное свойство родителя определяется через `EntityDefinitions` (fallback `cree9_parentid`)
|
||
- [ ] Проект находится подъёмом по родителям объекта до непустого `project`
|
||
|
||
🐞 Путь объекта (`#headerTitle`) не выводится. 🐞 Нет проверки «начало ≤ окончание».
|
||
|
||
---
|
||
|
||
## 4. Отчёты по проекту (stroy-bot-report-list) — `?page=reports&projectId=`
|
||
|
||
- [ ] Заголовок — название проекта
|
||
- [ ] Нет доступа — «Нет доступа» / «У вас нет прав на просмотр отчётов данного проекта.»
|
||
- [ ] Период по умолчанию — текущая неделя Пн–Вс; «С:», «По:», «Применить»
|
||
- [ ] Поиск «Поиск по любому полю...» (дата, номер, автор, компания, путь объекта, комментарий)
|
||
- [ ] Карточка «Отправить отчёт» (если `edit0 || aproove`)
|
||
- [ ] Карточки: `#номер`, дата, «✓ Утверждено», Пользователь, Компания (или «ID: n»), Объект (путь), Комментарий
|
||
- [ ] Копировать (`edit0 || aproove`) → форма отчёта с `copyFromId`
|
||
- [ ] Удалить (`aproove`, или `edit0` и не утверждён) → «Удалить отчёт?» → мягкое удаление `cree9_deleted = true`
|
||
- [ ] Клик / Enter / Space по карточке → форма отчёта с `reportId`
|
||
- [ ] Сортировка: дата desc, номер desc
|
||
- [ ] Пусто — «Отчёты не найдены за выбранный период.»
|
||
- [ ] Права: «Доступы» `user/Id` + `project/Id` (lookup)
|
||
|
||
🐞 Нет пагинации Dataverse (`@odata.nextLink` не читается). 🐞 Неделя по умолчанию считается в UTC.
|
||
|
||
---
|
||
|
||
## 5. Форма отчёта (stroy-bot-report) — `?page=report&projectId=[&reportId=|©FromId=]`
|
||
|
||
### Режимы
|
||
- [ ] Нет projectId — «Не указан projectId в URL»
|
||
- [ ] `reportId`: NoAccess / Approve (`aproove && !approved`) / Edit (`edit0 && !approved && дней < editDays`, по умолчанию 5) / ReadOnly
|
||
- [ ] `copyFromId`: Create, предзаполнены объект, компания, смена, комментарий, работы (с персоналом/техникой), персонал, техника; дата — сегодня, номер — 0, фото — пусто
|
||
- [ ] Без параметров — Create, смена — первая из «Смены», дата — сегодня
|
||
|
||
### Поля
|
||
- [ ] «← Вернуться назад»
|
||
- [ ] Заголовок «Отчет №N» / «Новый отчет», «Проект: …», бейдж «Утверждён» / «На утверждении»
|
||
- [ ] Дата отчета*, Смена*, Объект* (пикер с путями; смена объекта очищает работы), Компания* (с фильтром по «Компании по проекту», fallback — все)
|
||
- [ ] Работы: «+ Выбрать работу» («Сначала выберите объект»), Значение, План-факт (П / Ф / +/-, цвет), Комментарий
|
||
- [ ] Вложенные «Персонал на работе» / «Техника на работе»: Кол-во, Часы, «+ Добавить профессию / технику»
|
||
- [ ] Персонал: Кол-во, Часы, Тип часов (работы / простоя), Комментарий (обязателен для простоя)
|
||
- [ ] Техника: то же + «Часы ремонта» (комментарий обязателен для простоя и ремонта)
|
||
- [ ] Общий комментарий (contentEditable), Enter не отправляет форму SharePoint
|
||
- [ ] Фото: «Открыть папку с фото», «Добавить фото» (multiple), превью с удалением
|
||
|
||
### Пикер
|
||
- [ ] Поиск, группы для техники («Фильтры», чипы, «Все»), drill-down для работ (крошки «Все работы › …», «Выбрать «X»», «Нет работ на этом уровне»)
|
||
- [ ] Создание новой техники и новой работы (Ед. изм., План, Родительская работа)
|
||
|
||
### Сохранение
|
||
- [ ] Валидация (все сообщения из исходника)
|
||
- [ ] Номер = количество неудалённых отчётов проекта + 1
|
||
- [ ] При правке — удалить все старые строки (сначала дочерние), создать заново
|
||
- [ ] Фото → `DocLib/{projectId}_{number}`
|
||
- [ ] «Отчет успешно сохранен!», кнопка меняется на «← Вернуться назад»
|
||
- [ ] Утверждение: подтверждение → `cree9_aprooved = true` → «Отчет утвержден!»
|
||
- [ ] Права: «Доступы» `projectId` + `userId*` (несколько вариантов имени поля)
|
||
|
||
🐞 Create без проверки NoAccess. 🐞 Номер может совпасть после мягкого удаления. 🐞 Дата «сегодня» — UTC.
|
||
|
||
---
|
||
|
||
## 6. Импорт работ (stroy-bot-import-works) — `?page=import&projectId=`
|
||
|
||
- [ ] «ИМПОРТ РАБОТ» + название проекта
|
||
- [ ] Нет projectId — «Не указан projectId в URL»; нет `UniqueId0` — «Проект не привязан к справочнику проектов. Обратитесь к администратору.»
|
||
- [ ] Загрузка работ из API постранично по 200 с прогрессом «Загрузка работ... X из Y»
|
||
- [ ] Выбор объекта (модалка с поиском, сброс ×)
|
||
- [ ] Таблица: чекбокс, #, Наименование (+ бейдж объекта, «✓ импортировано», подзаголовок), Код СНБ, Ед. изм., Объём
|
||
- [ ] Поиск с debounce 250 мс по всем полям; пагинация по 100
|
||
- [ ] «Выделить всё на странице» / «Снять все на странице» (фактически — все отфильтрованные)
|
||
- [ ] Уже импортированные — неактивны, «Уже импортировано»
|
||
- [ ] «Импортировать» (нужен объект, иначе тост) и «Импорт с созданием объекта» (поиск/создание объекта и раздела по названиям из сметы)
|
||
- [ ] Подсказка «Объекты из сметы:» (3 строки + «ещё N»)
|
||
- [ ] Тосты «✓ Успешно импортировано: N» / «Импортировано: N, ошибок: M»
|
||
- [ ] Защита от дублей по `cree9_comment` = id работы из сметы
|
||
|
||
🐞 Пагинация в модалке объектов не выводится (видны только первые 100).
|
||
|
||
---
|
||
|
||
## 7. Ресурсы проекта (stroy-bot-project-assigner) — `?page=resources&projectId=`
|
||
|
||
- [ ] Нет projectId — «Проект не найден. Откройте страницу через список проектов.»
|
||
- [ ] Вкладки «Профессии (N)» и «Компании (N)»
|
||
- [ ] Слева «Доступные»: поиск, очистка ✕, «уже добавлено», «+», «Ничего не найдено» / «Нет элементов»
|
||
- [ ] Справа «Привязаны к проекту»: «−», «Ничего не добавлено»
|
||
- [ ] Оптимистичное добавление / удаление с откатом и ошибкой
|
||
- [ ] На узких экранах колонки друг под другом
|
||
|
||
---
|
||
|
||
## 8. Привязка к справочнику (stroy-bot-projects-binder) — `?page=binder&projectId=`
|
||
|
||
- [ ] Карточка проекта: название, Описание, Адрес, Статус (цвет), Начало, Окончание, Координаты
|
||
- [ ] Бейдж «Привязан» / «Не привязан», `UniqueName · UniqueId0`, «Отвязать»
|
||
- [ ] Поиск по справочнику (debounce 400 мс, пустой — все), пагинация ← / →, «{page} / {total} · всего: N»
|
||
- [ ] Карточки результатов: name, Код, Описание, Адрес, Координаты; выбор / снятие выбора; «Связать»
|
||
- [ ] Сообщения успеха и ошибок
|
||
- [ ] Запись `UniqueId0` и `UniqueName` в «Проекты»
|
||
|
||
---
|
||
|
||
## Открытые вопросы
|
||
|
||
- Схема списка **«Доступы»**: в репозиториях встречаются и поля `projectId`/`userId`, и lookup `user`/`project`. Проверить на сайте.
|
||
- Схема списка **«Объекты»**: родитель читается то как `parentId`, то как `parent/Id`. Проверить на сайте.
|