From 3ede7f2af429ed7664b349d83b02209258c101dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=93=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D1=86=D0=BA=D0=B8=D0=B9?= Date: Tue, 27 Oct 2026 10:44:09 +0500 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81?= =?UTF-8?q?=D1=81=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B,=20=D0=B6=D1=83?= =?UTF-8?q?=D1=80=D0=BD=D0=B0=D0=BB=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=B8=20CHANGELOG=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Требования приходят из чата и меняются — фиксируем, что просили, что решили и что выехало: регламент в docs/PROCESS.md, ADR 0001 по исключению поставщиков вместо удаления, шаблон задачи для Gitea, пустой CHANGELOG. Co-Authored-By: Claude Opus 5.5 (1M context) --- .gitea/ISSUE_TEMPLATE/zapros.md | 20 +++++ CHANGELOG.md | 8 ++ docs/PROCESS.md | 33 ++++++++ docs/adr/0001-isklyuchenie-postavshchikov.md | 87 ++++++++++++++++++++ docs/adr/README.md | 37 +++++++++ 5 files changed, 185 insertions(+) create mode 100644 .gitea/ISSUE_TEMPLATE/zapros.md create mode 100644 CHANGELOG.md create mode 100644 docs/PROCESS.md create mode 100644 docs/adr/0001-isklyuchenie-postavshchikov.md create mode 100644 docs/adr/README.md diff --git a/.gitea/ISSUE_TEMPLATE/zapros.md b/.gitea/ISSUE_TEMPLATE/zapros.md new file mode 100644 index 0000000..cc75f80 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/zapros.md @@ -0,0 +1,20 @@ +--- +name: Запрос +about: Пункт из чата, устная просьба или найденная проблема +--- + +## Источник + +- Кто: +- Когда: +- Где: Teams / устно / сам нашёл + +> Цитата как есть + +## Суть + +Что не так или что нужно, своими словами. + +## Как проверить + +Что сделать руками, чтобы убедиться, что готово. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5f1df2e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Журнал изменений + +Формат — [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/). Версия = версия решения +в `config/package-solution.json`, на каждый деплой — тег `vX.Y.Z`. + +Разделы: **Добавлено**, **Изменено**, **Исправлено**, **Удалено**. + +## [Не выпущено] diff --git a/docs/PROCESS.md b/docs/PROCESS.md new file mode 100644 index 0000000..2354957 --- /dev/null +++ b/docs/PROCESS.md @@ -0,0 +1,33 @@ +# Как ведётся работа над порталом + +Проект ведёт один разработчик. Требования приходят из Teams-чата и устно, поэтому вся +история — что просили, что решили, что выехало — хранится здесь и в Gitea, а не в памяти. + +## Где что лежит + +| Что | Где | Отвечает на вопрос | +| --- | --- | --- | +| Задачи | Gitea Issues `ct-forms-portal` | Что надо сделать, кто и когда попросил | +| Решения | `docs/adr/` | Почему сделано именно так, какие были варианты | +| Изменения | `CHANGELOG.md` | Что и в какой версии выехало на прод | +| Код | коммиты с `(#номер)` | Каким кодом закрыта задача | + +## Путь запроса + +1. **Пришло сообщение** (чат, устно) — каждый пункт становится issue. В issue — цитата или + скрин как есть, дата, кто попросил. +2. **Разбор.** Метка по типу: `bug`, `ux`, `feature`, `perf`, `справочники`, + `вопрос-бизнесу`, `смена-модели`. + - Если пункт меняет устройство данных (`смена-модели`) — сначала ADR, потом код. + - Если нужен ответ бизнеса (`вопрос-бизнесу`) — вопрос в чат, issue ждёт ответа. +3. **Работа.** Ветка `fix/<номер>-кратко` или `feat/<номер>-кратко`. Баг — сначала падающий + Jest-тест, потом фикс. Коммиты — `тип: описание (#номер)`. +4. **Деплой.** Запись в `CHANGELOG.md`, тег версии `vX.Y.Z` (= версия в + `config/package-solution.json`), issue закрывается, в чат — короткий список изменений. + +## Вопрос, который задаём каждому новому пункту + +> Это меняет то, как устроены данные, или только как они показываются? + +Только показ или поведение — делаем. Меняет данные — сначала проходим весь путь: +где создаётся, кто видит, что уходит в отчёт, INCORE и согласование. Потом ADR. diff --git a/docs/adr/0001-isklyuchenie-postavshchikov.md b/docs/adr/0001-isklyuchenie-postavshchikov.md new file mode 100644 index 0000000..5e38aa8 --- /dev/null +++ b/docs/adr/0001-isklyuchenie-postavshchikov.md @@ -0,0 +1,87 @@ +# 0001. Исключение поставщика из сравнения вместо удаления + +- Статус: Принято +- Дата: 2026-10-27 +- Задача: #1 +- Источник: Асиля Сарниязова, Teams, 2026-10-23, п.4: «Я случайно удалила из таблицы + поставщика — и не смогла вернуть его назад, хоть и есть КП» + +## Контекст + +На Шаге 3 (таблица сравнения) крестик на колонке поставщика удаляет его безвозвратно во всех +трёх формах — СТ, ОИД, КПС: + +- колонка убирается из состояния формы, введённые цены стираются; +- при сохранении все офферы по позициям СТ уходят в корзину и заново пишутся только + оставшиеся поставщики (обычная правка записи на списках офферов заблокирована ресивером); +- вернуть поставщика можно только повторной загрузкой КП на Шаге 2, цены, введённые руками, + теряются. + +Офферы читает не только портал: + +- СТ — бэкенд `api.tnsu.kz/Report/CT` (PDF/Excel-отчёт, уходит в пакет INCORE); +- ОИД — поток ИИ-комментария читает «Оценку поставщиков ОИД» сам; +- потоки уведомлений — внешние, читают ли они офферы, по коду не определить. + +В закупочных системах (SAP Ariba, Coupa, Procore и др.) участника не удаляют, а отклоняют +с причиной, и это остаётся в истории. + +## Варианты + +**А. Флаг `isExcluded` на каждом оффере** в списках «Оценка поставщиков», «… ОИД», «… КПС». + +- Плюс: одна колонка, исключённые лежат рядом с обычными. +- Минус: все сторонние читатели начнут видеть исключённых, пока каждый не добавит фильтр — + бэкенд отчёта СТ (иначе исключённый попадёт в PDF и INCORE), поток ИИ ОИД, возможно потоки + уведомлений. Выкатка строго по порядку: колонка → бэкенд и потоки → портал. + +**Б. JSON-снимок в шапке СТ** — колонка `excludedSuppliers` (Note) в «Сравнительной таблице» +каждой формы. + +- Плюс: «Оценка поставщиков» не меняется, сторонние читатели ничего не замечают. +- Минус: размер. Строка оффера — 200–300 символов; 3 поставщика × 100 позиций = 60–90 тыс. + символов, с комплектами — вдвое больше. Предел многострочной колонки SP — около 64 тыс. + Сохранение упадёт на обычных объёмах. + +**В. Отдельный список «Исключённые предложения»** под каждую форму («…», «… ОИД», «… КПС»): +те же колонки, что в «Оценке поставщиков», плюс лукап на СТ. + +- Плюс: в «Оценке поставщиков» только активные поставщики — бэкенд, отчёт, INCORE и потоки + не дорабатываются, порядок выкатки не важен. +- Плюс: одна строка на оффер, объём не ограничен. +- Минус: три новых списка, перенос строк между списками при исключении и возврате. + +## Решение + +Вариант **В**. + +- Крестик исключает поставщика: колонка скрывается, итоги, минимумы, рекомендация и ИИ его + не учитывают. Если исключили выбранного — выбор сбрасывается. +- При исключении **причина обязательна**. Она хранится вместе с исключёнными строками. +- Под таблицей у автора — плашка «Исключены из сравнения: поставщик — причина [Вернуть]». +- **Согласующий исключённых пока не видит.** Данные для него грузятся так же, но показ + выключен константой — включить можно без доработки хранения. +- **Повторная загрузка КП** исключённого поставщика на Шаге 2 его не возвращает: он остаётся + исключённым до «Вернуть». +- При сохранении цены исключённых пишутся в «Исключённые предложения», в «Оценку + поставщиков» не попадают. При открытии СТ исключённые читаются по id СТ. +- «Вернуть» → при сохранении строки переезжают обратно в «Оценку поставщиков». +- Поставщик без цен — одна строка-маркер без позиции, чтобы колонка не терялась. +- Позицию сняли на Шаге 1 — её строки в «Исключённых» тоже уходят в корзину. +- Запись офферов и исключённых — в общем модуле для трёх форм, чтобы позже перенести + сохранение на бэкенд без переделки компонентов. + +## Последствия + +- Три новых списка на `/sites/sed` — описать в `provisioning/manifests/{ct,oid,kps}`, + создать через `Provision-Lists.ps1` (сначала тест, потом бой). +- Доработка Шага 3 и загрузки СТ во всех трёх формах, Jest-тесты на исключение и возврат. +- Попутно закрываются баги удаления: в ОИД выбор остаётся на удалённом поставщике, в КПС + удалённый поставщик без КП возвращается после перезагрузки. + +## Ответы на открытые вопросы (2026-10-27, Тимур) + +1. Согласующий исключённых — заложить, но пока не показывать. +2. Повторная загрузка КП не возвращает исключённого поставщика. +3. Причина исключения — обязательная. +4. Списки создаются через `Provision-Lists.ps1` по манифестам (сначала тест, потом бой). diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..4db82de --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,37 @@ +# Журнал архитектурных решений (ADR) + +Одно решение — один файл `NNNN-kratkoe-nazvanie.md`. Файлы не переписываются задним числом: +если решение пересмотрели, пишется новый ADR со ссылкой «Заменяет NNNN», а у старого статус +меняется на «Заменено NNNN». + +Статусы: **Предложено** → **Принято** → (**Заменено** / **Отменено**). + +| № | Решение | Статус | Дата | +| --- | --- | --- | --- | +| [0001](0001-isklyuchenie-postavshchikov.md) | Исключение поставщика из сравнения вместо удаления | Принято | 2026-10-27 | + +## Шаблон + +```markdown +# NNNN. Название + +- Статус: Предложено +- Дата: ГГГГ-ММ-ДД +- Задача: #номер +- Источник: кто и где попросил + +## Контекст +Что происходит сейчас и почему это проблема. + +## Варианты +Что рассматривали, плюсы и минусы каждого. + +## Решение +Что выбрали. + +## Последствия +Что меняется, что придётся сделать, какие риски. + +## Открытые вопросы +Что ещё не решено. +```