# Правила работы с KILN website

Этот файл обязателен к прочтению в начале каждой сессии. Затем прочитайте
`TECHNICAL_CONTEXT.md` и документы, относящиеся к задаче. Для изменений на
границе с ботом дополнительно прочитайте `/srv/kiln-bot/AGENTS.md` и
`/srv/kiln-bot/api_site_contract.md`.

## Перед началом работы

1. Выполните `git status --short`, `git branch --show-current`,
   `git log -5 --oneline` и сравните текущий HEAD с upstream через
   `git ls-remote`. Не делайте `pull`, `rebase`, checkout другой ветки или
   очистку рабочей копии автоматически.
2. Считайте существующие незакоммиченные изменения пользовательскими. Не
   перезаписывайте и не форматируйте несвязанные файлы.
3. На production-сервере рабочая ветка сайта —
   `feat/menu-postgres-yandex-feed`. Не переносите её на `main` без отдельного
   решения владельца.
4. Не читайте и не выводите содержимое `.env*`, дампов БД, cookie, токенов,
   приватных ключей и персональных данных. Допустимо проверять только наличие
   переменных без вывода значений.

## Инварианты

- Браузер обращается к публичным API сайта. `BOT_API_KEY`, СБИС, SMTP, SMS,
  Telegram и MAX доступны только серверной стороне.
- СБИС через бот является источником цены, доступности, остатков, графика,
  зон, тарифов и платёжных ссылок. Сайт не вычисляет эти значения независимо.
- Создание заказа идемпотентно по `client_ref`. После timeout сначала
  проверяйте прежний запрос; не создавайте новый заказ с другим идентификатором.
- Не показывайте оплату до состояния, разрешающего оплату, и наличия ссылки от
  бота. Не меняйте оркестрацию СБИС, доставки и подтверждения рестораном на
  стороне сайта.
- Старые `/o/*` и `/z/*`, публичные ссылки из писем/SMS, завершённые заказы,
  брони и переписка должны оставаться доступными согласно контракту.
- `/ma` и UI Mini App принадлежат сайту; подпись Telegram, сессия Mini App и
  связка с ресторанным чатом принадлежат боту. MAX остаётся чатовым каналом.
- Администратор сайта не создаёт и не удаляет номенклатуру СБИС. Редакционные
  данные сайта не должны затираться автоматической синхронизацией.
- Не удаляйте историю, аудит и ПДн-записи прямыми запросами. Используйте
  предусмотренные состояния, архивирование и retention-процедуры.

## Изменения базы и контрактов

- Не меняйте уже применённые SQL-файлы в `drizzle/`. Добавляйте новую
  идемпотентную миграцию с уникальным следующим номером и обновляйте
  `src/db/schema.ts` в том же коммите.
- Перед production-миграцией обязательны дамп PostgreSQL, проверка миграции на
  копии и описанный rollback. Миграции production выполняются только по явно
  поставленной задаче.
- Контракт сайта с ботом находится только в
  `/srv/kiln-bot/api_site_contract.md`. Изменяйте его аддитивно: сначала бот и
  контракт, затем типы/адаптер сайта. Не копируйте контракт в этот репозиторий.
- При изменении поведения обновляйте `README.md`, `TECHNICAL_CONTEXT.md`,
  `DEPLOY.md` и специализированную документацию, которую затрагивает задача.

## Безопасные проверки

- Без БД: `npm run typecheck`, `npm run lint`.
- `npm test` записывает данные в PostgreSQL и требует generated-файлы из
  `data/import/`, а часть тестов требует отдельный HTTP-сервер. Запускайте его
  только с явным `DATABASE_URL` изолированной тестовой БД.
- Не запускайте обычный `docker compose up` из production checkout: локальный
  и production Compose используют один каталог и по умолчанию одно имя
  проекта. Для тестов используйте отдельный checkout/Compose project и volume.
- `npm run build` запускает синхронизацию данных Яндекса и пишет в ignored
  cache. Учитывайте сеть и проверяйте diff после сборки.
- Visual-тест требует уже запущенный тестовый сайт и Chromium/Playwright.

## Выпуск

- Не коммитьте, не отправляйте изменения и не деплойте без разрешения в
  текущей задаче. Никогда не используйте force-push.
- Перед выпуском проверьте diff, тесты по зоне риска, отсутствие секретов и
  состояние обоих контрактных проектов.
- Для межпроектного изменения выпускайте совместимый бот первым, сайт вторым.
- После разрешённого deployment проверьте `/health`, `/api/info`, основные
  клиентские сценарии и логи; при ошибке используйте заранее подготовленный
  rollback, а не ручное исправление production-данных.
