feat: default locale Russian, geo determines language for other countries
- localization-svc: defaultLocale ru, resolveLocale only by geo - web-svc: DEFAULT_LOCALE ru, layout lang=ru, embeddedTranslations fallback ru - countryToLocale: default ru when no country or unknown country Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
695
docs/architecture/01-perplexity-analogue-design.md
Normal file
695
docs/architecture/01-perplexity-analogue-design.md
Normal file
@@ -0,0 +1,695 @@
|
||||
# Архитектура аналога Perplexity.ai — полная спецификация
|
||||
|
||||
Документ описывает полную архитектуру системы на базе микросервисов K3s с акцентом на:
|
||||
- **ВСЕ сервисы в `services/`.** Папка `apps/` удаляется. Микросервисная архитектура: chat, search, discover, finance, travel, auth, library, memory, create, notifications, projects, web (UI), cache-worker.
|
||||
- **~10 000 DAU** (ежедневных пользователей)
|
||||
- **Клиентская логика** — максимум на клиенте; персональные данные — только для аккаунтов
|
||||
- **Предварительная обработка и кэш** — новости, finance, travel, повторяющиеся запросы
|
||||
- **Полное совпадение** с Perplexity.ai по страницам и логике
|
||||
|
||||
---
|
||||
|
||||
## 1. Карта страниц (URL-структура, 1:1 Perplexity)
|
||||
|
||||
| URL | Страница | Описание |
|
||||
|-----|----------|----------|
|
||||
| `/` | Home | Поисковая строка + виджеты discover/новости |
|
||||
| `/search`, `/search/new?q=` | Search | Поисковый чат (Quick/Pro/Deep) |
|
||||
| `/c/[threadId]` | Chat/Thread | Окно конкретного чата/треда |
|
||||
| `/finance` | Finance | Рынок, heatmap, вкладки |
|
||||
| `/finance/[ticker]` | Ticker Detail | Детальная страница акции/индекса |
|
||||
| `/finance/predictions/[id]` | Predictions | Polymarket prediction markets |
|
||||
| `/travel` | Travel | Trending, Inspiration Cards, отели, маршруты |
|
||||
| `/discover` | Discover | Новости по темам (или часть Home) |
|
||||
| `/library` | Library | История поисков, сохранённые треды |
|
||||
| `/spaces` | Spaces | Список проектов/пространств |
|
||||
| `/spaces/templates` | Space Templates | Шаблоны Spaces |
|
||||
| `/collections/[id]` | Collections | Публичные коллекции (read-only Space) |
|
||||
| `/patents` | Patents | Поиск и анализ патентов |
|
||||
| Profile/Settings | Account | Профиль, Preferences, Personalize, Billing, My Connectors |
|
||||
| — | Desktop app | Electron/Tauri (pplx.ai-аналог) |
|
||||
| — | iOS / Android | Нативные приложения, voice search |
|
||||
| — | Chrome extension | Расширение для браузера |
|
||||
|
||||
---
|
||||
|
||||
## 2. Карта функциональностей
|
||||
|
||||
### 2.1 Сводная матрица
|
||||
|
||||
| Категория | Функционал | Клиент | Сервер (обязательно) | Кэш/Фоново |
|
||||
|-----------|------------|--------|----------------------|------------|
|
||||
| **Поиск** | Quick Search | ✅ UI, локальное состояние | LLM, Researcher | ✅ Кэш по query_hash |
|
||||
| **Поиск** | Pro Search | ✅ UI, стриминг | LLM, Mastra workflow | ✅ Кэш по query_hash |
|
||||
| **Поиск** | Deep Research | ✅ UI, прогресс | LLM, Mastra | ✅ Кэш по query_hash |
|
||||
| **Discover** | Новости по темам | ✅ Рендер | Агрегация | ✅ **Pre-compute + Redis** |
|
||||
| **Finance** | Рынок, heatmap, watchlist | ✅ Рендер, watchlist в LS | Агрегация данных | ✅ **Pre-compute + Redis** |
|
||||
| **Travel** | Маршруты, отели | ✅ UI stepper | Агрегация, LLM | ✅ **Pre-compute популярных** |
|
||||
| **Проекты** | Spaces, файлы | ✅ CRUD UI | Хранение файлов, эмбеддинги | — |
|
||||
| **Чат** | Сообщения, история | ✅ localStorage / IndexedDB | Только LLM, без хранения | Опционально: user preference |
|
||||
| **Медиа** | Images, Videos | ✅ Рендер | SearXNG proxy | ✅ Кэш по query |
|
||||
| **Виджеты** | Погода, акции, калькулятор | ✅ Калькулятор на клиенте | API-прокси | ✅ Погода/акции по ключу |
|
||||
| **Профиль** | Account, prefs | ✅ Preferences в LS | Auth только (SSO) | — |
|
||||
| **Биллинг** | Тарифы, оплата | ✅ UI | ЮKassa, лимиты | — |
|
||||
| **Collections** | Публичные шаблоны | ✅ Рендер | projects-svc | Redis/PostgreSQL |
|
||||
| **Library** | История, сохранённое | ✅ UI | library-svc (аккаунты) | PostgreSQL |
|
||||
| **Memory** | Персональная память AI | ✅ UI | memory-svc | PostgreSQL + Redis |
|
||||
| **Create/Labs** | Дашборды, отчёты, экспорт | ✅ UI | chat-svc + create-svc | — |
|
||||
| **Patents** | Поиск патентов | ✅ Рендер | search-svc + patents API | Redis |
|
||||
| **Export thread** | Экспорт тредов в PDF/MD | ✅ UI | create-svc / library-svc | — |
|
||||
| **Notifications** | Push, email, напоминания | ✅ Клиент + SW | notifications-svc | — |
|
||||
| **PWA/Офлайн** | Service worker, установка | ✅ SPA | Static + SW | — |
|
||||
| **Model Council** | 3 модели параллельно, синтез | ✅ UI (Max) | chat-svc | — |
|
||||
| **Background Assistant** | Фоновые задачи (Max) | ✅ Desktop/Mobile | chat-svc + queue | — |
|
||||
|
||||
### 2.2 Детальное описание функциональностей
|
||||
|
||||
#### A. Поисковый чат (Core)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Quick Search | 1 запрос, базовые модели, без хранения истории |
|
||||
| Pro Search | Многошаговый поиск, Mastra workflow, параллельные actions |
|
||||
| Deep Research | Расширенный анализ, отчёт, визуализация этапов |
|
||||
| **Answer Modes** | Standard, Focus, Academic, Writing + вертикали (Travel, Finance) |
|
||||
| **Travel Mode** | Отдельный системный промпт, фокус на отели/маршруты/бронирование |
|
||||
| Классификация | Classifier → skipSearch, sources, widgets |
|
||||
| Actions | webSearch, academicSearch, socialSearch, scrapeURL, uploadsSearch (параллельно) |
|
||||
| Writer | Финальный ответ с цитированием источников |
|
||||
| **Step-by-step Learning** | Режим обучения: подсказки, guided questions, уровень сложности |
|
||||
| **Response preferences** | Настройки формата/стиля ответов (Preferences) |
|
||||
| **Input bar «+»** | Меню: файлы, источники, режимы (Quick/Pro/Deep/Create/Learn) |
|
||||
| **Model Council** | Запуск 3 моделей параллельно → сравнение → синтез ответа (Max) |
|
||||
|
||||
#### B. Discover (Новости)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Агрегация новостей | По темам: tech, finance, travel, world, science |
|
||||
| Суммаризация | LLM-сводка каждой новости/блока |
|
||||
| Обновление | Фоновая задача каждые 15–30 мин |
|
||||
| Кэш | Redis: `discover:{topic}:{date}` TTL 30 мин |
|
||||
|
||||
#### C. Finance
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Market Summary | Индексы, futures, VIX |
|
||||
| Heatmap S&P 500 | Сектора, gainers/losers |
|
||||
| **Вкладки** | Crypto, Earnings, Predictions, Screener, Politicians Watchlist, Watchlist |
|
||||
| Recent Developments | Новости с суммаризацией и таймстампами |
|
||||
| **Popular Spaces for Finance Research** | Блок коллекций по категории finance (SEC, Buffett, S&P Transcripts) |
|
||||
| Standouts | Выделенные акции с кратким LLM-анализом |
|
||||
| Watchlist | Клиент: localStorage; сервер: агрегация данных по тикерам |
|
||||
| **Analyst ratings** | Рейтинги аналитиков по акциям (FMP, Benzinga и т.п.) |
|
||||
| **Auditable financials** | Ссылки на SEC filings в ответах и на странице тикера |
|
||||
| **ETF Holdings** | Детали холдингов ETF на странице тикера |
|
||||
| **Heatmap hover** | Live-синтез причины движения цены при наведении (LLM on demand) |
|
||||
| **Stock graphs** | Графики в ответах чата (мобильный/desktop) |
|
||||
| Кэш | Redis: `finance:summary`, `finance:heatmap`, `finance:news:{ticker}` TTL 2–5 мин |
|
||||
|
||||
#### D. Travel
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Trending Destinations | Карточки с изображениями (pre-compute) |
|
||||
| **Inspiration Cards** | Курируемые статьи («Лучшие тропы в Словении», «Лесные отели в Швеции») |
|
||||
| Поиск мест, маршруты | Генерация itineraries (LLM) |
|
||||
| Отели | Tripadvisor (рейтинги, отзывы, ссылки) |
|
||||
| **Партнёрское бронирование** | Tripadvisor, Selfbook (прямое бронирование) |
|
||||
| Stepper UI | Поиск → Места → Маршрут → Отели → Билеты |
|
||||
| Answer Mode: Travel | Вертикаль чата с фокусом на путешествия |
|
||||
| Кэш | Redis: `travel:trending`, `travel:inspiration`, `travel:itinerary:{hash}` TTL 1–24 ч |
|
||||
|
||||
#### E. Collections (публичные)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Collections | Публичные read-only Spaces с предзагруженным контекстом |
|
||||
| Категории | finance, travel, product, research — для Popular Spaces |
|
||||
| Примеры | SEC Findings, Buffett letters, S&P 500 Transcripts |
|
||||
| API | `GET /collections?category=finance`, `GET /collections/:id` |
|
||||
|
||||
#### F. Проекты (Spaces)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| CRUD проектов | Создание, переименование, архивация |
|
||||
| Файлы в проекте | Загрузка, парсинг, эмбеддинги |
|
||||
| Чаты в проекте | Контекст проекта во всех чатах |
|
||||
| Internal Knowledge Search | Поиск по файлам + веб |
|
||||
| Space Templates | Шаблоны под финансы, маркетинг, продукт, travel |
|
||||
|
||||
#### G. Library
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| История поисков | Список тредов для авторизованного пользователя |
|
||||
| Сохранённое | Saved threads, закладки |
|
||||
| **Гости** | Только localStorage/IndexedDB, при закрытии — потеря |
|
||||
| **Аккаунты** | Синхронизация на сервере (library-svc, PostgreSQL) |
|
||||
|
||||
#### H. Медиа
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Search Images | SearXNG, LLM формирует query |
|
||||
| Search Videos | SearXNG, LLM формирует query |
|
||||
| Кэш | Redis: `media:images:{query_hash}`, `media:videos:{query_hash}` TTL 1 ч |
|
||||
|
||||
#### I. Виджеты
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Weather | API (Open-Meteo и т.п.) |
|
||||
| Stock | Yahoo Finance / Financial Modeling Prep |
|
||||
| Calculation | **Полностью на клиенте** (mathjs и т.п.) |
|
||||
| Кэш | Погода/акции: Redis по location/ticker TTL 5–15 мин |
|
||||
|
||||
#### J. Профиль и Connectors
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Account | Аватар, имя, email (только просмотр) |
|
||||
| Preferences | Appearance, Language, Autosuggest, Homepage widgets, **Response preferences** |
|
||||
| Personalize | Watchlists, настройки персонализации |
|
||||
| Billing | Подписка, история платежей |
|
||||
| **My Connectors** | Интеграции (Google Drive, Dropbox и т.п.) — Pro/общие пользователи |
|
||||
| **App Connectors** | Enterprise: SharePoint, OneDrive, Box — автосинхронизация файлов в Space |
|
||||
|
||||
#### K. Memory (персональная память AI)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Хранение | memory-svc, PostgreSQL (user_id, key, value, embedding) |
|
||||
| Извлечение | Семантический поиск по памяти при каждом запросе (если Pro/Max) |
|
||||
| Формат | Факты, предпочтения, контекст из прошлых тредов |
|
||||
| UI | Просмотр/удаление памяти в Profile → Personalize |
|
||||
| Enterprise Memory | Организационная память (org_id), доступна всем участникам |
|
||||
|
||||
#### L. Create / Labs
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Генерация | Таблицы, отчёты, дашборды по запросу (Pro) |
|
||||
| Экспорт | .xlsx, .csv, .md, .pdf из ответов |
|
||||
| Image generation | Генерация изображений (Pro, DALL·E/Stable Diffusion) |
|
||||
| API | `POST /api/v1/create` — тип (table/dashboard/image), prompt |
|
||||
|
||||
#### M. Patents
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Страница | `/patents` — поиск по USPTO, EPO, патентам РФ |
|
||||
| Интеграция | patents API или Google Patents; LLM-суммаризация |
|
||||
| Кэш | Redis `patents:{query_hash}` TTL 1 ч |
|
||||
|
||||
#### N. Enterprise
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| **Audit logs** | Логи: query, answer, model, sources, user_id, timestamp (compliance) |
|
||||
| **Granular feature access** | Доступ к API, список Spaces, модели по ролям админа |
|
||||
| **Domain-based sign-up** | Ограничение регистрации по верифицированным доменам email |
|
||||
| **Usage guidelines** | Guidelines организации на homepage для членов |
|
||||
| **Enterprise Memory** | Общая память на уровень org |
|
||||
|
||||
#### O. Клиентские приложения
|
||||
| Платформа | Описание |
|
||||
|----------|----------|
|
||||
| **Desktop** | Electron или Tauri, единый код с web |
|
||||
| **iOS / Android** | React Native или Capacitor; **voice search** (Web Speech API / native) |
|
||||
| **Chrome extension** | Всплывающее окно, быстрый поиск со страницы |
|
||||
| **PWA / Офлайн** | Service worker кэширует статику (JS, CSS, assets); workbox; установка на домашний экран; офлайн-fallback |
|
||||
|
||||
#### O.1 Export thread
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| API | `POST /api/v1/library/threads/:id/export` или `POST /api/v1/export` с `contentType: 'thread'` |
|
||||
| Форматы | PDF, Markdown |
|
||||
| Реализация | create-svc или library-svc; рендер треда → PDF (puppeteer/jsPDF) или MD (template) |
|
||||
| UI | Кнопка Export в окне чата/треда |
|
||||
|
||||
#### O.2 Notifications
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| **Push** | Web Push API (VAPID); уведомление при готовности ответа (Pro/Deep); настройки в Preferences |
|
||||
| **Email** | Опция «уведомить по email при завершении» для долгих запросов (Deep Research) |
|
||||
| **Напоминания** | «Напомнить через N» — отложенная задача, push/email по расписанию |
|
||||
| **Сервис** | notifications-svc; очереди (Redis/Bull) или вызов от chat-svc по событию |
|
||||
|
||||
#### O.3 Model Council (Max)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Логика | Запрос → параллельный запуск 3 выбранных моделей (GPT-4, Claude, и др.) |
|
||||
| Синтез | Отдельный LLM-вызов для сравнения и сведения в единый ответ |
|
||||
| UI | Выбор моделей в input bar; side-by-side или сводный вид |
|
||||
| API | `POST /api/v1/chat` с `modelCouncil: true`, `models: ['gpt-4','claude','...']` |
|
||||
|
||||
#### O.4 Background Assistant (Max)
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| Назначение | Выполнение задач в фоне (Desktop/Mobile app), когда приложение свёрнуто |
|
||||
| Архитектура | Queue (Redis/Bull); worker подхватывает задачи; push при готовности |
|
||||
| Сценарии | «Найди отели в Париже» → фон → уведомление с результатом |
|
||||
| API | `POST /api/v1/tasks` (создать фоновую задачу); polling или WebSocket/SSE для статуса |
|
||||
|
||||
#### P. Образование
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| **Step-by-step Learning** | Режим в input bar «+»; ответы с подсказками, guided questions |
|
||||
| **Quizzes / Flashcards** | Генерация тестов и карточек по теме (Pro/Education) |
|
||||
| **Education Pro** | Тариф со скидкой для студентов/преподавателей (верификация) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Микросервисы K3s
|
||||
|
||||
### 3.1 Карта сервисов
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CLIENT (SPA / PWA) │
|
||||
│ Next.js (SSR для статики) / React SPA — максимум логики, localStorage, IndexedDB │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐
|
||||
│ API Gateway │ │ Auth Service │ │ Web (CDN/Static) │
|
||||
│ (Kong / Traefik) │ │ (Keycloak/Supabase) │ │ S3/MinIO + CDN │
|
||||
└───────────────────────┘ └───────────────────────┘ └───────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ BACKEND MICROSERVICES (K3s) │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ chat-svc │ │ search-svc │ │ discover-svc│ │ finance-svc │ │
|
||||
│ │ LLM, Mastra │ │ SearXNG, │ │ News feed │ │ Market data │ │
|
||||
│ │ Writer │ │ Scraper │ │ Summari-zer│ │ Heatmap │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ travel-svc │ │ media-svc │ │ projects-svc│ │ cache-worker│ │
|
||||
│ │ Itineraries │ │ Images/Videos│ │ Files, │ │ Pre-compute │ │
|
||||
│ │ Tripadvisor │ │ SearXNG │ │ Embeddings │ │ Background │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ billing-svc │ │ upload-svc │ │ library-svc │ │ memory-svc │ │
|
||||
│ │ ЮKassa │ │ File parse │ │ Threads, │ │ AI Memory, │ │
|
||||
│ │ Subscriptions│ │ Embeddings │ │ History │ │ Enterprise │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ # Create, Audit, Notifications │
|
||||
│ │ create-svc │ │ audit-svc │ │notifications│ │
|
||||
│ │ Tables, │ │ Query+Answer│ │ Push, Email │ │
|
||||
│ │ Dashboards │ │ logging │ │ Reminders │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ИНФРАСТРУКТУРА │
|
||||
│ Redis (кэш + сессии) │ PostgreSQL (billing, projects) │ MinIO (файлы) │
|
||||
│ SearXNG (self-hosted) │ LLM Provider (OpenAI/Ollama) │ Vector DB (optional) │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 Описание микросервисов
|
||||
|
||||
| Сервис | Язык | Replicas (10k DAU) | Назначение |
|
||||
|--------|------|--------------------|------------|
|
||||
| **api-gateway** | — (Kong/Traefik) | 2 | Роутинг, rate limit, JWT validation |
|
||||
| **auth-svc** | Node/Go | 2 | SSO (Google, Apple, Email magic link), JWT |
|
||||
| **chat-svc** | Node.js | 3–5 | LLM, Mastra workflow, Writer, streaming |
|
||||
| **search-svc** | Node.js | 3 | SearXNG, scrape, Researcher actions |
|
||||
| **discover-svc** | Node.js | 2 | Агрегация новостей, суммаризация (фоново) |
|
||||
| **finance-svc** | Node.js | 2 | Market data, heatmap, news по тикерам |
|
||||
| **travel-svc** | Node.js | 2 | Itineraries, Tripadvisor, trending |
|
||||
| **media-svc** | Node.js | 2 | Images/Videos через SearXNG |
|
||||
| **projects-svc** | Node.js | 2 | CRUD проектов, файлы, эмбеддинги, **Collections** |
|
||||
| **billing-svc** | Node.js | 1 | ЮKassa, subscriptions, лимиты |
|
||||
| **upload-svc** | Node.js | 2 | Парсинг PDF/DOCX, embedding, chunking |
|
||||
| **library-svc** | Node.js | 2 | История тредов, сохранённое для аккаунтов |
|
||||
| **memory-svc** | Node.js | 2 | Персональная память AI, Enterprise Memory, векторный поиск |
|
||||
| **create-svc** | Node.js | 1–2 | Create (таблицы, дашборды), экспорт, image generation |
|
||||
| **audit-svc** | Node.js | 1 | Audit logs для Enterprise (query, answer, model, user) |
|
||||
| **notifications-svc** | Node.js | 1–2 | Web Push, Email, напоминания; очереди задач |
|
||||
| **cache-worker** | Node.js | 1–2 | Cron: pre-compute discover, finance, travel inspiration |
|
||||
|
||||
### 3.3 K3s манифесты (базовая структура)
|
||||
|
||||
```yaml
|
||||
# namespaces
|
||||
perplexica-prod
|
||||
perplexica-cache
|
||||
|
||||
# Deployments с HPA
|
||||
chat-svc: min 2, max 8, CPU 70%
|
||||
search-svc: min 2, max 6
|
||||
discover-svc: min 1, max 4
|
||||
finance-svc: min 1, max 4
|
||||
travel-svc: min 1, max 3
|
||||
media-svc: min 1, max 4
|
||||
projects-svc: min 1, max 4 (включая Collections)
|
||||
upload-svc: min 1, max 4
|
||||
library-svc: min 1, max 3
|
||||
memory-svc: min 1, max 3
|
||||
create-svc: min 1, max 2
|
||||
audit-svc: min 1, max 1
|
||||
notifications-svc: min 1, max 2
|
||||
billing-svc: min 1, max 2
|
||||
cache-worker: min 1, max 1 (CronJob)
|
||||
auth-svc: min 2, max 4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Стратегия кэширования и предобработки
|
||||
|
||||
### 3.1 Ключевой принцип
|
||||
|
||||
> **Не суммировать и не обрабатывать по запросу то, что можно сделать заранее и переиспользовать.**
|
||||
|
||||
### 3.2 Кэш-слои
|
||||
|
||||
| Слой | Что кэширует | Ключ | TTL | Источник |
|
||||
|------|--------------|------|-----|----------|
|
||||
| **Discover** | Новости по теме + суммаризация | `discover:{topic}` | 30 мин | cache-worker каждые 15 мин |
|
||||
| **Finance** | Market summary, heatmap | `finance:summary`, `finance:heatmap` | 5 мин | cache-worker каждые 2 мин |
|
||||
| **Finance** | News по тикеру | `finance:news:{ticker}` | 15 мин | cache-worker при обновлении |
|
||||
| **Travel** | Trending destinations | `travel:trending` | 6 ч | cache-worker каждые 4 ч |
|
||||
| **Travel** | Inspiration Cards | `travel:inspiration` | 6 ч | cache-worker каждые 4 ч |
|
||||
| **Travel** | Популярные маршруты | `travel:itinerary:{hash}` | 24 ч | On first request, reuse |
|
||||
| **Search** | Идентичные запросы | `search:{query_hash}:{mode}` | 1–24 ч | On first request |
|
||||
| **Media** | Images/Videos query | `media:{type}:{query_hash}` | 1 ч | On first request |
|
||||
| **Widgets** | Погода, акции | `widget:{type}:{key}` | 5–15 мин | On first request |
|
||||
|
||||
### 3.4 Cache-worker (фоновые задачи)
|
||||
|
||||
```
|
||||
Cron расписание:
|
||||
├── */2 * * * * finance:summary, finance:heatmap
|
||||
├── */15 * * * * discover:{topic} для всех тем
|
||||
├── 0 */4 * * * travel:trending, travel:inspiration (Inspiration Cards)
|
||||
└── 0 * * * * Инвалидация устаревших search cache
|
||||
```
|
||||
|
||||
### 3.5 Логика поискового кэша
|
||||
|
||||
1. Входящий запрос → `query_hash = sha256(normalize(query) + mode + sources)`
|
||||
2. Проверка Redis: `GET search:{query_hash}`
|
||||
3. Если есть → отдать из кэша (без LLM)
|
||||
4. Если нет → выполнить полноценный flow, сохранить в кэш
|
||||
5. Популярные запросы (частота > N/день) → приоритет в cache-worker для pre-warm
|
||||
|
||||
---
|
||||
|
||||
## 4. Клиентская архитектура (без хранения данных)
|
||||
|
||||
### 4.1 Что на клиенте (включая My Connectors UI)
|
||||
|
||||
| Компонент | Реализация |
|
||||
|-----------|------------|
|
||||
| UI/UX | React, Next.js (SSR только для статики) |
|
||||
| Состояние чата | Zustand/Context — в памяти, при refresh теряется (или опционально IndexedDB) |
|
||||
| Preferences | localStorage: theme, language, units |
|
||||
| Watchlist (finance) | localStorage |
|
||||
| Калькулятор | Полностью локально (mathjs) |
|
||||
| Роутинг | Client-side |
|
||||
| **PWA / Офлайн** | Service worker (Workbox): кэш static (JS, CSS, assets); offline fallback; manifest для установки |
|
||||
|
||||
### 4.2 Что храним / не храним
|
||||
|
||||
**Не храним на сервере (гости):**
|
||||
- История чатов — только в памяти/IndexedDB клиента
|
||||
- Preferences — только в localStorage
|
||||
|
||||
**Храним для аккаунтов:**
|
||||
- История тредов, сохранённое — library-svc (PostgreSQL)
|
||||
- Projects, файлы, подписка — projects-svc, billing-svc
|
||||
- Кэш поиска — обезличенный по query_hash, без user_id
|
||||
|
||||
### 4.3 Режимы пользователя
|
||||
|
||||
| Режим | Данные | Описание |
|
||||
|-------|--------|----------|
|
||||
| **Гость** | Всё на клиенте | Чат в памяти, при закрытии — потеря |
|
||||
| **Аккаунт** | Auth + billing | Проекты, подписка — в БД; чаты опционально |
|
||||
|
||||
### 4.4 UI/UX требования
|
||||
|
||||
| Область | Требование |
|
||||
|---------|------------|
|
||||
| **Discover, Finance, Travel** | Skeleton/placeholder при cold start; timeout с сообщением; кнопка повтора при ошибке |
|
||||
| **Поиск (Pro/Deep)** | Отображение этапов (Classifier → Researcher → Writer); оценка времени ожидания |
|
||||
| **Загрузка файлов** | Прогресс по этапам: парсинг → chunking → эмбеддинги; индикация; кнопка Cancel; timeout 300 с |
|
||||
| **Гости** | Предупреждение при закрытии: история теряется без аккаунта; CTA «Сохранить в аккаунт» |
|
||||
| **Rate limit** | Сообщение при 429; предупреждение при 80% лимита; предложение апгрейда при достижении |
|
||||
| **Ошибки** | Сообщение + Retry/Cancel; fallback при частичном сбое (например, виджет не загрузился) |
|
||||
| **Travel Stepper** | Сохранение состояния шагов при уходе; скелетон между шагами |
|
||||
| **Мобильный** | Адаптивность heatmap, Discover; жесты; SettingsButtonMobile |
|
||||
|
||||
---
|
||||
|
||||
## 5. API контракты (основные)
|
||||
|
||||
### 5.1 Chat/Search
|
||||
|
||||
```
|
||||
POST /api/v1/chat
|
||||
Body: { query, mode?, sources?, fileIds?, answerMode?, learningMode?, responsePrefs? }
|
||||
answerMode: 'standard' | 'focus' | 'academic' | 'writing' | 'travel' | 'finance'
|
||||
learningMode: boolean # Step-by-step Learning
|
||||
responsePrefs: { format?, length?, tone? } # из Preferences
|
||||
Response: SSE stream
|
||||
Cache: Проверка query_hash до вызова LLM
|
||||
|
||||
POST /api/v1/search/cached
|
||||
Query: ?q=...&mode=...
|
||||
Response: JSON (если есть в кэше) или 404 → fallback на /chat
|
||||
```
|
||||
|
||||
### 5.2 Discover
|
||||
|
||||
```
|
||||
GET /api/v1/discover?topic=tech|finance|travel|...
|
||||
Response: { items: [{ title, summary, source, url }] }
|
||||
Source: Redis, refresh от cache-worker
|
||||
```
|
||||
|
||||
### 5.3 Finance
|
||||
|
||||
```
|
||||
GET /api/v1/finance/summary
|
||||
GET /api/v1/finance/heatmap
|
||||
GET /api/v1/finance/news/:ticker
|
||||
GET /api/v1/finance/watchlist?tickers=AAPL,GOOG
|
||||
GET /api/v1/finance/analyst-ratings/:ticker # Analyst ratings
|
||||
GET /api/v1/finance/sec-filings/:ticker # Ссылки на SEC filings
|
||||
GET /api/v1/finance/etf-holdings/:symbol # ETF Holdings
|
||||
GET /api/v1/finance/price-context/:ticker # Heatmap hover: LLM-синтез причины движения
|
||||
Response: JSON из Redis / live
|
||||
```
|
||||
|
||||
### 5.4 Travel
|
||||
|
||||
```
|
||||
GET /api/v1/travel/trending
|
||||
GET /api/v1/travel/inspiration # Inspiration Cards (pre-compute)
|
||||
POST /api/v1/travel/itinerary
|
||||
Body: { destination, days, preferences }
|
||||
Cache: По hash параметров
|
||||
```
|
||||
|
||||
### 5.5 Collections
|
||||
|
||||
```
|
||||
GET /api/v1/collections?category=finance|travel|product|research
|
||||
GET /api/v1/collections/:id
|
||||
Response: Публичный Space с контекстом (read-only)
|
||||
```
|
||||
|
||||
### 5.6 Library
|
||||
|
||||
```
|
||||
GET /api/v1/library/threads # Для авторизованных
|
||||
POST /api/v1/library/threads # Сохранить тред
|
||||
DELETE /api/v1/library/threads/:id
|
||||
```
|
||||
|
||||
### 5.7 Auth
|
||||
|
||||
```
|
||||
POST /auth/login/email
|
||||
GET /auth/oauth/{provider}
|
||||
POST /auth/refresh
|
||||
GET /auth/me
|
||||
```
|
||||
|
||||
### 5.8 Connectors
|
||||
|
||||
```
|
||||
GET /api/v1/connectors # Список доступных (Pro)
|
||||
POST /api/v1/connectors/:type # Подключить (Google Drive, Dropbox)
|
||||
DELETE /api/v1/connectors/:id # Отключить
|
||||
```
|
||||
|
||||
### 5.9 Memory
|
||||
|
||||
```
|
||||
GET /api/v1/memory # Список записей памяти (Pro/Max)
|
||||
POST /api/v1/memory # Добавить запись (внутренний вызов от chat-svc)
|
||||
DELETE /api/v1/memory/:id # Удалить запись
|
||||
```
|
||||
|
||||
### 5.10 Create / Labs
|
||||
|
||||
```
|
||||
POST /api/v1/create
|
||||
Body: { type: 'table' | 'dashboard' | 'image', prompt, context? }
|
||||
Response: { url?, data?, imageUrl? }
|
||||
|
||||
POST /api/v1/export
|
||||
Body: { format: 'xlsx' | 'csv' | 'md' | 'pdf', contentId?, contentType?: 'create' | 'thread' }
|
||||
Body (thread): { format: 'pdf' | 'md', threadId }
|
||||
Response: blob / download URL
|
||||
```
|
||||
|
||||
### 5.10.1 Export thread
|
||||
|
||||
```
|
||||
POST /api/v1/library/threads/:id/export
|
||||
Query: ?format=pdf|md
|
||||
Response: blob (application/pdf или text/markdown)
|
||||
Реализация: create-svc или library-svc + puppeteer/jsPDF для PDF
|
||||
```
|
||||
|
||||
### 5.11 Patents
|
||||
|
||||
```
|
||||
GET /api/v1/patents?q=...
|
||||
Response: { patents: [{ title, abstract, filingDate, url, summary }] }
|
||||
Source: Google Patents / USPTO API; LLM-суммаризация; Redis кэш
|
||||
```
|
||||
|
||||
### 5.12 Enterprise Audit
|
||||
|
||||
```
|
||||
GET /api/v1/admin/audit-logs?from=&to=&userId=
|
||||
Response: [{ query, answerSnippet, model, sources, userId, timestamp }]
|
||||
Только для org admin
|
||||
```
|
||||
|
||||
### 5.13 Notifications
|
||||
|
||||
```
|
||||
POST /api/v1/notifications/subscribe # Web Push подписка (VAPID)
|
||||
Body: { endpoint, keys: { p256dh, auth } }
|
||||
|
||||
POST /api/v1/notifications/preferences # Настройки: push при ответе, email, напоминания
|
||||
Body: { pushOnAnswer?, emailOnDeepResearch?, reminders?: [...] }
|
||||
|
||||
POST /api/v1/notifications/remind # «Напомнить через N»
|
||||
Body: { threadId?, query?, remindAt: ISO8601 }
|
||||
```
|
||||
|
||||
### 5.14 Model Council (Max)
|
||||
|
||||
```
|
||||
POST /api/v1/chat
|
||||
Body: { ..., modelCouncil: true, models: ['gpt-4o','claude-sonnet','...'] }
|
||||
Response: SSE с этапами: 3 ответа → синтез
|
||||
```
|
||||
|
||||
### 5.15 Background Assistant (Max)
|
||||
|
||||
```
|
||||
POST /api/v1/tasks # Создать фоновую задачу
|
||||
Body: { query, mode?, callback?: 'push' | 'poll' }
|
||||
Response: { taskId }
|
||||
|
||||
GET /api/v1/tasks/:id # Статус задачи
|
||||
Response: { status, result?, error? }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Порядок реализации (best practices)
|
||||
|
||||
### Фаза 0 — Инфраструктура
|
||||
1. K3s кластер, PostgreSQL, Redis, MinIO
|
||||
2. API Gateway (Traefik/Kong)
|
||||
3. Auth-svc (Keycloak или Supabase Auth)
|
||||
|
||||
### Фаза 1 — Ядро
|
||||
4. chat-svc с Mastra (Classifier → parallel actions → Writer)
|
||||
5. search-svc (SearXNG, actions)
|
||||
6. cache-worker + Redis стратегия
|
||||
7. Кэш для search по query_hash
|
||||
|
||||
### Фаза 2 — Discover + Finance
|
||||
8. discover-svc + cache-worker pre-compute
|
||||
9. finance-svc + cache-worker
|
||||
10. Клиент: Discover, Finance страницы
|
||||
|
||||
### Фаза 3 — Travel
|
||||
11. travel-svc, Tripadvisor, Selfbook
|
||||
12. Inspiration Cards (cache-worker), Stepper UI
|
||||
13. Answer Mode: Travel
|
||||
|
||||
### Фаза 4 — Проекты, Collections, Library, биллинг
|
||||
14. projects-svc, upload-svc, **Collections** (Popular Spaces по категориям)
|
||||
15. library-svc (история для аккаунтов)
|
||||
16. billing-svc, ЮKassa
|
||||
17. Клиент: Spaces UI, Library, Profile, Billing, My Connectors
|
||||
|
||||
### Фаза 5 — Memory, Create, Finance+, Patents, Enterprise
|
||||
18. memory-svc (персональная память, Enterprise Memory)
|
||||
19. create-svc (таблицы, дашборды, экспорт, image generation)
|
||||
20. finance-svc: Analyst ratings, SEC links, ETF Holdings, heatmap hover, stock graphs
|
||||
21. Patents page: search-svc + patents API, `/patents`
|
||||
22. audit-svc (Enterprise audit logs)
|
||||
23. Enterprise: domain sign-up, usage guidelines, granular feature access
|
||||
24. Step-by-step Learning, Response preferences, Input bar «+»
|
||||
|
||||
### Фаза 6 — Клиенты и образование
|
||||
25. Desktop app (Electron/Tauri)
|
||||
26. iOS / Android (React Native/Capacitor), voice search
|
||||
27. Chrome extension
|
||||
28. Step-by-step Learning UI, Quizzes/Flashcards
|
||||
29. Education Pro тариф
|
||||
|
||||
### Фаза 7 — Export, Notifications, PWA, Model Council, Background
|
||||
30. Export thread: POST /library/threads/:id/export (PDF, MD)
|
||||
31. PWA: Service worker (Workbox), manifest, offline fallback
|
||||
32. notifications-svc: Web Push (VAPID), email, напоминания
|
||||
33. Model Council (Max): параллельный запуск 3 моделей, синтез
|
||||
34. Background Assistant (Max): POST /tasks, queue, push при готовности
|
||||
|
||||
### Фаза 8 — Оптимизация
|
||||
35. Pre-warm популярных запросов в cache-worker
|
||||
36. CDN для статики
|
||||
37. Мониторинг, алерты, SLO
|
||||
|
||||
---
|
||||
|
||||
## 7. Латенси по сценариям (пользователь)
|
||||
|
||||
| Сценарий | Ожидаемое время | Cold / промах кэша |
|
||||
|----------|-----------------|--------------------|
|
||||
| Discover / Finance (кэш) | <500 ms | 5–30 с |
|
||||
| Finance редкий тикер | 10–20 с (cold fill) | — |
|
||||
| Travel itinerary | 15–60 с | — |
|
||||
| Pro/Deep Search | 30–120 с | — |
|
||||
| Загрузка файла (эмбеддинги) | 30–300 с | — |
|
||||
| Медиа (Images/Videos) | 3–10 с | — |
|
||||
|
||||
## 8. Оценка нагрузки (10k DAU)
|
||||
|
||||
| Метрика | Оценка | Решение |
|
||||
|---------|--------|---------|
|
||||
| RPS пиковый | ~50–100 | HPA, 3–5 реплик chat-svc |
|
||||
| LLM вызовов/день | ~30k (3 на юзера) | Кэш снижает до ~10k |
|
||||
| Redis memory | ~4–8 GB | Кэш discover/finance/search |
|
||||
| Storage | ~100 GB | Файлы проектов, логи |
|
||||
|
||||
---
|
||||
|
||||
## 9. Безопасность и compliance
|
||||
|
||||
- HTTPS везде
|
||||
- JWT с коротким TTL (15 мин), refresh token
|
||||
- Rate limiting: 100 req/min на IP, 300 Pro Search/день (Free)
|
||||
- Не логировать персональные запросы в plaintext
|
||||
- Кэш — только по hash, без привязки к user_id
|
||||
1547
docs/architecture/02-k3s-microservices-spec.md
Normal file
1547
docs/architecture/02-k3s-microservices-spec.md
Normal file
File diff suppressed because it is too large
Load Diff
282
docs/architecture/03-cache-and-precompute-strategy.md
Normal file
282
docs/architecture/03-cache-and-precompute-strategy.md
Normal file
@@ -0,0 +1,282 @@
|
||||
# Стратегия кэширования и предварительной обработки
|
||||
|
||||
## Принципы
|
||||
|
||||
1. **Не делать по запросу то, что можно сделать заранее**
|
||||
2. **Кэшировать по обезличенному ключу** (query hash, topic, ticker)
|
||||
3. **Фоновые воркеры** обновляют кэш по расписанию
|
||||
4. **Первый запрос** — холодный, заполняет кэш для последующих
|
||||
|
||||
---
|
||||
|
||||
## 1. Discover (Новости)
|
||||
|
||||
### Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ cache-worker (CronJob каждые 15 мин) │
|
||||
│ │
|
||||
│ 1. Агрегировать новости по темам (tech, finance, travel, world, ...) │
|
||||
│ 2. Для каждой новости: суммаризация через LLM (batch) │
|
||||
│ 3. Сохранить в Redis: discover:{topic} = JSON │
|
||||
│ TTL = 30 мин │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ discover-svc (HTTP GET /discover?topic=tech) │
|
||||
│ │
|
||||
│ 1. Redis GET discover:tech │
|
||||
│ 2. Если есть → отдать сразу │
|
||||
│ 3. Если нет (cold) → синхронно выполнить агрегацию + суммаризацию, │
|
||||
│ сохранить в Redis, отдать │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Redis схема
|
||||
|
||||
| Ключ | Значение | TTL |
|
||||
|------|----------|-----|
|
||||
| `discover:tech` | `{ items: [{ title, summary, source, url, fetched_at }] }` | 30 min |
|
||||
| `discover:finance` | аналогично | 30 min |
|
||||
| `discover:travel` | аналогично | 30 min |
|
||||
|
||||
### UX при cold start
|
||||
- Skeleton карточек новостей; timeout 30 с; Retry при ошибке; предупреждение о задержке при cold
|
||||
|
||||
### Cron расписание
|
||||
|
||||
```
|
||||
*/15 * * * * cache-worker --task=discover
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Finance (Рынок, новости по тикерам)
|
||||
|
||||
### Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ cache-worker (CronJob каждые 2 мин) │
|
||||
│ │
|
||||
│ 1. Market summary: индексы, futures, VIX │
|
||||
│ 2. Heatmap S&P 500 │
|
||||
│ 3. News для топ-20 тикеров (по популярности) → суммаризация │
|
||||
│ 4. Redis: finance:summary, finance:heatmap, finance:news:AAPL, ... │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ finance-svc │
|
||||
│ │
|
||||
│ GET /finance/summary → Redis finance:summary │
|
||||
│ GET /finance/heatmap → Redis finance:heatmap │
|
||||
│ GET /finance/news/AAPL → Redis finance:news:AAPL (или cold fill) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Redis схема
|
||||
|
||||
| Ключ | Значение | TTL |
|
||||
|------|----------|-----|
|
||||
| `finance:summary` | Market data JSON | 5 min |
|
||||
| `finance:heatmap` | Heatmap JSON | 5 min |
|
||||
| `finance:news:AAPL` | News + summary | 15 min |
|
||||
| `finance:news:TSLA` | News + summary | 15 min |
|
||||
|
||||
### Cold fill для редких тикеров
|
||||
|
||||
Skeleton heatmap/карточки; timeout 20 с.
|
||||
|
||||
Если запрос на `finance:news:XOM` — в кэше нет:
|
||||
1. Выполнить запрос к API + суммаризацию
|
||||
2. Сохранить в Redis
|
||||
3. Отдать пользователю
|
||||
|
||||
---
|
||||
|
||||
## 3. Travel (Маршруты, тренды, Inspiration Cards)
|
||||
|
||||
### Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ cache-worker (CronJob каждые 4–6 ч) — task=travel │
|
||||
│ │
|
||||
│ 1. Trending destinations → Redis travel:trending │
|
||||
│ 2. Inspiration Cards (курируемые статьи) → Redis travel:inspiration │
|
||||
│ Примеры: «Лучшие тропы в Словении», «Лесные отели в Швеции», │
|
||||
│ «Скрытые пляжи Португалии» — LLM генерация/суммаризация batch │
|
||||
│ 3. (Опционально) Pre-warm популярных маршрутов: Paris 5d, Tokyo 7d │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ travel-svc │
|
||||
│ │
|
||||
│ GET /travel/inspiration → Redis travel:inspiration (отдать сразу) │
|
||||
│ GET /travel/trending → Redis travel:trending │
|
||||
│ POST /travel/itinerary → hash → Redis или LLM │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Redis схема
|
||||
|
||||
| Ключ | Значение | TTL |
|
||||
|------|----------|-----|
|
||||
| `travel:trending` | Список направлений с картинками | 6 h |
|
||||
| `travel:inspiration` | `[{ title, summary, image, url }]` — Inspiration Cards | 6 h |
|
||||
| `travel:itinerary:{hash}` | Сгенерированный маршрут | 24 h |
|
||||
|
||||
### UX при cold start
|
||||
- Skeleton trending/inspiration; itinerary: прогресс по этапам, 60 с timeout
|
||||
|
||||
### Реализация Inspiration Cards в cache-worker
|
||||
|
||||
```typescript
|
||||
// cache-worker/src/tasks/travel.ts
|
||||
export async function runTravelPrecompute(redis: Redis) {
|
||||
const trending = await fetchTrendingDestinations();
|
||||
await redis.setex('travel:trending', 6 * 60 * 60, JSON.stringify(trending));
|
||||
|
||||
const inspirationTopics = [
|
||||
'best hiking trails Slovenia',
|
||||
'forest hotels Sweden solitude',
|
||||
'hidden beaches Portugal',
|
||||
'weekend getaways Europe',
|
||||
// ... курированный список тем
|
||||
];
|
||||
const inspiration = await Promise.all(
|
||||
inspirationTopics.map(async (topic) => {
|
||||
const article = await generateOrFetchArticle(topic); // LLM или партнёрский API
|
||||
return { title: article.title, summary: article.summary, image: article.image, url: article.url };
|
||||
})
|
||||
);
|
||||
await redis.setex('travel:inspiration', 6 * 60 * 60, JSON.stringify(inspiration));
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 4. Поиск (Search / Chat)
|
||||
|
||||
### Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ chat-svc POST /api/v1/chat │
|
||||
│ │
|
||||
│ 1. query_normalized = normalize(query) // lowercase, trim, etc. │
|
||||
│ 2. query_hash = sha256(query_normalized + mode + sources) │
|
||||
│ 3. Redis GET search:result:{query_hash} │
|
||||
│ 4. Если есть и не expired → отдать (stream из сохранённого или JSON) │
|
||||
│ 5. Если нет → полный pipeline → сохранить в Redis → отдать │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Redis схема
|
||||
|
||||
| Ключ | Значение | TTL |
|
||||
|------|----------|-----|
|
||||
| `search:result:{query_hash}` | `{ text, sources, widgets }` | 1 h (Quick) / 24 h (Pro, если low churn) |
|
||||
|
||||
### UX при Pro/Deep
|
||||
- AssistantSteps: отображение этапов (Classifier → Researcher → Writer); оценка времени
|
||||
|
||||
### Pre-warm популярных запросов
|
||||
|
||||
cache-worker раз в час:
|
||||
1. Анализ логов/метрик: топ-50 запросов за последние 24ч (без user_id, только query)
|
||||
2. Для каждого: проверка кэша, если нет — выполнить pipeline, сохранить
|
||||
|
||||
---
|
||||
|
||||
## 5. Медиа (Images, Videos)
|
||||
|
||||
```
|
||||
query_hash = sha256(search_query)
|
||||
Redis: media:images:{query_hash}, media:videos:{query_hash}
|
||||
TTL: 1 h
|
||||
```
|
||||
|
||||
Одинаковые запросы на картинки/видео отдаются из кэша.
|
||||
|
||||
### UX
|
||||
- Skeleton grid; timeout 15 с; Retry при ошибке
|
||||
|
||||
---
|
||||
|
||||
## 6. Виджеты
|
||||
|
||||
| Виджет | Ключ кэша | TTL |
|
||||
|--------|-----------|-----|
|
||||
| Погода | `widget:weather:{location}` | 15 min |
|
||||
| Акции | `widget:stock:{ticker}` | 5 min |
|
||||
| Калькулятор | **Не кэшируем** — на клиенте |
|
||||
|
||||
---
|
||||
|
||||
## 7. Реализация cache-worker
|
||||
|
||||
### Задачи (tasks)
|
||||
|
||||
```typescript
|
||||
// cache-worker/src/tasks/discover.ts
|
||||
export async function runDiscoverPrecompute(redis: Redis) {
|
||||
const topics = ['tech', 'finance', 'travel', 'world', 'science'];
|
||||
for (const topic of topics) {
|
||||
const items = await aggregateNews(topic);
|
||||
const summarized = await summarizeBatch(items); // batch LLM call
|
||||
await redis.setex(
|
||||
`discover:${topic}`,
|
||||
30 * 60, // 30 min
|
||||
JSON.stringify({ items: summarized, updated_at: Date.now() })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// cache-worker/src/tasks/finance.ts
|
||||
export async function runFinancePrecompute(redis: Redis) {
|
||||
const summary = await fetchMarketSummary();
|
||||
await redis.setex('finance:summary', 5 * 60, JSON.stringify(summary));
|
||||
|
||||
const heatmap = await fetchHeatmap();
|
||||
await redis.setex('finance:heatmap', 5 * 60, JSON.stringify(heatmap));
|
||||
|
||||
const topTickers = ['AAPL', 'TSLA', 'GOOGL', 'MSFT', ...];
|
||||
for (const ticker of topTickers) {
|
||||
const news = await fetchNewsForTicker(ticker);
|
||||
const summarized = await summarizeNews(news);
|
||||
await redis.setex(
|
||||
`finance:news:${ticker}`,
|
||||
15 * 60,
|
||||
JSON.stringify(summarized)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// cache-worker/src/tasks/travel.ts
|
||||
export async function runTravelPrecompute(redis: Redis) {
|
||||
const trending = await fetchTrendingDestinations();
|
||||
await redis.setex('travel:trending', 6 * 60 * 60, JSON.stringify(trending));
|
||||
}
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
cache-worker --task=discover # только discover
|
||||
cache-worker --task=finance # только finance
|
||||
cache-worker --task=travel # trending + Inspiration Cards
|
||||
cache-worker --task=all # все задачи
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Метрики кэширования
|
||||
|
||||
| Область | Снижение LLM вызовов |
|
||||
|---------|----------------------|
|
||||
| Discover | ~60–80% |
|
||||
| Finance | ~60–80% |
|
||||
| Search | ~30–50% |
|
||||
212
docs/architecture/04-pages-logic-verification.md
Normal file
212
docs/architecture/04-pages-logic-verification.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# Сверка логики страниц с Perplexity.ai
|
||||
|
||||
Соответствие архитектуры структуре Perplexity.ai (фев 2026).
|
||||
|
||||
---
|
||||
|
||||
## 1. Карта страниц Perplexity.ai
|
||||
|
||||
| URL | Страница | Описание (фактическая логика) |
|
||||
|-----|----------|-------------------------------|
|
||||
| `/` | Home | Главная: поисковая строка + виджеты discover/новости |
|
||||
| `/search` / `/search/new?q=` | Search | Поисковый чат, Quick/Pro/Deep modes |
|
||||
| `/c/[threadId]` | Chat/Thread | Окно конкретного чата/треда |
|
||||
| `/finance` | Finance | Финансы: рынок, heatmap, вкладки |
|
||||
| `/finance/[ticker]` | Ticker Detail | Детальная страница акции/индекса |
|
||||
| `/finance/predictions/[id]` | Predictions | Prediction markets (Polymarket) |
|
||||
| `/travel` | Travel | Путешествия: trending, inspiration, отели |
|
||||
| `/discover` | Discover | Новости по темам (может быть часть Home) |
|
||||
| `/library` | Library | История поисков, сохранённое |
|
||||
| `/spaces` | Spaces | Список проектов/пространств |
|
||||
| `/spaces/templates` | Space Templates | Шаблоны Spaces |
|
||||
| `/collections/[id]` | Collections | Публичные коллекции (SEC, Buffett и т.д.) |
|
||||
| Profile/Settings | Account | Профиль, настройки, биллинг |
|
||||
|
||||
---
|
||||
|
||||
## 2. Finance (`/finance`) — детальная сверка
|
||||
|
||||
### Perplexity (фактически)
|
||||
| Элемент | Есть в Perplexity | Есть в архитектуре |
|
||||
|--------|-------------------|---------------------|
|
||||
| Вкладки: Crypto, Earnings, Predictions, Screener, Politicians Watchlist, Watchlist | ✅ | ✅ (roadmap 2.1) |
|
||||
| Index Movement (S&P Futures, NASDAQ Fut., Dow Futures, VIX) | ✅ | ✅ |
|
||||
| Market Summary + новости (обновление ~4 мин) | ✅ | ✅ |
|
||||
| S&P 500 Heatmap (секторы, акции) | ✅ | ✅ |
|
||||
| Recent Developments (новости с таймстампами) | ✅ | ✅ |
|
||||
| Popular Spaces for Finance Research (collections) | ✅ | ✅ **Collections** по категории, `GET /collections?category=finance` |
|
||||
| Standouts (акция с анализом) | ✅ | ✅ (roadmap 2.1) |
|
||||
| Create Watchlist | ✅ | ✅ |
|
||||
| Prediction Markets (Polymarket) | ✅ | ✅ |
|
||||
| Gainers / Losers / Active | ✅ | ✅ |
|
||||
| Equity Sectors | ✅ | ✅ |
|
||||
| Popular Cryptocurrencies | ✅ | ✅ |
|
||||
| Fixed Income (TIPS, Treasuries, Municipals) | ✅ | ✅ |
|
||||
| Источники: FMP, Unusual Whales, Quartr, Fiscal.ai, S&P Global | ✅ | ✅ (roadmap) |
|
||||
| Детальная страница тикера `/finance/AAPL` | ✅ | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 3. Travel (`/travel`) — детальная сверка
|
||||
|
||||
### Perplexity (фактически, 2025)
|
||||
| Элемент | Есть в Perplexity | Есть в архитектуре |
|
||||
|--------|-------------------|---------------------|
|
||||
| Trending Destinations (карточки с изображениями) | ✅ | ✅ |
|
||||
| Inspiration Cards (курируемые статьи) | ✅ | ✅ **travel:inspiration**, cache-worker, `GET /travel/inspiration` |
|
||||
| Поиск мест, генерация маршрутов | ✅ | ✅ |
|
||||
| Отели (Tripadvisor) | ✅ | ✅ |
|
||||
| Партнёрское бронирование (Selfbook) | ✅ | ✅ Tripadvisor, Selfbook в 01-perplexity-analogue-design |
|
||||
| Answer Modes — Travel vertical | ✅ | ✅ **answerMode: 'travel'** в chat-svc, отдельный системный промпт |
|
||||
| Stepper UI (Поиск → Места → Маршрут → Отели → Билеты) | ? | ✅ |
|
||||
| Агентский ассистент (реал-тайм) | ✅ | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 4. Discover / Home
|
||||
|
||||
### Perplexity
|
||||
- **Home** — поиск + виджеты (discover-лента новостей по темам).
|
||||
- **Discover** может быть отдельной страницей или встроена в Home.
|
||||
|
||||
### Архитектура
|
||||
- discover-svc, GET /discover?topic=
|
||||
- Home: виджеты discover/news
|
||||
- Pre-compute, Redis кэш
|
||||
|
||||
---
|
||||
|
||||
## 5. Spaces / Projects / Collections
|
||||
|
||||
### Perplexity
|
||||
| Концепт | Описание |
|
||||
|--------|----------|
|
||||
| **Spaces** | Приватные/шарируемые проекты, файлы, чаты |
|
||||
| **Collections** | Публичные шаблоны (SEC Findings, Buffett letters, S&P 500 Transcripts) |
|
||||
| **Space Templates** | Готовые Spaces под финансы, маркетинг, продукт, travel |
|
||||
|
||||
### Архитектура
|
||||
- Projects/Spaces
|
||||
- Space Templates
|
||||
- Collections: projects-svc, GET /collections?category=, GET /collections/:id
|
||||
|
||||
---
|
||||
|
||||
## 6. Library
|
||||
|
||||
### Perplexity
|
||||
- История поисков
|
||||
- Сохранённое (saved threads?)
|
||||
|
||||
### Архитектура
|
||||
- Гости: localStorage/IndexedDB, при закрытии теряется
|
||||
- Аккаунты: library-svc, PostgreSQL, синхронизация тредов
|
||||
|
||||
---
|
||||
|
||||
## 7. Profile / Account
|
||||
|
||||
### Perplexity
|
||||
- Account, Preferences, Personalize, Billing, Connectors
|
||||
- Appearance, Language, Autosuggest, Homepage widgets
|
||||
- My Connectors (интеграции)
|
||||
|
||||
### Архитектура
|
||||
- Профиль, биллинг
|
||||
- Preferences: localStorage (гости) + сервер (аккаунты)
|
||||
- My Connectors: GET/POST/DELETE /api/v1/connectors
|
||||
|
||||
---
|
||||
|
||||
## 8. Поиск (Search) и режимы
|
||||
|
||||
### Perplexity
|
||||
- **Quick Search** — быстрый ответ
|
||||
- **Pro Search** — многошаговый, прозрачные шаги
|
||||
- **Deep Research** — углублённый отчёт
|
||||
- **Focus** — режим без отвлечений
|
||||
- **Answer Modes** — Standard, Academic, Writing, etc. + вертикали (Travel)
|
||||
|
||||
### Архитектура
|
||||
- Quick, Pro, Deep Research
|
||||
- Answer Modes: Standard, Focus, Academic, Writing, Travel, Finance (answerMode в body)
|
||||
|
||||
---
|
||||
|
||||
## 9. Покрытие фич Perplexity 2025–2026
|
||||
|
||||
По данным [Perplexity Changelog](https://www.perplexity.ai/changelog/). Все перечисленные фичи **добавлены в архитектуру** (01, 02, [06-roadmap-specification](./06-roadmap-specification.md)).
|
||||
|
||||
### 9.1 Поиск и ответы ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Model Council** — запуск 3 моделей параллельно | ✅ §2.2.A, §5.14, фаза 7 (Max) |
|
||||
| **Step-by-step Learning** | ✅ chat-svc, learningMode, §2.2.A, §2.2.P, input bar «+» |
|
||||
| **Response preferences** | ✅ answerMode + responsePrefs в body, Preferences |
|
||||
| **Memory** | ✅ memory-svc, §2.2.K, GET/POST/DELETE /api/v1/memory |
|
||||
| **Input bar «+»** | ✅ UI: файлы, источники, режимы (Quick/Pro/Deep/Create/Learn) |
|
||||
|
||||
### 9.2 Генерация и Create ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Labs / Create** | ✅ create-svc, §2.2.L, POST /api/v1/create |
|
||||
| **Image generation** | ✅ create-svc, type: 'image' |
|
||||
| **Экспорт** | ✅ POST /api/v1/export, форматы xlsx/csv/md/pdf |
|
||||
|
||||
### 9.3 Finance ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Analyst ratings** | ✅ GET /api/v1/finance/analyst-ratings/:ticker |
|
||||
| **Auditable financials / SEC** | ✅ GET /api/v1/finance/sec-filings/:ticker |
|
||||
| **ETF Holdings** | ✅ GET /api/v1/finance/etf-holdings/:symbol |
|
||||
| **Heatmap hover** | ✅ GET /api/v1/finance/price-context/:ticker |
|
||||
| **Stock graphs** в ответах | ✅ finance-svc, §2.2.C |
|
||||
|
||||
### 9.4 Commerce и Shopping
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Instant Buy / PayPal** | Отложен (низкий приоритет) |
|
||||
| **Virtual Try On** | Отложен |
|
||||
| **Shopping** | Отложен |
|
||||
|
||||
### 9.5 Продукты и платформы ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Comet AI Browser** | Отдельный продукт, вне scope |
|
||||
| **Desktop app** | ✅ §1 карта страниц, фаза 6, Electron/Tauri |
|
||||
| **iOS / Android** | ✅ фаза 6, voice search |
|
||||
| **Chrome extension** | ✅ фаза 6 |
|
||||
| **Voice search** | ✅ §2.2.O, Web Speech API / native |
|
||||
| **Background Assistant** | ✅ §2.2.O.4, POST /api/v1/tasks, фаза 7 (Max) |
|
||||
|
||||
### 9.6 Образование ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Quizzes / Flashcards** | ✅ §2.2.P, Pro/Education |
|
||||
| **Education Pro** | ✅ roadmap 7.1 |
|
||||
|
||||
### 9.7 Прочие страницы ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Patents page** `/patents` | ✅ §2.2.M, GET /api/v1/patents, search-svc |
|
||||
| **Персональные хабы** | Коллекции по категории (расширяемо) |
|
||||
| **Export thread** | ✅ POST /library/threads/:id/export (PDF, MD) |
|
||||
| **Notifications** | ✅ notifications-svc, Web Push, Email, напоминания |
|
||||
| **PWA / Офлайн** | ✅ Service worker (Workbox), manifest, offline fallback |
|
||||
|
||||
### 9.8 Enterprise ✅
|
||||
|
||||
| Фича Perplexity | В архитектуре |
|
||||
|-----------------|---------------|
|
||||
| **Audit logs** | ✅ audit-svc, GET /api/v1/admin/audit-logs |
|
||||
| **Granular feature access** | ✅ §2.2.N |
|
||||
| **Domain-based sign-up** | ✅ auth-svc, §2.2.N |
|
||||
| **Usage guidelines** | ✅ §2.2.N |
|
||||
| **Enterprise Memory** | ✅ memory-svc, org_id |
|
||||
108
docs/architecture/05-gaps-and-best-practices.md
Normal file
108
docs/architecture/05-gaps-and-best-practices.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Production checklist и требования
|
||||
|
||||
## 0. Узкие места и митигации
|
||||
|
||||
| Область | Узкое место | Митигация (внедрено/требуется) |
|
||||
|---------|-------------|---------------------------------|
|
||||
| **Пользователь** | Холодный старт 5–30 с | Skeleton, timeout, Retry — см. §8 UI/UX |
|
||||
| **Пользователь** | Загрузка файлов 30–300 с | Прогресс по этапам + кнопка Cancel; pre-upload preview |
|
||||
| **Пользователь** | Гости: история теряется | Предупреждение при закрытии; CTA «Сохранить в аккаунт» |
|
||||
| **Пользователь** | Rate limit 300 Pro Search/день | 429 + предупреждение при 80%; предложение апгрейда |
|
||||
| **Инфраструктура** | SearXNG — единый инстанс | Очередь запросов в search-svc; при росте — пул инстансов |
|
||||
| **Инфраструктура** | cache-worker зависает | `activeDeadlineSeconds` во всех CronJob (5–20 мин) |
|
||||
| **Инфраструктура** | Redis/PostgreSQL без HA | Sentinel/Cluster и Read replica при масштабировании |
|
||||
| **Инфраструктура** | travel-svc без HPA | HPA 1–4 replicas добавлен в 02-k3s-microservices-spec |
|
||||
| **Функции** | Внешние API (LLM, FMP, TA) | Retry + circuit breaker; fallback при частичном сбое |
|
||||
|
||||
## 1. Инфраструктура
|
||||
|
||||
| Компонент | Helm chart | Namespace |
|
||||
|-----------|------------|-----------|
|
||||
| Redis | bitnami/redis | perplexica-infra |
|
||||
| PostgreSQL | bitnami/postgresql | perplexica-infra |
|
||||
| MinIO | bitnami/minio | perplexica-infra |
|
||||
| SearXNG | Deployment | perplexica-infra |
|
||||
|
||||
## 2. Secrets
|
||||
|
||||
- notifications-secrets (vapid_public, vapid_private, smtp_url)
|
||||
- redis-credentials (url)
|
||||
- db-credentials (url)
|
||||
- auth-secrets (jwt_secret)
|
||||
- llm-credentials (openai)
|
||||
- finance-keys (fmp)
|
||||
- travel-keys (tripadvisor)
|
||||
- yookassa-credentials (shop_id, secret)
|
||||
|
||||
## 3. Сетевые политики (NetworkPolicy)
|
||||
|
||||
- Ingress: только из ingress-controller
|
||||
- chat-svc → search-svc, Redis
|
||||
- cache-worker → Redis, discover-svc, finance-svc, travel-svc
|
||||
- Redis, PostgreSQL: без внешнего доступа
|
||||
|
||||
## 4. PodDisruptionBudget
|
||||
|
||||
Минимум 2 доступных пода для: chat-svc, search-svc.
|
||||
|
||||
## 5. Observability
|
||||
|
||||
- Prometheus: метрики `/metrics` из каждого сервиса
|
||||
- Grafana: дашборды
|
||||
- Structured JSON логи
|
||||
- OpenTelemetry/Jaeger: распределённые трейсы
|
||||
- Алерты: latency, error rate, availability
|
||||
|
||||
## 6. Резервирование и масштабирование
|
||||
|
||||
| Область | Решение |
|
||||
|---------|---------|
|
||||
| chat-svc | HPA, кэш по query_hash |
|
||||
| Redis | Sentinel / Cluster при росте |
|
||||
| PostgreSQL | Read replica, PgBouncer |
|
||||
| SearXNG | Очередь запросов в search-svc/media-svc; кэш media; при росте — пул инстансов |
|
||||
| cache-worker | Ограничение concurrency, batch size; `activeDeadlineSeconds` для защиты от зависаний |
|
||||
|
||||
## 7. Безопасность
|
||||
|
||||
- CORS: ограничить Access-Control-Allow-Origin
|
||||
- Rate limiting: API Gateway / Ingress
|
||||
- TLS (cert-manager / Let's Encrypt)
|
||||
- Retry + circuit breaker для внешних API (FMP, Tripadvisor, LLM)
|
||||
|
||||
## 8. UI/UX
|
||||
|
||||
| Компонент | Требование |
|
||||
|-----------|------------|
|
||||
| Discover, Finance, Travel | Skeleton при cold start; timeout; Retry |
|
||||
| Pro/Deep Search | Этапы (Classifier → Researcher → Writer); оценка времени |
|
||||
| Загрузка файлов | Прогресс по этапам: парсинг → chunking → эмбеддинги; кнопка Cancel; timeout 300 с |
|
||||
| Гости | Предупреждение при закрытии; CTA «Сохранить в аккаунт» для переноса истории |
|
||||
| Rate limit | 429 + предупреждение при 80% лимита; предложение апгрейда при достижении лимита |
|
||||
| Ошибки | Сообщение + Retry/Cancel |
|
||||
| Travel Stepper | Сохранение состояния; skeleton между шагами |
|
||||
| Медиа | Skeleton grid; 15 с timeout |
|
||||
|
||||
## 9. Чек-лист развёртывания
|
||||
|
||||
- [ ] Ingress path-based routing
|
||||
- [ ] Probes /health, /ready во всех сервисах
|
||||
- [ ] HPA: chat-svc, search-svc, discover-svc, finance-svc, travel-svc, upload-svc, memory-svc
|
||||
- [ ] Redis, PostgreSQL, MinIO, SearXNG
|
||||
- [ ] Secrets
|
||||
- [ ] TLS
|
||||
- [ ] Rate limiting
|
||||
- [ ] Prometheus + алерты
|
||||
- [ ] Backup PostgreSQL, MinIO
|
||||
- [ ] PDB для chat-svc, search-svc
|
||||
- [ ] Runbook оператора
|
||||
- [ ] UI/UX: skeleton, timeout, rate limit feedback, guest warning, file upload progress+cancel
|
||||
|
||||
## 10. Ссылки (внутри architecture)
|
||||
|
||||
- [04-pages-logic-verification.md §9](./04-pages-logic-verification.md#9-покрытие-фич-perplexity-20252026) — покрытие vs Perplexity 2026
|
||||
- [06-roadmap-specification.md](./06-roadmap-specification.md) — roadmap и спеки фич
|
||||
- [01-perplexity-analogue-design.md](./01-perplexity-analogue-design.md)
|
||||
- [02-k3s-microservices-spec.md](./02-k3s-microservices-spec.md)
|
||||
- [03-cache-and-precompute-strategy.md](./03-cache-and-precompute-strategy.md)
|
||||
- [04-pages-logic-verification.md](./04-pages-logic-verification.md)
|
||||
63
docs/architecture/06-roadmap-specification.md
Normal file
63
docs/architecture/06-roadmap-specification.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Roadmap и спецификация фич
|
||||
|
||||
**docs/architecture — самодостаточный проект.** Все спеки фич находятся здесь. Порядок реализации — в [01-perplexity-analogue-design.md §6](./01-perplexity-analogue-design.md#6-порядок-реализации-best-practices).
|
||||
|
||||
---
|
||||
|
||||
## 1. Спецификация фич (детали)
|
||||
|
||||
Все пункты определены в [01-perplexity-analogue-design.md](./01-perplexity-analogue-design.md), [02-k3s-microservices-spec.md](./02-k3s-microservices-spec.md), [04-pages-logic-verification.md §9](./04-pages-logic-verification.md#9-покрытие-фич-perplexity-20252026).
|
||||
|
||||
### 1.1 Memory (memory-svc)
|
||||
- **Сервис:** memory-svc, порт 3010
|
||||
- **Хранение:** PostgreSQL (user_id, org_id, key, value, embedding)
|
||||
- **API:** GET/POST/DELETE /api/v1/memory
|
||||
- **Фаза:** 5
|
||||
|
||||
### 1.2 Create / Labs (create-svc)
|
||||
- **API:** POST /api/v1/create, POST /api/v1/export
|
||||
- **Фаза:** 5
|
||||
|
||||
### 1.3 Finance расширения
|
||||
- analyst-ratings, sec-filings, etf-holdings, price-context
|
||||
- **Фаза:** 5
|
||||
|
||||
### 1.4 Patents, Enterprise, Step-by-step Learning
|
||||
- **Фаза:** 5–6
|
||||
|
||||
### 1.5 Export thread
|
||||
- **API:** POST /api/v1/library/threads/:id/export?format=pdf|md
|
||||
- **Фаза:** 7
|
||||
|
||||
### 1.6 Notifications (notifications-svc)
|
||||
- **Сервис:** notifications-svc, порт 3013
|
||||
- **Web Push, Email, напоминания**
|
||||
- **Фаза:** 7
|
||||
|
||||
### 1.7 PWA / Офлайн
|
||||
- Service worker (Workbox), manifest, offline fallback
|
||||
- **Фаза:** 7
|
||||
|
||||
### 1.8 Model Council (Max)
|
||||
- modelCouncil: true в POST /api/v1/chat
|
||||
- **Фаза:** 7
|
||||
|
||||
### 1.9 Background Assistant (Max)
|
||||
- POST /api/v1/tasks, GET /api/v1/tasks/:id
|
||||
- **Фаза:** 7
|
||||
|
||||
---
|
||||
|
||||
## 2. Связь с functional-inventory
|
||||
|
||||
**docs/functional-inventory** — описание **текущего** кода Perplexica (инвентаризация).
|
||||
**docs/architecture** — целевая архитектура (что строить).
|
||||
|
||||
При миграции можно сопоставлять 01-api-routes → новые сервисы, 05-agents → Mastra и т.д. Правки в architecture **не требуют** правок в functional-inventory.
|
||||
|
||||
---
|
||||
|
||||
## Ссылки
|
||||
|
||||
- [Perplexity Changelog](https://www.perplexity.ai/changelog/)
|
||||
- [ЮKassa](https://yookassa.ru/developers/payments/recurring-payments)
|
||||
@@ -1,406 +0,0 @@
|
||||
# Архитектура микросервисов GooSeek
|
||||
|
||||
Документ описывает план разбиения монолитного приложения GooSeek на микросервисы.
|
||||
|
||||
---
|
||||
|
||||
## 1. Текущая архитектура (монолит)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Next.js Application (monolith) │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ API Routes │ Agents/Search │ Models/Providers │ Data │
|
||||
│ /api/chat │ classifier │ OpenAI, Anthropic │ SQLite│
|
||||
│ /api/search │ researcher │ Ollama, Groq... │ config│
|
||||
│ /api/images │ widgets │ registry │ uploads│
|
||||
│ /api/videos │ writer │ │ │
|
||||
│ /api/uploads │ media (image/video) │ │ │
|
||||
│ /api/chats │ │ │ │
|
||||
│ /api/providers │ │ │ │
|
||||
│ /api/config │ │ │ │
|
||||
│ /api/suggestions │ │ │ │
|
||||
│ /api/weather │ │ │ │
|
||||
│ /api/discover │ │ │ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ External: SearXNG │ Yahoo Finance │ Open-Meteo │ LLM APIs (OpenAI, etc.) │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Предлагаемые микросервисы
|
||||
|
||||
### 2.1 Общая схема
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ Frontend │────▶│ Gateway │────▶│ Chat │────▶│ Research │
|
||||
│ (Next.js) │ │ (BFF/API) │ │ Service │ │ Service │
|
||||
└──────────────┘ └──────────────┘ └──────┬───────┘ └──────┬───────┘
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ ▼
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ │ Config/Chats │ │ LLM Proxy │ │ Search │
|
||||
└────────────▶│ Service │ │ Service │ │ Service │
|
||||
└──────────────┘ └──────────────┘ └──────┬───────┘
|
||||
│ │ │
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ Storage │ │ Providers │ │ Uploads │
|
||||
│ Service │ │ (external) │ │ Service │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Описание сервисов
|
||||
|
||||
### 3.1 Frontend (Next.js UI)
|
||||
|
||||
**Назначение:** Только UI — страницы, компоненты, клиентский state.
|
||||
|
||||
**Содержимое:**
|
||||
- `src/app/page.tsx`, `layout.tsx`, маршруты страниц
|
||||
- `src/components/` — все UI компоненты
|
||||
- `src/lib/hooks/` — клиентские хуки
|
||||
- `src/lib/actions.ts` — вызовы к Gateway API
|
||||
|
||||
**Исключить:** Все API routes (`src/app/api/`), серверная логика агентов, прямые вызовы DB.
|
||||
|
||||
**API:** Вызывает только Gateway.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Gateway (Backend-for-Frontend / API Gateway)
|
||||
|
||||
**Назначение:** Единая точка входа для клиента, роутинг, валидация, агрегация.
|
||||
|
||||
**Реализация:** Отдельный Node.js сервис (Fastify/Express) или часть Next.js API routes, которая только проксирует.
|
||||
|
||||
**Маршруты:**
|
||||
- `POST /api/chat` → Chat Service
|
||||
- `POST /api/search` → Chat Service (API mode)
|
||||
- `GET/POST /api/chats/*` → Storage Service
|
||||
- `POST /api/uploads` → Uploads Service
|
||||
- `GET/POST /api/providers/*` → Config + LLM Proxy
|
||||
- `GET/POST /api/config/*` → Storage Service (config)
|
||||
- `POST /api/suggestions` → Chat Service
|
||||
- `POST /api/images` → Chat/Media Service
|
||||
- `POST /api/videos` → Chat/Media Service
|
||||
- `GET /api/weather` → Widgets Service (или inline)
|
||||
- `POST /api/discover` → Search Service
|
||||
|
||||
**Зависимости:** Chat, Storage, Uploads, Search. Не содержит бизнес-логики.
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Chat Service (Оркестратор)
|
||||
|
||||
**Назначение:** Главный оркестратор диалога: классификация, планирование, вызов research и writer.
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/agents/search/index.ts` — SearchAgent
|
||||
- `src/lib/agents/search/api.ts` — APISearchAgent
|
||||
- `src/lib/agents/search/classifier.ts`
|
||||
- `src/lib/agents/search/widgets/` — executor + виджеты (weather, stock, calc)
|
||||
- `src/lib/prompts/search/` — classifier, writer, researcher prompts
|
||||
- `src/lib/session.ts`
|
||||
|
||||
**API (внутренние):**
|
||||
- `POST /classify` — классификация запроса
|
||||
- `POST /search` — полный пайплайн (classify → research → widgets → write)
|
||||
- `POST /suggestions` — генерация подсказок
|
||||
|
||||
**Вызывает:**
|
||||
- Research Service — для поиска
|
||||
- LLM Proxy — для LLM вызовов (classify, write, suggestions)
|
||||
- Widgets (внешние API: Yahoo Finance, погода) — можно вынести в отдельный сервис
|
||||
|
||||
**Поток данных:**
|
||||
1. Классификация (LLM)
|
||||
2. Параллельно: Research Service + виджеты
|
||||
3. Генерация ответа (LLM)
|
||||
4. Сохранение в Storage (через Gateway или напрямую)
|
||||
|
||||
---
|
||||
|
||||
### 3.4 Research Service
|
||||
|
||||
**Назначение:** Выполнение исследовательского цикла — tools (web, academic, social, scrape, uploads).
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/agents/search/researcher/` — Researcher, ActionRegistry
|
||||
- `src/lib/agents/search/researcher/actions/` — webSearch, academicSearch, socialSearch, scrapeURL, uploadsSearch, plan, done
|
||||
- `src/lib/prompts/search/researcher.ts`
|
||||
|
||||
**API:**
|
||||
- `POST /research` — вход: classification, query, chatHistory, config → выход: searchFindings, findings
|
||||
|
||||
**Вызывает:**
|
||||
- Search Service — SearXNG (web, academic, social)
|
||||
- Uploads Service — семантический поиск по файлам
|
||||
- LLM Proxy — для researcher agent (tool calls)
|
||||
- Внешние URL — scrape
|
||||
|
||||
**Важно:** Researcher — это LLM-driven agent с tool calls. LLM решает, какой tool вызвать. Либо LLM живёт в Chat Service и вызывает tools по HTTP, либо Research Service сам держит копию researcher LLM — тогда нужно дублировать LLM-вызовы.
|
||||
|
||||
**Рекомендация:** Оставить researcher внутри Chat Service, а в Research Service вынести только **действия** (web search, scrape, uploads search) как отдельные HTTP endpoints. Chat Service вызывает Research Service по каждому tool call. Это уменьшает связанность, но увеличивает сетевые вызовы.
|
||||
|
||||
**Альтернатива:** Research как один сервис с LLM — получает query и classification, сам итерирует и возвращает готовые findings. Меньше round-trips, но дублирование LLM-инфраструктуры.
|
||||
|
||||
---
|
||||
|
||||
### 3.5 Search Service (SearXNG + обёртка)
|
||||
|
||||
**Назначение:** Обёртка над SearXNG для веб/академического/медиа поиска.
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/searxng.ts`
|
||||
- Вызовы: webSearch, academicSearch, socialSearch, image, video — все идут через `searchSearxng`
|
||||
|
||||
**API:**
|
||||
- `GET /search?q=...&engines=...&categories=...`
|
||||
- `GET /images?q=...`
|
||||
- `GET /videos?q=...`
|
||||
|
||||
**Внешняя зависимость:** SearXNG (уже отдельный сервис/контейнер).
|
||||
|
||||
**Реализация:** Минимальный Node.js/Fastify сервис, который проксирует к SearXNG и добавляет логику (rate limiting, fallback, кэш).
|
||||
|
||||
---
|
||||
|
||||
### 3.6 Uploads Service
|
||||
|
||||
**Назначение:** Загрузка файлов, парсинг (PDF, DOCX, TXT), эмбеддинги, семантический поиск.
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/uploads/manager.ts` — UploadManager
|
||||
- `src/lib/uploads/store.ts` — UploadStore (поиск по эмбеддингам)
|
||||
- `src/lib/utils/splitText.ts`, `computeSimilarity.ts`
|
||||
- Зависимости: pdf-parse, officeparser
|
||||
|
||||
**API:**
|
||||
- `POST /upload` — multipart, возвращает fileIds
|
||||
- `POST /search` — query, fileIds → chunks (семантический поиск)
|
||||
- `GET /files/:id` — метаданные файла
|
||||
|
||||
**Вызывает:** LLM Proxy — только для embedding модели (можно вынести в отдельный Embedding Service).
|
||||
|
||||
**Хранение:** Файлы на диске/volume, `uploaded_files.json`, `.content.json` с chunks.
|
||||
|
||||
---
|
||||
|
||||
### 3.7 Storage Service
|
||||
|
||||
**Назначение:** Централизованное хранилище: чаты, сообщения, конфигурация.
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/db/` — schema, migrations, drizzle
|
||||
- `src/lib/config/` — ConfigManager, modelProviders
|
||||
|
||||
**API:**
|
||||
- `GET/POST/PUT/DELETE /chats`
|
||||
- `GET/POST/PUT/DELETE /chats/:id`
|
||||
- `GET/POST/PUT/DELETE /messages`
|
||||
- `GET/POST /config`
|
||||
- `GET/POST /config/providers`
|
||||
|
||||
**База:** SQLite (или PostgreSQL при масштабировании). config.json можно мигрировать в ту же БД или отдельную таблицу.
|
||||
|
||||
---
|
||||
|
||||
### 3.8 LLM Proxy Service (опционально)
|
||||
|
||||
**Назначение:** Единая точка для вызовов LLM и embedding — OpenAI, Anthropic, Ollama, Groq, Gemini и т.д.
|
||||
|
||||
**Исходники:**
|
||||
- `src/lib/models/` — registry, providers, base LLM/Embedding
|
||||
|
||||
**API:**
|
||||
- `POST /chat` — text generation (streaming)
|
||||
- `POST /embed` — embedding
|
||||
- `GET /providers` — список провайдеров и моделей
|
||||
|
||||
**Конфигурация:** Берёт из Storage Service (config/providers) или env.
|
||||
|
||||
**Альтернатива:** LLM Proxy можно не выделять в отдельный сервис — каждый сервис (Chat, Research, Uploads) сам подключается к провайдерам. Но тогда дублирование кода и конфигурации. Рекомендуется вынести в общую библиотеку или отдельный сервис.
|
||||
|
||||
---
|
||||
|
||||
### 3.9 Geo Device Service (реализован)
|
||||
|
||||
**Назначение:** Определение геопозиции пользователя, типа устройства, браузера и ОС.
|
||||
|
||||
**Расположение:** `apps/geo-device-service/`
|
||||
|
||||
**API:**
|
||||
- `GET /api/context` — контекст по IP и заголовкам (User-Agent, Accept-Language)
|
||||
- `POST /api/context` — контекст с дополнительными данными от клиента (screen, timezone, Geolocation API)
|
||||
|
||||
**Данные:**
|
||||
- **geo** — latitude, longitude, city, country, timezone (geoip-lite по IP или из body)
|
||||
- **device** — type (desktop/mobile/tablet), vendor, model
|
||||
- **browser** — name, version (ua-parser-js)
|
||||
- **os** — name, version
|
||||
- **client** — screenWidth, viewportHeight, timezone, language, hardwareConcurrency, deviceMemory, doNotTrack (из POST body)
|
||||
|
||||
**Запуск:** `npm run dev:geo` или `PORT=4002 npm run start -w geo-device-service`
|
||||
|
||||
**Интеграция:** Frontend вызывает `/api/geo-context` (проксирует к сервису), клиент — `fetchContextWithClient()` из `@/lib/geoDevice`.
|
||||
|
||||
---
|
||||
|
||||
### 3.10 Localization Service (реализован)
|
||||
|
||||
**Назначение:** Локализация на основе геопозиции. Определяет locale (язык) пользователя по данным из Geo Device Service.
|
||||
|
||||
**Расположение:** `apps/localization-service/`
|
||||
|
||||
**Зависимость:** Geo Device Service (вызывает `/api/context` для получения countryCode, client.language, Accept-Language).
|
||||
|
||||
**API:**
|
||||
- `GET /api/locale` — resolve locale по IP/заголовкам (гео через geo-device-service)
|
||||
- `POST /api/locale` — resolve locale с client data (screen, language, geo)
|
||||
- `GET /api/translations/:locale` — переводы для UI
|
||||
- `GET /api/locales` — список поддерживаемых локалей
|
||||
|
||||
**Данные (LocalizationContext):**
|
||||
- **locale** — BCP 47 language code (ru, en, de, ...)
|
||||
- **source** — geo | accept-language | client | fallback
|
||||
|
||||
**Приоритет определения locale:**
|
||||
1. client.language (браузер navigator.language)
|
||||
2. Accept-Language заголовок
|
||||
3. countryCode из геопозиции
|
||||
4. fallback: en
|
||||
|
||||
**Запуск:** `npm run dev:locale` или `PORT=4003 npm run start -w localization-service`
|
||||
|
||||
**Конфигурация:** `GEO_DEVICE_SERVICE_URL` — URL geo-device-service (по умолчанию http://localhost:4002)
|
||||
|
||||
**Интеграция:** Frontend вызывает `/api/locale`, `/api/translations/[locale]` (проксирует к сервису), клиент — `fetchLocaleWithClient()`, `fetchTranslations()` из `@/lib/localization`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Матрица зависимостей
|
||||
|
||||
| Сервис | От кого получает вызовы | Кого вызывает |
|
||||
|----------------|----------------------------------|----------------------------------|
|
||||
| Gateway | Frontend | Chat, Storage, Uploads, Search |
|
||||
| Localization | Frontend | Geo Device Service |
|
||||
| Geo Device | Frontend, Localization | — |
|
||||
| Chat | Gateway | Research, LLM Proxy, Storage |
|
||||
| Research | Chat | Search, Uploads, LLM Proxy |
|
||||
| Search | Research, Chat (media) | SearXNG (внешний) |
|
||||
| Uploads | Gateway, Research | LLM Proxy (embedding) |
|
||||
| Storage | Gateway, Chat | — |
|
||||
| LLM Proxy | Chat, Research, Uploads | OpenAI, Anthropic, Ollama... |
|
||||
|
||||
---
|
||||
|
||||
## 5. Разбиение по репозиториям/папкам
|
||||
|
||||
### Вариант A: Монорепо (рекомендуется для старта)
|
||||
|
||||
```
|
||||
gooseek/
|
||||
├── apps/
|
||||
│ ├── frontend/ # Next.js UI
|
||||
│ ├── gateway/ # BFF / API Gateway
|
||||
│ ├── chat-service/ # SearchAgent, classifier, writer, widgets
|
||||
│ ├── research-service/ # Researcher, actions
|
||||
│ ├── search-service/ # SearXNG wrapper
|
||||
│ ├── uploads-service/ # UploadManager, UploadStore
|
||||
│ ├── storage-service/ # DB, config
|
||||
│ ├── llm-proxy/ # Models registry, providers
|
||||
│ ├── geo-device-service/ # Геопозиция, устройство, браузер
|
||||
│ ├── localization-service/ # Локализация (зависит от geo-device)
|
||||
│ ├── shared-types/ # Общие типы, DTO
|
||||
│ └── shared-utils/ # formatHistory, splitText, computeSimilarity
|
||||
├── docker-compose.yaml
|
||||
└── package.json # Turborepo/nx workspace
|
||||
```
|
||||
|
||||
### Вариант B: polyrepo
|
||||
|
||||
Отдельные репозитории для каждого сервиса. Больше гибкости в деплое, но сложнее координация изменений.
|
||||
|
||||
---
|
||||
|
||||
## 6. Порядок миграции (фазы)
|
||||
|
||||
### Фаза 1: Выделение Search Service
|
||||
- Обернуть SearXNG в отдельный сервис
|
||||
- Chat/Research вызывают его по HTTP вместо прямого импорта `searchSearxng`
|
||||
- **Риск:** Низкий. SearXNG уже внешний.
|
||||
|
||||
### Фаза 2: Выделение Storage Service
|
||||
- Вынести DB + config в отдельный сервис
|
||||
- Gateway и Chat переходят на HTTP к Storage
|
||||
- **Риск:** Средний. Много точек входа в DB.
|
||||
|
||||
### Фаза 3: Выделение Uploads Service
|
||||
- Вынести UploadManager + UploadStore
|
||||
- Research (uploadsSearch action) и Gateway вызывают Uploads по HTTP
|
||||
- **Риск:** Средний. Embedding модель — зависимость.
|
||||
|
||||
### Фаза 4: Выделение LLM Proxy
|
||||
- Общая обёртка над провайдерами
|
||||
- Chat, Research, Uploads вызывают LLM Proxy
|
||||
- **Риск:** Высокий. Много мест используют LLM напрямую.
|
||||
|
||||
### Фаза 5: Выделение Research Service
|
||||
- Researcher + actions в отдельный сервис
|
||||
- Chat вызывает Research по одному endpoint «проведи исследование»
|
||||
- **Риск:** Высокий. Тесная связь с Session, streaming.
|
||||
|
||||
### Фаза 6: Gateway + развязка Frontend
|
||||
- Frontend только UI, все вызовы через Gateway
|
||||
- Gateway — тонкий роутер без бизнес-логики
|
||||
- **Риск:** Средний. Рефакторинг API routes.
|
||||
|
||||
---
|
||||
|
||||
## 7. Ключевые вызовы и риски
|
||||
|
||||
1. **Streaming:** Текущий chat stream идёт от SearchAgent до клиента. При разбиении нужно решить: стримить через Gateway (proxy) или от Chat Service напрямую (WebSocket/SSE через Gateway как туннель).
|
||||
|
||||
2. **Session/state:** SessionManager — in-memory. При масштабировании Chat Service нужен Redis или аналог для shared state.
|
||||
|
||||
3. **Латентность:** Каждый HTTP hop добавляет ~10–50ms. Research делает много итераций — если Research в отдельном сервисе, round-trips умножаются.
|
||||
|
||||
4. **Embedding в Uploads:** Uploads нужна embedding модель. Варианты: вызывать LLM Proxy, или держать тяжёлую модель (transformers) внутри Uploads.
|
||||
|
||||
5. **Конфигурация:** Сейчас config.json на диске. При микросервисах — централизованный config (env, vault, или Storage Service).
|
||||
|
||||
---
|
||||
|
||||
## 8. Минимальный MVP разбиения
|
||||
|
||||
Если цель — не полный microservices, а **модульность и возможность деплоить части отдельно**:
|
||||
|
||||
| Сервис | Код | Отдельный процесс |
|
||||
|---------------|-----------------------------|-------------------|
|
||||
| **search-api**| `searxng.ts` + route | Да (отдельный порт) |
|
||||
| **uploads-api**| `uploads/` + route | Да |
|
||||
| **chat** | Всё остальное (agents, LLM, DB) | Один процесс |
|
||||
| **frontend** | Next.js UI | Отдельно (static/SSR) |
|
||||
|
||||
Так получается 3–4 контейнера вместо 1, но без глубокой декомпозиции логики.
|
||||
|
||||
---
|
||||
|
||||
## 9. Следующие шаги
|
||||
|
||||
1. Определить: полное разбиение или MVP.
|
||||
2. Выбрать стек для каждого сервиса (Node.js/Fastify, Next.js API routes, Go и т.д.).
|
||||
3. Описать контракты API (OpenAPI/JSON Schema) для межсервисного взаимодействия.
|
||||
4. Настроить docker-compose для локальной разработки.
|
||||
5. Внедрить общие пакеты (shared-types, shared-utils) в монорепо.
|
||||
6. Начать с Фазы 1 (Search Service) как пилот.
|
||||
129
docs/architecture/MIGRATION.md
Normal file
129
docs/architecture/MIGRATION.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Миграция GooSeek на микросервисную архитектуру
|
||||
|
||||
**Ссылки:** [01-perplexity-analogue-design.md](./01-perplexity-analogue-design.md), [02-k3s-microservices-spec.md](./02-k3s-microservices-spec.md)
|
||||
|
||||
---
|
||||
|
||||
## Текущий статус
|
||||
|
||||
### Реализовано (Фаза 0–2)
|
||||
|
||||
| Компонент | Описание | Статус |
|
||||
|-----------|----------|--------|
|
||||
| **services/discover-svc** | Агрегация новостей, Redis кэш | ✅ |
|
||||
| **services/search-svc** | SearXNG proxy, кэш по query_hash | ✅ |
|
||||
| **services/finance-svc** | Market summary, heatmap, news (базово) | ✅ |
|
||||
| **services/travel-svc** | Trending, Inspiration (базово) | ✅ |
|
||||
| **services/cache-worker** | Pre-compute: discover, finance, travel | ✅ |
|
||||
| **Redis, PostgreSQL** | Локально или в K8s (см. deploy/k3s) | ✅ |
|
||||
| **api/v1/discover** | Прокси к discover-svc | ✅ |
|
||||
| **services/library-svc** | История тредов (PostgreSQL) | ✅ |
|
||||
| **services/projects-svc** | Collections, Spaces (заглушка) | ✅ |
|
||||
| **api/v1/library** | Прокси к library-svc | ✅ |
|
||||
| **api/v1/collections** | Прокси к projects-svc | ✅ |
|
||||
| **deploy/k3s/** | library-svc, projects-svc, chat-svc, ingress | ✅ |
|
||||
| **services/chat-svc** | LLM, Mastra, Writer, Classifier, Researcher | ✅ |
|
||||
| **api/chat** | При CHAT_SVC_URL проксирует на chat-svc | ✅ |
|
||||
| **services/auth-svc** | SSO, JWT, Bearer, GET /api/auth/me (миграция из apps/auth-mcs) | ✅ |
|
||||
| **services/memory-svc** | Персональная память AI, Enterprise Memory | ✅ |
|
||||
| **api/v1/memory** | Прокси к memory-svc | ✅ |
|
||||
| **services/create-svc** | Create (stub), Export PDF/MD | ✅ |
|
||||
| **api/v1/create, api/v1/export** | Прокси к create-svc | ✅ |
|
||||
| **finance-svc** | + analyst-ratings, sec-filings, etf-holdings (FMP) | ✅ |
|
||||
| **search-svc** | + GET /api/v1/patents (SearXNG) | ✅ |
|
||||
| **api/v1/patents** | Прокси к search-svc | ✅ |
|
||||
| **services/notifications-svc** | Web Push, preferences, reminders | ✅ |
|
||||
| **api/v1/notifications** | Прокси к notifications-svc | ✅ |
|
||||
| **services/billing-svc** | Тарифы Free/Pro/Max, ЮKassa, подписки | ✅ |
|
||||
| **api/v1/billing** | Прокси к billing-svc | ✅ |
|
||||
| **services/audit-svc** | Enterprise audit logs (stub) | ✅ |
|
||||
| **api/v1/admin/audit-logs** | Прокси к audit-svc | ✅ |
|
||||
| **страница /profile** | Account, Preferences, Personalize, Billing, Connectors | ✅ |
|
||||
| **services/auth-svc** | SSO, JWT, Bearer, GET /api/auth/me | ✅ |
|
||||
| **services/web-svc** | UI + прокси (миграция из apps/frontend) | ✅ |
|
||||
| **services/geo-device-svc** | Геопозиция, устройство | ✅ |
|
||||
| **services/localization-svc** | Локализация | ✅ |
|
||||
|
||||
### В разработке / запланировано
|
||||
|
||||
- **Миграция apps → services завершена:** auth-svc, web-svc, geo-device-svc, localization-svc в services/
|
||||
- **API Gateway** (Traefik/Kong) для production
|
||||
|
||||
### deploy/k3s — HPA и PDB
|
||||
|
||||
| Файл | Описание |
|
||||
|------|----------|
|
||||
| hpa.yaml | HPA для chat-svc, search-svc, discover-svc, finance-svc; PDB для chat, search |
|
||||
|
||||
---
|
||||
|
||||
## Запуск (только Kubernetes)
|
||||
|
||||
Развёртывание в Kubernetes (Docker Desktop → Settings → Kubernetes, не Docker-контейнеры):
|
||||
|
||||
```bash
|
||||
./deploy/k3s/deploy.sh
|
||||
```
|
||||
|
||||
Конфигурация сервисов: `deploy/k3s/deploy.config.yaml`. Миграции БД выполняются автоматически при деплое.
|
||||
|
||||
---
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
|------------|----------|--------------|
|
||||
| `REDIS_URL` | Redis connection string | `redis://localhost:6379` |
|
||||
| `SEARXNG_URL` | SearXNG instance | `https://searx.tiekoetter.com` |
|
||||
| `SEARXNG_FALLBACK_URL` | Доп. инстансы (через запятую) | — |
|
||||
| `DISCOVER_SVC_URL` | discover-svc (для frontend proxy) | `http://localhost:3002` |
|
||||
| `SEARCH_SVC_URL` | search-svc — при установке frontend вызывает его вместо прямого SearXNG | `http://localhost:3001` |
|
||||
| `CHAT_SVC_URL` | chat-svc — при установке /api/chat проксирует сюда | `http://localhost:3005` |
|
||||
| `MEMORY_SVC_URL` | memory-svc (персональная память AI) | `http://localhost:3010` |
|
||||
| `CREATE_SVC_URL` | create-svc (Create, Export) | `http://localhost:3011` |
|
||||
| `NOTIFICATIONS_SVC_URL` | notifications-svc (Web Push, reminders) | `http://localhost:3013` |
|
||||
| `BILLING_SVC_URL` | billing-svc (тарифы, подписки, ЮKassa) | `http://localhost:3008` |
|
||||
| `AUTH_SERVICE_URL` | auth-svc (Bearer validation) | `http://localhost:3014` |
|
||||
| `GHOST_URL`, `GHOST_CONTENT_API_KEY` | Ghost для topic=gooseek (discover-svc) | — |
|
||||
| `NEWS_REGION` | Регион новостей: america\|eu\|russia\|china\|auto | `auto` |
|
||||
| `FMP_API_KEY` | Financial Modeling Prep (finance summary, analyst-ratings, sec-filings, etf-holdings) | — |
|
||||
| `YOOKASSA_SHOP_ID`, `YOOKASSA_SECRET` | ЮKassa для billing-svc (оплата Pro/Max) | — |
|
||||
| `BILLING_RETURN_URL` | URL возврата после оплаты | `http://localhost:3000/profile?tab=billing` |
|
||||
| `POSTGRES_URL` | PostgreSQL (library-svc, memory-svc, notifications-svc, billing-svc) | `postgresql://gooseek:gooseek@localhost:5432/gooseek` |
|
||||
|
||||
---
|
||||
|
||||
## Сборка Docker-образов
|
||||
|
||||
```bash
|
||||
# discover-svc, search-svc, notifications-svc, auth-svc
|
||||
docker build -t gooseek/discover-svc:latest -f services/discover-svc/Dockerfile services/discover-svc
|
||||
docker build -t gooseek/search-svc:latest -f services/search-svc/Dockerfile services/search-svc
|
||||
docker build -t gooseek/notifications-svc:latest -f services/notifications-svc/Dockerfile services/notifications-svc
|
||||
docker build -t gooseek/auth-svc:latest -f services/auth-svc/Dockerfile services/auth-svc
|
||||
|
||||
# chat-svc, create-svc, billing-svc
|
||||
docker build -t gooseek/chat-svc:latest -f services/chat-svc/Dockerfile services/chat-svc
|
||||
docker build -t gooseek/create-svc:latest -f services/create-svc/Dockerfile services/create-svc
|
||||
docker build -t gooseek/billing-svc:latest -f services/billing-svc/Dockerfile services/billing-svc
|
||||
docker build -t gooseek/audit-svc:latest -f services/audit-svc/Dockerfile services/audit-svc
|
||||
```
|
||||
|
||||
## deploy/k3s — манифесты
|
||||
|
||||
| Файл | Описание |
|
||||
|------|----------|
|
||||
| search-svc.yaml | SearXNG proxy, Redis cache |
|
||||
| notifications-svc.yaml | Web Push, PostgreSQL, VAPID |
|
||||
| auth-svc.yaml | better-auth, namespace gooseek-auth, PVC |
|
||||
| discover-svc.yaml | + GHOST_URL, GHOST_CONTENT_API_KEY (optional) |
|
||||
| cache-worker.yaml | CronJob finance/discover/travel, activeDeadlineSeconds |
|
||||
| hpa.yaml | HPA + PDB для chat, search, discover, finance, travel, memory |
|
||||
| audit-svc.yaml | Enterprise audit logs |
|
||||
| ingress.yaml | + /api/v1/search, /api/v1/notifications, /api/v1/admin |
|
||||
|
||||
---
|
||||
|
||||
## Порядок реализации (roadmap)
|
||||
|
||||
См. [01-perplexity-analogue-design.md §6](./01-perplexity-analogue-design.md#6-порядок-реализации-best-practices).
|
||||
@@ -1,38 +1,30 @@
|
||||
# GooSeek Architecture
|
||||
# Архитектура аналога Perplexity.ai
|
||||
|
||||
GooSeek is a Next.js application that combines an AI chat experience with search.
|
||||
**Отдельный проект.** Документы самодостаточны; все спеки и roadmap — внутри этой папки.
|
||||
|
||||
For a high level flow, see [WORKING.md](WORKING.md). For deeper implementation details, see [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
||||
Целевая система для ~10 000 DAU с **полным совпадением** логики Perplexity.ai:
|
||||
- **ВСЁ в `services/`.** Папка `apps/` удаляется. Никаких app — только микросервисы.
|
||||
- Микросервисы в K3s (chat, search, discover, finance, travel, auth, library, memory, create, notifications, projects, cache-worker, web/frontend)
|
||||
- Максимум логики на клиенте; персональные данные только для аккаунтов
|
||||
- Предварительная обработка и кэширование (discover, finance, travel+inspiration, поиск)
|
||||
|
||||
## Key components
|
||||
## Документы
|
||||
|
||||
1. **User Interface**
|
||||
| Документ | Описание |
|
||||
|----------|----------|
|
||||
| [01-perplexity-analogue-design.md](./01-perplexity-analogue-design.md) | Карта функциональностей, микросервисы, стратегия кэша, порядок реализации |
|
||||
| [02-k3s-microservices-spec.md](./02-k3s-microservices-spec.md) | K3s манифесты, Deployment, Service, CronJob для каждого сервиса |
|
||||
| [03-cache-and-precompute-strategy.md](./03-cache-and-precompute-strategy.md) | Детальная стратегия кэширования: discover, finance, travel, search |
|
||||
| [04-pages-logic-verification.md](./04-pages-logic-verification.md) | Сверка логики страниц с Perplexity.ai — полное совпадение |
|
||||
| [05-gaps-and-best-practices.md](./05-gaps-and-best-practices.md) | Production checklist, требования инфраструктуры |
|
||||
| [06-roadmap-specification.md](./06-roadmap-specification.md) | Roadmap и спецификация фич (Memory, Create, Notifications и др.) |
|
||||
|
||||
- A web based UI that lets users chat, search, and view citations.
|
||||
## Быстрый старт
|
||||
|
||||
2. **API Routes**
|
||||
1. Прочитать `01-perplexity-analogue-design.md` для общего понимания
|
||||
2. Использовать `02-k3s-microservices-spec.md` для развёртывания
|
||||
3. Реализовать `cache-worker` и Redis по `03-cache-and-precompute-strategy.md`
|
||||
|
||||
- `POST /api/chat` powers the chat UI.
|
||||
- `POST /api/search` provides a programmatic search endpoint.
|
||||
- `GET /api/providers` lists available providers and model keys.
|
||||
## Отношение к functional-inventory
|
||||
|
||||
3. **Agents and Orchestration**
|
||||
|
||||
- The system classifies the question first.
|
||||
- It can run research and widgets in parallel.
|
||||
- It generates the final answer and includes citations.
|
||||
|
||||
4. **Search Backend**
|
||||
|
||||
- A meta search backend is used to fetch relevant web results when research is enabled.
|
||||
|
||||
5. **LLMs (Large Language Models)**
|
||||
|
||||
- Used for classification, writing answers, and producing citations.
|
||||
|
||||
6. **Embedding Models**
|
||||
|
||||
- Used for semantic search over user uploaded files.
|
||||
|
||||
7. **Storage**
|
||||
- Chats and messages are stored so conversations can be reloaded.
|
||||
**docs/functional-inventory** — описание **текущего** кода (инвентаризация). Используется только для справки при миграции. Правки в architecture **не требуют** правок в functional-inventory.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How GooSeek Works
|
||||
|
||||
This is a high level overview of how GooSeek answers a question.
|
||||
This is a high level overview of how Perplexica answers a question.
|
||||
|
||||
If you want a component level overview, see [README.md](README.md).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user