# Frontend: данные, state и интеграции

## HTTP (Axios)
Правила:
- Один `axios` instance на приложение (базовая конфигурация, таймауты, baseURL).
- Интерсепторы:
  - запрос: проставление auth (если есть), `Accept-Language` (из i18n), корреляционных id (если приняты заголовки);
  - ответ: нормализация ошибок в единый тип ошибки фронта (для UI), без утечки внутренних деталей.
- Компоненты/страницы не знают формат backend ошибок: они работают с нормализованным типом (например, `ApiError` + `kind`/`status`/`code`/`field`).
- Повторные запросы/ретраи — только осознанно (избегать “магических” глобальных ретраев, особенно для non-idempotent).

Рекомендуемое размещение:
- `src/shared/api/http.ts` — создание axios instance.
- `src/shared/api/errors.ts` — нормализация ошибок (`AxiosError` -> `ApiError`).
- `src/shared/api/client.ts` — thin client функции, вызываемые из фич.

## State (Pinia)
Правила:
- Store создаётся “по фиче” (не один глобальный store на всё приложение).
- Store хранит состояние UI/экрана и кэш данных на уровне UI, но не заменяет backend source-of-truth.
- Побочные эффекты (HTTP) живут в actions (или в отдельном service слое фичи), не в компонентах.
- Store не должен зависеть от Vue компонентов; компоненты потребляют store, а не наоборот.

Рекомендуемое размещение:
- `src/features/<feature>/store.ts`
- `src/features/<feature>/api.ts` (вызовы backend через `shared/api`)
- `src/features/<feature>/types.ts` (типы фичи, если нужны)

## Router (vue-router)
Правила:
- Использовать named routes и `route meta` для auth/ролей/заголовков/хлебных крошек.
- Guards не должны делать тяжёлые запросы без необходимости; “проверки доступа” должны опираться на уже известное состояние, либо иметь явную стратегию загрузки.

## i18n (vue-i18n)
Правила:
- UI-тексты только через i18n ключи (не “захардкоженные строки” в компонентах, кроме редких технических случаев).
- Ошибки показывать пользователю через стабильные i18n ключи (не прокидывать `err.message` от backend).
- Форматирование дат/чисел — централизованно (helpers), а не “в каждом компоненте по-своему”.

## Cookies (vue3-cookies)
Правила:
- Доступ к cookies через один адаптер/обёртку (например, `src/shared/lib/cookies.ts`), чтобы:
  - централизовать имена ключей,
  - избежать разрастания “магических строк”,
  - упростить тестирование/замену механизма хранения при необходимости.
- Не хранить в cookies чувствительные данные без необходимости; соблюдать политики безопасности (SameSite, secure) на стороне сервера.

## WebSocket (если используется)
Контракт:
- Формат сообщений и каналы описываются в AsyncAPI YAML: `specs/asyncapi/<service-name>.v<major>.yaml`.

Правила клиента:
- Один WS client на приложение (в `src/shared/ws/*`), а не “подключение в каждом компоненте”.
- Для браузерных клиентов используем только `wss://` (клиенты работают по https); `ws://` запрещён.
- Авто-reconnect только осознанно: backoff + jitter; должен быть способ выключить/сбросить соединение при logout.
- Heartbeat обязателен (ping/pong или app-level), чтобы не держать “мертвые” соединения.
- Обработка входящих сообщений:
  - безопасный парсинг (не падать на неожиданных payload),
  - нормализация в типы UI и диспатч в Pinia store/handlers,
  - отсутствие утечки PII в логи/аналитику.
- Cleanup обязателен (unmount/route change/logout).

## PWA (vite-plugin-pwa)
Правила:
- PWA включается осознанно: кеширование не должно ломать авторизацию и отдавать устаревшие данные как актуальные.
- Не кешировать API-ответы “навсегда” через service worker без явной стратегии.
- Предусмотреть UX обновления (например, “доступна новая версия” и перезагрузка).
