9.8 KiB
Decision Log
Лёгкий трекер решений. В отличие от ADR (фиксируют архитектуру), фиксирует контекст — почему сделан тот или иной выбор.
Когда создавать запись
- Выбрали технологию (БД, провайдер, фреймворк)
- Отложили функциональность
- Изменили подход
- Архитектурный компромисс
2026-05-11: Структура документации — адаптация template
Контекст: Рядом с кодом появился template/ — универсальный стартовый набор документации. В проекте была собственная структура, частично пересекающаяся с template.
Решение: Взять template за основу, адаптировать под VoIdea. Старые файлы перемещены в /old/. Созданы 27 файлов: инфраструктура, 12 документов, 5 чеклистов, 4 runbook, CI/CD.
Альтернативы: Оставить как есть — дублирование. Полностью перейти на template — потеря уникальных docs/blocks/.
Статус: действует
2026-05-11: PostgreSQL-only + systemd (без Docker)
Контекст: Ранее проект планировался с Docker для деплоя, но целевая среда — VPS с Ubuntu и PostgreSQL. Docker добавляет сложность без необходимости.
Решение:
- PostgreSQL на всех этапах (dev + prod)
- Единый
DATABASE_URLв env (вместо 5 полей) - systemd + venv для запуска на VPS
- FastAPI StaticFiles для раздачи фронтенда
- Dockerfile и docker-compose.yml перемещены в /old/
Альтернативы: Docker — удобно, но лишний слой абстракции для одного сервиса.
Статус: действует
2026-05-11: Все 11 агентов зарегистрированы
Контекст: 5 из 11 агентов (SecurityAgent, QATesterAgent, FixAgent, UITestAgent, RolloutAgent) существовали в коде, но не были подключены к registry и __init__.py.
Решение: Добавлены все 5 в registry.py и __init__.py. Все 11 агентов доступны через API.
Статус: действует
2026-05-11: Rate limiting, crypto, email, sync — инфраструктурные сервисы
Контекст: Проекту требовались базовые сервисы: защита от перегрузок (rate limiting), шифрование данных (crypto), отправка писем (email), синхронизация данных (sync).
Решение:
- slowapi (30/min health, 60/min default) через конфиг
- AES-256 (Fernet via PBKDF2) — graceful degradation без ключа
- aiosmtplib + Jinja2 (welcome, notification шаблоны)
- Sync service с pull (updated_at) + push (конфликт по timestamp)
Статус: действует
2026-05-11: Переименование проекта VoIdea → VoIdeaAI
Контекст: Потребовалось единое имя для всех компонентов. VoIdeaAI точнее отражает AI-составляющую (агенты, Whisper).
Решение: Переименованы config.py, main.py, .env.example, webui (index.html, vite.config.ts PWA, LoginPage, RegisterPage), docs/architecture.md. Слоган: «Идеи рождаются вслух, решения приходят мгновенно!»
Статус: действует
2026-05-11: Phase 2-4 — endpoint wiring (OAuth, password reset, voice)
Контекст: Сервисы для Yandex OAuth (+Disk API), password recovery и Whisper были написаны, но не интегрированы в API и фронтенд.
Решение:
- AuthService.oauth_or_register_login — регистрация/логин через OAuth (поиск по oauth_id, затем по email, затем создание)
- POST /auth/oauth/yandex (URL) + POST /auth/oauth/yandex/callback (обмен code → токены) — настоящий OAuth-флоу
- POST /auth/forgot-password + POST /auth/reset-password — восстановление пароля через email
- POST /voice/transcribe — загрузка аудио, транскрибация через Whisper API
- LoginPage.tsx — поле email (вместо username), кнопка «Войти через Яндекс», ссылка «Забыли пароль?»
- RegisterPage.tsx — поле имени (display_name), авто-логин после регистрации
- OAuthCallback.tsx — обработка callback от Яндекса (чтение code → POST на бэкенд → токены → редирект)
- VoiceInput.tsx — MediaRecorder + Web Speech API с fallback на Whisper API
- AuthContext.tsx — исправлена сигнатура login(email, password) и register(email, password, display_name)
- App.tsx — маршрут /oauth/callback
- app/api/v1/voice.py — новый роутер voice
- config.py — oauth_yandex_redirect_uri по умолчанию http://localhost:3000/oauth/callback
Статус: действует
2026-05-11: Phase 2-4 — завершение (openai_key, SMTP fallback, forgot/reset pages, VoiceInput, migration)
Контекст: После первой волны Phase 2-4 оставались неприкрытые края: whisper_service использовал неправильный ключ, при отключённом SMTP письма просто не отправлялись (без лога), отсутствовали страницы сброса пароля, голосовой ввод не был встроен в формы, не было миграции.
Решение:
- config.py / whisper_service — добавлено поле
openai_api_key, whisper_service пробует его первым, затемai_yandex_keyкак fallback - email_service.py — при отключённом SMTP письмо логируется в консоль (logging.info) вместо возврата False
- ForgotPasswordPage.tsx — форма ввода email, POST /auth/forgot-password, сообщение об отправке
- ResetPasswordPage.tsx — чтение
?token=из URL, форма нового пароля, POST /auth/reset-password - VoiceInput в IdeaCreate/IdeaEdit — иконка микрофона рядом с полем «Описание», вставка распознанного текста в textarea
- alembic/versions/001_create_all_tables.py — ручная initial migration (5 таблиц: users, ideas, agent_configs, log_entries, backlog_tasks)
- .env.example — добавлен OPENAI_API_KEY
- App.tsx — маршруты /forgot-password и /reset-password
Статус: действует
2026-05-11: Дирижёр, 13 ролевых агентов, верификация, голосовые команды
Контекст: Проекту требовался голосовой AI-ассистент, который понимает пользователя, выбирает нужного эксперта, проверяет ответ и позволяет управлять голосом.
Решение:
- Дирижёр (ConductorAgent) — оркестратор: выбирает агента → генерация → верификация → пользователь. Самообучение через историю + рейтинг + похожие кейсы.
- 13 ролевых агентов — Бизнес-аналитик, Организатор задач, Юрист, Финансовый консультант, Архитектор решений, Тестировщик, UI-дизайнер, SMM-специалист, Лайф-коуч, Эксперт по доступности, Критик, Копирайтер, Хранитель. Каждый с уникальным system prompt из таблицы.
- Верификация ответов — встроена в Дирижёра: LLM проверяет ответ (галлюцинации, противоречия, ошибки) → confidence (0-100) → автокоррекция / предупреждение / запрос уточнения.
- Рейтинг от пользователя — POST /voice/rate, 5 звёзд на фронтенде, сохранение в БД.
- Голосовые команды (useVoiceCommands) — фоновый SpeechRecognition (continuous) слушает «Стоп», «Повтори», «Уточнить». Работает параллельно с TTS.
- Confidence badge — зелёный/жёлтый/красный индикатор на каждом ответе.
- Обновлены модели — ConductorInteraction (confidence_score, verification_status).
- Обновлена миграция — +2 колонки в conductor_interactions.
Статус: действует
Формат записи
## YYYY-MM-DD: Название
**Контекст:** Почему встал вопрос
**Решение:** Что выбрали
**Альтернативы:** Что рассматривали
**Статус:** действует | пересмотреть через N | заменено