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:
home
2026-02-23 15:10:38 +03:00
parent 8fc82a3b90
commit cd6b7857ba
606 changed files with 26148 additions and 14297 deletions

View File

@@ -1,23 +1,144 @@
# Недоделки — начать отсюда
## Задача (исходный запрос)
Продолжить оптимизацию из AUDIT-PERFORMANCE.md и AGENTS.MD.
## Задача
Полная переделка сервиса GooSeek по документации docs/architecture (микросервисная архитектура аналога Perplexity.ai).
## Сделано
- Динамический import для pdf-parse в `manager.ts` — загрузка только при парсинге PDF
- Обновлён AUDIT-PERFORMANCE.md с отметками о выполненных пунктах
## Статус: миграция завершена ✅
## Осталось сделать (в порядке приоритета)
## 2025-02: SQLite → library-svc, api-gateway
- **Удалён SQLite** (web-svc, chat-svc): chats, messages — локальная история
- **library-svc расширен:** thread_messages, GET threads/:id, POST/PATCH messages, export PDF/MD
- **chat-svc:** сохранение в library-svc (при auth), SQLite удалён
- **api-gateway:** новый сервис на порту 3015, прокси всех /api/* на микросервисы
- **web-svc:** только UI, rewrites /api/* на api-gateway; config, providers — в chat-svc
- **media-svc (порт 3016):** images + videos — LLM rephrase, SearXNG/search-svc; api-gateway проксирует /api/images, /api/videos
- **suggestions-svc (порт 3017):** AI follow-up suggestions; api-gateway проксирует /api/suggestions
- **master-agents-svc (порт 3018):** Master Agent — адаптируется к задаче, автоматически выбирает инструменты (web_search, scrape_url, calculator, get_stock_quote, image_search)
1. **Миграция better-sqlite3 → libsql** — приоритет по audit (отложено).
- **Блокировщик:** `src/lib/db/migrate.ts` использует better-sqlite3 (sync API). Нужна полная переработка под async libsql перед миграцией db/index.ts.
- Файлы: `src/lib/db/index.ts`, `src/lib/db/migrate.ts`, `drizzle.config.ts`, `package.json`
- Шаги: переписать migrate.ts на createClient из @libsql/client, затем заменить в index.ts.
## Сделано (текущая сессия — web-svc только UI)
- **web-svc:** удалены папки agents, models, prompts, uploads, utils, config (server) — остался только UI
- **chat-svc:** GET/POST config, providers CRUD, models CRUD, POST /api/v1/uploads
- **travel-svc:** POST /api/v1/weather (proxy Open-Meteo)
- **api-gateway:** маршруты config, providers, uploads, weather
- **web-svc:** rewrites config/providers/weather → gateway; uploads — тонкий proxy к chat-svc; layout fetch config с gateway
2. **Опционально: pdf-parse в worker** — отложено из‑за Turbopack.
- Текущий подход (динамический import) уже снимает нагрузку со старта.
- Worker через child_process требует отдельный .cjs в известном path; Turbopack трассирует fork() и падает. Варианты: сборка с webpack для route uploads или вынос в отдельный Nodeсервис.
## Сделано (текущая сессия)
- **chat-svc → memory-svc:** при mode balanced/quality + Authorization — fetch GET /api/v1/memory, инжект memoryContext в writer prompt
- **Profile Personalize:** список AI Memory, Add (key+value), Delete; требует auth
- **web-svc chat proxy:** передача Authorization в chat-svc
- **useChat:** отправка Bearer token при запросе к /api/chat
- **My Connectors:** projects-svc GET/POST/DELETE /api/v1/connectors, Proxy, Profile UI (Google Drive, Dropbox coming soon)
- **Finance tabs:** Overview, Crypto, Gainers & Losers, Watchlist — finance-svc gainers/losers/crypto, localStorage watchlist
- **finance/[ticker] Add to watchlist:** кнопка ★, localStorage gooseek_finance_watchlist
- **Background Assistant (Max):** chat-svc POST/GET /api/v1/tasks (stub), web-svc proxy, ingress
- **finance-svc price-context:** GET /api/v1/finance/price-context/:ticker — LLM-синтез причины движения (OPENAI_API_KEY), fallback news+quote
- **Export thread:** GET /api/v1/library/threads/:id/export?format=pdf|md — web-svc route, данные из SQLite → create-svc
- **Navbar Export:** при наличии chatId — использует thread export API
- **create-svc POST /create:** table/dashboard — LLM генерация (gpt-4o-mini), image — 501
- **Страница /finance/[ticker]:** блок Price movement context (summary или news)
- **/metrics:** travel-svc, library-svc, memory-svc, create-svc — gooseek_up gauge; K3s Prometheus аннотации
- **Finance heatmap:** страница /finance — блок S&P 500 Sector Heatmap, fetch /api/v1/finance/heatmap
- **Finance-svc heatmap:** fetch с FMP api/v3/sector-performance при FMP_API_KEY
- **Collections на /finance:** Popular Spaces for Finance Research — fetch /api/v1/collections?category=finance
- **deploy/k3s/cache-worker.yaml:** CronJob finance (2m), discover (15m), travel (4h), activeDeadlineSeconds 300/600/1200
- **finance-svc:** fetchWithRetry для FMP API (3 попытки, backoff 500/1000/1500 ms)
- **docs/RUNBOOK.md:** Runbook оператора — health, Redis, cache-worker, типичные сбои, порты
- **Pro/Deep Search:** AssistantSteps — оценка времени ~3090 sec
- **K3s Prometheus:** аннотации prometheus.io/scrape, port, path в chat, search, discover, finance
- **CORS:** ALLOWED_ORIGINS в chat-svc, search-svc, discover-svc, finance-svc
- **Медиа:** SearchImages, SearchVideos — timeout 15s, error + Retry
- **Prometheus /metrics:** chat-svc, search-svc, discover-svc, finance-svc (gooseek_up gauge)
- **UI/UX:** DataFetchError + Retry; timeout 15s + Retry для Discover, Finance, Travel
- **File upload:** Cancel, timeout 300s, error handling в Attach и AttachSmall
- **HPA:** travel-svc, memory-svc добавлены в hpa.yaml
- **GuestWarningBanner:** предупреждение гостям, beforeunload, CTA «Save to account»
- **Rate limit 429:** toast в useChat при 429
- **/finance/predictions/[id]:** finance-svc stub API, страница (Polymarket coming soon)
- **deploy/k3s/hpa.yaml:** HPA для chat, search, discover, finance, travel, memory; PDB для chat, search
- **/spaces/templates:** projects-svc GET /api/v1/templates, страница, прокси, ingress
- **Health/ready probes:** web-svc `/api/health`, `/api/ready`; chat-svc `/ready`; K3s chat-svc readinessProbe → `/ready`
- **PWA:** @ducanh2912/next-pwa, Service worker (sw.js), offline fallback `/offline`, метаданные в layout, `next build --webpack`
- **Исправлен TS:** finance/[ticker] quote.high/quote.low optional
- **finance-svc:** GET /api/v1/finance/quote/:ticker (FMP quote)
- **Страница /finance/[ticker]:** котировка, новости, SEC filings
- **Страница /spaces:** список коллекций
- **Страница /collections/[id]:** детали коллекции
- **Sidebar:** Spaces, переводы nav.spaces
- **Удалён deprecated /api/discover** — дублировал discover-svc
- **Ghost** — опционально для Discover (topic=gooseek), см. docs
- **deploy/k3s:** search-svc.yaml, notifications-svc.yaml, auth-svc.yaml
- **Ingress:** /api/v1/search, /api/v1/notifications
- **discover-svc:** GHOST_URL, GHOST_CONTENT_API_KEY (optional Secret)
- **MIGRATION.md:** сборка образов search/auth/notifications
## Сделано (ранее)
- Микросервисы: discover, search, finance, travel, chat, memory, create, notifications, billing, auth, library, projects
- web-svc: UI + прокси к микросервисам
- deploy/k3s: манифесты, ingress
- apps/ удалён — всё в services/
## Сделано (текущая сессия)
- **Patents page:** DataFetchError компонент вместо кастомного error div (консистентность с Discover, Finance, Travel)
- **Model Council (Max):** параллельный запуск 3 моделей → синтез ответа
- chat-svc: modelCouncil, councilModels в body; councilLlms → SearchAgent
- SearchAgent: runCouncilWritersAndSynthesis — 3× generateText параллельно, synthesis prompt, stream синтеза
- writer.ts: getSynthesisPrompt
- web-svc: body schema, proxy, локальный agent с councilLlms
- useChat: modelCouncil + councilModels из localStorage (fallback: chatModel × 3)
- InputBarPlus: переключатель «Model Council» (Max)
## Сделано (последнее)
- **Input bar «+»:** меню режимов, источников, Learn, Create
- Кнопка «+» слева от Optimization — Popover с Mode (Quick/Pro/Deep), Sources (Web/Academic/Social), Step-by-step Learning, Create (подсказка)
- InputBarPlus в EmptyChatMessageInput
- **Inspiration Cards:** LLM в cache-worker (travel task)
- Курируемые темы → gpt-4o-mini → title+summary для 4 карточек
- Без OPENAI_API_KEY — fallback stub
- Redis travel:inspiration TTL 6h
- **create-svc image:** DALL·E 3 генерация изображений
- type: 'image' — вызов OpenAI /v1/images/generations (dall-e-3, 1024x1024, standard, vivid)
- Ответ: { type, url, b64?, format }
- Proxy timeout 120s для image
- **Step-by-step Learning:** learningMode в chat
- Preferences: switch «Step-by-step Learning» — объяснять пошагово, разбивать сложные концепции
- localStorage learningMode → body.learningMode → writer prompt block
- chat-svc, web-svc: learningMode в config, SearchAgentConfig, getWriterPrompt
- **Response preferences:** format, length, tone в chat
- Preferences: Response format (paragraph/bullets/outline), length (short/medium/long), tone (neutral/professional/casual/concise)
- localStorage → responsePrefs в body → writer prompt
- chat-svc, web-svc: responsePrefs в config и getWriterPrompt
- **travel-svc itinerary:** LLM-генерация маршрутов (gpt-4o-mini)
- POST /api/v1/travel/itinerary { query, days? } — Redis travel:itinerary:{hash} TTL 4h
- TravelStepper Route step: выбор длительности (114 дней), fetch itinerary, отображение по дням
- **Answer Mode: Travel (и finance, academic, writing):** вертикали ответа в чате
- chat-svc, web-svc: `answerMode` в body, SearchAgentConfig
- writer: travel/finance-специфичные блоки в системном промпте
- AnswerMode UI: селектор Standard | Travel | Finance | Academic | Writing | Focus
- URL: `?answerMode=travel` — автовыбор при переходе с /travel (карточки destinations)
- **Travel Stepper:** сохранение состояния между шагами (Поиск → Места → Маршрут → Отели → Билеты)
- travel-svc: POST/GET `/api/v1/travel/stepper/state`, Redis `travel:stepper:{sessionId}` TTL 24h
- TravelStepper компонент: модальное окно, шаги, persist в API + sessionStorage fallback
- Кнопка «Plan a trip» на /travel
- **NetworkPolicy:** `deploy/k3s/network-policies.yaml` — gooseek-allow-internal (inter-pod traffic)
## Сделано (profile-svc)
- **profile-svc (порт 3019):** личные данные и персонализация пользователя
- PostgreSQL: user_profiles (userId, displayName, avatarUrl, timezone, locale, profileData, preferences, personalization)
- GET/PATCH /api/v1/profile — требует Authorization Bearer
- Profile page: редактирование displayName, загрузка из profile-svc
- Settings: preferences и personalization сохраняются в profile-svc при auth (синхронизация между устройствами)
- api-gateway: маршрут /api/v1/profile → profile-svc
- deploy/k3s/profile-svc.yaml, deploy.config.yaml
## llm-svc (порт 3020)
- **llm-svc:** микросервис провайдеров LLM — единый источник для Ollama, OpenAI, Timeweb, Gemini и др.
- API: GET/POST/PATCH/DELETE /api/v1/providers, GET/POST/DELETE /api/v1/providers/:id/models
- chat-svc: при LLM_SVC_URL — получает провайдеров из llm-svc (config, ModelRegistry)
- api-gateway: /api/v1/providers → llm-svc
- deploy: llm-svc.yaml, deploy.config.yaml (llm-svc: false по умолчанию)
- В K8s: llm-svc деплоится через deploy.sh, LLM_SVC_URL задаётся в ConfigMap chat-svc
## Контекст для продолжения
- Изменённые файлы: `apps/frontend/src/lib/uploads/manager.ts`
- db используется в: `api/chat`, `api/chats`, `api/chats/[id]`, `lib/agents/search`
- Порты: discover 3002, search 3001, finance 3003, travel 3004, chat 3005, memory 3010, create 3011, notifications 3013, billing 3008, media 3016, suggestions 3017, master-agents 3018, profile 3019, llm 3020
- Ghost: опционально → http://localhost:2369, админка /ghost, Content API Key в .env
- Redis ключи: discover:{topic}, finance:summary, travel:trending, travel:stepper:{sessionId}, cache-worker