mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 01:14:58 +03:00
73 lines
14 KiB
Markdown
73 lines
14 KiB
Markdown
Если в окружении не доступен инструмент, например - Python, PHP, попробуй docker, если в проекте есть его файлы.
|
||
|
||
Тесты: гонять только те, что относятся к изменённому в текущем шаге. Полный
|
||
прогон — только по моему явному указанию, никогда по своей инициативе. Полный
|
||
набор идёт ~20 минут, и гонять его после каждой правки запрещено.
|
||
|
||
Без моего явного указания не меняй ничего!
|
||
Если я задал вопросы, это не значит что ты можешь менять файлы!
|
||
Любые правки только после моего явного указания, например - "делай".
|
||
Соблюдай инструкцию по коммитам.
|
||
Используй glab, gh если доступны.
|
||
|
||
Учетные данные / доступы:
|
||
- Для штатной локальной браузерной проверки тестовые учётные записи демо-сотрудников перечислены в `apps/backend/chatballs/identity/demo_seed/data/ru/organization.json` (`accounts`, включая роль `ADMIN`); общий пароль — поле `demoPassword` того же файла. Это также описано в `.skaro/specs/0006-demonstratsionnye-dannye.md` основной копии проекта (R-5). Проверить, что демо-набор уже установлен в используемой базе; не запускать seed ради проверки.
|
||
- Без явного указания владельца не менять, не сбрасывать, не bootstrap-ить и не пересоздавать никакие учетные данные, пароли, TOTP, recovery-коды, сессии и права доступа.
|
||
- Если для проверки нужен вход в приложение, использовать только уже существующие учетные данные, предоставленные владельцем, и не выполнять команды, которые могут изменить пароль или состояние аккаунта.
|
||
- Любые команды управления аккаунтами, включая `bootstrap_owner`, password reset/change, seed пользователей и изменение ролей, требуют отдельного явного подтверждения владельца перед запуском.
|
||
|
||
Production deployment / миграция:
|
||
- Не принимать самостоятельно решения о способе переноса production-данных, bind mounts, путях хранения, переключении каталогов или удалении старого deployment.
|
||
- Перед любым изменяющим действием в production сначала представить владельцу точный план миграции и получить его явное согласование. Разрешение на диагностику или общая просьба «исправить» не являются разрешением самостоятельно выбирать архитектуру миграции.
|
||
|
||
UI / дизайн:
|
||
- Никакой отсебятины в UI: не добавлять экраны, блоки, карточки, иконки, тексты, анимации, цвета, layout-решения и состояния, которых нет в утверждённом дизайн-макете (`design/baseline/<фича>/*.dc.html`). Макет — источник истины, README рядом с ним лишь пересказ.
|
||
- Если UI-этап еще не наступил, UI не считается реализованным и не должен маскироваться под готовый продуктовый интерфейс.
|
||
- Для построения UI использовать существующие компоненты и их стили, если они уже реализованы; если подходящего компонента нет, создавать переиспользуемый компонент в рамках существующей системы.
|
||
- Не упрощать UI, анимации, иконки, состояния или поведение по своему усмотрению. Любое отклонение от baseline требует явного согласования до правок.
|
||
- Технические временные заглушки UI не считать готовой реализацией и не использовать как основу продуктового UI без отдельного явного разрешения.
|
||
|
||
Один стандарт на один элемент:
|
||
- Ссылки во всём приложении выглядят одинаково. Единая база — класс `.link` из `shared/links.css`, одинаковый и для `<a>`, и для `<button>`. Роль задаётся модификатором: `.is-strong` (имя сущности), `.is-neutral` (тёмное имя, синее при наведении), `.is-muted` (второстепенная, «Назад», «Отмена»), `.is-mono` (идентификаторы), `.has-icon` (с иконкой). Заводить в фиче свой `*-name-link`, `*-meta-link`, `*-link-button` запрещено.
|
||
- Действие, а не переход, оформляется `<button className="link">`, а не `<a href="#">` с `preventDefault`.
|
||
- Выпадающие меню — только antd `Dropdown` с `overlayClassName="app-dropdown"` и триггером `.row-menu-button`. Своих меню на `position: absolute/fixed`, ручном расчёте координат и подложек-скримов не делать: портал закрывается по клику вне и по Esc сам и не обрезается `overflow`.
|
||
- Перед тем как написать свой элемент, искать существующий в `shared/` и в соседних фичах. Второй стандарт того же элемента — это дефект, а не свобода реализации.
|
||
|
||
Никаких служебных записок в продукте:
|
||
- В продуктовом UI не должно быть служебной лексики. Запрещены на экране: коды спек и решений (SPEC-*, ADR-*, DG-*), номера правил (P1-P5 и любые другие), слова «инвариант», «констрейнт», «миграция», «scope» в техническом смысле, имена таблиц, полей и enum-значений БД и API (`allowCheckoutActions`, `Conversation.channel`, `PROTECT`, `OK`/`ERROR` как есть), ссылки на внутренние документы и любые пометки для разработчика.
|
||
- Пользователю показывается следствие и способ исправить, а не внутреннее правило. «Коммерческие действия недоступны непродуктовому каналу. Назначьте продукт» — да. «Запрещено инвариантом P1» — нет.
|
||
- Технические коды остаются в коде, комментариях, логах и API-ответах, но не в текстах интерфейса.
|
||
- Это относится и к baseline-макетам: служебный текст, попавший в макет, не является основанием выводить его на экран. Макет реализуется, дополняется по указанию владельца, служебная лексика в реализацию не переносится.
|
||
- Правило действует на прод в первую очередь: ни одна служебная пометка не должна доезжать до пользователя.
|
||
|
||
Engineering rules / обязательные практики:
|
||
- Соблюдать DRY, KISS, SRP, separation of concerns и NO GOD FILES.
|
||
- Не реализовывать полноценную страницу, feature или крупный workflow одним большим компонентом/файлом.
|
||
- Если компонент превышает примерно 200 строк или смешивает layout, state, data/model и subviews, разделить его до завершения задачи.
|
||
- Если новый или измененный файл превышает примерно 300 строк из-за текущей работы, остановиться и вынести части в меньшие модули до финального ответа или коммита.
|
||
- Page-компоненты должны быть преимущественно composition-only: subviews выносить в соседние компоненты, демо/static data в model/data файл, повторяемый UI в shared/local reusable components.
|
||
- Не инлайнить сложный UI повторно. Выносить компонент, если структура повторяется или секция имеет отдельную ответственность.
|
||
- Если реализация по задаче конфликтует с этими правилами, остановиться и явно сообщить blocker вместо поставки плохой структуры.
|
||
|
||
Язык интерфейса:
|
||
- Текста, который видит человек, в коде не бывает. Строка живёт в словаре и подставляется через `t(...)`: во фронтенде это `src/i18n` приложения (`packages/ui` — свой словарь), на бэкенде `chatballs/i18n`. Русский каталог — источник ключей, английский обязан его повторить: пропущенный перевод во фронтенде ловит `tsc`, на бэкенде — тест каталога.
|
||
- Ключ пишется от смысла, а не от фразы: `settings.storage_bucket_name`, а не пересказ текста. Строку переформулируют чаще, чем переименовывают.
|
||
- Число не склоняют вручную: формы задаёт словарь, форму выбирает `tn(...)`. Дату, размер файла и разряды числа форматирует `fmt` — прибитые `"ru-RU"` и свои списки месяцев запрещены.
|
||
- Что записано в базу, переводится по коду, а не текстом: системные события диалога, уведомления и подписи журнала аудита хранят код, а фразу собирает бэкенд на языке читателя. Писать в историю готовую русскую фразу нельзя — её потом не перевести.
|
||
- Язык запроса выбирается цепочкой: профиль сотрудника → организация → установка → браузер. Письмо получает язык адресата, а не отправителя.
|
||
- На бэкенде `t(...)` не вызывается на уровне модуля: язык там свой на каждый запрос, а константа посчиталась бы один раз при импорте.
|
||
- Текст, уходящий наружу — клиенту в мессенджер, письмо, кнопку виджета, — берёт язык не запроса, а организации: `t(..., language=customer_language(organization))`. Язык оператора, нажавшего кнопку, к речи компании с её клиентом отношения не имеет, и половина такого текста вообще рождается в воркере, где запроса нет.
|
||
- Системный промпт агента не переводится: его читает модель. Язык ответа задаёт отдельная директива по полю `AIAgent.answer_language` — по умолчанию «как у клиента».
|
||
- Демо-набор ставится на языке организации: манифесты лежат в `demo_seed/data/<язык>/`, наборы ключей в них совпадают. Бинарные вложения (аватары, голосовые) общие, текстовые документы — свои на каждый язык.
|
||
|
||
Definition of Done:
|
||
- Запускать только тесты, относящиеся к изменениям текущей итерации: изменил
|
||
presence — гоняешь тесты присутствия, изменил тексты — гоняешь каталог i18n.
|
||
Полный прогон всех тестов выполнять ТОЛЬКО по явному указанию владельца.
|
||
Использовать `--reuse-db`; `--create-db` — лишняя минута на переигрывание
|
||
миграций, она нужна только когда схема действительно поменялась.
|
||
- Измененные файлы должны быть проверены на NO GOD violations.
|
||
- Новый компонент не должен владеть несвязанными ответственностями.
|
||
- Не должно быть придуманных текстов, иконок, layout-решений или состояний вне design/docs.
|
||
- Любое отклонение от design/docs должно быть явно указано.
|