Files
stroy-bot-monorepo/docs/PORTING-GUIDE.md
T
Тимур Городецкий 11bf491095 docs: add porting guide and shared Dataverse helpers
Common rules for moving the remaining stroy-bot-* sections into the
monorepo, so every section follows the same structure and keeps 1:1
behaviour with its old web part.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:50:54 +05:00

55 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Как переносится раздел из stroy-bot-* в монорепо
Образец — главная страница: `src/webparts/stroyBot/pages/hub/` + `app/project/`.
## Главное правило
**Поведение 1:1 со старым web part.** Те же запросы (URL, `$select`, `$filter`, `$expand`, `$top`, `$orderby`), те же поля, те же правила доступа, **те же тексты** (дословно), те же валидации. Известные баги переносятся как есть. Любое сознательное отличие записывается в `docs/MIGRATION-CHECKLIST.md` в блок «Сознательные отличия».
Меняется только слой интерфейса: HTML-строки и `innerHTML` → React-компоненты на `@tnsu/ui-kit`.
## Структура раздела
```
pages/<раздел>/
<Раздел>Page.tsx — страница: собирает компоненты, обрабатывает loading / error / empty
<Раздел>Page.module.scss
texts.ts — ВСЕ пользовательские тексты раздела (дословно из старого кода)
<раздел>Types.ts — типы данных
<раздел>Repository.ts — запросы: функции-конструкторы URL + функции загрузки/записи
<раздел>Repository.test.ts — тесты URL и сценариев на fakeHttpClient
<раздел>Rules.ts — чистые функции (права, валидация, дерево, форматирование)
<раздел>Rules.test.ts
use<Что-то>.ts — хуки состояния (загрузка, сохранение)
<Компонент>.tsx — под-компоненты, один компонент — один файл
```
## Правила кода (стайл-гайд проекта)
- TypeScript строго, **без `any`**. Ответы сервера описываются интерфейсами.
- Компонент ≤ ~300 строк, функция ≤ ~50 строк. Больше — разбивать.
- Логика — в `*Rules.ts` / `*Repository.ts` / хуках, не в JSX.
- Имена списков — `LISTS` из `config/lists.ts`; таблицы Dataverse — `DV_TABLES` из `config/dataverse.ts`; адреса — из `useAppServices().settings`.
- Внутренние имена полей SharePoint / колонок Dataverse — константами в `*Repository.ts` раздела (схемы в разных старых репо отличаются — не унифицировать без проверки).
- Комментарии — «почему», а не «что». Без мёртвого кода.
- `null` в своих типах не использовать (линтер) — `undefined`. Внешние ответы с `null` приводить через `?? undefined`.
- Стили: SCSS-модули, `@import '../../../../styles/design-tokens';`, токены вместо цветов. Без magic numbers без комментария.
- Форматирование — `.prettierrc` (одинарные кавычки, 120 символов, без висячих запятых).
## Данные
- Клиенты: `const { sharePoint, dataverse, tnsuApi, settings, page } = useAppServices();`
- SharePoint: `shared/sharepoint/spRest.ts` (`listItemsUrl`, `getJson`, `fetchCurrentUserId`). Запись — `sharePoint.fetch(url, { method: 'POST', headers, body })` с **теми же заголовками**, что в старом коде (verbose `__metadata` / `X-HTTP-Method: MERGE` / `IF-MATCH` — как было).
- Dataverse: `shared/dataverse/dataverseRest.ts` (`dataverseUrl`, `dataverseGet/Post/Patch/Delete`).
- Корпоративный API: `tnsuApi.fetch(`${settings.apiBaseUrl}/...`)`.
- Текущий пользователь: `page.userId` (legacyPageContext.userId) или `fetchCurrentUserId` — как в старом коде раздела.
- Маршрут: `useRouter()` → `route.projectId`, `route.objectId`, `route.reportId`, `route.copyFromId`; переход — `navigate({ page, projectId, ... })`; ссылка — `<RouteLink to={...}>`.
- Ссылки старых web parts на другие страницы (`SendReport.aspx?...`, `worksPageUrl`) → `navigate` / `RouteLink` на раздел приложения.
## UI
- ui-kit: `Button`, `IconButton`, `Dialog`, `confirmModal`, `Alert`, `Badge`, `Spinner`, `TextInput`, `TextArea`, `Select`, `Checkbox`, `Tabs`, `DataTable`, `FormCard`, `FormField`, `FormGrid`, `FormActions`, `FormHeader`, `Icon` (имена — `ICON_NAMES` в ките).
- `alert()` / `confirm()` → `Alert` / `confirmModal` (тексты те же).
- Чего нет в ките (дерево, тосты, контекстное меню, хлебные крошки) — делать в `pages/<раздел>/` своего раздела. Существующие файлы в `shared/` не менять; `EmptyState` и `useOutsideClose` — переиспользовать.
- Всегда явные состояния: загрузка (`Spinner`), ошибка (`Alert variant="err"`), пусто (`EmptyState`).
## Тесты
- `shared/testing/fakeHttpClient.ts` — заглушка: проверяем точные URL и тела запросов против старого кода, сценарии успеха и ошибок.
- Чистые функции правил — отдельными тестами.
- Запуск: `npx heft test --clean`. Должно быть 0 ошибок линтера и все тесты зелёные.