feat: travel service with 2GIS routing, POI, hotels + finance providers + UI overhaul
- Add travel-svc microservice (Amadeus, TravelPayouts, 2GIS, OpenRouteService) - Add travel orchestrator with parallel collectors (events, POI, hotels, flights) - Add 2GIS road routing with transport cost calculation (car/bus/taxi) - Add TravelMap (2GIS MapGL) and TravelWidgets components - Add useTravelChat hook for streaming travel agent responses - Add finance heatmap providers refactor - Add SearXNG settings, API proxy routes, Docker compose updates - Update Dockerfiles, config, types, and all UI pages for consistency Made-with: Cursor
This commit is contained in:
188
CONTINUE.md
188
CONTINUE.md
@@ -1,141 +1,87 @@
|
||||
# Недоделки — начать отсюда
|
||||
|
||||
## Последнее исправление (28.02.2026)
|
||||
## Последнее изменение (01.03.2026)
|
||||
|
||||
### Fix: auth-svc не собирался в Docker
|
||||
- Добавлена строка сборки `auth-svc` в `Dockerfile.all`
|
||||
- Удалён дубликат `ratelimit_tiered.go` (конфликт типов с Redis-версией)
|
||||
- Добавлен REDIS_URL в api-gateway для rate limiting
|
||||
- Пересоздан тестовый пользователь через API
|
||||
### СДЕЛАНО: Маршруты по дорогам + стоимость проезда
|
||||
|
||||
#### Что сделано:
|
||||
|
||||
**1. `backend/internal/travel/twogis.go` — 2GIS Routing API клиент:**
|
||||
- Метод `GetRoute(ctx, points, transport)` — POST `routing.api.2gis.com/routing/7.0.0/global`
|
||||
- Поддержка transport: `driving`, `taxi`, `walking`, `bicycle`
|
||||
- Парсинг WKT LINESTRING из `outcoming_path.geometry[].selection`
|
||||
- Сборка `RouteDirection` с geometry, distance, duration, steps
|
||||
|
||||
**2. `backend/internal/travel/service.go` — переключение на 2GIS:**
|
||||
- `GetRoute()` сначала пробует 2GIS Routing, fallback на OpenRouteService
|
||||
- `mapProfileToTwoGISTransport()` — маппинг профилей
|
||||
|
||||
**3. `backend/internal/agent/travel_data_client.go` — обновлённый клиент:**
|
||||
- `GetRoute(ctx, points, transport)` — полный `RouteDirectionResult` с geometry
|
||||
- `GetRouteSegments()` — маршруты между каждой парой точек
|
||||
- Новые типы: `RouteDirectionResult`, `RouteGeometryResult`, `RouteStepResult`, `RouteSegmentResult`
|
||||
|
||||
**4. `backend/internal/agent/travel_orchestrator.go` — дорожные маршруты:**
|
||||
- `emitTravelWidgets()` вызывает `buildRoadRoute()` вместо прямых линий
|
||||
- `buildTransportSegments()` — маршруты между каждой парой точек
|
||||
- `calculateTransportCosts()` — расчёт стоимости (машина ~8₽/км, автобус ~2.5₽/км, такси ~100₽+18₽/км)
|
||||
- `routeDirection` и `segments` передаются в виджеты `travel_map` и `travel_itinerary`
|
||||
|
||||
**5. Фронтенд — отображение дорожных маршрутов:**
|
||||
- `types.ts` — новые типы `RouteSegment`, `TransportCostOption`, расширены `TravelMapWidgetParams` и `TravelItineraryWidgetParams`
|
||||
- `useTravelChat.ts` — извлечение `routeDirection` и `segments` из виджетов, новые state
|
||||
- `travel/page.tsx` — передача `routeDirection` в `TravelMap`
|
||||
- `TravelWidgets.tsx` — `TransportSegmentCard` между элементами маршрута с иконками машина/автобус/такси и ценами
|
||||
|
||||
---
|
||||
|
||||
## Последнее изменение (28.02.2026)
|
||||
### СДЕЛАНО ранее: Переработка POI коллектора — 2GIS как основной источник
|
||||
|
||||
**Обновлён дизайн страниц авторизации:**
|
||||
|
||||
### Сделано (полностью)
|
||||
|
||||
#### Страницы авторизации в стиле сайта
|
||||
- `/login` — переделана с градиентным фоном, фирменным логотипом, анимациями
|
||||
- `/register` — аналогично, единый стиль с login
|
||||
- `/forgot-password` — сброс пароля в новом дизайне
|
||||
- `/reset-password` — установка нового пароля в новом дизайне
|
||||
|
||||
Изменения:
|
||||
- `bg-gradient-main` вместо простого `bg-base`
|
||||
- Фирменный логотип GooSeek (font-black italic + иконка Sparkles)
|
||||
- Gradient blur декорации на фоне
|
||||
- Карточка с градиентной рамкой и backdrop-blur
|
||||
- Анимации появления (framer-motion)
|
||||
- Footer с копирайтом
|
||||
(см. предыдущую версию CONTINUE.md)
|
||||
|
||||
---
|
||||
|
||||
**Ранее: Spaces как у Perplexity + коллаборация:**
|
||||
|
||||
### Сделано (полностью)
|
||||
|
||||
#### 1. Backend - Space Members
|
||||
- Добавлена таблица `space_members` (space_id, user_id, role)
|
||||
- Добавлена таблица `space_invites` (приглашения по токену)
|
||||
- Методы: `GetMembers`, `AddMember`, `RemoveMember`, `IsMember`
|
||||
- Методы: `CreateInvite`, `GetInviteByToken`, `DeleteInvite`
|
||||
- Обновлён `GetByMemberID` - возвращает пространства где пользователь участник
|
||||
|
||||
#### 2. Frontend - Types & API
|
||||
- Добавлены типы: `SpaceMember`, `SpaceInvite`
|
||||
- Обновлён тип `Space` с полями `members`, `memberCount`, `userId`
|
||||
- API методы: `fetchSpaceMembers`, `inviteToSpace`, `removeSpaceMember`, `acceptSpaceInvite`, `fetchSpaceThreads`
|
||||
|
||||
#### 3. Страница /spaces - Новый дизайн
|
||||
- Карточки пространств с градиентным фоном
|
||||
- Показывает: название, описание, кол-во участников, кол-во тредов
|
||||
- Аватары участников на карточке
|
||||
- Поиск по пространствам
|
||||
- Требует авторизации
|
||||
|
||||
#### 4. Страница /spaces/[id] - Детали пространства
|
||||
- Заголовок с названием и описанием
|
||||
- Табы: Треды / Участники
|
||||
- Список тредов пространства с датами
|
||||
- Список участников с ролями (owner/admin/member)
|
||||
- Кнопка "Начать новый тред"
|
||||
- Модалка приглашения участников по email
|
||||
- Удаление участников (для admin/owner)
|
||||
|
||||
#### 5. Страница /spaces/new - Создание
|
||||
- Превью карточки в реальном времени
|
||||
- Выбор иконки (эмодзи)
|
||||
- Выбор цвета (6 вариантов)
|
||||
- Переключатель приватности
|
||||
- AI инструкции для пространства
|
||||
|
||||
#### 6. Ранее добавлено
|
||||
- Селектор модели (Auto/GooSeek 1.0)
|
||||
- Ollama клиент для бесплатной модели
|
||||
- Обновлённая кнопка "Войти" в сайдбаре
|
||||
|
||||
### Файлы изменены/созданы
|
||||
|
||||
```
|
||||
backend/internal/db/
|
||||
└── space_repo.go (UPDATED - members, invites)
|
||||
|
||||
backend/webui/src/
|
||||
├── lib/
|
||||
│ ├── types.ts (UPDATED - SpaceMember, SpaceInvite)
|
||||
│ └── api.ts (UPDATED - space members API)
|
||||
├── app/(main)/spaces/
|
||||
│ ├── page.tsx (REWRITTEN - новый дизайн)
|
||||
│ ├── new/page.tsx (REWRITTEN - с превью)
|
||||
│ └── [id]/page.tsx (NEW - детали пространства)
|
||||
└── components/
|
||||
├── Sidebar.tsx (UPDATED - кнопка войти)
|
||||
└── ChatInput.tsx (UPDATED - селектор модели)
|
||||
|
||||
backend/internal/llm/
|
||||
├── ollama.go (NEW)
|
||||
└── client.go (UPDATED)
|
||||
|
||||
backend/pkg/config/config.go (UPDATED - Ollama config)
|
||||
backend/cmd/agent-svc/main.go (UPDATED - Ollama support)
|
||||
```
|
||||
|
||||
## Осталось сделать
|
||||
|
||||
### Высокий приоритет:
|
||||
1. **Backend API endpoints** — добавить API для:
|
||||
- `GET /api/v1/spaces/:id/members`
|
||||
- `POST /api/v1/spaces/:id/invite`
|
||||
- `DELETE /api/v1/spaces/:id/members/:userId`
|
||||
- `POST /api/v1/spaces/invite/:token/accept`
|
||||
- `GET /api/v1/spaces/:id/threads`
|
||||
### Высокий приоритет
|
||||
|
||||
2. **Email отправка** — отправлять email с приглашением
|
||||
1. **Цены отелей из SearXNG** — LLM не всегда извлекает цены (0 RUB/night). Нужно:
|
||||
- Добавить fallback: если цена 0, попробовать парсить из snippet
|
||||
- Файл: `backend/internal/agent/travel_hotels_collector.go`
|
||||
|
||||
3. **Ollama в docker-compose** — добавить сервис ollama
|
||||
2. **Авиабилеты для маршрутов** — "Золотое кольцо" не имеет IATA кода. Нужно:
|
||||
- Если destination не IATA, искать билеты до первого конкретного города в маршруте
|
||||
- Файл: `backend/internal/agent/travel_flights_collector.go`
|
||||
|
||||
### Средний приоритет:
|
||||
4. **OAuth провайдеры** — Google, GitHub, Yandex
|
||||
5. **Подтверждение email** — отправка письма при регистрации
|
||||
6. **Real-time обновления** — WebSocket для тредов в пространстве
|
||||
7. **Уведомления** — когда кто-то добавляет сообщение в тред
|
||||
### Средний приоритет
|
||||
|
||||
### Низкий приоритет:
|
||||
8. **Интеграция оплаты** — ЮKassa для пополнения баланса
|
||||
9. **2FA** — TOTP аутентификация
|
||||
10. **Экспорт тредов** — PDF/Markdown
|
||||
3. **Drag & drop в ItineraryWidget** — перетаскивание элементов между днями
|
||||
4. **Кеш SearXNG результатов** — Redis кеш на 10-30 минут
|
||||
5. **Сохранение draft в БД** — персистентность TripDraft через trip_drafts таблицу
|
||||
|
||||
### Низкий приоритет
|
||||
|
||||
6. **Экспорт маршрута** — PDF/Markdown
|
||||
7. **Real-time обновления** — WebSocket для тредов
|
||||
|
||||
---
|
||||
|
||||
## Контекст
|
||||
|
||||
### Модели:
|
||||
| ID | Provider | Тариф |
|
||||
|----|----------|-------|
|
||||
| auto | ollama | Бесплатно |
|
||||
| gooseek-1.0 | timeweb | По тарифу |
|
||||
### Архитектура travel pipeline:
|
||||
|
||||
### Роли в пространстве:
|
||||
- `owner` — создатель, полные права
|
||||
- `admin` — может приглашать/удалять участников
|
||||
- `member` — может создавать треды
|
||||
```
|
||||
User -> /travel page -> streamTravelAgent() -> api-gateway -> chat-svc -> agent-svc
|
||||
-> RunTravelOrchestrator:
|
||||
1. Planner Agent (LLM) -> TripBrief
|
||||
2. Geocode destinations -> travel-svc -> 2GIS Geocoder API
|
||||
3. Parallel collectors:
|
||||
- Events: SearXNG -> Crawl4AI -> LLM extraction -> geocode (2GIS)
|
||||
- POI: 2GIS Places API (primary) -> LLM enrichment -> SearXNG fallback
|
||||
- Hotels: SearXNG -> Crawl4AI -> LLM extraction -> geocode (2GIS)
|
||||
- Transport: TravelPayouts API
|
||||
4. Itinerary Builder (LLM) -> ItineraryDay[]
|
||||
5. Road routing: 2GIS Routing API -> RouteDirection (дорожная геометрия)
|
||||
6. Transport costs: calculateTransportCosts() -> машина/автобус/такси
|
||||
7. Widget emission -> NDJSON stream -> frontend (карта 2GIS MapGL)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user