Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Esprit Monorepo

Монорепозиторий для продуктовой команды Esprit. Содержит:

  • apps/support-app — операционное приложение для саппорта (тикеты, авторизация)
  • apps/login-app — кастомный стор авхода (редирект на внешнее приложение авторизации)
  • packages/ui — UI-библиотека с Tailwind, Storybook и VitePress
  • packages/core — typed API client, AuthService, TokenManager, mock fetcher'ы

Требования

  • Node.js 20+
  • pnpm 9.12.0 (указан в packageManager, Corepack активирует автоматически)
  • Git — для клонирования и conventional commits

Структура проекта

esprit-mono/
├── apps/
│   ├── login-app/          # Приложение авторизации
│   ├── support-app/        # Приложение саппорта
│   ├── Dockerfile          # Универсальный Dockerfile (APP_NAME=login-app|support-app)
│   └── nginx.conf
├── packages/
│   ├── ui/                 # @esprit/ui — компоненты, Storybook, VitePress
│   └── core/               # @esprit/core — HttpClient, auth, mocks
├── deployment/             # Ansible деплой
│   ├── playbook.yml        # Основной playbook деплоя
│   ├── rollback.yml        # Откат к предыдущей версии
│   ├── monitoring.yml      # Мониторинг здоровья
│   ├── post-deploy-check.yml
│   ├── inventory/          # staging.yml, production.yml
│   ├── templates/          # docker-compose.yml.j2, env.j2, nginx.conf.j2
│   ├── Makefile            # make deploy-staging, make rollback-production, ...
│   └── env.template        # cp env.template .env — для ручного деплоя
├── .gitlab-ci.yml          # CI/CD pipeline (GitLab)
├── docker-compose.yml      # Запуск в Docker (локально)
├── docker-build.sh
└── turbo.json

Технологическая карта

  • Vue 3 + <script setup> + строгий TypeScript
  • Vite для dev/build, Vitest + Testing Library для unit-тестов
  • Pinia, Vue Router, Suspense, Teleport, Provide/Inject
  • Tailwind дизайн-система, Storybook 8, VitePress документация
  • pnpm workspaces + Turborepo pipeline
  • Husky, lint-staged, ESLint 9 (flat config), Prettier, Stylelint, Commitlint (conventional commits)
  • Docker — контейнеризация приложений и Storybook

Быстрый старт

Локальная разработка

pnpm install
pnpm dev             # support-app на http://localhost:8081
pnpm dev:login       # login-app на http://localhost:8080
pnpm dev:all         # Storybook + оба приложения (параллельно)

