klg-asutk-app/docs/АРХИТЕКТУРА_ТЕХНОЛОГИЙ.md
Yuriy 0150aba4f5 Consolidation: KLG ASUTK + PAPA integration
- Unify API: lib/api.ts uses /api/v1, inbox uses /api/inbox (rewrites)
- Remove localhost refs: openapi, inbox page
- Add rewrites: /api/inbox|tmc -> inbox-server, /api/v1 -> FastAPI
- Add stub routes: knowledge/insights, recommendations, search, log-error
- Transfer from PAPA: prompts (inspection, tmc), scripts, supabase, data/tmc-requests
- Fix inbox-server: ORDER BY created_at, package.json
- Remove redundant app/api/inbox/files route (rewrites handle it)
- knowledge/ in gitignore (large PDFs)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 17:18:31 +03:00

352 lines
9.5 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.

# Архитектура технологий системы
## Обзор
Система использует современный стек технологий для обеспечения масштабируемости, производительности и надёжности.
## Компоненты
### 1. PostgreSQL - CRUD и авторизация
**Назначение**: Основная база данных для операционных данных и авторизации
**Использование**:
- Хранение пользователей и ролей
- CRUD операции для воздушных судов, аудитов, рисков
- Транзакционные данные
- Связи между сущностями
**Конфигурация**:
```env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=klg
DB_USER=klg
DB_PASSWORD=klg
```
**Файлы**:
- `lib/database/connection.ts` - подключение
- `lib/database/schema.sql` - схема БД
---
### 2. S3/MinIO + Parquet - Хранение данных
**Назначение**: Объектное хранилище для больших объёмов данных в формате Parquet
**Использование**:
- Хранение исторических данных
- Экспорт/импорт больших объёмов
- Архивные копии
- Данные для аналитики
**Конфигурация**:
```env
MINIO_ENDPOINT=http://localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=klg-data
```
**Файлы**:
- `lib/storage/s3-client.ts` - клиент S3/MinIO
- `lib/parquet/polars-utils.ts` - утилиты для Parquet
**Использование**:
```typescript
import { uploadParquetFile, getParquetFile } from '@/lib/storage/s3-client';
// Загрузка Parquet файла
await uploadParquetFile('aircraft/data.parquet', buffer);
// Получение файла
const data = await getParquetFile('aircraft/data.parquet');
```
---
### 3. ClickHouse - Аналитика и тяжёлые списки
**Назначение**: Колоночная БД для аналитических запросов и больших объёмов данных
**Использование**:
- Аналитические запросы
- Агрегации по большим объёмам данных
- Отчёты и дашборды
- Исторические данные
**Конфигурация**:
```env
CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_DB=klg_analytics
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
```
**Файлы**:
- `lib/analytics/clickhouse-client.ts` - клиент ClickHouse
- `scripts/clickhouse-init/init.sql` - инициализация схемы
**Использование**:
```typescript
import { queryClickHouse, insertClickHouse } from '@/lib/analytics/clickhouse-client';
// Аналитический запрос
const analytics = await queryClickHouse(`
SELECT operator, COUNT(*) as total
FROM aircraft_analytics
GROUP BY operator
`);
// Вставка данных
await insertClickHouse('aircraft_analytics', data);
```
---
### 4. OpenSearch - Полнотекстовый поиск
**Назначение**: Поиск по всем данным системы с поддержкой полнотекстового поиска
**Использование**:
- Поиск воздушных судов
- Поиск в документах
- Поиск в аудитах и рисках
- Нечёткий поиск (fuzzy search)
**Конфигурация**:
```env
OPENSEARCH_URL=http://localhost:9200
OPENSEARCH_USERNAME=
OPENSEARCH_PASSWORD=
```
**Файлы**:
- `lib/search/opensearch-client.ts` - клиент OpenSearch
**Использование**:
```typescript
import { searchAircraft, indexDocument } from '@/lib/search/opensearch-client';
// Индексация документа
await indexDocument('aircraft', aircraftId, aircraftData);
// Поиск
const results = await searchAircraft('RA-12345', {
operator: 'Аэрофлот',
status: 'Активен'
});
```
---
### 5. Airflow/Prefect + Python (Polars/DuckDB) - Пайплайны
**Назначение**: Оркестрация ETL пайплайнов для обработки данных
**Использование**:
- Импорт данных из ФАВТ
- Обработка больших объёмов данных
- Конвертация форматов (CSV → Parquet)
- Загрузка данных в аналитические хранилища
**Конфигурация**:
```env
PREFECT_API_URL=http://localhost:4200/api
MINIO_ENDPOINT=http://localhost:9000
CLICKHOUSE_URL=http://localhost:8123
```
**Файлы**:
- `scripts/pipelines/aircraft_pipeline.py` - пайплайн обработки ВС
- `scripts/pipelines/favt_import_pipeline.py` - пайплайн импорта ФАВТ
- `scripts/pipelines/requirements.txt` - Python зависимости
**Установка**:
```bash
pip install -r scripts/pipelines/requirements.txt
```
**Запуск пайплайна**:
```bash
# Через Prefect CLI
prefect deployment run aircraft-data-pipeline
# Или напрямую
python scripts/pipelines/aircraft_pipeline.py
```
---
### 6. OpenAPI → Генерация типов на фронт
**Назначение**: Автоматическая генерация TypeScript типов из OpenAPI схемы
**Использование**:
- Типобезопасность API
- Автодополнение в IDE
- Валидация запросов/ответов
- Документация API
**Файлы**:
- `openapi.json` - OpenAPI схема
- `scripts/openapi-generate.ts` - генератор типов
**Генерация типов**:
```bash
npm run generate:types
```
**Использование**:
```typescript
import { Aircraft, APIEndpoints } from '@/lib/api/generated-types';
// Типизированный запрос
const aircraft: Aircraft = await fetch('/api/aircraft/123').then(r => r.json());
```
---
## Docker Compose
Все сервисы запускаются через Docker Compose:
```bash
docker-compose up -d
```
**Сервисы**:
- `db` - PostgreSQL (5432)
- `minio` - MinIO S3 (9000, 9001)
- `clickhouse` - ClickHouse (8123, 9000)
- `opensearch` - OpenSearch (9200)
- `opensearch-dashboards` - Dashboards (5601)
- `redis` - Redis (6379)
- `prefect` - Prefect UI (4200)
- `backend` - FastAPI (8000)
- `frontend` - Next.js (3000)
---
## Поток данных
### Импорт данных из ФАВТ
1. **Python скрипт** (`fetch_favt_registry.py`) загружает CSV с сайта ФАВТ
2. **Prefect пайплайн** (`favt_import_pipeline.py`):
- Читает CSV
- Конвертирует в Parquet через Polars
- Сохраняет в S3/MinIO
- Импортирует в PostgreSQL
3. **Данные синхронизируются**:
- PostgreSQL - для операционных запросов
- ClickHouse - для аналитики
- OpenSearch - для поиска
### Обработка данных
1. **Пайплайн** (`aircraft_pipeline.py`):
- Загружает данные из PostgreSQL
- Обрабатывает через Polars/DuckDB
- Сохраняет в Parquet
- Загружает в S3 и ClickHouse
### Поиск
1. При создании/обновлении записи:
- Данные сохраняются в PostgreSQL
- Индексируются в OpenSearch
2. При поиске:
- Запрос идёт в OpenSearch
- Результаты возвращаются с релевантностью
---
## Переменные окружения
Создайте файл `.env.local`:
```env
# PostgreSQL
DB_HOST=localhost
DB_PORT=5432
DB_NAME=klg
DB_USER=klg
DB_PASSWORD=klg
# MinIO/S3
MINIO_ENDPOINT=http://localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=klg-data
# ClickHouse
CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_DB=klg_analytics
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
# OpenSearch
OPENSEARCH_URL=http://localhost:9200
# Prefect
PREFECT_API_URL=http://localhost:4200/api
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
```
---
## Запуск системы
1. **Запуск всех сервисов**:
```bash
docker-compose up -d
```
2. **Инициализация ClickHouse**:
```bash
docker-compose exec clickhouse clickhouse-client < scripts/clickhouse-init/init.sql
```
3. **Создание bucket в MinIO**:
- Откройте http://localhost:9001
- Логин: minioadmin / minioadmin
- Создайте bucket `klg-data`
4. **Генерация типов из OpenAPI**:
```bash
npm run generate:types
```
5. **Запуск пайплайнов**:
```bash
# Установка зависимостей
pip install -r scripts/pipelines/requirements.txt
# Запуск Prefect сервера (уже в Docker)
# Запуск пайплайна
prefect deployment run aircraft-data-pipeline
```
---
## Мониторинг
- **Prefect UI**: http://localhost:4200
- **MinIO Console**: http://localhost:9001
- **OpenSearch Dashboards**: http://localhost:5601
- **ClickHouse**: http://localhost:8123/play
---
## Дополнительная информация
См. также:
- `docs/MASHTABIRUEMOST.md` - масштабируемость
- `docs/DEPLOYMENT.md` - развёртывание
- `scripts/pipelines/` - примеры пайплайнов