moex-vibe/README.md

168 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MoexVibe
Веб-приложение для анализа ценных бумаг Московской биржи (MOEX).
## Содержание
- [О проекте](#о-проекте)
- [Стек технологий](#стек-технологий)
- [Быстрый старт](#быстрый-старт)
- [Docker](#docker)
- [Тестирование](#тестирование)
- [Структура проекта](#структура-проекта)
- [Команды](#команды)
- [Переменные окружения](#переменные-окружения)
---
## О проекте
npm workspaces монорепозиторий:
| Пакет | Назначение |
| --------------- | -------------------------------------------------- |
| `apps/backend` | NestJS API (единственная точка доступа к MOEX ISS) |
| `apps/frontend` | React SPA на Vite |
| `apps/docs` | Сайт документации Docusaurus |
| `packages/design-system` | Дизайн-система (Storybook, MUI-адаптер, UI-компоненты) |
---
## Стек технологий
- **Бэкенд:** NestJS, TypeScript, OpenAPI (Swagger)
- **Фронтенд:** React, TypeScript, Vite, TanStack Query, lightweight-charts
- **Дизайн-система:** MUI v7, Storybook 10, lightweight-charts
- **Документация:** Docusaurus
- **Инфраструктура:** Docker, docker-compose
---
## Быстрый старт
```bash
# Настройка локального окружения
cp apps/backend/.env.example apps/backend/.env
# Установка зависимостей и подготовка базы данных
npm install
npm exec -w apps/backend -- prisma migrate dev
# Запуск бэкенда (http://localhost:3000)
npm run dev:backend
# Запуск фронтенда (http://localhost:5173)
npm run dev:frontend
```
Swagger UI: http://localhost:3000/api/docs
---
## Docker
```bash
docker compose up --build
```
- Фронтенд: http://localhost:80
- Бэкенд: http://localhost:3000
---
## Тестирование
```bash
npm run test:backend
npm run test:frontend
```
Интеграционные тесты с MOEX — опциональны:
```bash
npm run test:integration -w apps/backend
```
---
## Структура проекта
```
apps/
backend/ — NestJS API, единая точка доступа к MOEX ISS
frontend/ — React SPA на Vite
docs/ — сайт документации Docusaurus
packages/
design-system/ — дизайн-система (MUI-адаптер, UI-компоненты, Storybook)
docs/
features/ — спецификации и планы реализации (SDD)
epics/ — продуктовые эпики
inbox.md — идеи и заметки
roadmap.md — запланированные эпики и фичи
```
---
## Команды
| Команда | Что делает |
| ---------------------------------- | --------------------------------------------------------------------------- |
| `npm run dev:backend` | Запуск NestJS в режиме watch на :3000 |
| `npm run dev:frontend` | Vite dev-сервер на :5173, проксирует `/api` → :3000 |
| `npm run dev:docs` | Docusaurus dev-сервер (опубликованная документация) |
| `npm run build:backend` | `nest build` |
| `npm run build:frontend` | `tsc -b && vite build` (в две фазы) |
| `npm run build:docs` | `docusaurus build` |
| `npm run build:design-system` | Сборка дизайн-системы (`tsc`) |
| `npm run build:storybook` | Статическая сборка Storybook |
| `npm run test:backend` | `vitest run` (SWC, не ts-jest) |
| `npm run test:frontend` | Frontend Vitest suite |
| `npm run test:design-system` | Unit-тесты дизайн-системы (Vitest) |
| `npm run test:storybook` | Браузерные тесты Storybook (Vitest browser mode + Playwright) |
| `npm run storybook` | Storybook dev-сервер на :6006 (инженерный workbench, не docs) |
| `npm run lint` | ESLint для backend, frontend и design-system |
| `npm run lint:design-system` | ESLint для дизайн-системы |
| `npm run format` | Prettier для всех `*.{ts,tsx}` |
| `npm run codegen -w apps/frontend` | `openapi-typescript` из запущенного локального Swagger → `src/api/types.ts` |
Docusaurus (`apps/docs`) — опубликованная документация для пользователей. Storybook (`packages/design-system`) — инженерный workbench для разработки компонентов.
Интеграционные тесты с MOEX: `npm run test:integration -w apps/backend`.
Один backend-тест: `npm exec -w apps/backend -- vitest run src/path/to/test.spec.ts`
---
## Переменные окружения
| Переменная | По умолчанию | Описание |
| ------------------------------------ | -------------------------------- | -------------------------------------------------------------- |
| `PORT` | 3000 | Порт бэкенда |
| `MOEX_BASE_URL` | `https://iss.moex.com/iss` | Адрес MOEX ISS |
| `MOEX_RATE_LIMIT` | 10 | Запросов/с к MOEX |
| `MOEX_CIRCUIT_BREAKER_THRESHOLD` | 5 | Ошибок до открытия circuit breaker |
| `MOEX_CIRCUIT_BREAKER_RESET_SECONDS` | 30 | Секунд до попытки закрыть circuit breaker |
| `T_BANK_TOKEN` | `''` | Токен T-Bank Invest (серверный) |
| `T_BANK_BASE_URL` | `invest-public-api.tbank.ru:443` | gRPC endpoint T-Bank Invest |
| `T_BANK_CA_CERT_PATH` | `''` | Путь к PEM root CA для gRPC TLS |
| `T_BANK_APP_NAME` | `ksv741.moex-vibe` | Имя приложения для T-Bank |
| `T_BANK_RATE_LIMIT_PER_SECOND` | 5 | Rate limiter для OperationsService и UsersService (запросов/с) |
| `T_BANK_INSTRUMENTS_RATE_LIMIT` | 20 | Rate limiter для InstrumentsService (запросов/с) |
| `T_BANK_REQUEST_TIMEOUT_MS` | 10000 | Таймаут gRPC-запроса (мс) |
| `CACHE_MARKET_DATA_TTL` | 900 | TTL рыночных данных (с) |
| `CACHE_HISTORY_TTL` | 3600 | TTL истории (с) |
| `CACHE_CANDLES_TTL` | 3600 | TTL свечей (с) |
| `CACHE_SECURITY_TTL` | 86400 | TTL спецификации (с) |
| `CACHE_SEARCH_TTL` | 3600 | TTL результатов поиска (с) |
| `CACHE_DIVIDENDS_TTL` | 86400 | TTL дивидендных данных (с) |
| `CACHE_TBANK_ACCOUNTS_TTL` | 3600 | TTL брокерских счетов T-Bank (с) |
| `CACHE_TBANK_PORTFOLIO_TTL` | 60 | TTL брокерского портфеля T-Bank (с) |
| `CACHE_TBANK_OPERATIONS_TTL` | 300 | TTL брокерских операций T-Bank (с) |
| `CACHE_TBANK_POSITIONS_TTL` | 60 | TTL брокерских позиций T-Bank (с) |
| `CACHE_TBANK_INSTRUMENT_TTL` | 86400 | TTL инструментов T-Bank (с) |
| `DATABASE_URL` | `file:./dev.db` | URL SQLite для Prisma |
| `JWT_SECRET` | `dev-jwt-secret-...` | Secret для access token |
| `JWT_REFRESH_SECRET` | `dev-refresh-secret-...` | Secret для refresh token |
| `JWT_ACCESS_EXPIRES` | `15m` | TTL access token |
| `JWT_REFRESH_EXPIRES` | `7d` | TTL refresh token |