Vite proxy (support-app): В dev-режиме запросы /auth/* и /support/* проксируются на внешние API (см. apps/support-app/vite.config.ts). Это устраняет проблемы CORS при локальной разработке.

Запуск в Docker

docker-compose up -d --build
Сервис URL
Login App http://localhost:8080
Support App http://localhost:8081
Storybook http://localhost:6006

Health checks: http://localhost:8080/health, http://localhost:8081/health

Переменные Docker (опционально):

NODE_VERSION=20-alpine PNPM_VERSION=9.12.0 docker-compose up -d --build

Ручная сборка образов:

./docker-build.sh
# или
docker build -f apps/Dockerfile --build-arg APP_NAME=login-app -t esprit-login-app:latest .
docker build -f apps/Dockerfile --build-arg APP_NAME=support-app -t esprit-support-app:latest .
docker build -f packages/ui/Dockerfile -t esprit-storybook:latest .

Production деплой

# Staging (автоматически при push в develop)
git push origin develop

# Production (вручную в GitLab UI после push в main)
git push origin main
# → GitLab → CI/CD → Pipelines → deploy:production → Play ▶️

Процесс разработки

Workflow

  1. Task intake — заведите issue, определите acceptance criteria
  2. Branchingfeat/*, fix/*, chore/*; base branch main
  3. Commits — conventional commits (feat:, fix:, docs:, и т.д.), валидируются commitlint
  4. Testspnpm test --filter <package> перед PR
  5. Code review — создаём Merge Request, CI должен пройти, ревью минимум от 1 senior

Инструменты

Команда Описание
pnpm lint ESLint, Stylelint, Prettier по всем пакетам
pnpm lint:fix Автоисправление линтером
pnpm test Vitest во всех рабочих пространствах (UI/Core/Apps)
pnpm build Каскадная сборка (core → ui → apps) с Turborepo cache
pnpm storybook Storybook UI-библиотеки (порт 6006)
pnpm docs VitePress документация дизайн-системы
pnpm ci lint + test + build (используется в CI)

Husky + lint-staged следят за форматированием при коммите. Commitlint проверяет conventional commits.

API mocking

@esprit/core предоставляет createSupportMockFetcher и createAuthMockFetcher. Для production задайте VITE_*_API_URL и VITE_*_USE_MOCKS=false.


UI библиотека (@esprit/ui)

  • Философия: композиция через Composition API, единые дизайн-токены, Storybook + VitePress
  • Storybook: pnpm storybook (порт 6006)
  • Документация: pnpm docs — гайды по компонентам и токенам
  • Использование: import { Button, Modal, Alert, Input } from '@esprit/ui'

Переменные окружения

Общие (support-app, login-app)

Переменная Описание
VITE_SUPPORT_API_URL URL API саппорта
VITE_SUPPORT_USE_MOCKS Использовать mock fetcher для support API
VITE_AUTH_API_URL URL API авторизации
VITE_AUTH_USE_MOCKS Использовать mock fetcher для auth API
VITE_LOGIN_APP_URL URL login-app (для редиректов guard'ов)
VITE_SUPPORT_APP_URL URL support-app (для редиректов)
VITE_DEFAULT_LOCALE Базовая локаль (en), переопределяется доменом (.ruru)
VITE_PORTAL_URL URL портала (support-app config)
VITE_AUTH_BASE_URL Базовый URL внешнего приложения авторизации

Redirect-based авторизация (login-app)

Переменная По умолчанию Описание
VITE_AUTH_MODE redirect redirect или api (OAuth PKCE)
VITE_AUTH_URL /login Путь для авторизации
VITE_AUTH_CONSUMER freescout-auth Идентификатор потребителя
VITE_AUTH_THEME Тема интерфейса авторизации
VITE_AUTH_LOCALE ru_RU Локаль (ru)
VITE_AUTH_LOCALE_EN en_EN Локаль (en)
VITE_ONE_TIME_CODE_PARAM one_time_code GET-параметр с one-time кодом
VITE_MOBILE_CODE_PARAM mobile_code GET-параметр с mobile кодом

Refresh token (опционально)

Переменная Описание
VITE_USE_HTTPONLY_REFRESH_TOKEN Использовать httpOnly cookie вместо localStorage

Архитектура

Apps

App Port Роуты Описание
support-app 8081 /, /tickets, /ticket/:id, /new, /components-examples Мультиязычная панель саппорта, guard installAuthGuard, стор session. При отсутствии токена — редирект на login-app.
login-app 8080 / (AuthView) Авторизация через редирект на внешнее приложение. Точки входа: сайт (channel=site), мобильная игра (channel=game). Композиции useRedirectAuth, useOneTimeCode (legacy).

Структура src: src/modules/* — бизнес-фичи, src/app/* — провайдеры, guards, config. Алиасы @support/*, @login/*, @esprit/ui, @esprit/core.

Packages

  • @esprit/ui — Vite library mode, Tailwind дизайн-токены, Storybook 8, VitePress, Vitest
  • @esprit/coreHttpClient с интерсепторами, AuthService, TokenManager, mock fetcher'ы (createAuthMockFetcher, createSupportMockFetcher)

Инфраструктура

Turborepo, pnpm workspaces, глобальные алиасы (tsconfig.base.json), Husky + lint-staged, Commitlint. CI/CD: GitLab CI/CD (.gitlab-ci.yml) — install → lint → test → build → docker → security → deploy → verify.


CI/CD и деплой

Pipeline (GitLab CI/CD)

Этап Описание Время (с кешем)
Install pnpm с кешированием по pnpm-lock.yaml ~20s
Test Lint + Vitest (параллельно) ~1m
Build turbo run build (core → ui → apps) ~2m
Docker login-app + support-app (параллельно, BuildKit cache) ~1m
Security Trivy (HIGH/CRITICAL блокируют production) ~2m
Deploy Staging (авто) / Production (вручную) ~3m
Verify Health checks, логи, ресурсы ~1m

Общее время: ~6–8 минут с кешем, ~12–15 минут cold start.

Ветки: develop → Staging (автоматически), main → Production (ручной запуск job в GitLab UI).

Первоначальная настройка

1. GitLab Variables

Settings → CI/CD → Variables:

Переменная Тип Protected Описание
SSH_DEPLOY_KEY File Yes Приватный SSH ключ для deploy

GitLab автоматически предоставляет: CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD.

2. Генерация SSH ключа

ssh-keygen -t ed25519 -C "gitlab-ci-deploy" -f ~/.ssh/gitlab_deploy_key
cat ~/.ssh/gitlab_deploy_key.pub   # → в authorized_keys на сервере
# Содержимое ~/.ssh/gitlab_deploy_key → в GitLab Variables как SSH_DEPLOY_KEY

3. Настройка сервера

Требования: Ubuntu 20.04+ / Debian 11+, 2GB RAM, 20GB disk, порты 22, 80, 443.

# Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo systemctl enable docker && sudo systemctl start docker

# Пользователь deploy
sudo useradd -m -s /bin/bash deploy
sudo usermod -aG docker deploy
echo "deploy ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/deploy
sudo chmod 0440 /etc/sudoers.d/deploy

# SSH
sudo -u deploy mkdir -p /home/deploy/.ssh
sudo -u deploy nano /home/deploy/.ssh/authorized_keys  # вставить публичный ключ
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh

# Директории
sudo -u deploy mkdir -p /opt/esprit-apps/backups
sudo chown -R deploy:deploy /opt/esprit-apps

# Firewall
sudo ufw allow 22/tcp && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
sudo ufw enable

# SSL (production) — Certbot
sudo apt install certbot
sudo certbot certonly --standalone -d login.yourdomain.com -d support.yourdomain.com

4. Inventory

Обновите deployment/inventory/staging.yml и production.yml:

Переменная Описание Пример
ansible_host IP или домен сервера staging.example.com
ansible_user SSH пользователь deploy
domain_login Домен login-app login.esprit.example.com
domain_support Домен support-app support.esprit.example.com
login_app_port Порт (внутри Docker) 3001
support_app_port Порт (внутри Docker) 3002
ssl_enabled SSL для production true
ssl_cert_path Путь к сертификату /etc/letsencrypt/live/.../fullchain.pem
ssl_key_path Путь к приватному ключу /etc/letsencrypt/live/.../privkey.pem
vite_auth_api_url URL API auth https://api.../auth
vite_support_api_url URL API support https://api.../support
vite_login_app_url URL login-app https://login...
vite_support_app_url URL support-app https://support...
vite_default_locale Локаль ru

5. DNS

A-записи: login.yourdomain.com, support.yourdomain.com → IP сервера.

6. Проверка подключения

cd deployment
ansible -i inventory/staging.yml app_servers -m ping
ansible -i inventory/production.yml app_servers -m ping

Ручной деплой (через Makefile)

cd deployment
cp env.template .env
nano .env   # REGISTRY_USER, REGISTRY_PASSWORD, REGISTRY_URL, PROJECT_PATH, IMAGE_TAG

# Деплой
make deploy-staging         # Staging
make deploy-production      # Production (с подтверждением)

Команды управления (Makefile)

cd deployment

# Деплой
make deploy-staging
make deploy-production

# Откат
make rollback-staging
make rollback-production

# Мониторинг
make monitoring-staging
make monitoring-production

# Проверка
make check-staging
make check-production

# Логи
make logs-staging
make logs-production

# Тест подключения
make ping-staging
make ping-production

make help   # Все команды

Переменные Makefile: REGISTRY_URL, REGISTRY_USER, REGISTRY_PASSWORD, PROJECT_PATH, IMAGE_TAG (из .env или окружения).

Ручной деплой через Ansible

cd deployment
ansible-playbook -i inventory/production.yml \
  -e "registry_url=registry.gitlab.com" \
  -e "registry_user=your_user" \
  -e "registry_password=your_token" \
  -e "image_tag=latest" \
  -e "project_path=your-group/esprit-mono" \
  -e "environment=production" \
  playbook.yml

Мониторинг на сервере

# Статус
docker ps
docker stats esprit-login-app esprit-support-app

# Логи
docker logs -f esprit-support-app
docker logs --tail 100 esprit-login-app 2>&1 | grep -i error

# Health check
docker inspect esprit-login-app | jq '.[].State.Health'

# Ручная проверка (стейдж)
curl -f https://test-login.espritgames.ru/ && echo "✅ Login OK"
curl -f https://test-support.espritgames.ru/ && echo "✅ Support OK"

Откат

  • Makefile: make rollback-production
  • GitLab UI: Pipelines → предыдущий успешный pipeline → Run rollback:production или deploy:production
  • Ansible: ansible-playbook -i inventory/production.yml rollback.yml

Чеклист перед production

  • SSH_DEPLOY_KEY в GitLab Variables
  • Docker (>= 24.0), Docker Compose (>= 2.0) на сервере
  • Пользователь deploy, группа docker, /opt/esprit-apps
  • Firewall: 22, 80, 443
  • SSL сертификаты (production)
  • Inventory обновлён
  • DNS настроен
  • ansible ... -m ping успешен
  • Тестовый деплой на staging прошёл

Экстренные процедуры

Приложение не отвечает:

  1. ssh deploy@server "docker ps"
  2. ssh deploy@server "docker logs --tail 100 esprit-support-app"
  3. ssh deploy@server "docker restart esprit-support-app"
  4. При необходимости: make rollback-production

Высокая нагрузка: docker stats --no-stream, free -h на сервере.

Очистка места: docker image prune -af --filter "until=168h" или docker system prune -af.


API

Authentication

Endpoint Method Description
/.well-known/openid-configuration GET OpenID Connect конфигурация
/.well-known/jwks.json GET Публичные ключи для JWT
/auth/register POST Регистрация { email, password }
/auth/login POST Вход с OAuth 2.0 (client_id, redirect_uri, state, code_challenge)
/auth/token POST Обмен code на токены
/refresh POST Обновление access token
/auth/userinfo GET Информация о пользователе
/auth/logout POST Инвалидация сессии
/auth/external/{platform}/auth GET OAuth внешнего провайдера
/auth/external/{platform}/callback GET Callback от провайдера
/exchange/onetime_code POST Обмен one_time_code на токены (redirect flow)
/auth/code-exchange POST Legacy: обмен one_time_code + channel на accessToken

Redirect flow: login-app → редирект на внешнее приложение → callback с one_time_code → POST /exchange/onetime_code → токены → редирект на support-app с access_token, refresh_token, expires_in в URL.

OAuth 2.0 PKCE (режим api): state, code_verifier, code_challenge → POST /auth/login → редирект с code → POST /auth/token.

Tickets

Endpoint Method Description
/tickets GET Список тикетов
/tickets POST Создание { subject, priority, message }
/tickets/:id GET Детали тикета
/tickets/:id/conversation GET, POST Сообщения диалога (POST: { body, author })

HttpClient

import { HttpClient } from '@esprit/core'
import { createSupportMockFetcher } from '@esprit/core/mocks'

const client = new HttpClient({
  baseUrl: 'https://api.esprit.io',
  fetcher: createSupportMockFetcher({ tickets }),
  getAccessToken: () => tokenManager.getToken(),
  refreshToken: () => authService.refresh(),
})

При 401 клиент вызывает refreshToken; при провале — onUnauthorized (очистка токена, редирект).


Troubleshooting

Docker: "error getting credentials"

Не используйте sudo для docker. При необходимости:

sudo chown -R "$USER":staff ~/.docker

Перезапустите Docker Desktop.

Порт занят

Измените маппинг в docker-compose.yml:

ports:
  - '8082:80'

Pipeline: "repository not found" при клонировании

Ошибка fatal: repository 'https://gitlab.espritgames.ru/frontend/esprit-mono.git/' not found возникает до запуска джобов — Runner не может склонировать репозиторий. Исправляется в настройках GitLab и Runner, не в .gitlab-ci.yml.

Что проверить:

  1. Путь проекта
    GitLab → проект → Settings → General — убедитесь, что путь репозитория именно frontend/esprit-mono. Если проект переносили или переименовывали, URL мог измениться.

  2. Доступ Runner к проекту
    Runner deploy (t3_C9N1Nz) должен быть зарегистрирован в этом проекте или в группе frontend.

    • Settings → CI/CD → Runners: если используется shared runner — админу GitLab нужно выдать группе/проекту доступ к этому runner.
    • На сервере с runner: в config.toml проверьте url — должен быть https://gitlab.espritgames.ru/.
  3. CI_JOB_TOKEN (для приватных репо)
    GitLab 15.9+ может ограничивать доступ CI job token.

    • Settings → CI/CD → Token Access: для проекта или группы не должно быть запрета доступа к этому репо (или включите разрешение для этого проекта).
  4. Переменные CI/CD
    Settings → CI/CD → Variables: убедитесь, что нет переменных вроде GIT_REPOSITORY_URL или GIT_STRATEGY, которые подменяют URL или способ клонирования.

  5. Репозиторий не удалён
    В Settings → General → Advanced проверьте, что проект не в процессе удаления и репозиторий доступен по HTTPS в браузере (логин при необходимости).

После изменений перезапустите pipeline (Retry).

Pipeline: Install падает

Проверьте cache в GitLab UI, попробуйте очистить (CI/CD → Pipelines → Clear runner caches).

Деплой: SSH ошибка

  • Проверьте SSH_DEPLOY_KEY в GitLab Variables
  • Тест: ssh -i <path-to-key> deploy@your-server
  • Проверьте права: ~/.ssh 700, authorized_keys 600

Health checks timeout

  • Проверьте логи контейнеров: docker logs esprit-login-app
  • Увеличьте timeout в deployment/playbook.yml
  • Убедитесь, что приложения отвечают на / или /health

Нужно передеплоить ту же версию

GitLab → Pipelines → найдите нужный pipeline → Retry job deploy:production.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages