11bf491095
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>
55 lines
5.7 KiB
Markdown
55 lines
5.7 KiB
Markdown
# Как переносится раздел из 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 ошибок линтера и все тесты зелёные.
|