Initial commit: VoIdeaAI - voice-first AI idea assistant

This commit is contained in:
2026-05-13 12:51:42 +03:00
commit 688d043dad
421 changed files with 47915 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
# VoIdea — Project Guide
## Documentation Map
| Документ | Описание | Для кого |
|----------|----------|----------|
| `SPECIFICATION.md` | Стек, причины выбора, ключевые решения | Все, кто входит в проект |
| `TECHNICAL.md` | Архитектура, схемы, data flow | Разработчики |
| `webui/STYLE_GUIDE.md` | Код-стайл, Zustand, формы, a11y, ESLint, тесты | Frontend-разработчики |
| `versioning.md` | SemVer, CHANGELOG, agent versioning | Все |
| `user-guide.md` | Пользовательская инструкция | Пользователи |
| `admin-guide.md` | Администрирование VPS | Администраторы |
| `docs/blocks/00-rules.md` | Конституция проекта | Все |
| `docs/design-system/README.md` | Дизайн-токены + генераторы | UI/UX + разработчики |
## Quick Start
```bash
# Backend
python -m venv venv
.\venv\Scripts\activate # Windows
source venv/bin/activate # Linux
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8020
# Frontend
cd webui
npm install
npm run dev
```
## VPS Deploy
```bash
# Ubuntu 22.04+
git clone <repo> /opt/voidea
cd /opt/voidea
chmod +x deploy/deploy.sh
./deploy/deploy.sh
```
See `admin-guide.md` for full VPS setup.
## Architecture Principles
1. **Documentation first** — decisions are written down before code.
2. **Purity over speed** — "кривой код = переписать сразу".
3. **Growth-proof** — все решения принимаются с учётом будущих мобильных приложений и объединения проектов.
4. **VPS-ready** — весь код пишется сразу для Ubuntu + Nginx + systemd.
5. **Accessibility by default** — WCAG AA, enforced by CI.
+59
View File
@@ -0,0 +1,59 @@
# VoIdea — Specification
## Overview
VoIdea ("Голос Идей") — гибридное приложение для фиксации и проработки идей с помощью группового ИИ-анализа. Работает как PWA (устанавливается на телефон), с перспективой нативных iOS/Android-клиентов.
## Stack & Rationale
| Layer | Choice | Why |
|-------|--------|-----|
| Frontend framework | React 18.3 LTS | Стабильность, экосистема, перспектива React 19 |
| Language | TypeScript 5.5 strict | Типобезопасность, самодокументируемость |
| Styling | Tailwind CSS 3.4 | Utility-first, тёмная тема из коробки, PWA-ready |
| State management | Zustand | 1.1 KB, без Provider, работает вне React (можно читать токен в api/client) |
| Forms | react-hook-form + zod | Валидация через схему = один источник истины (типы TS = runtime) |
| Routing | react-router-dom 6 | Стандарт React |
| PWA | vite-plugin-pwa | Service worker + manifest из коробки |
| Build | Vite 5 | Быстрая сборка, HMR |
| Backend | FastAPI (Python) | Асинхронный, Pydantic-валидация |
| Database | PostgreSQL | ACID, JSONB |
| Queue | Celery + Redis | AI-вызовы, бэкапы, email |
## Key Decisions
### Zustand over Context
- Context ререндерит ВСЕХ подписчиков при изменении. Zustand — только тех, кто читает изменившееся поле.
- Zustand-стор можно читать вне React (в `api/client.ts` для token refresh).
- Для существующего `AuthContext` — постепенный перенос в `stores/auth.ts`.
### react-hook-form + zod over native forms
- Валидация через zod-схему: TypeScript тип = runtime тип, расхождение невозможно.
- `errors` из коробки, `isSubmitting`, `dirty`/`touched`.
- Для простых форм (2 поля: логин) — можно оставить нативный `<form>`.
### WCAG AA
- Целевой уровень доступности: AA (стандарт для РФ/ЕС).
- Enforcement: eslint-plugin-jsx-a11y в CI.
### Error Boundaries
- Глобальный ErrorBoundary — защита от белого экрана.
- Per-page для VoiceChat (голосовые API могут падать).
### i18n
- Сейчас: только русский.
- Но строки вынесены в `constants/strings.ts`, рендерятся через `<T>`, что позволит перейти на react-i18next без переписывания UI.
## Project Documentation Map
```
PROJECT_GUIDE.md ← навигатор по всей документации
├── SPECIFICATION.md ← этот файл
├── TECHNICAL.md ← архитектура и схемы
├── STYLE_GUIDE.md ← код-стайл webui
├── versioning.md ← версионирование
├── user-guide.md ← пользовательская инструкция
├── admin-guide.md ← администрирование
├── docs/blocks/ ← блоки правил
└── docs/design-system/ ← дизайн-токены + генераторы
```
+118
View File
@@ -0,0 +1,118 @@
# VoIdea — Technical Architecture
## System Overview
```
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Client │────▶│ Nginx │────▶│ FastAPI │────▶ PostgreSQL
│ (PWA/Web)│ │ :80/443 │ │ :8020 │────▶ Redis
└──────────┘ └──────────┘ └──────────┘ ┌──────────┐
│ Celery │
│ (AI/backup)
└──────────┘
```
## Frontend (webui/) Architecture
### Layer Structure
```
pages/ ← Route-level components (1 page = 1 route)
├── LoginPage.tsx
├── IdeaEdit.tsx
└── AdminPage.tsx
components/ ← Shared UI
├── Layout.tsx
├── ErrorBoundary.tsx
├── SkipToContent.tsx
├── VoiceChat.tsx
└── HelpFAB.tsx
stores/ ← Zustand stores
├── auth.ts (migration target from AuthContext)
├── ideas.ts
└── settings.ts
api/ ← HTTP client
├── client.ts
└── endpoints.ts
constants/ ← i18n-ready strings
└── strings.ts
hooks/ ← Custom hooks
├── useVoiceCommands.ts
└── useBroadcastChannel.ts
types/ ← Shared TS types
└── index.ts
```
### Data Flow
```
User Action (click, voice)
→ Page component
→ Zustand store action (or react-hook-form submit)
→ api/client.ts (fetch with JWT)
→ FastAPI endpoint
→ Service layer
→ Database / AI
← Response
← JSON
← Store update (set state)
← React re-render (only subscribers)
← UI update
```
### Auth Flow
```
Login/Register
→ POST /api/v1/auth/login
← { access_token, refresh_token }
→ setTokens() → localStorage
→ Zustand store: user = fetched /users/me
→ apiFetch() reads token from store (not localStorage)
On page load:
→ isAuthenticated() checks localStorage
→ GET /users/me
→ 200: setUser(data)
→ 401: clearTokens(), redirect /login
```
### Error Boundary Flow
```
Error in render
→ <ErrorBoundary> catches (componentDidCatch)
→ Logs to console.error
→ Shows <ServerErrorPage /> (fallback UI)
→ User clicks "На главную"
→ navigate("/")
```
## Backend Layer
See `app/` directory structure. Key modules:
- `app/api/v1/` — REST endpoints (auth, ideas, users, admin, agents, sync)
- `app/services/` — Business logic
- `app/models/` — SQLAlchemy ORM
- `app/schemas/` — Pydantic request/response
- `app/agents/` — 11 system agents (DocAgent, QATesterAgent, etc.)
- `app/integrations/` — AI providers (YandexGPT, GigaChat), OAuth
- `app/core/` — Config, security, DB, dependencies
## Design Tokens
Source of truth: `docs/design-system/tokens.json`
Generators:
| Platform | Generator | Output |
|----------|-----------|--------|
| Web (CSS) | `generators/css_generator.py` | `app/design-tokens/css/theme.css` |
| iOS (Swift) | `generators/swift_generator.py` | `app/design-tokens/swift/Colors.swift` |
| Android (Kotlin) | `generators/kotlin_generator.py` | `app/design-tokens/kotlin/colors.xml` |
## Backups
- Cron: daily at 03:00 (server time)
- Retention: 7 days
- Output: `/opt/voidea/backups/`
- Tool: `tools/backup_db.py`
+57
View File
@@ -0,0 +1,57 @@
# VPS: Первый запуск — чеклист
## 1. PostgreSQL
```bash
sudo -u postgres psql
CREATE USER voidea WITH PASSWORD 'your_strong_password';
CREATE DATABASE voidea OWNER voidea;
\q
```
## 2. SSL (Let's Encrypt)
```bash
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d voidea.ru -d www.voidea.ru
```
## 3. Nginx config
В репозитории готовый конфиг: `deploy/voidea.nginx.conf`.
`deploy.sh` скопирует его автоматически. После получения SSL:
```bash
# Отредактируйте server_name в deploy/voidea.nginx.conf если нужно
# deploy.sh сделает остальное, либо вручную:
sudo ln -sf /etc/nginx/sites-available/voidea /etc/nginx/sites-enabled/
sudo systemctl reload nginx
```
## 4. .env на VPS
```bash
sudo -u voidea nano /opt/voidea/.env
```
Обязательно задать:
- `DATABASE_URL` (пароль от PostgreSQL)
- `JWT_SECRET_KEY` (сгенерировать: `openssl rand -hex 64`)
- `JWT_RESET_SECRET_KEY` (отдельный, тоже сгенерировать)
- `ENCRYPTION_KEY` (сгенерировать: `openssl rand -hex 32`)
- `SYSTEM_OWNER_EMAIL` (ваш email)
- `OAUTH_YANDEX_ID` / `OAUTH_YANDEX_SECRET`
- `SMTP_HOST/USER/PASS` (для сброса пароля)
- `SERVER_EXTERNAL_URL=https://voidea.ru`
## 5. Запуск
```bash
sudo bash /opt/voidea/deploy/deploy.sh
```
## 6. Проверка
```bash
sudo systemctl status voidea-api
sudo systemctl status voidea-worker
sudo systemctl status voidea-beat
curl -s https://voidea.ru/health | jq .
```
## 7. Debug mode
После деплоя debug mode включится автоматически на 48ч.
Проверить статус: админ-панель → Журналы.
+101
View File
@@ -0,0 +1,101 @@
# Руководство администратора VoIdeaAI
## Ролевая модель
| Роль | Описание |
|------|----------|
| Owner | Полный доступ, управление systemd-сервисами |
| Admin | Полный доступ к данным, управление пользователями и тарифами |
| Moderator | Ограниченные права, настраиваемые через permissions |
| User | Стандартный пользователь |
## Вкладки админ-панели
### Пользователи
- Поиск пользователей по имени или email
- Редактирование роли (user/moderator/admin)
- Назначение прав модераторам (чекбоксы)
- Блокировка/разблокировка
- Owner защищён от изменений
### Агенты
- Просмотр списка агентов
- Включение/отключение агентов
- Редактирование описания
### Журналы
- Фильтрация по уровню (DEBUG, INFO, WARNING, ERROR)
- Фильтрация по источнику
- Просмотр деталей записи
### Обратная связь
- Просмотр отзывов пользователей
- Изменение статуса (new, read, replied, done)
- Удаление отзывов
### Тарифы
- Создание новых тарифных планов
- Редактирование существующих
- Удаление
- Параметры: название, код, цена, описание, features JSON
### Фичи
- Трекер функций (backlog)
- Статусы: pending, in_progress, done
- Категория: feature, general
- Приоритет: low, medium, high, critical
### Сервисы (Owner only, production)
- Статус systemd-юнитов
- Перезапуск сервисов
- Доступно только в production
### Система
- Версия приложения
- Окружение
- Статус БД
- Версия Python
### Telegram Bot
Вкладка «Telegram Bot» в админ-панели:
- **Список команд** — все зарегистрированные @bot_command хендлеры
- **Включение/отключение** — toggle для каждой команды
- **Синхронизация** — принудительная синхронизация команд с Telegram API
- Команды автоматически синхронизируются при старте сервера
- Для работы требуется `TELEGRAM_BOT_TOKEN` в .env
## Развёртывание (VPS Ubuntu 22.04+)
```bash
# Клонирование
git clone https://github.com/anomalyco/voidea /opt/voidea
cd /opt/voidea
# Настройка окружения
cp .env.example .env
# Заполните DATABASE_URL, JWT_SECRET_KEY, SYSTEM_OWNER_EMAIL
# --- Backend ---
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
alembic upgrade head
# --- Frontend ---
cd webui
npm ci # чистая установка (lockfile)
npm run build # сборка в dist/
cd ..
# --- Deploy скрипт (автоматизация) ---
chmod +x deploy/deploy.sh
./deploy/deploy.sh
# Сервисы запускаются через systemd
sudo systemctl start voidea-web # Uvicorn
sudo systemctl start voidea-celery # Celery worker
sudo systemctl start voidea-nginx # Nginx reverse proxy
```
См. `deploy/deploy.sh` для полной автоматизации. Jenkins/GitHub Actions — `deploy.yml`.
+113
View File
@@ -0,0 +1,113 @@
# ADR-001: Выбор PostgreSQL как основной СУБД
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
Для проекта VoIdea требуется база данных с поддержкой:
- Сложных запросов (аналитика идей)
- JSONB для гибкости (метаданные, настройки)
- ACID транзакции (финансовые операции, подписки)
- Масштабируемость (тысячи пользователей)
- Хорошая работа с Python (asyncpg)
Рассматривались:
- **PostgreSQL** — реляционная, ACID, JSONB, mature
- **MongoDB** — документоориентированная, гибкость, шардинг
- **SQLite** — простая, не подходит для production
---
## Решение
**PostgreSQL** выбран как основная СУБД.
### Обоснование
| Критерий | PostgreSQL | MongoDB | SQLite |
|----------|------------|---------|--------|
| ACID | ✅ Полный | ❌ Eventual | ✅ Полный |
| JSONB | ✅ Отличный | ✅ Лучший | ❌ Limited |
| Масштабируемость | ✅ Хорошая | ✅ Отличная | ❌ Плохая |
| Python async | ✅ asyncpg | ✅ motor | ❌ |
| Сложные запросы | ✅ Отличные | ❌ Limited | ⚠️ Basic |
| Зрелость | ✅ 20+ лет | ⚠️ 15 лет | ✅ |
### Преимущества для VoIdea
1. **JSONB** — хранение зашифрованных данных, настроек агентов
2. **ACID** — безопасность транзакций (подписки, платежи)
3. **Индексы** — поиск по метаданным, пользователям
4. **PostGIS** — геолокация (future: автоопределение региона)
5. **Full-text search** — поиск в идеях
---
## Последствия
### Положительные
- Надёжная, проверенная база данных
- Отличная производительность
- Большое сообщество
- Хорошая документация
- Mature ORM (SQLAlchemy async)
### Отрицательные
- Требует установку и настройку (PostgreSQL server)
- Миграции Alembic для схемы
- Начальная настройка (создание пользователя, базы)
### Миграция
Для локальной разработки:
```bash
# Windows
# Скачать PostgreSQL с postgresql.org/download/windows
# или использовать Chocolatey:
choco install postgresql
# Ubuntu (VPS)
apt install postgresql postgresql-contrib
```
---
## Реализация
### Конфигурация в .env
```bash
DB_HOST=localhost
DB_PORT=5432
DB_NAME=voidea
DB_USER=voidea
DB_PASS=your_secure_password
```
### SQLAlchemy async setup
```python
from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine(
f"postgresql+asyncpg://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}",
echo=True
)
```
---
## Ответственный
**Decision maker:** Owner
**Review date:** При масштабировании (> 10,000 пользователей)
---
*Создано: 2026-05-10*
*Обновлено при изменениях SpecAgent*
+397
View File
@@ -0,0 +1,397 @@
# ADR-002: Архитектура системных агентов
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
Проект VoIdea требует автоматизации через AI-агентов. Необходимо определить:
- Количество агентов
- Их обязанности
- Взаимодействие между агентами
- Стек реализации
Рассматривались:
- **Один суперагент** — всё в одном, сложно масштабировать
- **Ручное управление** — человек выполняет всё
- **11 отдельных агентов** — модульность, специализация
---
## Решение
**11 системных агентов**, каждый со своей ответственностью.
### Список агентов
| Агент | Ответственность | Триггеры |
|-------|-----------------|----------|
| DocAgent | Документация, комментарии | pre-commit, push, manual |
| AuditAgent | Соблюдение правил, прогресс | pre-commit, daily, manual |
| SecurityAgent | Безопасность, уязвимости | pre-commit, weekly, manual |
| SpecAgent | Спецификации, версионирование | tag creation, push |
| ObserverAgent | Наблюдение за пользователями | continuous, daily report |
| QATesterAgent | Функциональное тестирование | pre-commit, daily, manual |
| FixAgent | Исправление багов | QATesterAgent results |
| UITestAgent | Визуальное тестирование | weekly, manual |
| RolloutAgent | Постепенное развёртывание | after tests, manual |
| EvolutionAgent | Саморазвитие агентов | daily, learning |
| BacklogAgent | Управление задачами | continuous |
---
## Архитектура
### Структура файлов
```
app/agents/
├── __init__.py # Публичный API
├── base.py # Базовый класс Agent
├── doc_agent.py # DocAgent
├── audit_agent.py # AuditAgent
├── security_agent.py # SecurityAgent
├── spec_agent.py # SpecAgent
├── observer_agent.py # ObserverAgent
├── qa_tester_agent.py # QATesterAgent
├── fix_agent.py # FixAgent
├── ui_test_agent.py # UITestAgent
├── rollout_agent.py # RolloutAgent
├── evolution_agent.py # EvolutionAgent
└── backlog_agent.py # BacklogAgent
```
### Базовый класс
```python
from abc import ABC, abstractmethod
from typing import Any, Optional
class BaseAgent(ABC):
name: str
version: str
@abstractmethod
async def run(self, context: dict) -> AgentResult:
"""Основной метод выполнения"""
pass
@abstractmethod
async def health_check(self) -> bool:
"""Проверка работоспособности"""
pass
async def get_status(self) -> AgentStatus:
"""Текущий статус агента"""
pass
async def get_metrics(self) -> AgentMetrics:
"""Метрики работы агента"""
pass
```
---
## Меж-агентское взаимодействие
### Делегирование
```python
class AgentA:
async def process(self, task):
if task.requires_agent_b:
result = await delegate_to(
target=AgentB,
task=task,
timeout=30
)
# continue processing
```
### Event-driven
```python
class EventBus:
async def publish(self, event: AgentEvent):
await self._handlers[event.type].handle(event)
class AgentB:
@event_handler(AgentEventTypes.TASK_DELEGATED)
async def handle_delegated_task(self, event):
# process task
```
---
## Описание поведения каждого агента
### DocAgent
**Цель:** Поддержание документации в актуальном состоянии.
**Обязанности:**
- Создание README.md для новых модулей
- Обновление docs при изменении кода
- Генерация docstrings
- Ведение Runbook
**Триггеры:**
- Создание нового файла
- Изменение существующего > 50 строк
- Создание новой папки
- Push в main/develop
**Взаимодействие:**
- SpecAgent → обновление спецификаций
- AuditAgent → проверка актуальности docs
---
### AuditAgent
**Цель:** Контроль соблюдения правил проекта.
**Обязанности:**
- Проверка code style (ruff)
- Проверка типизации (mypy)
- Контроль прогресса по плану
- Фиксация отклонений
**Триггеры:**
- pre-commit hook
- Ежедневно 09:00
- По запросу администратора
**Взаимодействие:**
- SecurityAgent → проверка безопасности
- DocAgent → обновление отчётов
---
### SecurityAgent
**Цель:** Обеспечение безопасности проекта.
**Обязанности:**
- Сканирование уязвимостей
- Проверка input валидации
- Контроль зависимостей (safety)
- Соответствие 152-ФЗ
**Триггеры:**
- pre-commit hook
- Еженедельно (полное сканирование)
- При добавлении зависимости
**Взаимодействие:**
- FixAgent → исправление уязвимостей
- RolloutAgent → блокировка при критических уязвимостях
---
### SpecAgent
**Цель:** Управление спецификациями и версионированием.
**Обязанности:**
- Генерация CHANGELOG
- Обновление project.json
- Управление ADR
- Версионирование кода
**Триггеры:**
- Создание git tag
- Push в main
- Изменение спецификаций
**Взаимодействие:**
- DocAgent → обновление docs
- EvolutionAgent → фиксация изменений
---
### ObserverAgent
**Цель:** Сбор и анализ данных о пользователях.
**Обязанности:**
- Сбор метрик использования
- Генерация идей для развития
- Выявление паттернов поведения
- Отчёты для EvolutionAgent
**Триггеры:**
- Непрерывный сбор данных
- Ежедневный отчёт
- По запросу EvolutionAgent
**Метрики (MVP):**
- page_views
- session_duration
- feature_usage_frequency
- conversion_rate
**Взаимодействие:**
- EvolutionAgent → данные для анализа
- RolloutAgent → метрики для решения
---
### QATesterAgent
**Цель:** Функциональное тестирование.
**Обязанности:**
- Создание временных аккаунтов
- Выполнение тестов
- Очистка временных данных
- Генерация отчётов
**Триггеры:**
- pre-commit hook
- Ежедневно в 06:00
- Вручную через админ-панель
- После FixAgent исправления
**Взаимодействие:**
- FixAgent → исправление найденных багов
- UITestAgent → визуальное тестирование
- RolloutAgent → результаты для решения
---
### FixAgent
**Цель:** Автоматическое исправление багов.
**Обязанности:**
- Анализ багов из QATesterAgent
- Генерация исправлений
- Создание PR
- Валидация исправлений
**Триггеры:**
- Результаты QATesterAgent
- Критические ошибки в логах
- По запросу человека
**Взаимодействие:**
- QATesterAgent → повторное тестирование
- DocAgent → обновление документации
- Git → создание PR
---
### UITestAgent
**Цель:** Визуальное тестирование интерфейса.
**Обязанности:**
- Скриншот-тестирование
- Проверка layout
- Accessibility testing
- Кросс-браузерное тестирование
**Триггеры:**
- Еженедельно
- После изменений в UI
- Вручную через админ-панель
**Взаимодействие:**
- QATesterAgent → результаты
- FixAgent → исправление визуальных багов
---
### RolloutAgent
**Цель:** Управление развёртыванием.
**Обязанности:**
- Контроль этапов rollout (3→1%→5%→15%→100%)
- Мониторинг метрик
- Принятие решения о переходе
- Откат при проблемах
**Триггеры:**
- После успешных тестов
- Ежедневный мониторинг
- По решению человека
**Взаимодействие:**
- ObserverAgent → метрики
- FixAgent → исправление проблем
- BacklogAgent → создание задач
---
### EvolutionAgent
**Цель:** Саморазвитие агентов.
**Обязанности:**
- Анализ эффективности агентов
- Генерация предложений по улучшению
- Обновление capabilities
- Обучение на данных
**Триггеры:**
- Ежедневно
- При обнаружении новых паттернов
- По запросу BacklogAgent
**Взаимодействие:**
- ObserverAgent → данные о пользователях
- Все агенты → улучшение работы
---
### BacklogAgent
**Цель:** Управление отложенными задачами.
**Обязанности:**
- Создание задач из предложений
- Приоритизация
- Отслеживание статуса
- Напоминания
**Триггеры:**
- Непрерывный мониторинг
- По предложению других агентов
- Вручную через админ-панель
**Взаимодействие:**
- Все агенты → создание задач
- RolloutAgent → задачи для реализации
---
## Последствия
### Положительные
- Модульность — легко добавлять новых агентов
- Специализация — каждый делает своё
- Тестируемость — можно тестировать отдельно
- Масштабируемость — агенты работают параллельно
### Отрицательные
- Сложность координации
- Возможные конфликты агентов
- Overhead на коммуникацию
---
## Ответственный
**Decision maker:** Owner
**Review date:** При добавлении новых агентов
---
*Создано: 2026-05-10*
*Обновлено при изменениях EvolutionAgent*
+243
View File
@@ -0,0 +1,243 @@
# ADR-003: OAuth схема авторизации
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
Проект VoIdea поддерживает несколько способов авторизации:
- Email + пароль
- OAuth провайдеры (Яндекс, Google, Apple)
Необходимо определить правила привязки провайдеров к аккаунтам.
---
## Решение
**Один пользователь = один провайдер**
> Нельзя привязать Google к аккаунту, зарегистрированному через Яндекс.
---
## Правила
### Основные
1. **При регистрации через OAuth** — аккаунт привязан к этому провайдеру навсегда
2. **При регистрации через email** — можно использовать только email + пароль
3. **Нельзя добавить второй провайдер** — даже если email совпадает
### Примеры
| Действие | Результат |
|----------|-----------|
| Регистрация через Яндекс → Вход через Google | ❌ Ошибка: создай новый аккаунт |
| Регистрация через Google → Вход через Яндекс | ❌ Ошибка: создай новый аккаунт |
| Регистрация через email → Вход через Яндекс | ❌ Ошибка: это разные аккаунты |
| Регистрация через Яндекс → Повторный вход через Яндекс | ✅ Работает |
---
## Обоснование
### Почему один провайдер
1. **Безопасность**
- Меньше точек входа для атак
- Сложнее украсть аккаунт
- Чёткая атрибуция действий
2. **Простота реализации**
- Не нужно merge аккаунтов
- Не нужно решать конфликты данных
- Понятная модель данных
3. **Privacy**
- Данные не смешиваются между провайдерами
- Пользователь понимает что использует
4. **Яндекс vs Google**
- Разные экосистемы
- Разные данные пользователя
- Разная политика безопасности
---
## Структура данных
### Users table
```sql
CREATE TABLE users (
id UUID PRIMARY KEY,
-- Идентификация
email VARCHAR(255) UNIQUE, -- NULL если OAuth без email
password_hash VARCHAR(255), -- NULL если OAuth-only
-- OAuth (только один провайдер)
oauth_provider VARCHAR(20), -- yandex|google|apple|null
oauth_id VARCHAR(255), -- ID в системе провайдера
-- Метаданные
email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- Constraints
CONSTRAINT users_oauth_xor_email CHECK (
-- OAuth с email
(oauth_provider IS NOT NULL AND email IS NOT NULL) OR
-- Email-only
(oauth_provider IS NULL AND email IS NOT NULL AND password_hash IS NOT NULL)
)
);
CREATE UNIQUE INDEX uq_users_oauth
ON users(oauth_provider, oauth_id)
WHERE oauth_provider IS NOT NULL;
```
---
## OAuth Flow
### Пример: Яндекс OAuth
```python
async def yandex_oauth_callback(code: str, db: AsyncSession):
# 1. Получаем access_token
token_data = await yandex_api.get_token(code)
# 2. Получаем данные пользователя
user_data = await yandex_api.get_user_info(token_data.access_token)
# 3. Проверяем/создаём аккаунт
user = await db.execute(
select(User).where(
User.oauth_provider == 'yandex',
User.oauth_id == user_data.id
)
)
if not user:
# Новый пользователь
user = User(
email=user_data.email,
oauth_provider='yandex',
oauth_id=user_data.id
)
db.add(user)
await db.commit()
# 4. Создаём JWT session
return create_jwt_session(user.id)
```
---
## Google OAuth
Аналогично Яндексу, с заменой endpoint-ов.
### Различия
| Параметр | Яндекс | Google |
|----------|--------|--------|
| OAuth endpoint | oauth.yandex.ru | oauth2.googleapis.com |
| User info | login.yandex.ru | www.googleapis.com/oauth2/v2/userinfo |
| Scope | login:email, profile | email, profile |
---
## Apple OAuth (отложено)
Apple будет реализован ближе к коммерческой версии.
### Требования
- App Store Developer Account ($99/год)
- Private Key для подписи (в Keychain)
- Тот же принцип: один пользователь = один провайдер
---
## Защита от привязки чужого аккаунта
### Проблема
Злоумышленник может попытаться привязать Google к чужому email.
### Решение
1. **Email verification**
- OAuth возвращает verified email
- Привязка только verified email
2. **Separate tables**
- OAuth и email разделены логически
- Разные flows для входа
3. **Audit logging**
- Все попытки OAuth логируются
- Подозрительная активность → SecurityAgent
---
## Последствия
### Положительные
- Простая модель данных
- Безопасность выше
- Понятно для пользователя
- Легко реализовать
### Отрицательные
- Пользователь не может "добавить" Google к существующему аккаунту
- При потере доступа к провайдеру — сложнее восстановить
- Нельзя merge аккаунты
### Workaround для пользователя
При потере доступа к OAuth провайдеру:
1. Обращение в поддержку
2. Подтверждение личности
3. Смена email (если нужно)
4. Сброс пароля на email
---
## Конфигурация
```bash
# .env
OAUTH_YANDEX_ID=your_yandex_client_id
OAUTH_YANDEX_SECRET=your_yandex_secret
OAUTH_YANDEX_REDIRECT_URI=http://localhost:8020/auth/yandex/callback
OAUTH_GOOGLE_ID=your_google_client_id
OAUTH_GOOGLE_SECRET=your_google_secret
OAUTH_GOOGLE_REDIRECT_URI=http://localhost:8020/auth/google/callback
# Apple - зарезервировано для будущего
# OAUTH_APPLE_ID=
# OAUTH_APPLE_TEAM_ID=
```
---
## Ответственный
**Decision maker:** Owner
**Review date:** При добавлении Apple OAuth
---
*Создано: 2026-05-10*
*См. также: docs/backlog/oauth-schema-note.md*
+294
View File
@@ -0,0 +1,294 @@
# ADR-004: Постепенное развёртывание (Rollout)
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
При выпуске нового функционала требуется минимизировать риски и быстро реагировать на проблемы.
Рассматривались:
- **Big bang** — сразу на всех пользователей
- **Feature flags** — включение для избранных
- **Постепенное развёртывание** — процент от пользователей
---
## Решение
**Поэтапное развёртывание с мониторингом**
```
Stage 0: Development → Тестирование агентами
Stage 1: 3 users → Первые пользователи
Stage 2: 1% → Расширение выборки
Stage 3: 5% → Продолжение
Stage 4: 15% → Почти все
Stage 5: 100% → Production
```
---
## Этапы
### Stage 0: Development
**Кто:** Агенты (QATesterAgent, FixAgent, UITestAgent)
**Критерии перехода:**
- Все тесты пройдены
- Нет критических ошибок
- Документация обновлена
**Действия:**
```python
async def promote_to_stage_1():
# 1. Финальная проверка тестов
test_results = await QATesterAgent.run_full_suite()
# 2. Проверка документации
await AuditAgent.verify_docs_complete()
# 3. Решение о переходе
if test_results.success:
RolloutAgent.set_stage(1)
notify_admins("Готов к rollout: 3 пользователя")
```
---
### Stage 1: 3 users
**Кто:** 3 добровольца (beta testers)
**Критерии перехода в Stage 2:**
- 2 дня без критических ошибок
- Error rate < 1%
- User feedback положительный
- ObserverAgent не фиксирует аномалий
**Действия:**
```python
async def check_stage_1_health():
metrics = await ObserverAgent.get_metrics(days=2)
# Проверки
if metrics.error_rate < 0.01:
if metrics.user_satisfaction > 0.8:
if not metrics.anomalies_detected:
await promote_to_stage_2()
else:
await analyze_anomalies()
else:
await log_issue("Low satisfaction")
```
---
### Stage 2: 1% пользователей
**Кто:** ~10 пользователей (при 1000 MAU)
**Критерии перехода в Stage 3:**
- 2 дня стабильности
- Нет regresion
- Performance acceptable (< 500ms)
---
### Stage 3: 5% пользователей
**Кто:** ~50 пользователей
**При проблемах:** Откат до Stage 2
---
### Stage 4: 15% пользователей
**Кто:** ~150 пользователей
**При проблемах:** Откат до Stage 3
---
### Stage 5: 100% (Production)
**Кто:** Все пользователи
**Критерии:**
- Все предыдущие stages стабильны
- Мониторинг непрерывный
- Подготовлен changelog для магазинов
---
## Мониторинг
### ObserverAgent отслеживает
```python
class RolloutMetrics:
error_rate: float # Цель: < 1%
response_time_p95: float # Цель: < 500ms
user_satisfaction: float # Цель: > 0.8
feature_usage: float # Цель: рост
complaints_count: int # Цель: 0
rollback_requests: int # Цель: 0
```
### При аномалиях
1. **Alert** → RolloutAgent получает уведомление
2. **Analysis** → FixAgent анализирует логи
3. **Decision** → Человек + агент решают
4. **Action** → Откат или продолжение
---
## Откат (Rollback)
### Когда
- Error rate > 5%
- Критические баги в production
- Решение человека
### Процедура
```python
async def rollback_to(stage: int):
# 1. Приостановить rollout
RolloutAgent.pause()
# 2. Зафиксировать состояние
await AuditAgent.log_rollback(stage)
# 3. Откатить код
await git.revert_to_stable_version()
# 4. Уведомить
notify_admins(f"Откат до Stage {stage}")
# 5. Создать задачу
await BacklogAgent.create_task(
title=f"Rollback reason: ...",
priority="high"
)
# 6. После исправления → вернуться к Stage 0
```
---
## UI в админ-панели
### Dashboard
```
Rollout Status: Stage 2 (1%)
Progress:
[████████░░░░░░░░░░░░░░░░░░░] 1%
Metrics:
- Error rate: 0.5% ✓
- Response time: 234ms ✓
- Users: 10/1000
Actions:
[Приостановить] [Откат] [Форсировать]
```
### История
```
Stage 0 → Stage 1: 2026-05-10 (PASSED)
Stage 1 → Stage 2: 2026-05-12 (PASSED)
Stage 2 → Stage 3: 2026-05-14 (IN PROGRESS)
```
---
## Feature Flags
Для гибкости используем Feature Flags:
```sql
CREATE TABLE feature_flags (
id UUID PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
enabled BOOLEAN DEFAULT FALSE,
rollout_percentage INT DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
```
```python
async def is_feature_enabled(user_id: UUID, feature: str) -> bool:
flag = await db.get_feature_flag(feature)
if not flag.enabled:
return False
# Проверка процента
user_hash = hash(user_id)
return (user_hash % 100) < flag.rollout_percentage
```
---
## Последствия
### Положительные
- Минимизация рисков
- Быстрая реакция на проблемы
- Эволюция с обратной связью
- Прозрачность для команды
### Отрицательные
- Медленнее релиз
- Сложнее управление
- Требуется мониторинг
---
## Конфигурация
```yaml
rollout:
stages:
- name: development
users: 0
duration: unlimited
- name: "3 users"
users: 3
duration: 2 days
- name: "1%"
users_percentage: 1
duration: 2 days
- name: "5%"
users_percentage: 5
duration: 2 days
- name: "15%"
users_percentage: 15
duration: 3 days
- name: "100%"
users_percentage: 100
duration: unlimited
```
---
## Ответственный
**Decision maker:** Owner + RolloutAgent
**Review date:** После каждого успешного rollout
---
*Создано: 2026-05-10*
*Управляется RolloutAgent*
+330
View File
@@ -0,0 +1,330 @@
# ADR-005: Design Tokens как единый источник стилей
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
Проект VoIdea работает на нескольких платформах:
- Web (PWA)
- iOS (Swift/SwiftUI)
- Android (Kotlin)
Требуется унифицировать стили (цвета, шрифты, отступы) между всеми платформами.
Рассматривались:
- **Ручное копирование** — непоследовательно, сложно поддерживать
- **Shared library** — требует синхронизации
- **Design Tokens (JSON)** — единый источник, генераторы
---
## Решение
**Design Tokens в JSON + генераторы для каждой платформы**
```
docs/design-system/tokens.json (источник истины)
├── generators/css_generator.py → app/design-tokens/css/theme.css
├── generators/swift_generator.py → app/design-tokens/swift/Colors.swift
└── generators/kotlin_generator.py → app/design-tokens/kotlin/colors.xml
```
---
## Структура tokens.json
```json
{
"version": "1.0.0",
"project": "VoIdea",
"themes": ["system", "dark", "light"],
"colors": {
"primary": {
"500": "#6366F1",
"600": "#4F46E5",
"default": "#6366F1",
"hover": "#4F46E5"
},
"background": {
"system": "auto",
"dark": "#0F172A",
"light": "#FFFFFF"
},
"semantic": {
"error": "#EF4444",
"warning": "#F59E0B",
"success": "#22C55E",
"info": "#3B82F6"
}
},
"typography": {
"font_family": {
"primary": "Inter, system-ui, sans-serif"
},
"size": {
"xs": "0.75rem",
"sm": "0.875rem",
"base": "1rem"
}
},
"spacing": {
"xs": "0.25rem",
"sm": "0.5rem",
"md": "1rem",
"lg": "1.5rem"
},
"border_radius": {
"sm": "0.25rem",
"md": "0.5rem",
"lg": "0.75rem"
}
}
```
---
## Генераторы
### CSS Generator
```python
# docs/design-system/generators/css_generator.py
def generate(tokens: dict) -> str:
css = ":root {\n"
for category, values in tokens.items():
if category == "colors":
for name, value in flatten(values):
css += f" --color-{name}: {value};\n"
elif category == "typography":
for name, value in flatten(values):
css += f" --font-{name}: {value};\n"
elif category == "spacing":
for name, value in flatten(values):
css += f" --spacing-{name}: {value};\n"
css += "}\n"
return css
```
**Выход:** `app/design-tokens/css/theme.css`
```css
:root {
--color-primary: #6366F1;
--color-background-dark: #0F172A;
--font-family-primary: Inter, system-ui, sans-serif;
--spacing-md: 1rem;
}
```
---
### Swift Generator
```python
# docs/design-system/generators/swift_generator.py
def generate(tokens: dict) -> str:
swift = "import SwiftUI\n\n"
swift += "enum Colors {\n"
for name, value in flatten(tokens["colors"]):
snake_to_camel = to_camel_case(name)
swift += f' static let {snake_to_camel} = Color(hex: "{value}")\n'
swift += "}\n"
swift += "enum Typography {\n"
# ... font generation
return swift
```
**Выход:** `app/design-tokens/swift/Colors.swift`
```swift
import SwiftUI
enum Colors {
static let primary = Color(hex: "#6366F1")
static let backgroundDark = Color(hex: "#0F172A")
}
enum Typography {
static let fontFamilyPrimary = "Inter"
static let fontSizeBase: CGFloat = 16
}
```
---
### Kotlin Generator
```python
# docs/design-system/generators/kotlin_generator.py
def generate(tokens: dict) -> str:
xml = '<?xml version="1.0" encoding="utf-8"?>\n'
xml += '<resources>\n'
for name, value in flatten(tokens["colors"]):
safe_name = name.replace("_", "_")
xml += f' <color name="{safe_name}">{value}</color>\n'
xml += '</resources>\n'
return xml
```
**Выход:** `app/design-tokens/kotlin/colors.xml`
```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#6366F1</color>
<color name="background_dark">#0F172A</color>
</resources>
```
---
## Темы
### System (Auto)
```css
@media (prefers-color-scheme: dark) {
:root[data-theme="system"] {
--color-background: #0F172A;
--color-text: #F8FAFC;
}
}
@media (prefers-color-scheme: light) {
:root[data-theme="system"] {
--color-background: #FFFFFF;
--color-text: #0F172A;
}
}
```
### Dark / Light
```css
[data-theme="dark"] {
--color-background: #0F172A;
--color-text: #F8FAFC;
}
[data-theme="light"] {
--color-background: #FFFFFF;
--color-text: #0F172A;
}
```
---
## CI/CD Integration
```yaml
# .github/workflows/design-system.yml
on:
push:
paths:
- 'docs/design-system/tokens.json'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate CSS
run: python -m generators css
- name: Generate Swift
run: python -m generators swift
- name: Generate Kotlin
run: python -m generators kotlin
- name: Commit
run: |
git add app/design-tokens/
git commit -m "style: regenerate design tokens"
git push
```
---
## Правила использования
1. **Никогда не редактировать сгенерированные файлы вручную**
2. **Все изменения только в tokens.json**
3. **После изменения tokens.json → запустить генераторы**
4. **DocAgent обновляет документацию**
---
## Maintenance
### Обновление tokens.json
1. Открыть `docs/design-system/tokens.json`
2. Внести изменения
3. Запустить `python -m generators all`
4. Проверить сгенерированные файлы
5. Зафиксировать в git
### Добавление новых token
```json
{
"new_token": {
"system": "auto",
"dark": "#value",
"light": "#value"
}
}
```
---
## Последствия
### Положительные
- Единый источник истины
- Согласованность между платформами
- Легко добавлять темы
- Автоматическая генерация
### Отрицательные
- Дополнительный слой абстракции
- Требует генерацию при изменениях
- Разные форматы вывода
---
## Ответственный
**Decision maker:** Frontend team
**Review date:** При добавлении новой платформы
---
*Создано: 2026-05-10*
*Обновляется DocAgent при изменениях*
+156
View File
@@ -0,0 +1,156 @@
# ADR-006: Версионирование агентов
**Статус:** принято
**Дата:** 2026-05-10
---
## Контекст
11 системных агентов VoIdea самообучаются — их код, промпты и capabilities изменяются
автоматически через EvolutionAgent или вручную. Без контроля версий невозможно:
- Отследить, когда и какой агент изменился
- Понять, какие изменения были внесены
- Откатить агента до предыдущей версии при проблемах
- Синхронизировать версии агентов между окружениями (local → VPS)
Рассматривались:
- **Единая версия для всех** — не отражает индивидуальных изменений
- **Только git** — не покрывает runtime-эволюцию (изменение промптов без коммита)
- **A.B.C для каждого агента** — точный контроль, авто-детект изменений
---
## Решение
**A.B.C (SemVer) для каждого агента**, changelog в `CHANGELOG/agents/<name>.md`.
### Правила бампа
| Компонент | Когда меняется | Кто меняет |
|-----------|---------------|------------|
| **A (major)** | Breaking change: сигнатура `run()` или публичные методы | EvolutionAgent (анализ кода) |
| **B (minor)** | Новая capability: новый метод, новый prompt, новая роль | EvolutionAgent (добавление capability) |
| **C (patch)** | Внутренние правки: багфикс, оптимизация, уточнение промпта | Сам агент (авто-сравнение checksum) |
### Механика
```
Каждый Agent.run()
→ compute_checksum() — SHA256 от __file__ агента
→ сравнивает с AgentConfig.checksum в БД
→ не совпал → bump_version("patch") → запись в changelog → обновление БД
→ совпал → ничего
EvolutionAgent
→ добавляет capability → bump_version("minor") → запись в changelog
→ обнаружил breaking change → bump_version("major") → запись в changelog
```
### Хранение
```
CHANGELOG/agents/
├── doc_agent.md
├── audit_agent.md
├── security_agent.md
├── spec_agent.md
├── observer_agent.md
├── qa_tester_agent.md
├── fix_agent.md
├── ui_test_agent.md
├── rollout_agent.md
├── evolution_agent.md
└── backlog_agent.md
```
Формат changelog агента:
```markdown
# audit_agent Changelog
## 1.0.2 (2026-05-10)
- Fixed: ruff output parsing for Windows paths
## 1.0.1 (2026-05-09)
- Fixed: missing error handling in health_check
## 1.0.0 (2026-05-08)
- Initial version
```
### Разделение ответственности
| Аспект | Владелец | Где хранится |
|--------|----------|--------------|
| Версия проекта | SpecAgent | `project.json`, `CHANGELOG/v*.md` |
| Версия агента | EvolutionAgent | `AgentConfig.version` (БД) |
| Changelog проекта | SpecAgent | `CHANGELOG/v*.md` |
| Changelog агента | EvolutionAgent | `CHANGELOG/agents/<name>.md` |
---
## Архитектура
### Изменения в моделях БД
```python
class AgentConfig(SQLBase, UUIDMixin, TimestampMixin):
__tablename__ = "agent_configs"
agent_name: str # unique
is_enabled: bool
version: str # "1.0.0" — новое поле
checksum: str # SHA256 — новое поле
config: str | None # JSON
last_run_at: datetime # DateTime вместо String
```
### Изменения в BaseAgent
```python
class BaseAgent(ABC):
name: str
version: str = "1.0.0"
CHANGELOG_DIR = "CHANGELOG/agents/"
def compute_checksum(self) -> str:
"""SHA256 от __file__ агента"""
...
def bump_version(self, version_type: str = "patch") -> str:
"""Увеличить A/B/C, обновить self.version"""
...
def write_changelog(self, version: str, entries: list[str]) -> None:
"""Дописать запись в CHANGELOG/agents/<name>.md"""
...
```
---
## Последствия
### Положительные
- Полная traceability изменений каждого агента
- Автоматическое версионирование без участия человека
- Совместимо с git (checksum детектит и runtime-изменения)
- Единый формат changelog для всех агентов
### Отрицательные
- Дополнительная нагрузка на БД (чтение/запись checksum при каждом run)
- SHA256 файла не детектит изменения в импортируемых зависимостях
- Patch-версия может расти быстро при частых правках
---
## Ответственный
**Decision maker:** Owner
**Review date:** При изменении архитектуры агентов
---
*Создано: 2026-05-10*
+40
View File
@@ -0,0 +1,40 @@
# Управление промптами агентов
## Принцип
Промпты — это код. Они версионируются, хранятся в репозитории и проходят code review. Никаких hardcoded промптов в Python-коде.
## Где хранить
В VoIdea используется **два формата** с fallback:
| Формат | Расположение | Назначение |
|--------|-------------|------------|
| YAML | `docs/agent_prompts.yaml` | Настройки провайдера, температуры, токенов |
| Markdown | `docs/specs/agents/<role>.md` | Детальные промпты с примерами |
`PromptLoader` пробует YAML первым, если не нашёл — падает на MD-спецификацию.
## Структура YAML
```yaml
coordinator:
provider: yandex_gpt # yandex_gpt | gigachat
temperature: 0.7 # 0.0-1.0
max_tokens: 2000 # макс. длина ответа
```
## Структура MD
```markdown
# Роль
**Провайдер:** Yandex GPT
**Температура:** 0.7
**Макс. токенов:** 2000
## Prompt Template
```
Ты — {role}. Описание.
```
```
+50
View File
@@ -0,0 +1,50 @@
# Паттерны промптов
## 1. System + User разделение
```python
system_prompt = "Ты — бизнес-аналитик. Анализируй идеи."
user_prompt = f"Название: {idea.title}\nОписание: {idea.content}"
full_prompt = f"{system_prompt}\n\n{user_prompt}"
```
Используется: `AIProvider.format_prompt()`
## 2. Structured output
```python
system_prompt = """
Ты — финансовый консультант.
Ответ верни ТОЛЬКО в формате JSON:
{
"roi": число,
"risk_level": "low|medium|high",
"recommendations": [строка, ...]
}
"""
```
## 3. Few-shot (примеры)
```python
system_prompt = """
Ты — UI-дизайнер. Анализируй интерфейс.
Пример хорошего анализа:
Интерфейс: Экран входа
Проблема: Кнопка "Забыли пароль" не видна
Рекомендация: Высокий приоритет
Теперь проанализируй:
"""
```
## Параметры
| Параметр | Значение | Когда |
|----------|----------|-------|
| `temperature: 0.1-0.3` | Низкая | Юридические, финансовые |
| `temperature: 0.5-0.7` | Средняя | Стандартный анализ |
| `temperature: 0.8-1.0` | Высокая | Мозговой штурм |
| `max_tokens: 500` | Короткий | Классификация |
| `max_tokens: 4000` | Длинный | Детальный анализ |
+48
View File
@@ -0,0 +1,48 @@
# Хранение и загрузка промптов
## Загрузчик (PromptLoader)
```python
# app/integrations/ai/prompt_loader.py
def get_prompt_config(role: str) -> dict | None:
# 1. Пробуем YAML (docs/agent_prompts.yaml)
config = load_prompt_from_yaml(role)
if config:
return config
# 2. Пробуем MD (docs/specs/agents/<role>.md)
return load_prompt_from_spec(role)
```
## Порядок загрузки
1. `docs/agent_prompts.yaml` — если существует, ищет роль по ключу
2. `docs/specs/agents/<role>.md` — если YAML не дал результата, парсит MD
## Пример YAML-файла
```yaml
# docs/agent_prompts.yaml
coordinator:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
business_analyst:
provider: yandex_gpt
temperature: 0.5
max_tokens: 3000
```
## Пример MD-файла
```markdown
# docs/specs/agents/business_analyst.md
**Провайдер:** Yandex GPT
**Температура:** 0.5
## Prompt Template
```
Ты — бизнес-аналитик. Проанализируй идею...
```
```
@@ -0,0 +1,19 @@
# {Role Name}
**Провайдер:** {yandex_gpt | gigachat}
**Температура:** {0.1-1.0}
**Макс. токенов:** {500-4000}
## Описание
{Краткое описание роли AI-агента}
## Prompt Template
```text
Ты — {role_name}. {описание}.
{инструкции}
{формат ответа}
```
@@ -0,0 +1,14 @@
# Шаблон промпта в YAML
# Используйте как основу для нового AI-агента
role_name:
system_prompt: |
Ты — {role_name}. {описание роли}.
{инструкции}
{формат ответа}
provider: yandex_gpt # или gigachat
temperature: 0.7 # 0.1-1.0
max_tokens: 2000 # макс. длина
model: "" # опционально: конкретная модель
+57
View File
@@ -0,0 +1,57 @@
# Agent Prompts Configuration
# PromptLoader loads this first, falls back to docs/specs/agents/<role>.md
coordinator:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
business_analyst:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
architect:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
financial_advisor:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
lawyer:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
life_coach:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
organizer:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
smm_specialist:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
ui_designer:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
tester:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
accessibility_expert:
provider: yandex_gpt
temperature: 0.7
max_tokens: 2000
+31
View File
@@ -0,0 +1,31 @@
# Обзор системных агентов
## Что такое системный агент
Системный агент автоматизирует поддержку и развитие проекта. В отличие от AI-агента (анализирует идеи пользователя), системный агент работает **над проектом**: пишет документацию, проверяет правила, версионирует код.
## Список всех 11 агентов
| # | Агент | Роль | Триггеры |
|---|-------|------|----------|
| 1 | **DocAgent** | Пишет документацию | pre-commit, manual |
| 2 | **AuditAgent** | Проверяет правила и согласованность | pre-commit, push, cron |
| 3 | **EvolutionAgent** | Версионирует агентов (A.B.C + SHA256) | cron, event, manual |
| 4 | **SupervisorAgent** | Мониторит здоровье всех агентов | cron, event, manual |
| 5 | **BacklogAgent** | Управляет техдолгом и TODO | pre-commit, manual |
| 6 | **SpecAgent** | Управляет версией проекта, CHANGELOG | release, manual |
| 7 | **ObserverAgent** | Собирает метрики использования | cron, event |
| 8 | **SecurityAgent** | Проверяет конфиги, зависимости | pre-commit, cron |
| 9 | **QATesterAgent** | Проверяет тестовое покрытие | pre-commit, push |
| 10 | **FixAgent** | Анализирует и предлагает исправления | event, manual |
| 11 | **UITestAgent** | Визуальное тестирование UI | cron, manual |
| 12 | **RolloutAgent** | Постепенное развёртывание | release, manual |
## Когда добавлены
- **Ядро (1-4)**: с первого коммита
- **Расширение (5-12)**: по мере необходимости, все добавлены
## Статус
Все 12 агентов написаны и зарегистрированы в `AgentRegistry`. Через API `/api/v1/agents` доступны полностью.
+42
View File
@@ -0,0 +1,42 @@
# Стратегия тестирования API
## 9 обязательных сценариев
| # | Сценарий | Статус | Пример |
|---|----------|--------|--------|
| 1 | Missing field → 422 | Обязателен | `POST /ideas` без body |
| 2 | Wrong type → 422 | Обязателен | `title: 123` вместо строки |
| 3 | Invalid/expired token → 401 | Обязателен | `Authorization: Bearer bad` |
| 4 | Wrong permissions → 403 | Обязателен | user пытается в /admin |
| 5 | Not found → 404 | Обязателен | `GET /ideas/nonexistent` |
| 6 | Conflict → 409 | Обязателен | Дубликат email при регистрации |
| 7 | Success → 200/201 | Обязателен | Успешный CRUD |
| 8 | Rate limit → 429 | Когда реализован | 100 запросов подряд |
| 9 | Idempotency | Для DELETE/PATCH | Повторный delete → 404 |
## Цель: 4 группы endpoints
```
tests/integration/
├── conftest.py # async_client, auth headers
├── test_auth.py # register / login / refresh
├── test_ideas.py # CRUD + analyze
├── test_users.py # profile
└── test_admin.py # users / health / logs
```
Каждый файл — минимум 9 тестов (по 1 на сценарий). Итого ~36 тестов.
## Структура теста
```python
async def test_create_idea_success(async_client, user_token):
response = await async_client.post(
"/api/v1/ideas",
json={"title": "Test", "content": "Content"},
headers={"Authorization": f"Bearer {user_token}"},
)
assert response.status_code == 201
data = response.json()
assert data["title"] == "Test"
```
+27
View File
@@ -0,0 +1,27 @@
/* Auto-generated from design tokens — do not edit manually */
:root {
--color-primary-50: #EEF2FF;
--color-primary-500: #6366F1;
--color-primary-600: #4F46E5;
--color-primary: #6366F1;
--color-primary-hover: #4F46E5;
--color-background-dark: #0F172A;
--color-background-light: #FFFFFF;
--color-text-primary: {'system': 'auto', 'dark': '#F8FAFC', 'light': '#0F172A'};
--color-semantic-error: #EF4444;
--color-semantic-warning: #F59E0B;
--color-semantic-success: #22C55E;
--color-semantic-info: #3B82F6;
--font-primary: Inter, system-ui, sans-serif;
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
}
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" ?>
<resources>
<color name="primary_50">#FFEEF2FF</color>
<color name="primary_500">#FF6366F1</color>
<color name="primary_600">#FF4F46E5</color>
<color name="primary">#FF6366F1</color>
<color name="primary">#FF4F46E5</color>
<color name="background_dark">#FF0F172A</color>
<color name="background_light">#FFFFFFFF</color>
<color name="semantic_error">#FFEF4444</color>
<color name="semantic_warning">#FFF59E0B</color>
<color name="semantic_success">#FF22C55E</color>
<color name="semantic_info">#FF3B82F6</color>
<dimen name="spacing_xs">4dp</dimen>
<dimen name="spacing_sm">8dp</dimen>
<dimen name="spacing_md">16dp</dimen>
<dimen name="spacing_lg">24dp</dimen>
</resources>
+20
View File
@@ -0,0 +1,20 @@
// Auto-generated from design tokens do not edit manually
import SwiftUI
extension Color {
static let primary50 = Color(red: 0.9333, green: 0.9490, blue: 1.0000)
static let primary500 = Color(red: 0.3882, green: 0.4000, blue: 0.9451)
static let primary600 = Color(red: 0.3098, green: 0.2745, blue: 0.8980)
static let primary = Color(red: 0.3882, green: 0.4000, blue: 0.9451)
static let primary = Color(red: 0.3098, green: 0.2745, blue: 0.8980)
static let backgroundDark = Color(red: 0.0588, green: 0.0902, blue: 0.1647)
static let backgroundLight = Color(red: 1.0000, green: 1.0000, blue: 1.0000)
static let semanticError = Color(red: 0.9373, green: 0.2667, blue: 0.2667)
static let semanticWarning = Color(red: 0.9608, green: 0.6196, blue: 0.0431)
static let semanticSuccess = Color(red: 0.1333, green: 0.7725, blue: 0.3686)
static let semanticInfo = Color(red: 0.2314, green: 0.5098, blue: 0.9647)
static let spacingXs = CGFloat(0.25)
static let spacingSm = CGFloat(0.5)
static let spacingMd = CGFloat(1)
static let spacingLg = CGFloat(1.5)
}
+71
View File
@@ -0,0 +1,71 @@
# Архитектура VoIdeaAI
## Слои
```
┌──────────────────────────────────────────────────┐
│ API (FastAPI) │
│ HTTP роуты / Pydantic / OpenAPI / StaticFiles │
│ → Services │
├──────────────────────────────────────────────────┤
│ Services │
│ Бизнес-логика: auth, idea, user, agent, sync │
│ → Integrations, Data │
├──────────────────────────────────────────────────┤
│ Integrations │
│ AI Fallback Chain (YandexGPT → GigaChat) │
│ → Data │
├──────────────────────────────────────────────────┤
│ Tasks (Celery) │
│ Асинхронный анализ идей, прямой вызов при │
│ отсутствии Celery │
│ → Services, Integrations │
├──────────────────────────────────────────────────┤
│ Agents │
│ 11 системных агентов (Doc → Supervisor) │
│ → Services, Integrations │
├──────────────────────────────────────────────────┤
│ Data (SQLAlchemy) │
│ Модели: User, Idea, AgentConfig, BacklogTask, │
│ LogEntry, AgentReport, AgentMetrics │
│ → Core │
├──────────────────────────────────────────────────┤
│ Core │
│ Config, base, exceptions, security, dependencies │
│ Фундамент, не зависит ни от чего │
└──────────────────────────────────────────────────┘
```
## Ключевые решения
| Решение | Выбор | Причина |
|---------|-------|---------|
| БД | PostgreSQL (asyncpg) | Единая БД на всех этапах. VPS Ubuntu. |
| Фронтенд | FastAPI StaticFiles | Без Nginx, без Docker. One process |
| Фоновые задачи | Celery / прямой вызов | Graceful degradation при отсутствии Redis |
| AI провайдеры | FallbackChain: YandexGPT → GigaChat | 2 retry, таймауты |
| Аутентификация | JWT (access + refresh) | Stateless, без сессий |
| Версионирование агентов | A.B.C + SHA256 checksum | Независимое версионирование |
| Деплой | systemd + venv | Напрямую на VPS, без контейнеризации |
## DI и зависимости
```python
async def get_db() -> AsyncSession:
async with async_session_maker() as session:
yield session
class IdeaService:
def __init__(self, db: AsyncSession): ...
class AuthService:
def __init__(self, db: AsyncSession, settings: Settings): ...
```
## Правила слоёв
1. **API** не знает про БД — использует `Depends(get_db)` и сервисы
2. **Services** не импортируют HTTP — работают с бизнес-данными
3. **Integrations** оборачивают внешние API с таймаутами и ретраями
4. **Data** — SQLAlchemy модели без бизнес-логики
5. **Core** — фундамент без внешних зависимостей
+149
View File
@@ -0,0 +1,149 @@
# Agent Evolution System - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog
---
## Обзор
Система саморазвития агентов для адаптации к новым задачам и улучшения работы.
---
## Структура
### Файл эволюции агента
```yaml
# docs/agents/evolution.yaml
agents:
qa_tester:
version: 1.0
capabilities:
- functional_testing
- temp_user_creation
- cleanup
evolution_history:
- date: 2026-05-10
trigger: "Initial creation"
change: "Added basic testing capabilities"
success: true
next_potential_skills:
- performance_testing
- security_testing
fix:
version: 1.0
capabilities:
- bug_analysis
- code_fix
- pr_creation
evolution_history:
- date: 2026-05-10
trigger: "Initial creation"
change: "Basic fix capabilities"
success: true
next_potential_skills:
- refactoring
- optimization
```
---
## Триггеры эволюции
### 1. Автоматические
- **Успешное выполнение задачи** → агент обучается
- **Повторяющиеся паттерны** → оптимизация
- **Новые типы задач** → добавление capability
### 2. Ручные (человек)
- Добавление нового навыка
- Изменение поведения
- Приоритетная настройка
### 3. ObserverAgent
- Выявление потребности в новых навыках
- Анализ узких мест
- Предложения по улучшению
---
## Процесс эволюции
```
1. Сбор данных
→ ObserverAgent фиксирует паттерны
2. Анализ
→ EvolutionAgent анализирует эффективность
3. Предложение
→ Генерирует варианты улучшений
4. Тестирование
→ QATesterAgent тестирует новые возможности
5. Внедрение
→ DocAgent обновляет документацию
→ SpecAgent обновляет спецификации
6. Мониторинг
→ Отслеживание результатов
```
---
## Меж-агентское взаимодействие
### Делегирование задач
Агенты могут делегировать друг другу:
```python
# Пример: FixAgent → DocAgent
FixAgent.fix_bug(bug_id) DocAgent.update_docs()
```
Правила делегирования:
1. Агент A видит задачу для агента B
2. Проверяет доступность B
3. Отправляет задачу
4. B выполняет и возвращает результат
5. A продолжает работу
### Резервные агенты
При недоступности агента:
1. Поиск агента с похожими capabilities
2. Делегирование задачи
3. Уведомление человека (если критично)
---
## Метрики эволюции
- Tasks completed successfully
- Tasks failed
- Average execution time
- Self-improvements count
- Delegations made/received
---
## TODO
- [ ] Создать evolution.yaml
- [ ] Реализовать EvolutionAgent
- [ ] Добавить механизм меж-агентского взаимодействия
- [ ] Интегрировать с ObserverAgent
- [ ] Настроить мониторинг метрик
- [ ] Документировать процесс эволюции
---
*Создано: 2026-05-10*
*Управляется EvolutionAgent*
+45
View File
@@ -0,0 +1,45 @@
# Car Integration Note - VoIdea
**Date:** 2026-05-10
**Status:** Backlog
---
## Overview
Research and implement car head unit integration for VoIdea app.
---
## Research Topics
1. Android Auto
- How apps integrate
- Voice input support
- Requirements
2. Apple CarPlay
- Same as above for iOS
3. Bluetooth HID
- Universal controller support
- Gamepad protocol
4. CAN Bus
- Steering wheel buttons
- Complex integration
- Hardware requirements
---
## Action Items
- [ ] Research Android Auto app development
- [ ] Research Apple CarPlay requirements
- [ ] Test Bluetooth HID on Android
- [ ] Document findings
- [ ] Create integration plan
---
*Created: 2026-05-10*
+172
View File
@@ -0,0 +1,172 @@
# CHANGELOG Generation - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog
---
## Обзор
Автоматическая генерация CHANGELOG на основе коммитов и conventional commits.
---
## Структура файлов
```
CHANGELOG/
├── v1.0.md # При смене MAJOR (1.0.0 -> 1.1.0 -> ...)
├── v1.1.md # При смене MINOR
├── v2.0.md # При смене MAJOR
└── ...
```
### Правила
- **MAJOR (X)** → новый файл vX.0.md
- **MINOR (Y)** → новый файл vX.Y.md
- **PATCH (Z)** → добавляется в конец существующего файла
---
## Формат CHANGELOG файла
```markdown
# Changelog v1.0
## [1.0.5] - 2026-05-10
### Added
- Feature X (commit: abc123)
### Fixed
- Bug Y (commit: def456)
## [1.0.4] - 2026-05-09
### Added
- ...
## [1.0.0] - 2026-05-01
### Added
- Initial release
```
---
## Conventional Commits
| Тип | Влияние |
|-----|---------|
| `feat:` | Added (MINOR) |
| `fix:` | Fixed (PATCH) |
| `docs:` | Changed (no version) |
| `refactor:` | Changed (no version) |
| `test:` | Changed (no version) |
| `chore:` | Changed (no version) |
| `BREAKING:` | Major (MAJOR) |
---
## Генерация
### SpecAgent responsibilities
1. **Мониторинг тегов**
- При создании нового тега → запуск генерации
2. **Анализ коммитов**
- Парсинг conventional commits
- Группировка по типу
3. **Генерация файла**
- Определение какой файл создать/обновить
- Формирование записей
4. **Проверка**
- Валидация формата
- Сохранение в CHANGELOG/
---
## CI/CD Integration
### При push в main
```yaml
# .github/workflows/changelog.yml
name: Changelog
on:
push:
branches: [main]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Changelog
run: python scripts/generate_changelog.py
- name: Commit
run: |
git add CHANGELOG/
git commit -m "docs: update changelog"
git push
```
### При создании тега
```python
# scripts/generate_changelog.py
import git
from pathlib import Path
def generate_changelog(tag: str):
commits = get_commits_since_last_tag()
changes = {
'added': [],
'fixed': [],
'changed': []
}
for commit in commits:
type, message = parse_conventional_commit(commit.message)
changes[type].append(f"- {message} ({commit.hash[:7]})")
update_changelog_file(tag, changes)
```
---
## Ручная генерация
```bash
# При необходимости
python scripts/generate_changelog.py --tag 1.0.0 --from 0.9.0
```
---
## Автоматическая документация
После генерации:
1. DocAgent обновляет PROJECT_GUIDE.md (ссылка на новую версию)
2. SpecAgent обновляет project.json
3. Уведомление в админ-панель
---
## TODO
- [ ] Создать scripts/generate_changelog.py
- [ ] Настроить CI/CD workflow
- [ ] Интегрировать со SpecAgent
- [ ] Добавить тесты
- [ ] Документировать процесс
---
*Создано: 2026-05-10*
*Управляется SpecAgent*
@@ -0,0 +1,89 @@
# Design System Generators - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog
---
## Обзор
Создание CLI-генераторов для конвертации tokens.json в платформо-специфичные форматы.
---
## Формат
Python CLI скрипты в `docs/design-system/generators/`
```bash
python -m generators css # Генерирует CSS Variables
python -m generators swift # Генерирует Swift
python -m generators kotlin # Генерирует Kotlin XML
python -m generators all # Генерирует все форматы
```
---
## Генераторы
### 1. CSS Generator
**Вход:** `docs/design-system/tokens.json`
**Выход:** `app/design-tokens/css/theme.css`
**Формат выхода:**
```css
:root {
--color-primary: #6366F1;
--color-background-dark: #0F172A;
--spacing-md: 1rem;
}
```
### 2. Swift Generator
**Выход:** `app/design-tokens/swift/Colors.swift`
**Формат выхода:**
```swift
struct Colors {
static let primary = Color(hex: "#6366F1")
static let backgroundDark = Color(hex: "#0F172A")
}
```
### 3. Kotlin Generator
**Выход:** `app/design-tokens/kotlin/colors.xml`
**Формат выхода:**
```xml
<resources>
<color name="primary">#6366F1</color>
<color name="background_dark">#0F172A</color>
</resources>
```
---
## Интеграция
- Генераторы запускаются при изменении `tokens.json`
- CI/CD автоматизирует генерацию
- DocAgent обновляет документацию
---
## TODO
- [ ] Создать структуру генераторов
- [ ] Реализовать CSS Generator
- [ ] Реализовать Swift Generator
- [ ] Реализовать Kotlin Generator
- [ ] Интегрировать в CI/CD
- [ ] Добавить тесты
---
*Создано: 2026-05-10*
*Обновляется автоматически DocAgent*
+143
View File
@@ -0,0 +1,143 @@
# Export Formats - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (часть WebUI)
---
## Обзор
Экспорт идей в различных форматах для резервного копирования и интеграции.
---
## Поддерживаемые форматы
### 1. JSON
**Использование:** Резервное копирование, импорт в другие системы
```json
{
"version": "1.0.0",
"exported_at": "2026-05-10T12:00:00Z",
"ideas": [
{
"id": "uuid",
"title": "Моя идея",
"content": "Описание",
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-05T15:30:00Z",
"analysis": {
"coordinator": {...},
"organizer": {...}
}
}
]
}
```
### 2. Markdown
**Использование:** Интеграция с Obsidian, Notion, блогами
```markdown
# Моя идея
## Описание
Текст идеи
## Анализ
### Координатор
...
### Организатор
...
*Экспортировано: 2026-05-10*
```
### 3. PDF
**Использование:** Печать, отчёты, презентации
- Титульный лист с датой
- Оглавление
- Каждая идея — отдельная секция
- Анализ ИИ-агентов
### 4. CSV (опционально)
**Использование:** Аналитика, таблицы
```csv
id,title,created_at,analysis_count
uuid,Моя идея,2026-05-01,5
```
---
## API
```python
# Экспорт всех идей пользователя
GET /api/v1/export?format=json|markdown|pdf
# Экспорт одной идеи
GET /api/v1/ideas/{id}/export?format=json|markdown|pdf
# Параметры
?include_analysis=true # Включить ИИ-анализ
?include_metadata=true # Включить метаданные
```
---
## Обработка больших объёмов
1. **Асинхронная генерация** — Celery task
2. **Progress tracking** — WebSocket/SSE
3. **Download link** — после завершения
```python
# Celery task
@celery.task
def generate_export(user_id: UUID, format: str):
# 1. Создать задачу
export_task = create_export_task(user_id, format)
# 2. Генерация
result = await generate_file(export_task)
# 3. Уведомление
await notify_user(user_id, export_task.id)
return result
```
---
## Права доступа
- Экспорт только своих идей
- Анализ доступен только владельцу
- Логирование всех экспортов
---
## TODO
- [ ] Создать export service
- [ ] Реализовать JSON export
- [ ] Реализовать Markdown export
- [ ] Реализовать PDF export (weasyprint)
- [ ] Асинхронная генерация
- [ ] UI (кнопка экспорта)
- [ ] Тесты
- [ ] Документация
---
*Создано: 2026-05-10*
*Часть WebUI (Block 4)*
+181
View File
@@ -0,0 +1,181 @@
# FixAgent Mechanism - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog
---
## Обзор
Агент для автоматического анализа и исправления багов с созданием PR.
---
## Архитектура
### FixAgent responsibilities
1. **Анализ багов**
- Получение данных от QATesterAgent
- Анализ логов
- Определение причины
2. **Генерация исправлений**
- Написание кода
- Создание тестов
- Обновление документации
3. **Создание PR**
- Формирование pull request
- Описание изменений
- Добавление тестов
---
## Процесс работы
```python
async def fix_bug(bug_data: BugReport) -> FixResult:
# 1. Анализ
analysis = await analyze_bug(bug_data)
# 2. Поиск решения
solution = await find_solution(analysis)
# 3. Генерация кода
fix_code = await generate_fix(solution)
# 4. Создание PR
pr_url = await create_pr(fix_code, analysis)
# 5. Уведомление
await notify_about_pr(pr_url)
return FixResult(pr_url=pr_url)
```
---
## Анализ багов
### Источники данных
1. **QATesterAgent**
- Failed тесты
- Логи выполнения
- Скриншоты (если есть)
2. **Логи системы**
- Error логи
- Warning логи
- Traceback
3. **Пользовательские отчёты**
- Feedback из админ-панели
- Exception reports
### Типы анализа
- **Static analysis** — код ревью
- **Log analysis** — поиск паттернов
- **Test replay** — воспроизведение
---
## Генерация исправлений
### Правила
1. **Минимальные изменения** — исправлять только проблему
2. **Не ломать существующее** — регрессионные тесты
3. **Документация** — обновлять комментарии и docs
4. **Тесты** — добавлять новые тесты для предотвращения
### Формат PR
```markdown
## Fix: [Краткое описание]
### Проблема
[Описание бага]
### Причина
[Найденная причина]
### Решение
[Описание исправления]
### Тесты
- [ ] Добавлен тест для предотвращения
- [ ] Существующие тесты проходят
### Логи
[Связанные логи]
```
---
## Взаимодействие с другими агентами
### QATesterAgent
```
FixAgent → "Исправь баг X"
QATesterAgent → "Проверь исправление"
```
### DocAgent
```
FixAgent → "Обнови документацию"
DocAgent → "Документация обновлена"
```
### RolloutAgent
```
FixAgent → "Обнаружен критический баг"
RolloutAgent → "Приостановить rollout, исправить"
```
---
## Безопасность
### Ограничения
1. **Только PR, не direct push** — человек проверяет
2. **Scope ограничен** — один файл за раз
3. **Тесты обязательны** — без тестов PR не создаётся
4. **Логирование** — все действия фиксируются
### Что НЕ делает FixAgent
- Не удаляет файлы
- Не меняет чужие PR
- Не коммитит в main напрямую
- Не создаёт бесконечных PR (лимит: 3 на один баг)
---
## Метрики
- Bugs fixed
- PRs created
- PRs merged
- Average fix time
- False positives
---
## TODO
- [ ] Реализовать FixAgent
- [ ] Интегрировать с QATesterAgent
- [ ] Добавить анализ логов
- [ ] Создать шаблон PR
- [ ] Настроить безопасность
- [ ] Добавить метрики
- [ ] Написать тесты
---
*Создано: 2026-05-10*
*Управляется FixAgent*
+122
View File
@@ -0,0 +1,122 @@
# Hotkeys System - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (часть WebUI)
---
## Обзор
Настраиваемая система горячих клавиш для быстрого управления приложением.
---
## Структура хранения
### База данных (primary)
```sql
CREATE TABLE user_hotkeys (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
action VARCHAR(50) NOT NULL,
key_combination VARCHAR(100) NOT NULL,
modifier VARCHAR(20),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
```
### localStorage (backup for offline)
```javascript
// Ключ: 'voidea_hotkeys'
{
"new_idea": "ctrl+n",
"save": "ctrl+s",
"search": "/"
}
```
---
## Синхронизация
1. При входе → загрузить настройки из БД
2. При изменении → обновить БД и localStorage
3. При оффлайн → использовать localStorage
4. При восстановлении → sync БД → localStorage
---
## Дефолтные горячие клавиши
| Действие | Клавиша | Описание |
|----------|---------|----------|
| Новая идея | `Ctrl+N` | Создать новую идею |
| Сохранить | `Ctrl+S` | Сохранить текущее |
| Поиск | `/` | Фокус на поиск |
| Навигация вверх | `J` или `↑` | Предыдущая идея |
| Навигация вниз | `K` или `↓` | Следующая идея |
| Отправить на анализ | `Ctrl+Enter` | Запустить ИИ-анализ |
| Настройки | `Ctrl+,` | Открыть настройки |
| Помощь | `?` | Показать справку |
| Отмена | `Escape` | Закрыть модалку |
| Undo | `Ctrl+Z` | Отменить действие |
| Redo | `Ctrl+Shift+Z` | Повторить действие |
---
## UI настройки
### Страница настроек
```
├── Настройки
│ ├── Горячие клавиши
│ │ ├── Список действий
│ │ ├── Поле ввода (нажмите клавишу)
│ │ ├── Сброс на дефолт
│ │ └── Сохранить
```
### Ввод новой комбинации
1. Клик на поле ввода
2. Нажатие клавиши/комбинации
3. Автоматическое сохранение
4. Валидация (не конфликтует с системой)
---
## Обработка конфликтов
1. **Системные клавиши** (Ctrl+Alt+Del) — запрещено переназначать
2. **Браузерные** (Ctrl+T) — предупреждение
3. **Между пользователями** — индивидуально
---
## Поддерживаемые модификаторы
- `Ctrl` / `Cmd` (Mac)
- `Alt` / `Option`
- `Shift`
- Комбинации: `Ctrl+Shift+N`
---
## TODO
- [ ] Создать модель user_hotkeys
- [ ] Реализовать хуки для клавиш
- [ ] Добавить UI настроек
- [ ] Синхронизация БД ↔ localStorage
- [ ] Обработка конфликтов
- [ ] Тесты
- [ ] Документация для пользователей
---
*Создано: 2026-05-10*
*Часть WebUI (Block 4)*
+145
View File
@@ -0,0 +1,145 @@
# OAuth Schema - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (для фиксации ADR)
---
## Обзор
Схема авторизации: один пользователь = один провайдер. Нельзя привязать Google если уже есть Яндекс.
---
## Правила
### Основное правило
> Один пользователь = один провайдер (email или OAuth)
Это означает:
- Если зарегистрировался через Яндекс → только Яндекс
- Если зарегистрировался через Google → только Google
- Если зарегистрировался через email → только email + пароль
### Нельзя
- Привязать Google к аккаунту зарегистрированному через Яндекс
- Добавить второй OAuth провайдер
- Изменить email после регистрации через OAuth
---
## Структура данных
### Users table
```sql
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE,
password_hash VARCHAR(255), -- NULL если OAuth-only
-- OAuth данные (один провайдер)
oauth_provider VARCHAR(20), -- yandex|google|apple|null
oauth_id VARCHAR(255), -- ID в системе провайдера
-- Метаданные
email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- Constraints
CONSTRAINT users_oauth_xor_email CHECK (
(oauth_provider IS NOT NULL AND email IS NOT NULL) OR
(oauth_provider IS NULL AND email IS NOT NULL AND password_hash IS NOT NULL)
)
);
CREATE UNIQUE INDEX uq_users_oauth ON users(oauth_provider, oauth_id) WHERE oauth_provider IS NOT NULL;
```
### Почему один провайдер
1. **Безопасность** — меньше точек входа
2. **Простота** — не нужно merge аккаунтов
3. **Ясность** — пользователь знает что использует
4. **Privacy** — данные не смешиваются между провайдерами
---
## OAuth Flow
### Яндекс
```
1. Пользователь нажимает "Войти через Яндекс"
2. Редирект на Яндекс OAuth
3. Callback с code
4. Получение access_token
5. Получение данных пользователя
6. Поиск/создание user по oauth_provider + oauth_id
7. Создание JWT session
```
### Google
Аналогично Яндексу, с заменой endpoint-ов.
---
## Регистрация через email
```sql
-- При регистрации через email
INSERT INTO users (email, password_hash, oauth_provider, oauth_id)
VALUES ('user@example.com', 'hash123', NULL, NULL);
```
### Вход через email
```sql
-- Проверка пароля
SELECT * FROM users WHERE email = 'user@example.com' AND password_hash = verify('hash123');
```
---
## Защита от привязки чужого аккаунта
### Проблема
Злоумышленник может попытаться привязать Google к чужому email.
### Решение
1. **Email verification** — требуется подтверждение
2. **Password check** — для существующих пользователей
3. **Separate tables** — OAuth и email разделены логически
---
## Будущее (Apple OAuth)
### Apple будет реализован позже
Для Apple потребуется:
- App Store Developer Account
- Private Key для подписи
- Тот же принцип: один пользователь = один провайдер
---
## TODO
- [ ] Реализовать OAuth service
- [ ] Интегрировать Яндекс OAuth
- [ ] Интегрировать Google OAuth
- [ ] Зарезервировать место для Apple (не реализовывать)
- [ ] Тесты
- [ ] Документация
---
*Создано: 2026-05-10*
*См. также: docs/adr/003-oauth-schema.md*
@@ -0,0 +1,52 @@
# Observer Metrics Stages - VoIdea
**Date:** 2026-05-10
**Status:** Backlog
---
## Overview
Phased approach for implementing user observation metrics.
---
## Stage 1: Basic (MVP)
Metrics:
- page_views
- session_duration
- feature_usage_frequency
- conversion_rate
---
## Stage 2: Advanced (after stabilization)
Metrics:
- mouse_movements (heatmap)
- scroll_depth
- hesitation_moments
- speech_to_text_usage
---
## Stage 3: Experimental (v2)
Metrics:
- emotional_tone_voice_input
- time_of_idea_capture_to_completion
- collaboration_attempts
---
## Decision Criteria
Move to next stage when:
- Current stage stable for 1 month
- Infrastructure ready
- Storage/cost acceptable
---
*Created: 2026-05-10*
+175
View File
@@ -0,0 +1,175 @@
# QATesterAgent Mechanism - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog
---
## Обзор
Механизм функционального тестирования с созданием временных аккаунтов и очисткой.
---
## Архитектура
### QATesterAgent responsibilities
1. **Создание временных аккаунтов**
- Уникальный префикс: `test_*`
- Автоматическая генерация данных
- Ограничение по времени жизни
2. **Выполнение тестов**
- Функциональные тесты
- API тесты
- UI тесты (через UITestAgent)
3. **Очистка**
- Удаление временных данных
- Проверка целостности
- Логирование результатов
---
## Процесс работы
```python
async def run_tests(test_config: TestConfig) -> TestResult:
# 1. Создание временных аккаунтов
temp_users = await create_temp_users(count=test_config.count)
try:
# 2. Выполнение тестов
results = []
for user in temp_users:
result = await execute_test_suite(user, test_config)
results.append(result)
# 3. Сохранение результатов
await save_test_results(results)
# 4. Очистка
await cleanup_temp_users(temp_users)
return aggregate_results(results)
except Exception as e:
# При ошибке - очистка обязательна
await cleanup_temp_users(temp_users)
raise
```
---
## Правила очистки
### Безопасность
1. **Никогда не удалять пользователей без `test_` префикса**
2. **Использовать soft delete перед hard delete**
3. **Логировать все операции очистки**
4. **Проверять foreign key constraints**
5. **Тестировать очистку в staging**
### Механизм очистки
```python
async def cleanup_temp_users(users: list[TempUser]):
for user in users:
# 1. Soft delete
await user.soft_delete()
# 2. Проверка связанных данных
related = await check_related_entities(user.id)
if related:
await cleanup_related(related)
# 3. Hard delete (через время)
await schedule_hard_delete(user.id, delay_minutes=5)
```
---
## Конфигурация
```yaml
qa_tester:
max_temp_users: 10 # Максимум одновременно
user_ttl_minutes: 30 # Время жизни
auto_cleanup: true # Автоматическая очистка
cleanup_delay_minutes: 5 # Задержка перед hard delete
tests:
functional:
enabled: true
timeout_seconds: 300
api:
enabled: true
timeout_seconds: 60
ui:
enabled: true # Через UITestAgent
timeout_seconds: 120
```
---
## Триггеры
1. **pre-commit** — автоматически перед merge
2. **Ежедневно** — scheduled в cron
3. **Вручную** — кнопка в админ-панели
4. **После failed тестов** — FixAgent запускает повторно
---
## Статусы
Агент может находиться в состояниях:
- `idle` — готов к работе
- `creating_users` — создаёт temp аккаунты
- `running_tests` — выполняет тесты
- `cleaning` — очищает данные
- `error` — требует внимание
- `offline` — отключён
---
## Отчёты
После каждого теста создаётся отчёт:
```json
{
"test_id": "uuid",
"timestamp": "2026-05-10T12:00:00Z",
"status": "passed|failed",
"users_created": 3,
"users_cleaned": 3,
"tests_run": [
{
"name": "test_create_idea",
"status": "passed",
"duration_ms": 150
}
],
"bugs_found": [],
"logs": "..."
}
```
---
## TODO
- [ ] Реализовать QATesterAgent
- [ ] Создать механизм создания temp users
- [ ] Реализовать безопасную очистку
- [ ] Добавить отчёты в админ-панель
- [ ] Настроить триггеры
- [ ] Интегрировать с FixAgent
- [ ] Написать тесты механизма
---
*Создано: 2026-05-10*
*Управляется QATesterAgent*
+32
View File
@@ -0,0 +1,32 @@
# Rate Limiting Note - VoIdea
**Date:** 2026-05-10
**Status:** Backlog (implement later)
---
## Overview
Implement rate limiting for AI agents and API endpoints.
---
## Requirements
1. Per-user limits based on subscription tier
2. Queue overflow requests (up to 100)
3. 7-day TTL for queued requests
4. User notification on limit
---
## Implementation
- Redis for rate limit counters
- Celery for queue management
- API endpoint for queue status
- Admin panel for limit management
---
*Created: 2026-05-10*
+104
View File
@@ -0,0 +1,104 @@
# Rollout Process - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (для реализации после MVP)
---
## Обзор
Постепенное развёртывание нового функционала для минимизации рисков.
---
## Этапы rollout
```
Stage 0: Development → Тестирование агентами
Stage 1: 3 users → Первые пользователи
Stage 2: 1% → Расширение выборки
Stage 3: 5% → Продолжение
Stage 4: 15% → Почти все
Stage 5: 100% → Production
```
---
## Правила перехода
### Stage 0 → Stage 1 (3 users)
- Все тесты пройдены (QATesterAgent, UITestAgent, FixAgent)
- Решение принимает RolloutAgent или человек
- Полное логирование включено
### Stage 1 → Stage 2 (1%)
- 2 дня без критических ошибок
- Метрики стабильны
- ObserverAgent не фиксирует аномалий
### Stage 2 → Stage 3 (5%)
- Анализ логов stage 1-2
- При проблемах → возврат к stage 1
- Решение: RolloutAgent + человек
### Stage 3 → Stage 4 (15%)
- Продолжение мониторинга
- При проблемах → возврат к stage 3
### Stage 4 → Stage 5 (100%)
- Все проверки пройдены
- Подготовка changelog для магазинов приложений
- Финальное решение человека
---
## Мониторинг
### ObserverAgent отслеживает:
- Error rate (цель: < 1%)
- Response time (цель: < 500ms)
- User complaints (вход в приложение)
- Feature usage (цель: рост)
### При аномалиях:
1. RolloutAgent приостанавливает rollout
2. Направляет логи FixAgent
3. Если проблема подтверждена → исправление
4. После исправления → повторный test Stage 0
5. Если всё стабильно → продолжаем
---
## Контроль человеком
Админ-панель:
- Просмотр текущего stage
- История всех stage переходов
- Кнопка "Приостановить rollout"
- Кнопка "Откатить на предыдущий stage"
- Кнопка "Форсировать переход"
---
## Откат
При критических проблемах:
1. Откат на предыдущую стабильную версию
2. Фиксация проблемы в logs
3. BacklogAgent создаёт задачу
4. Цикл продолжается
---
## TODO
- [ ] Реализовать RolloutAgent
- [ ] Добавить feature flags в базу
- [ ] Создать UI в админ-панели
- [ ] Настроить мониторинг
- [ ] Подготовить runbook для rollback
---
*Создано: 2026-05-10*
*Управляется RolloutAgent и BacklogAgent*
+42
View File
@@ -0,0 +1,42 @@
# Temp Users Cleanup Note - VoIdea
**Date:** 2026-05-10
**Status:** Backlog
---
## Overview
Mechanism for QATesterAgent to clean up temporary test accounts.
---
## Requirements
1. Create temp users with unique prefix: est_
2. Track creation time
3. Clean up after test completion
4. Verify cleanup in logs
5. No cascade delete on real users
---
## Safety Rules
1. Never delete users without est_ prefix
2. Use soft delete before hard delete
3. Log all cleanup operations
4. Verify foreign key constraints
5. Test cleanup in staging first
---
## Implementation
- PostgreSQL trigger for auto-cleanup (optional)
- Celery task for scheduled cleanup
- Admin notification on cleanup
---
*Created: 2026-05-10*
+173
View File
@@ -0,0 +1,173 @@
# UI Themes - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (часть WebUI)
---
## Обзор
Три темы интерфейса: system (auto), dark, light.
---
## Структура
### Design Tokens
```json
{
"themes": ["system", "dark", "light"],
"colors": {
"background": {
"system": "auto",
"dark": "#0F172A",
"light": "#FFFFFF"
},
"text": {
"primary": {
"system": "auto",
"dark": "#F8FAFC",
"light": "#0F172A"
}
}
}
}
```
---
## Реализация
### CSS Variables
```css
/* Тема применяется через data-theme атрибут */
[data-theme="dark"] {
--color-background: #0F172A;
--color-text: #F8FAFC;
}
[data-theme="light"] {
--color-background: #FFFFFF;
--color-text: #0F172A;
}
[data-theme="system"] {
/* Читается из prefers-color-scheme */
}
```
---
## Структура хранения
### База данных
```sql
CREATE TABLE user_settings (
user_id UUID PRIMARY KEY REFERENCES users(id),
theme VARCHAR(10) DEFAULT 'system',
updated_at TIMESTAMP DEFAULT NOW()
);
```
### localStorage (PWA offline)
```javascript
localStorage.setItem('voidea_theme', 'dark');
```
---
## Синхронизация
1. При входе → загрузить тему из БД
2. При изменении → обновить БД и localStorage
3. При оффлайн → использовать localStorage
4. При восстановлении → sync БД → localStorage
---
## Определение system темы
```javascript
// CSS media query
@media (prefers-color-scheme: dark) {
:root[data-theme="system"] {
--color-background: #0F172A;
--color-text: #F8FAFC;
}
}
// JavaScript detection
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
```
---
## UI настройки
### Страница настроек
```
├── Настройки
│ ├── Внешний вид
│ │ ├── Тема
│ │ │ ├── 🌓 System (автоматически)
│ │ │ ├── 🌙 Dark
│ │ │ └── ☀️ Light
```
---
## Поддержка платформ
### Web (PWA)
- CSS Variables
- media query `prefers-color-scheme`
- Service Worker для offline
### React Native (future)
- React Native Appearance API
- `useColorScheme()` hook
### iOS (future)
- SwiftUI `ColorScheme`
- Адаптация из tokens.json
### Android (future)
- Material Design color schemes
- Адаптация из tokens.json
---
## Генерация стилей
```bash
# Из tokens.json
python -m generators css --themes dark,light
```
Генерирует `app/design-tokens/css/themes.css`
---
## TODO
- [ ] CSS Variables для всех тем
- [ ] JavaScript detection для system
- [ ] Синхронизация БД ↔ localStorage
- [ ] UI переключатель
- [ ] Генерация из tokens.json
- [ ] Тесты (переключение тем)
- [ ] Документация
---
*Создано: 2026-05-10*
*Часть WebUI (Block 4) и Design System*
+153
View File
@@ -0,0 +1,153 @@
# Undo/Redo System - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (часть WebUI)
---
## Обзор
Система отмены/повтора действий с сохранением истории в базе данных.
---
## Архитектура
### История хранится в БД
```sql
CREATE TABLE user_actions_history (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
action_type VARCHAR(50) NOT NULL,
entity_type VARCHAR(50) NOT NULL,
entity_id UUID NOT NULL,
previous_state JSONB NOT NULL,
new_state JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX ix_user_actions_user_id ON user_actions_history(user_id);
CREATE INDEX ix_user_actions_created_at ON user_actions_history(created_at);
```
---
## Типы действий
### Отменяемые
- Создание идеи
- Редактирование идеи
- Удаление идеи
- Изменение настроек
- Действия с ИИ-агентами
### Не отменяемые
- Авторизация (вход/выход)
- Удаление аккаунта
- Оплата
- Массовые операции
---
## Лимиты
- Максимум действий в истории: 100
- Срок хранения: 7 дней
- Автоочистка старых записей
---
## API
```python
# Отмена последнего действия
POST /api/v1/actions/undo
# Повтор отменённого действия
POST /api/v1/actions/redo
# Получить историю
GET /api/v1/actions/history?limit=10
# Очистка истории
DELETE /api/v1/actions/history
```
---
## Процесс undo
```python
async def undo(user_id: UUID) -> ActionResult:
# 1. Получить последнее действие
action = await get_last_action(user_id)
# 2. Валидация (можно ли отменить)
if not can_undo(action):
raise UndoNotAllowed()
# 3. Восстановление предыдущего состояния
await restore_previous_state(action)
# 4. Запись в redo stack
await add_to_redo_stack(action)
# 5. Удаление из истории
await remove_from_history(action)
return ActionResult(success=True)
```
---
## Правила безопасности
1. **Только владелец** — чужие действия нельзя отменить
2. **Целостность данных** — проверка foreign keys
3. **Логирование** — все undo/redo фиксируются
4. **Резервное копирование** — состояние сохраняется до применения
---
## UI
### Кнопки в интерфейсе
- Панель инструментов: Undo ↔ Redo
- Горячие клавиши: Ctrl+Z, Ctrl+Shift+Z
- Контекстное меню: "Отменить"
### Индикация
- Disabled состояние когда undo невозможен
- Tooltip с описанием действия
---
## Падение приложения
При "падении" и невозможности оперативно исправить:
1. **Состояние сохраняется в БД** — можно восстановить
2. **Последние 100 действий** — доступны после перезапуска
3. **Manual recovery** — админ может восстановить вручную
---
## TODO
- [ ] Создать модель user_actions_history
- [ ] Реализовать undo/redo логику
- [ ] Добавить API endpoints
- [ ] Создать UI компоненты
- [ ] Настроить очистку (celery)
- [ ] Тесты
- [ ] Документация
---
*Создано: 2026-05-10*
*Часть WebUI (Block 4)*
+70
View File
@@ -0,0 +1,70 @@
# System Audit - VoIdea
**Date:** 2026-05-10
**Status:** Active
---
## Overview
Audit system ensures project quality control through automatic agents and periodic checks.
---
## Audit Agents
### AuditAgent
**Responsibilities:**
- Rule compliance check (00-rules.md)
- Project progress monitoring
- Deviation detection
- Admin reports generation
**Triggers:**
- pre-commit hook
- Daily at 09:00 (cron)
- On admin request
### SecurityAgent
**Responsibilities:**
- Code vulnerability scanning
- Input validation
- Dependency checks
- 152-FZ compliance
- Suspicious activity logging
---
## Audit Types
### 1. Code Audit
- Ruff: 0 errors, < 10 warnings
- MyPy: strict mode, 0 errors
- Test coverage: > 80%
### 2. Security Audit
- Bandit: 0 high severity
- Safety: 0 critical vulnerabilities
- Secrets detection: 100%
### 3. Architecture Audit
- No cyclic dependencies
- ADR up to date
- All modules documented
### 4. Compliance Audit
- 152-FZ compliance
- Data retention policy
- RBAC verification
---
## Reports
Reports stored in: docs/insights/audit/
---
*Updated: 2026-05-10*
+35
View File
@@ -0,0 +1,35 @@
# Backlog System - VoIdea
**Date:** 2026-05-10
**Status:** Active
---
## Overview
Backlog is a system for managing deferred ideas, plans, and tasks.
## Data Model
See docs/backlog/temp-users-cleanup-note.md, docs/backlog/rate-limiting-note.md, docs/backlog/observer-metrics-stages-note.md, docs/backlog/car-integration-note.md
## Agent Versioning / EvolutionAgent Tasks
- [ ] EvolutionAgent: auto-detect agent changes via checksum comparison
- [ ] EvolutionAgent: minor/major bump on capability changes
- [ ] EvolutionAgent: write changelog entries to `CHANGELOG/agents/<name>.md`
- [ ] Create `CHANGELOG/agents/` directory with initial version files
- [ ] BaseAgent: implement `compute_checksum()`, `bump_version()`, `write_changelog()`
- [ ] AgentConfig: add version + checksum fields to DB model
---
## Storage
- PostgreSQL table: backlog_items
- Access via API: /api/v1/backlog/
- Admin panel: Backlog management
---
*Updated: 2026-05-10*
+25
View File
@@ -0,0 +1,25 @@
# Project Glossary - VoIdea
**Date:** 2026-05-10
---
## Terms
| Term | Definition |
|------|------------|
| VoIdea | Application for capturing and developing ideas with AI |
| Idea | Main entity - recorded user thought |
| Agent (AI) | AI agent for idea analysis (11 roles) |
| System Agent | Automatic agent for project support (11 agents) |
| Backlog | Deferred tasks/ideas system |
| Rollout | Gradual deployment (3-1-5-15-100%) |
| Design Tokens | Unified style source (tokens.json) |
| TDC | Template-Driven Configuration |
| Agent Version | SemVer (A.B.C) assigned to each system agent independently |
| Agent Checksum | SHA256 hash of agent's `__file__`, used to detect changes |
| Agent Changelog | Change history in `CHANGELOG/agents/<name>.md` |
---
*Updated: 2026-05-10*
+70
View File
@@ -0,0 +1,70 @@
# Versioning Rules - VoIdea
**Date:** 2026-05-10
---
## Format
MAJOR.MINOR.PATCH (SemVer)
- MAJOR (X.0.0): breaking changes, full releases
- MINOR (0.X.0): new functionality, backward compatible
- PATCH (0.0.X): bug fixes
---
## CHANGELOG
Location: CHANGELOG/
- New file on X change: vX.0.md
- New file on Y change: vX.Y.md
- PATCH appended to existing file
Examples:
- CHANGELOG/v1.0.md (1.0.0 -> 1.0.5)
- CHANGELOG/v1.1.md (1.1.0 -> 1.1.3)
- CHANGELOG/v2.0.md (2.0.0 -> ...)
---
## Generation
Auto-generated by SpecAgent on version change.
---
## Agent Versioning
Each system agent is versioned independently (A.B.C).
### Rules
| Component | When | Who |
|-----------|------|-----|
| A (major) | Breaking change in public interface | EvolutionAgent |
| B (minor) | New capability (method, role, prompt) | EvolutionAgent |
| C (patch) | Internal fixes, no behavior change | Agent itself (auto) |
### Mechanism
1. Agent runs → `compute_checksum()` (SHA256 of `__file__`)
2. Compares with `AgentConfig.checksum` in DB
3. Mismatch → auto-bump patch → update changelog → save new checksum
4. EvolutionAgent handles minor/major bumps via capability analysis
### Storage
`CHANGELOG/agents/<agent_name>.md` — flat file, all history in one file.
Format:
```markdown
# audit_agent Changelog
## 1.0.2 (2026-05-10)
- Fixed: ruff output parsing for Windows paths
```
---
*Updated: 2026-05-10*
+18
View File
@@ -0,0 +1,18 @@
# Pre-commit чеклист
Перед каждым коммитом:
- [ ] `ruff check .` — 0 errors
- [ ] `ruff format --check .` — форматирование в порядке
- [ ] `pytest` — все тесты зелёные
- [ ] CHANGELOG обновлён (если изменение влияет на пользователя)
- [ ] .env.example обновлён (если новая переменная)
- [ ] Нет секретов и токенов в коде
- [ ] Нет TODO/FIXME без тикета
- [ ] Миграция написана (если менялась БД)
- [ ] Docstrings написаны (для новых публичных методов)
**Автоматически (pre-commit hooks):**
- `ruff` — линтинг и форматирование
- `trailing-whitespace` — удаление лишних пробелов
- `check-added-large-files` — проверка больших файлов (>500KB)
+25
View File
@@ -0,0 +1,25 @@
# Code Review чеклист
## Безопасность
- [ ] Нет секретов, ключей, паролей в коде
- [ ] Нет чувствительных данных в логах
- [ ] Входные данные проходят Pydantic валидацию
- [ ] Проверены права доступа (RBAC)
## Качество
- [ ] Нет сырых Exception в API ответах
- [ ] Есть обработка ошибок для внешних вызовов
- [ ] Docstrings написаны (Google-style)
- [ ] Аннотации типов проставлены
- [ ] Ruff проходит (0 errors)
- [ ] mypy проходит (0 errors)
## Тесты
- [ ] Есть тесты на новую функциональность
- [ ] Есть smoke-тест на новые endpoint'ы
- [ ] Тесты проходят
## Документация
- [ ] .env.example обновлён
- [ ] CHANGELOG обновлён
- [ ] ADR создан (если архитектурное изменение)
+24
View File
@@ -0,0 +1,24 @@
# Pre-deploy чеклист
## База данных
- [ ] Миграции написаны и проверены (upgrade + downgrade)
- [ ] Резервная копия БД создана
- [ ] Проверено что данные не потеряются
## Конфигурация
- [ ] `.env` настроен для production
- [ ] Все секреты установлены (JWT_SECRET_KEY, пароль БД, AI ключи)
- [ ] CORS настроен на реальный домен
- [ ] LOG_LEVEL = WARNING (не DEBUG)
- [ ] DATABASE_URL указывает на production PostgreSQL
## Инфраструктура
- [ ] SSL сертификаты (Let's Encrypt)
- [ ] systemd unit настроен (`/etc/systemd/system/voidea.service`)
- [ ] Виртуальное окружение активировано (`venv/`)
- [ ] Health check проходит: `curl http://localhost:8020/health`
## CI/CD
- [ ] CI проходит (lint + test)
- [ ] Код запушен в main
- [ ] Health check проходит после деплоя
+28
View File
@@ -0,0 +1,28 @@
# Incident Response чеклист
## Immediate (первые 5 минут)
1. [ ] Определить severity
- **Critical**: сервис недоступен, данные потеряны
- **Major**: функциональность severely impacted
- **Minor**: не влияет на пользователей
2. [ ] Остановить кровотечение
- Rollback до последней стабильной версии
- Отключить проблемную функциональность
- Переключить на fallback (AI fallback, прямой вызов Celery)
3. [ ] Уведомить команду
## Investigation (15-30 минут)
4. [ ] Проверить логи (docker logs, journalctl)
5. [ ] Проверить метрики (когда началось, что изменилось)
6. [ ] Проверить последний деплой / изменения
7. [ ] Воспроизвести проблему (если возможно)
## Resolution
8. [ ] Применить исправление
9. [ ] Проверить что сервис восстановлен
10. [ ] Уведомить о восстановлении
## Postmortem (в течение 24 часов)
11. [ ] Написать postmortem
12. [ ] Создать задачу на предотвращение
13. [ ] Добавить мониторинг / тест на этот сценарий
+28
View File
@@ -0,0 +1,28 @@
# Definition of Done
Задача считается выполненной только когда ВСЕ пункты отмечены:
## Код
- [ ] Код написан (соответствует стилю проекта)
- [ ] Линт проходит (ruff — 0 errors)
- [ ] Форматирование соблюдено (ruff format)
## Тесты
- [ ] Тесты написаны (минимум 1 smoke-тест на endpoint)
- [ ] Тесты проходят (pytest — green)
- [ ] Покрытие новых строк > 80%
## Документация
- [ ] Docstrings написаны (Google-style)
- [ ] .env.example обновлён (если новая переменная)
- [ ] CHANGELOG обновлён (если изменение влияет на API/пользователя)
- [ ] ADR создан (если архитектурное изменение)
## Инфраструктура
- [ ] Миграция написана (если менялась БД)
- [ ] Миграция протестирована (upgrade + downgrade)
## Процесс
- [ ] PR создан
- [ ] Code review пройден (минимум 1 апрув)
- [ ] Ветка смержена в develop/main
+43
View File
@@ -0,0 +1,43 @@
# Conventional Commits
## Формат
```
<тип>[optional scope]: <описание>
[optional body]
[optional footer]
```
## Типы
| Тип | Описание | Влияние на версию |
|-----|----------|-------------------|
| `feat` | Новая функция | MINOR |
| `fix` | Исправление бага | PATCH |
| `BREAKING` | Несовместимое изменение (или `!` после типа) | MAJOR |
| `docs` | Документация | — |
| `style` | Форматирование | — |
| `refactor` | Рефакторинг | — |
| `test` | Тесты | — |
| `chore` | Обслуживание (deps, ci, конфиги) | — |
## Примеры для VoIdea
```
feat(api): add POST /ideas/{id}/analyze endpoint
fix: validate email format on registration
BREAKING: change API response format for ideas list
docs: add architecture overview
refactor: extract AnalysisService from api/ideas.py
test: add integration tests for auth endpoints
chore: add pre-commit config
chore(deps): update fastapi to 0.115.6
```
## Правила
- Описание в императиве (начинается с глагола)
- Без точки в конце заголовка
- Заголовок до 72 символов
- Тело коммита — ЧТО и ЗАЧЕМ, а не КАК
+144
View File
@@ -0,0 +1,144 @@
# 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.
**Статус:** действует
---
## Формат записи
```markdown
## YYYY-MM-DD: Название
**Контекст:** Почему встал вопрос
**Решение:** Что выбрали
**Альтернативы:** Что рассматривали
**Статус:** действует | пересмотреть через N | заменено
```
+61
View File
@@ -0,0 +1,61 @@
# Design System - VoIdea
**Purpose:** Unified source of truth for UI across all platforms
---
## Table of Contents
1. [tokens.json](tokens.json) - Primary source of truth
2. [tokens.yaml](tokens.yaml) - YAML version
3. [generators/](generators/) - Platform-specific generators
---
## Overview
Design tokens are the single source of truth for:
- Colors
- Typography
- Spacing
- Border radius
- Shadows
- Transitions
---
## Usage
### Web (CSS)
`ash
python generators/css_generator.py
`
### iOS (Swift)
`ash
python generators/swift_generator.py
`
### Android (Kotlin)
`ash
python generators/kotlin_generator.py
`
---
## Themes
1. **system** - Auto-detect based on OS preference
2. **dark** - Dark theme
3. **light** - Light theme
---
## Maintenance
Design tokens are auto-updated by system agents.
Never edit generated files manually.
---
*Updated: 2026-05-10*
@@ -0,0 +1,60 @@
"""Generate CSS custom properties from design tokens."""
import json
import os
_FILE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(_FILE_DIR)))
TOKENS_PATH = os.path.join(ROOT, "docs", "design-system", "tokens.json")
OUTPUT_PATH = os.path.join(ROOT, "app", "design-tokens", "css", "theme.css")
def load_tokens() -> dict:
with open(TOKENS_PATH, encoding="utf-8-sig") as f:
return json.load(f)
def generate(tokens: dict) -> str:
lines = [
"/* Auto-generated from design tokens — do not edit manually */",
":root {",
]
for color_name, shades in tokens.get("colors", {}).items():
if isinstance(shades, dict):
for shade, value in shades.items():
if shade != "system":
if shade == "default":
lines.append(f" --color-{color_name}: {value};")
elif shade == "hover":
lines.append(f" --color-{color_name}-hover: {value};")
else:
lines.append(f" --color-{color_name}-{shade}: {value};")
for family_name, value in tokens.get("typography", {}).get("font_family", {}).items():
lines.append(f" --font-{family_name}: {value};")
for size_name, value in tokens.get("typography", {}).get("size", {}).items():
lines.append(f" --font-size-{size_name}: {value};")
for space_name, value in tokens.get("spacing", {}).items():
lines.append(f" --spacing-{space_name}: {value};")
for radius_name, value in tokens.get("border_radius", {}).items():
lines.append(f" --radius-{radius_name}: {value};")
lines.append("}")
return "\n".join(lines) + "\n"
def main():
tokens = load_tokens()
css = generate(tokens)
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
f.write(css)
print(f"Written: {OUTPUT_PATH}")
if __name__ == "__main__":
main()
@@ -0,0 +1,60 @@
"""Generate Android colors.xml from design tokens."""
import json
import os
import xml.etree.ElementTree as ET
from xml.dom import minidom
_FILE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(_FILE_DIR)))
TOKENS_PATH = os.path.join(ROOT, "docs", "design-system", "tokens.json")
OUTPUT_PATH = os.path.join(ROOT, "app", "design-tokens", "kotlin", "colors.xml")
def load_tokens() -> dict:
with open(TOKENS_PATH, encoding="utf-8-sig") as f:
return json.load(f)
def hex_to_argb(hex_color: str) -> str:
h = hex_color.lstrip("#")
if len(h) == 6:
return f"FF{h}"
return h
def generate(tokens: dict) -> str:
root = ET.Element("resources")
for color_name, shades in tokens.get("colors", {}).items():
if isinstance(shades, dict):
for shade, value in shades.items():
if shade not in ("system",) and isinstance(value, str) and value.startswith("#"):
res_name = f"{color_name}_{shade}"
argb = hex_to_argb(value)
child = ET.SubElement(root, "color")
child.set("name", res_name)
child.text = f"#{argb}"
for space_name, value in tokens.get("spacing", {}).items():
dp = value.replace("rem", "").strip()
child = ET.SubElement(root, "dimen")
child.set("name", f"spacing_{space_name}")
child.text = f"{float(dp) * 16:.0f}dp"
rough_string = ET.tostring(root, encoding="unicode")
reparsed = minidom.parseString(rough_string)
return '<?xml version="1.0" encoding="utf-8"?>\n' + reparsed.toprettyxml(indent=" ")
def main():
tokens = load_tokens()
xml = generate(tokens)
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
f.write(xml)
print(f"Written: {OUTPUT_PATH}")
if __name__ == "__main__":
main()
@@ -0,0 +1,60 @@
"""Generate Swift Color enum from design tokens."""
from __future__ import annotations
import json
import os
_FILE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(_FILE_DIR)))
TOKENS_PATH = os.path.join(ROOT, "docs", "design-system", "tokens.json")
OUTPUT_PATH = os.path.join(ROOT, "app", "design-tokens", "swift", "Colors.swift")
def load_tokens() -> dict:
with open(TOKENS_PATH, encoding="utf-8-sig") as f:
return json.load(f)
def hex_to_rgb(hex_color: str) -> tuple[int, int, int]:
h = hex_color.lstrip("#")
return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
def generate(tokens: dict) -> str:
lines = [
"// Auto-generated from design tokens — do not edit manually",
"import SwiftUI",
"",
"extension Color {",
]
for color_name, shades in tokens.get("colors", {}).items():
if isinstance(shades, dict):
for shade, value in shades.items():
if shade not in ("system",) and isinstance(value, str) and value.startswith("#"):
try:
r, g, b = hex_to_rgb(value)
suffix = shade.capitalize()
swift_name = f"{color_name}{suffix}"
lines.append(f" static let {swift_name} = Color(red: {r/255:.4f}, green: {g/255:.4f}, blue: {b/255:.4f})")
except (ValueError, IndexError):
pass
for space_name, value in tokens.get("spacing", {}).items():
lines.append(f" static let spacing{space_name.capitalize()} = CGFloat({value.replace('rem', '').strip()})")
lines.append("}")
return "\n".join(lines) + "\n"
def main():
tokens = load_tokens()
swift = generate(tokens)
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
f.write(swift)
print(f"Written: {OUTPUT_PATH}")
if __name__ == "__main__":
main()
+55
View File
@@ -0,0 +1,55 @@
{
"version": "1.0.0",
"project": "VoIdea",
"updated": "2026-05-10",
"themes": ["system", "dark", "light"],
"colors": {
"primary": {
"50": "#EEF2FF",
"500": "#6366F1",
"600": "#4F46E5",
"default": "#6366F1",
"hover": "#4F46E5"
},
"background": {
"system": "auto",
"dark": "#0F172A",
"light": "#FFFFFF"
},
"text": {
"primary": {
"system": "auto",
"dark": "#F8FAFC",
"light": "#0F172A"
}
},
"semantic": {
"error": "#EF4444",
"warning": "#F59E0B",
"success": "#22C55E",
"info": "#3B82F6"
}
},
"typography": {
"font_family": {
"primary": "Inter, system-ui, sans-serif"
},
"size": {
"xs": "0.75rem",
"sm": "0.875rem",
"base": "1rem",
"lg": "1.125rem"
}
},
"spacing": {
"xs": "0.25rem",
"sm": "0.5rem",
"md": "1rem",
"lg": "1.5rem"
},
"border_radius": {
"sm": "0.25rem",
"md": "0.5rem",
"lg": "0.75rem"
}
}
+48
View File
@@ -0,0 +1,48 @@
# Стандарты документации
## Docs-as-code
Вся документация — в репозитории, в Markdown. Пишется параллельно с кодом.
## Где что хранить
| Тип | Расположение | Формат |
|-----|-------------|--------|
| Архитектура | `docs/architecture.md` | MD |
| ADR | `docs/adr/NNN-title.md` | MD (YAML frontmatter) |
| Decision Log | `docs/decision-log.md` | MD |
| Чеклисты | `docs/checklists/NN-name.md` | MD |
| Runbook | `docs/runbook/NN-name.md` | MD |
| Спеки агентов | `docs/specs/agents/<role>.md` | MD |
| Промпты | `docs/agent_prompts.yaml` + `docs/specs/agents/` | YAML + MD |
| Changelog | `CHANGELOG/v*.md`, `CHANGELOG/agents/*.md` | MD |
| Дизайн-система | `docs/design-system/` | MD + JSON |
## Когда что писать
- **ADR**: когда выбираем технологию или меняем архитектуру
- **Decision Log**: каждое решение, у которого есть альтернативы
- **Runbook**: когда делаем что-то вручную больше одного раза
- **Чеклист**: когда забыли что-то проверить
- **Спека агента**: когда создаём нового агента
## Docstrings
Google-style для всех публичных классов и методов.
```python
def calculate_roi(investment: float, return_value: float, years: int = 1) -> float:
"""Calculate Return on Investment.
Args:
investment: Initial investment amount
return_value: Total return after period
years: Investment period in years (default: 1)
Returns:
ROI as a percentage
Raises:
ValueError: If investment is zero or negative
"""
```
+60
View File
@@ -0,0 +1,60 @@
# Управление переменными окружения
## Принцип
Все настройки, которые меняются между окружениями — в переменных окружения. Никаких hardcoded значений.
## Формат: .env
```bash
# === Core ===
PROJECT_NAME=VoIdea
PROJECT_ENV=production
# === Server ===
SERVER_HOST=0.0.0.0
SERVER_PORT=8020
# === Database (PostgreSQL only) ===
DATABASE_URL=postgresql+asyncpg://voidea:password@localhost:5432/voidea
# === JWT ===
JWT_SECRET_KEY=your-secret-key
JWT_ALGORITHM=HS256
# === AI ===
AI_YANDEX_KEY=
AI_YANDEX_FOLDER_ID=
AI_GIGACHAT_CLIENT_ID=
AI_GIGACHAT_SECRET=
```
## Валидация при старте
```python
# app/core/config.py
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
database_url: str = "postgresql+asyncpg://voidea:password@localhost:5432/voidea"
jwt_secret_key: str = ""
@property
def sync_database_url(self) -> str:
return self.database_url.replace("+asyncpg", "")
```
## Синхронизация .env.example
- `.env.example` в репозитории
- Обновляется при каждом добавлении переменной
- Все переменные с комментариями
- Чувствительные значения пустые
- Секции разделены `# === Name ===`
## Secrets management
| Окружение | Где хранить |
|-----------|-------------|
| Local | `.env` (в .gitignore) |
| Production | GitHub Secrets / 1Password |
+49
View File
@@ -0,0 +1,49 @@
# Обработка ошибок
## Иерархия исключений
```python
# app/core/exceptions.py
AppError
AuthenticationError # 401 — неверный токен/пароль
ForbiddenError # 403 — нет прав
NotFoundError # 404 — ресурс не найден
ConflictError # 409 — дубликат, конфликт
ValidationError # 422 — неверные данные
ServiceUnavailableError # 503 — внешний сервис недоступен
```
## Матрица по слоям
| Слой | Что делаем | Пример |
|------|-----------|--------|
| **API** | HTTPException с detail и status_code | `raise HTTPException(404)` |
| **Services** | Бизнес-исключения (из AppError) | `raise NotFoundError("Idea", id)` |
| **Integrations** | try/except с fallback | `return AIResult(success=False)` |
| **Agents** | AgentResult(success=False, error=...) | Без HTTP-статусов |
| **Data/DB** | Ошибки не всплывают выше | Ловим в сервисе |
## Fallback pattern (AI провайдеры)
```python
# app/integrations/ai/fallback.py
# YandexGPT → GigaChat, 2 retry, 2s/5s backoff
# При недоступности всех — AgentResult(success=False, message=...)
```
## Graceful degradation
| Сервис недоступен | Реакция |
|-------------------|---------|
| PostgreSQL | 503 Service Unavailable |
| Redis | Работаем без Celery (прямой вызов), log WARNING |
| AI провайдер | Fallback на другой, потом Error |
| Celery | Выполняем задачу синхронно |
## Логирование ошибок
| Уровень | Когда |
|---------|-------|
| WARNING | Timeout, retry, fallback |
| ERROR | Ошибка внешнего API |
| CRITICAL | Исчерпаны все retry |
+840
View File
@@ -0,0 +1,840 @@
# VoIdeaAI — Финальная спецификация проекта
**Роль:** ты — старший архитектор ПО и продуктовый аналитик. Твоя задача — зафиксировать полное описание, промпты, архитектуру и все функциональные связи продукта VoIdeaAI.
**Цель:** голосовой AI-ассистент для генерации, проработки и сохранения идей с помощью группового ИИ-анализа. Пользователь говорит или печатает — система через оркестратора (Дирижёр) направляет запрос специализированному ролевому агенту, верифицирует ответ и возвращает результат с оценкой уверенности.
---
## 1. Общая архитектура
```
Browser (PWA — React + TypeScript + Tailwind)
│ Web Speech API (распознавание) / SpeechSynthesis (озвучивание)
│ HTTPS
Nginx (reverse proxy, SSL termination, Let's Encrypt)
FastAPI (Python 3.12+, async)
├── StaticFiles — /assets, /icons, SPA fallback
├── SecurityHeadersMiddleware — CSP, HSTS, X-Frame-Options и др.
├── CORSMiddleware — whitelist origins
├── Limiter (slowapi) — rate limiting на все endpoints
├── API v1 (/api/v1)
│ ├── /auth — регистрация, логин, OAuth, сброс пароля
│ ├── /voice — транскрибация, чат, сессии, рейтинг
│ ├── /users — профиль, настройки
│ ├── /ideas — CRUD идей
│ ├── /agents — список и управление агентами
│ ├── /admin — панель управления
│ └── /sync — синхронизация
├── ConductorAgent (Дирижёр) — оркестратор, точка входа
│ ├── → 13 Role Agents (ролевые)
│ └── Верификация (confidence 0-100%)
├── AgentRegistry — 12 Dev/Ops агентов (автоматизация)
├── LLM Service — OpenAI-compatible (OpenAI / YandexGPT / GigaChat)
├── Whisper Service — транскрибация аудио
├── Email Service — SMTP (Jinja2), password reset
├── Crypto Service — AES-256 Fernet (PBKDF2 600k итераций)
└── PostgreSQL — 8 таблиц (asyncpg)
```
**Ключевые принципы:**
- **PostgreSQL только** — единый `DATABASE_URL`, без SQLite
- **No Docker** — systemd + venv напрямую на VPS (Ubuntu)
- **Single-page app** — FastAPI StaticFiles раздаёт фронтенд
- **Агенты имеют прямой доступ к БД** — через переданную async-сессию
---
## 2. Технологический стек
| Компонент | Технология |
|-----------|-----------|
| Бэкенд | Python 3.12+, FastAPI, Uvicorn |
| Фронтенд | React 18, TypeScript, Tailwind CSS, Vite |
| PWA | manifest.json, service worker, иконки всех размеров |
| База данных | PostgreSQL 15+, asyncpg, SQLAlchemy 2.0 (async), Alembic |
| Аутентификация | JWT (HS256), bcrypt (passlib), OAuth 2.0 |
| ИИ-модели | OpenAI API (gpt-4o-mini), YandexGPT, GigaChat (fallback chain) |
| Распознавание речи | Web Speech API (браузер) → Whisper API (OpenAI, fallback) |
| Синтез речи | SpeechSynthesis API (браузер, русский голос) |
| Шифрование | AES-256-CBC + HMAC-SHA256 (Fernet), PBKDF2 |
| Rate limiting | slowapi (60/min default, 10/min auth, 3/min forgot-password) |
| Защита заголовков | CSP, HSTS, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection |
| Почта | aiosmtplib + Jinja2 (HTML-шаблоны) |
| Мониторинг | Prometheus + Grafana (VPS) |
| Развёртывание | systemd + venv, Nginx + certbot (Let's Encrypt) |
---
## 3. Аутентификация и OAuth
### 3.1 Email + пароль
- Регистрация: `POST /api/v1/auth/register` — email, пароль (8+ символов), имя
- Логин: `POST /api/v1/auth/login` — email + пароль
- JWT access token (60 мин) + refresh token (30 дней) с ротацией
- bcrypt для хешей паролей
- Brute-force защита: 5 неудачных попыток → блокировка на 15 минут (in-memory, в проде — Redis)
- Rate limit: 10/min на login, 5/min на register, 3/min на forgot-password
### 3.2 Яндекс OAuth
- 7 scopes: `login:email`, `login:info`, `login:avatar`, `cloud_api:disk.write`, `cloud_api:disk.app_folder`, `cloud_api:disk.read`, `cloud_api:disk.info`
- Папка на Диске: `/VoIdeaAI/`
- Методы: `upload_file()`, `ensure_app_folder()`, `get_disk_info()`
- Redirect URI настраивается через `OAUTH_YANDEX_REDIRECT_URI`
### 3.3 Google OAuth
- Scopes: `userinfo.email`, `userinfo.profile`, `drive.file`
- Папка на Диске: `/VoIdeaAI/`
- Активируется когда `OAUTH_GOOGLE_ID` не пуст
- Redirect: `http://localhost:8020/auth/google/callback`
**Пример запроса:**
```python
from app.integrations.oauth.google import is_available, get_authorize_url, exchange_code, get_user_info, upload_file
if is_available():
url = await get_authorize_url()
token = await exchange_code(code)
user = await get_user_info(token["access_token"])
await upload_file(token["access_token"], "idea.txt", content)
```
### 3.4 Apple OAuth
- Sign in with Apple через `appleid.apple.com`
- Активируется когда `OAUTH_APPLE_ID` не пуст
- Redirect: `http://localhost:8020/auth/apple/callback`
- iCloud Drive через CloudKit API
### 3.5 Password Reset
- JWT reset token с отдельным секретом (`JWT_RESET_SECRET_KEY`), 1 час
- HTML-письмо с кнопкой сброса (Jinja2-шаблон)
- Если SMTP не настроен — лог в консоль
- Rate limit: 3/min на forgot-password
### 3.6 2FA (TOTP)
- Включается через `ENABLE_2FA=true`
- PyOTP + QR-код для настройки
- Подтверждение кода при входе после пароля/OAuth
---
## 4. Голосовой ввод / вывод
### 4.1 Распознавание речи
**Цепочка приоритетов:**
1. **Web Speech API** (браузер, `SpeechRecognition`) — основной, бесплатный, работает онлайн
2. **MediaRecorder → Whisper API** (OpenAI `whisper-1`, `language=ru`) — fallback если Web Speech недоступен
3. Если ключ OpenAI не задан — возвращается ошибка
**Компонент VoiceInput (`webui/src/components/VoiceInput.tsx`):**
- Кнопка-микрофон с визуальной индикацией записи
- `onMouseDown/onTouchStart` — начало записи
- `onMouseUp/onTouchEnd` — остановка и отправка
- Автоматическая остановка через 5 секунд (MediaRecorder)
- Подавление шума через confidence ≥ 0.5
### 4.2 Текстовый ввод
- Поле ввода рядом с микрофоном, отправка по Enter
- Пользователь может говорить ИЛИ печатать
- Чекбокс «Озвучивать ответ» отключает TTS
### 4.3 Синтез речи (TTS)
- **SpeechSynthesis API** браузера (бесплатно, без серверной нагрузки)
- Язык: `ru-RU`, скорость: 0.9
- Автоматическое озвучивание ответов (кроме `needs_clarification`)
- Кнопка «Стоп» для прерывания
### 4.4 Голосовые команды
Фоновый `SpeechRecognition` (continuous mode) слушает команды:
| Команда | Действие |
|---------|----------|
| «Стоп» | Остановить TTS |
| «Повтори» | Повторить последний ответ |
| «Уточнить» | Открыть диалог уточнения запроса |
- Отключается при отсутствии сообщений в чате
- Confidence ≥ 0.5 для фильтрации шума
---
## 5. Оркестрация: Дирижёр
**Файл:** `app/agents/conductor_agent.py`
Дирижёр — единственная точка входа для пользовательских запросов. Полный pipeline:
```
User Input (текст/голос)
┌─ 0. Авто-создание сессии ─────────────────┐
│ Если session_id не передан → создаётся │
│ новая сессия + LLM генерирует title │
└────────────────────────────────────────────┘
┌─ 1. Сбор контекста ───────────────────────┐
│ • Недавние обсуждения пользователя (5) │
│ • Похожие успешные кейсы (word overlap) │
│ • История текущей сессии │
└────────────────────────────────────────────┘
┌─ 2. Маршрутизация (LLM) ──────────────────┐
│ "Определи лучшего агента для ответа" │
│ temperature=0.3, max_tokens=64 │
│ Ответ ТОЛЬКО именем агента │
└────────────────────────────────────────────┘
┌─ 3. Генерация ответа ─────────────────────┐
│ Выбранный RoleAgent + system_prompt │
│ temperature=0.7, max_tokens=1536 │
└────────────────────────────────────────────┘
┌─ 4. Верификация ──────────────────────────┐
│ Проверка: галлюцинации, противоречия, │
│ логические ошибки, пропущенные детали │
│ temperature=0.2, max_tokens=1024 │
│ Ответ JSON: confidence, issues, corrected │
└────────────────────────────────────────────┘
┌─ 5. Confidence scoring ───────────────────┐
│ ≥ 80% → verified (зелёный) │
│ 50-79% → warning (жёлтый) │
│ < 50% → needs_clarification (красный) │
│ issues_found → ответ скорректирован │
└────────────────────────────────────────────┘
┌─ 6. Логирование + самообучение ───────────┐
│ ConductorInteraction: input, output, │
│ confidence, agent, время, session_id │
└────────────────────────────────────────────┘
Response { response, agent_name, confidence,
verification_status, session_id,
interaction_id }
```
**Пример ответа:**
```json
{
"response": "Идея стартапа по экологии имеет ROI 150%...",
"agent_name": "Бизнес-аналитик",
"agent_description": "Оценивает идею с точки зрения бизнес-показателей",
"confidence": 85,
"verification_status": "verified",
"processing_time_ms": 2340.5,
"interaction_id": "a1b2c3d4-...",
"session_id": "e5f6g7h8-..."
}
```
---
## 6. Ролевые агенты (13 шт)
Все агенты описаны в `app/agents/role_agents.py`. Каждый имеет `name`, `description` и `system_prompt`.
| # | Агент | Описание | System prompt |
|---|-------|----------|--------------|
| 1 | **Бизнес-аналитик** | Оценивает идею: ROI, окупаемость, ЦА, конкуренты | *«Ты — Бизнес-аналитик. Дай оценку по критериям: ROI (%), срок окупаемости (месяцы), целевая аудитория (тыс. чел.), конкурентные преимущества...»* |
| 2 | **Организатор задач** | Разбивает на шаги, план реализации | *«Разбей идею на 5-7 шагов. Для каждого: название, срок, ответственный...»* |
| 3 | **Юрист** | Проверяет на законы РФ (152-ФЗ, 44-ФЗ и др.) | *«Проанализируй на соответствие законодательству РФ. Правовые риски, способы минимизации...»* |
| 4 | **Финансовый консультант** | Бюджет, прогноз доходов, точка безубыточности | *«Составь смету: разработка, маркетинг, поддержка. Прогноз дохода за год...»* |
| 5 | **Архитектор решений** | 2 варианта архитектуры (монолит / микросервисы) | *«Предложи 2 варианта. Вариант A — монолит, B — микросервисы. Технологии, сложность...»* |
| 6 | **Тестировщик** | Тест-кейсы (позитивные/негативные), инструменты | *«5-10 тест-кейсов. Шаги, ожидаемый результат, инструменты автоматизации...»* |
| 7 | **UI-дизайнер** | 2 варианта дизайна, цвета, шрифты, UX | *«2 варианта главного экрана. Цветовая схема, шрифты, расположение элементов...»* |
| 8 | **SMM-специалист** | Контент-план на месяц, платформы, хештеги | *«Контент-план: платформы (ВК, Telegram), форматы, частота, 3-4 примера постов...»* |
| 9 | **Лайф-коуч** | SMART-цели, квартальные этапы, метрики | *«Помоги сформулировать цель по SMART. Q1-Q4, 3 метрики прогресса...»* |
| 10 | **Эксперт по доступности** | Инклюзивность, WCAG 2.1 (AA) | *«Слабовидящие, глухие, моторные нарушения, когнитивные — доработки для WCAG 2.1...»* |
| 11 | **Критик** | Конструктивный разбор: подводные камни, улучшения | *«Что НЕ учтено? Подводные камни, улучшения. Тон — доброжелательный коллега...»* |
| 12 | **Копирайтер** | Продающий текст, сторителлинг | *«Упакуй идею в яркий текст: заголовки, метафоры, сторителлинг. Для инвесторов и команды...»* |
| 13 | **Хранитель** | Сохраняет идею в БД (название, описание, теги) | *«Оформи для сохранения: Название, Описание, Теги. Строгий формат...»* |
**Агенты 11-13** (Критик, Копирайтер, Хранитель) добавлены дополнительно к базовым 10 из оригинальной спецификации.
---
## 7. Dev/Ops агенты (12 шт)
Зарегистрированы в `app/agents/registry.py`. Используются через `AgentRegistry.run_agent()` для автоматизации разработки и поддержки.
| # | Агент | Описание |
|---|-------|----------|
| 1 | **DocAgent** | Генерация документации по коду |
| 2 | **BacklogAgent** | Управление бэклогом задач |
| 3 | **SpecAgent** | Написание спецификаций |
| 4 | **AuditAgent** | Аудит кода и безопасности |
| 5 | **ObserverAgent** | Мониторинг и наблюдаемость |
| 6 | **EvolutionAgent** | Предложения по эволюции кода |
| 7 | **SecurityAgent** | Проверки безопасности |
| 8 | **QATesterAgent** | Автоматическое тестирование |
| 9 | **FixAgent** | Исправление типовых ошибок |
| 10 | **UITestAgent** | UI-тестирование |
| 11 | **RolloutAgent** | Развёртывание и релизы |
| 12 | **ConductorAgent** | Дирижёр (в registry для Dev/Ops контекста) |
---
## 8. Связи агентов
```
┌──────────────────┐
│ Пользователь │
│ (голос / текст) │
└────────┬─────────┘
┌──────────────────┐
│ Дирижёр │ ←── AgentRegistry
│ (Conductor) │ (Dev/Ops)
└────────┬─────────┘
│ маршрутизация (LLM)
┌──────────────────────────────┐
│ 13 Role Agents │
│ │
│ Бизнес-аналитик │
│ Организатор задач │
│ Юрист │
│ Финансовый консультант │
│ Архитектор решений │
│ Тестировщик │
│ UI-дизайнер │
│ SMM-специалист │
│ Лайф-коуч │
│ Эксперт по доступности │
│ Критик │
│ Копирайтер │
│ Хранитель │
└──────────────┬───────────────┘
│ response
┌──────────────────┐
│ Верификация │
│ (внутри Дирижёра)│
│ confidence 0-100 │
└────────┬─────────┘
┌──────────────────┐
│ Пользователь │
│ + лог в БД │
└──────────────────┘
```
**Ключевые правила:**
- Дирижёр — **единственная точка входа** для пользователя
- Верификация выполняется **внутри Дирижёра** (не отдельный агент) — быстрее, меньше загрузки LLM
- Dev/Ops агенты вызываются через `/api/v1/agents/` (не через Дирижёр)
- 26 агентов всего: 1 Дирижёр + 13 ролевых + 12 dev/ops
- Все ролевые агенты имеют прямой доступ к БД через переданную `db: AsyncSession`
---
## 9. Самообучение
### 9.1 Рейтинг (1-5)
После каждого ответа пользователь может поставить оценку:
- Звёзды 1-5 в интерфейсе
- `POST /api/v1/voice/rate` — сохраняет `user_rating` в `ConductorInteraction`
- Используется для фильтрации успешных кейсов
### 9.2 Похожие кейсы (word overlap)
При обработке запроса:
1. Выборка успешных interaction (rating ≥ 4, confidence ≥ 70) за последние 7 дней
2. Сравнение через `_text_similarity()` — пересечение множеств слов
3. Если overlap > 30% — кейс подмешивается в контекст LLM
Пример:
```
Было: "придумай идею для стартапа в экологии"
Ответ: "Идея: переработка пластика..." (rating: 5)
```
Подмешивается в контекст похожего запроса.
### 9.3 Динамические команды
- Хранятся в таблице `voice_commands` (привязка к `user_id`)
- Если фраза сработала 3+ раза — система предлагает добавить как команду
- Поля: `phrase`, `action`, `agent_name`, `count`, `is_active`
### 9.4 ConductorInteraction (таблица логов)
| Поле | Описание |
|------|----------|
| `user_id` | FK → users |
| `session_id` | FK → sessions |
| `input_text` | Запрос пользователя |
| `detected_intent` | Распознанное намерение |
| `selected_agent` | Какой агент отвечал |
| `response_text` | Ответ агента |
| `user_rating` | 1-5 (заполняется позже) |
| `confidence_score` | 0-100 |
| `verification_status` | verified / warning / needs_clarification / issues_found |
| `processing_time_ms` | Время обработки |
| `context` | JSON с деталями верификации |
---
## 10. Сессии
**Модель:** `app/models/session.py`, таблица `sessions`
- **1 сессия = 1 обсуждение идеи**
- Авто-создание при первом сообщении без `session_id`
- Дирижёр формирует заголовок через LLM (до 7 слов) на основе первого запроса
- Статусы: `active`, `archived`
- Привязка к `idea_id` (когда идея сохранена)
**API:**
- `GET /api/v1/voice/sessions` — список сессий пользователя
- `GET /api/v1/voice/sessions/{id}` — детали сессии
- `GET /api/v1/voice/sessions/{id}/history` — история взаимодействий
- `DELETE /api/v1/voice/sessions/{id}` — удалить сессию
**UI:**
- Сайдбар слева со списком сессий
- Кнопка «Новый чат» → сброс текущей сессии
- Активная сессия подсвечена
- Кнопка удаления с confirm-диалогом
---
## 11. Интеграции с дисками
Единый интерфейс для облачных хранилищ. Все провайдеры создают папку `/VoIdeaAI/` и загружают файлы туда.
### 11.1 Яндекс.Диск (реализован)
`app/integrations/oauth/yandex.py`:
- `get_authorize_url()` → URL авторизации
- `exchange_code(code)` → токен
- `get_user_info(token)` → профиль
- `ensure_app_folder(token)` → создаёт /VoIdeaAI/
- `upload_file(token, local_path, remote_name)` → загружает файл
- `get_disk_info(token)` → квота
### 11.2 Google Drive
`app/integrations/oauth/google.py`:
- Активируется при непустом `OAUTH_GOOGLE_ID`
- `is_available()` → bool
- Те же методы: `get_authorize_url`, `exchange_code`, `get_user_info`, `ensure_app_folder`, `upload_file`, `get_disk_info`
- Использует `https://www.googleapis.com/drive/v3`
### 11.3 Apple iCloud Drive
`app/integrations/oauth/apple.py`:
- Активируется при непустом `OAUTH_APPLE_ID`
- `is_available()` → bool
- Те же методы (через CloudKit API)
- Требует дополнительной настройки entitlements в Apple Developer Console
---
## 12. Безопасность
### 12.1 Криптография
| Компонент | Метод |
|-----------|-------|
| Пароли | bcrypt (passlib, 12 раундов) |
| JWT Access Token | HS256, 60 мин, отдельный secret |
| JWT Refresh Token | HS256, 30 дней, ротация при каждом использовании |
| JWT Reset Token | HS256, 1 час, отдельный secret (`JWT_RESET_SECRET_KEY`) |
| Шифрование данных | AES-256-CBC + HMAC-SHA256 (Fernet), PBKDF2 600k итераций |
| Шифруются: идеи, ответы ConductorInteraction, логи |
### 12.2 Rate Limiting
| Endpoint | Лимит |
|----------|-------|
| `/login` | 10/min |
| `/register` | 5/min |
| `/refresh` | 10/min |
| `/forgot-password` | 3/min |
| `/reset-password` | 5/min |
| `/oauth/*` | 10/min |
| `/health` | 30/min |
| Все остальные | 60/min |
### 12.3 Security Headers
Все ответы содержат:
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security: max-age=31536000; includeSubDomains`
- `Content-Security-Policy: default-src 'self'; script-src 'self'; ...`
### 12.4 Brute Force
- 5 неудачных попыток логина за 15 минут → временная блокировка email
- In-memory (TODO: Redis в production)
- Не блокирует другие аккаунты с того же IP
### 12.5 Дополнительно
- CORS whitelist (настраивается)
- Токены в `localStorage` (с предупреждением о XSS)
- SQLAlchemy ORM (параметризованные запросы — защита от SQL injection)
- Pydantic-валидация всех входящих данных
- `is_active` check на каждом запросе
- `require_admin` dependency для админ-роутов
---
## 13. База данных (PostgreSQL)
### 13.1 Схема
```sql
-- 8 таблиц, все с UUID первичными ключами + created_at/updated_at
users
id UUID PRIMARY KEY
email VARCHAR(255) UNIQUE NOT NULL
password_hash VARCHAR(255) NULLABLE
display_name VARCHAR(255) NOT NULL
avatar_url VARCHAR(512) NULLABLE
is_active BOOLEAN DEFAULT true
is_superuser BOOLEAN DEFAULT false
oauth_provider VARCHAR(50) NULLABLE
oauth_id VARCHAR(255) NULLABLE
ideas
id UUID PRIMARY KEY
user_id UUID FK users(id) ON DELETE CASCADE
title VARCHAR(255) NOT NULL
description TEXT
tags TEXT
status VARCHAR(20) DEFAULT 'draft'
agent_configs
id UUID PRIMARY KEY
agent_name VARCHAR(100) NOT NULL
user_id UUID FK users(id) ON DELETE CASCADE
model VARCHAR(100)
enabled BOOLEAN DEFAULT true
backlog_tasks
id UUID PRIMARY KEY
title VARCHAR(255) NOT NULL
description TEXT
priority INTEGER DEFAULT 0
status VARCHAR(20) DEFAULT 'pending'
log_entries
id UUID PRIMARY KEY
level VARCHAR(10) NOT NULL
message TEXT NOT NULL
agent VARCHAR(100)
user_id UUID FK users(id) ON DELETE SET NULL
conductor_interactions
id UUID PRIMARY KEY
user_id UUID FK users(id) ON DELETE SET NULL
session_id UUID FK sessions(id) ON DELETE SET NULL
input_text TEXT NOT NULL
detected_intent VARCHAR(100)
selected_agent VARCHAR(100)
response_text TEXT
user_rating INTEGER NULLABLE
confidence_score INTEGER DEFAULT 80
verification_status VARCHAR(20) DEFAULT 'verified'
was_auto_routed BOOLEAN DEFAULT true
processing_time_ms FLOAT
context TEXT (JSON)
sessions
id UUID PRIMARY KEY
user_id UUID FK users(id) ON DELETE CASCADE
title VARCHAR(255) DEFAULT 'Новое обсуждение'
status VARCHAR(20) DEFAULT 'active'
idea_id UUID FK ideas(id) ON DELETE SET NULL
voice_commands
id UUID PRIMARY KEY
user_id UUID FK users(id) ON DELETE CASCADE
phrase VARCHAR(255) NOT NULL
action VARCHAR(50) NOT NULL
agent_name VARCHAR(100) NULLABLE
count INTEGER DEFAULT 0
is_active BOOLEAN DEFAULT true
```
### 13.2 Индексы
- `users.email` — UNIQUE
- `users(oauth_provider, oauth_id)` — для OAuth lookup
- `conductor_interactions(user_id)` — история пользователя
- `conductor_interactions(session_id)` — история сессии
- `sessions(user_id, status)` — список сессий
- `voice_commands(user_id)` — команды пользователя
---
## 14. Фронтенд (PWA)
### 14.1 Страницы и маршруты
| Маршрут | Страница | Описание |
|---------|----------|----------|
| `/` | Главная | SPA entry point |
| `/login` | LoginPage | Email + Яндекс OAuth + ссылка «Забыли пароль?» |
| `/register` | RegisterPage | Регистрация email+password |
| `/forgot-password` | ForgotPasswordPage | Форма ввода email |
| `/reset-password?token=` | ResetPasswordPage | Новый пароль |
| `/oauth/callback` | OAuthCallback | Обработка OAuth callback |
| `/voice` | VoiceChat | Голосовой ассистент с сайдбаром |
| `/ideas` | IdeaList | Список идей |
| `/ideas/new` | IdeaCreate | Новая идея |
| `/ideas/:id` | IdeaEdit | Редактирование идеи |
### 14.2 Ключевые компоненты
- **VoiceChat** — основной интерфейс: сайдбар сессий, список сообщений, confidence badge, звёзды рейтинга, кнопка «Уточнить», голосовые команды
- **VoiceInput** — кнопка микрофона, Web Speech API → Whisper fallback
- **VoiceCommands** — хук `useVoiceCommands` для фоновых команд «Стоп»/«Повтори»/«Уточнить»
- **AuthContext** — контекст аутентификации: `login()`, `register()`, `logout()`, `refreshToken()`
- **Layout** — навигация, пункт «Голос»
- **OAuthCallback** — обработка кода авторизации
- **ForgotPasswordPage / ResetPasswordPage** — сброс пароля
### 14.3 PWA
- manifest.json с иконками всех размеров (16, 32, 192, 512, apple-touch-icon)
- favicon.ico + SVG fallback
- service worker (Vite PWA plugin)
- Тёмная тема (Tailwind `dark:` классы)
- Адаптивный дизайн (mobile-first)
---
## 15. API Reference
### 15.1 Auth (`/api/v1/auth`)
| Метод | Endpoint | Тело | Ответ |
|-------|----------|------|-------|
| POST | `/register` | `{email, password, display_name}` | `TokenResponse` |
| POST | `/login` | `{email, password}` | `TokenResponse` |
| POST | `/refresh` | `{refresh_token}` | `TokenResponse` (ротация) |
| GET | `/oauth/yandex` | — | `{url, provider}` |
| POST | `/oauth/yandex/callback` | `{code}` | `TokenResponse` |
| GET | `/oauth/google` | — | `{url, provider}` |
| POST | `/oauth/google/callback` | `{code}` | `TokenResponse` |
| GET | `/oauth/apple` | — | `{url, provider}` |
| POST | `/oauth/apple/callback` | `{code}` | `TokenResponse` |
| POST | `/forgot-password` | `{email}` | `{message}` |
| POST | `/reset-password` | `{token, new_password}` | `{message}` |
### 15.2 Voice (`/api/v1/voice`)
| Метод | Endpoint | Тело / Параметры | Ответ |
|-------|----------|-------------------|-------|
| POST | `/transcribe` | `file: UploadFile` (audio) | `{text}` |
| POST | `/chat` | `{text, session_id?}` | `ChatResponse` |
| POST | `/rate` | `{interaction_id, rating}` | `{status}` |
| GET | `/agents` | — | `[{name, description}]` |
| GET | `/sessions` | `?status=` | `[SessionResponse]` |
| GET | `/sessions/{id}` | — | `SessionResponse` |
| GET | `/sessions/{id}/history` | — | `[{interactions}]` |
| DELETE | `/sessions/{id}` | — | `{status}` |
### 15.3 Ideas (`/api/v1/ideas`)
| Метод | Endpoint | Описание |
|-------|----------|----------|
| GET | `/` | Список идей |
| POST | `/` | Создать идею |
| GET | `/{id}` | Детали идеи |
| PUT | `/{id}` | Обновить идею |
| DELETE | `/{id}` | Удалить идею |
### 15.4 Admin (`/api/v1/admin`)
Под защитой `require_admin`:
- `GET /users` — список пользователей
- `GET /logs` — просмотр логов
- `GET /agents` — статус агентов
---
## 16. Фазы реализации
- **Фаза 0: База данных** — Модели (8 таблиц), миграция Alembic, SQLAlchemy async, UUID primary keys
- **Фаза 1: Сессии** — Авто-создание сессии, авто-title (LLM), сайдбар, история, удаление
- **Фаза 2: Сохранение идей** — Хранитель (Keeper Agent), кнопка «Сохранить», экспорт на Яндекс.Диск / Google Drive / iCloud
- **Фаза 3: Команды + самообучение** — Встроенные и динамические голосовые команды, VoiceHelpPage, docs/voice-commands.md
- **Фаза 4: UI/анимация** — Dark-стили VoiceChat, анимированная волна микрофона, микро-анимации переходов
- **Фаза 5: Multi-сессия** — BroadcastChannel API, параллельные обсуждения, переключение между сессиями без потери контекста
- **Фаза 6: Rate limit** — Применение slowapi ко всем auth endpoints, настройка лимитов
- **Фаза 7: Security hardening** — Security headers middleware, brute force (5 попыток), refresh token rotation, отдельный reset secret
- **Фаза 8: 2FA (TOTP)** — PyOTP + QR-код, подтверждение кода при входе, настройка через профиль
- **Фаза 9: VPS deploy** — Nginx + certbot (Let's Encrypt) + systemd + Alembic upgrade + production .env + мониторинг
- **Фаза 10: Google/Apple OAuth** — Активация роутов авторизации, Drive клиенты, полная интеграция с дисками
---
## 17. Ключевые архитектурные решения
| Решение | Обоснование |
|---------|-------------|
| **PostgreSQL-only** | Единый `DATABASE_URL`. Никакого SQLite. Дев и прод на одном PostgreSQL |
| **systemd (no Docker)** | Прямое управление процессом, простота деплоя на Ubuntu VPS |
| **FastAPI StaticFiles** | Фронтенд раздаётся бэкендом — не нужен отдельный сервер для SPA |
| **Дирижёр = единственная точка входа** | Верификация внутри Дирижёра (не отдельный агент) — быстрее, меньше загрузки LLM |
| **Confidence scoring** | ≥80% OK, 50-79% warning, <50% уточнение. Прозрачность для пользователя |
| **Web Speech → Whisper** | Бесплатный браузерный API как primary, Whisper API как fallback |
| **SpeechSynthesis (TTS)** | Браузерный API — бесплатно, без серверной нагрузки |
| **Пустой OAuth ID = флаг** | `bool(oauth_google_id)` — естественный gate, не может быть рассинхрона |
| **Отдельный JWT reset secret** | Reset token не может быть использован как access/refresh и наоборот |
| **Refresh token rotation** | Каждый refresh выдаёт новую пару — старый токен становится недействительным |
| **Brute force in-memory** | Достаточно для MVP. В проде — Redis с TTL |
| **Агенты имеют прямой доступ к БД** | Все внутренние агенты работают через переданную async-сессию |
---
## 18. Примеры использования
### Пример 1: Пользователь придумывает стартап
**Запрос:** «Придумай идею для стартапа в сфере экологии»
**Pipeline:**
1. Дирижёр создаёт сессию «Стартап в экологии»
2. Маршрутизация → Бизнес-аналитик
3. Бизнес-аналитик генерирует: ROI, окупаемость, ЦА, конкуренты
4. Верификация: confidence 92%, verified
5. Ответ + звёзды рейтинга
**UI:**
```
┌─────────────────────────────────────┐
│ ← Стартап в экологии [85%] │
│ │
│ Придумай идею для стартапа... │
│ ─────────────────────────────────── │
│ Бизнес-аналитик [92%] │
│ Идея: переработка пластика... │
│ ★ ★ ★ ★ ☆ │
└─────────────────────────────────────┘
```
### Пример 2: Пользователь уточняет
**Запрос:** «А какие юридические риски?»
1. Дирижёр определяет: нужен Юрист
2. Юрист анализирует: 152-ФЗ, ответственность за экологию
3. Confidence: 73% → warning
4. Пользователь может уточнить или поставить оценку
### Пример 3: Сохранение идеи
**Команда:** «Сохрани идею»
1. Дирижёр → Хранитель
2. Хранитель формулирует: название, описание, теги
3. Идея сохраняется в БД + экспорт на Яндекс.Диск (если OAuth подключён)
---
## 19. Файловая структура (ключевые файлы)
```
voidea/
├── app/
│ ├── api/v1/
│ │ ├── auth.py — аутентификация + OAuth + password reset
│ │ ├── voice.py — транскрибация, чат, сессии, рейтинг
│ │ ├── ideas.py — CRUD идей
│ │ ├── admin.py — админ-панель
│ │ └── agents.py — управление агентами
│ ├── agents/
│ │ ├── conductor_agent.py — Дирижёр (оркестратор)
│ │ ├── role_agents.py — 13 ролевых агентов + верификация
│ │ ├── conductor_storage.py — логирование, рейтинг, похожие кейсы
│ │ ├── registry.py — 12 dev/ops агентов
│ │ └── base.py — базовый класс агента
│ ├── core/
│ │ ├── config.py — настройки (.env)
│ │ ├── security.py — JWT, bcrypt, хеши
│ │ ├── middleware.py — SecurityHeadersMiddleware
│ │ ├── limiter.py — shared slowapi limiter
│ │ ├── dependencies.py — get_db, get_current_user
│ │ └── database.py — async SQLAlchemy engine
│ ├── models/
│ │ ├── user.py, idea.py, session.py, conductor.py
│ │ ├── voice_command.py, agent.py, backlog.py, log.py
│ ├── services/
│ │ ├── auth_service.py — логин, регистрация, OAuth, brute force
│ │ ├── session_service.py — CRUD сессий
│ │ ├── whisper_service.py — OpenAI Whisper API
│ │ ├── llm_service.py — единый LLM-клиент
│ │ ├── email_service.py — SMTP + Jinja2
│ │ ├── password_reset_service.py — JWT reset token
│ │ └── crypto_service.py — AES-256 Fernet
│ └── integrations/oauth/
│ ├── yandex.py — Яндекс OAuth + Disk (работает)
│ ├── google.py — Google OAuth + Drive (stub, ждёт OAuth)
│ └── apple.py — Apple OAuth + iCloud (stub, ждёт OAuth)
├── webui/
│ ├── src/
│ │ ├── components/
│ │ │ ├── VoiceChat.tsx — чат + сайдбар + text input
│ │ │ ├── VoiceInput.tsx — микрофон (Speech → Whisper)
│ │ ├── pages/
│ │ │ ├── LoginPage.tsx, RegisterPage.tsx
│ │ │ ├── ForgotPasswordPage.tsx, ResetPasswordPage.tsx
│ │ │ ├── OAuthCallback.tsx
│ │ └── hooks/
│ │ └── useVoiceCommands.ts — голосовые команды
│ ├── public/
│ │ ├── favicon.ico / .svg / .png
│ │ ├── apple-touch-icon.png
│ │ ├── site.webmanifest
│ │ └── icons/ (192, 512, android-chrome)
│ └── index.html
├── alembic/versions/
│ └── 001_create_all_tables.py
├── docs/
│ ├── full.md ← данный файл (финальная спецификация)
│ ├── architecture.md — архитектурная документация
│ └── decision-log.md — лог ключевых решений
├── .env.example
└── requirements.txt
```
---
*VoIdeaAI — идеи рождаются вслух, решения приходят мгновенно!*
*Документ финальной спецификации. Версия 1.0.0.*
+41
View File
@@ -0,0 +1,41 @@
# Git Flow
## Ветки
```
main # Стабильная, production-ready
develop # Интеграция фич
feature/* # Новая функция (от develop)
hotfix/* # Срочное исправление (от main)
```
| Ситуация | Ветка | Цель |
|----------|-------|------|
| Новая фича | `feature/ai-analysis` | develop |
| Баг в production | `hotfix/crash-on-empty` | main |
| Эксперимент | `experiment/new-auth` | — |
## Conventional Commits
```
<тип>[scope]: <описание>
[body]
[footer]
```
| Тип | Пример | Версия |
|-----|--------|--------|
| `feat` | `feat(api): add analyze endpoint` | MINOR |
| `fix` | `fix: handle empty list` | PATCH |
| `BREAKING` | `feat!: change response format` | MAJOR |
| `docs` | `docs: add architecture doc` | — |
| `refactor` | `refactor: extract IdeaService` | — |
| `test` | `test: add auth integration tests` | — |
| `chore` | `chore: add pre-commit config` | — |
## Правила коммитов
- Заголовок до 72 символов, императив, без точки
- Тело: ЧТО и ЗАЧЕМ, а не КАК
- PR → squash merge (1 PR = 1 коммит в develop)
+191
View File
@@ -0,0 +1,191 @@
# System Prompt for AI (OpenCode) - VoIdea
**Role:** Senior Software Architect and Product Analyst
**Project:** VoIdea - Voice Ideas Application
---
## 1. Primary Rule
**00-rules.md is PRIORITY.** If something is not described in a specific block - check 00-rules.md first. Only then ask user.
---
## 2. Project Overview
VoIdea is a hybrid app (mobile + web) for capturing and developing ideas using group AI analysis.
### Key Features
- Voice input
- 11 AI agents for idea analysis
- Cross-device sync
- AES-256 encryption
- Offline support (PWA)
### Tech Stack
- Backend: Python FastAPI, Port 8020
- Database: PostgreSQL
- Cache: Redis + Celery
- Frontend: React + TypeScript + Tailwind CSS
---
## 3. Working with AI Agents
### AI Agents (11 roles for idea analysis)
1. Coordinator
2. Task Organizer
3. Business Analyst
4. Lawyer
5. Financial Advisor
6. Solution Architect
7. Tester
8. UI Designer
9. SMM Specialist
10. Life Coach
11. Accessibility Expert
Prompts stored in: docs/agent_prompts.yaml (TDC)
### System Agents (11 agents for automation)
1. DocAgent - Documentation
2. AuditAgent - Rules compliance
3. SecurityAgent - Security
4. SpecAgent - Specifications, versioning
5. ObserverAgent - User behavior
6. QATesterAgent - Functional testing
7. FixAgent - Bug fixes
8. UITestAgent - Visual testing
9. RolloutAgent - Gradual deployment
10. EvolutionAgent - Self-improvement
11. BacklogAgent - Task management
---
## 4. Architecture
Layers (dependencies only inward):
`
API -> Services -> Integrations -> Data Layer -> Core
`
SOLID principles apply.
Module public API in __init__.py only.
---
## 5. Code Style
- UTF-8, 4 spaces, 88 char line length
- snake_case for vars/functions
- PascalCase for classes
- UPPER_SNAKE_CASE for constants
- Type annotations required
- Imports: stdlib -> third-party -> local
---
## 6. Documentation
- Google-style docstrings
- README.md in each app/* folder
- Update docs on changes
- TODO with task number
---
## 7. Testing
- Unit tests: tests/unit/
- Integration tests: tests/integration/
- Minimum 1 smoke test per endpoint
- pytest with asyncio_mode=auto
---
## 8. Versioning
Format: MAJOR.MINOR.PATCH
CHANGELOG: CHANGELOG/vX.Y.md (new file on X or Y change)
Conventional Commits: feat, fix, docs, refactor, test, chore
---
## 9. Security
- .env never in git
- JWT: HS256, 60min access, 30 days refresh
- Passwords: bcrypt
- Pydantic validation on all inputs
- RBAC: user, admin, owner
---
## 10. Design System
Source of truth: docs/design-system/tokens.json
Includes: colors, typography, spacing, shadows
Themes: system (auto), dark, light
---
## 11. Error Handling
| Layer | Action |
|-------|--------|
| API | HTTPException with detail and status_code |
| Services | Business exceptions, no HTTP |
| Integrations | try/except with fallback |
| DB | Errors don't bubble up |
---
## 12. Logging
Format: [ISO8601] [LEVEL] [component] message key=val
No f-strings in logger (lazy evaluation).
Never log: passwords, JWT, API keys, raw email.
---
## 13. Rollout Process
Gradual deployment: 3 users -> 1% -> 5% -> 15% -> 100%
Controlled by RolloutAgent.
Manual trigger via admin panel.
---
## 14. Project Structure
`
voidea/
├── app/
│ ├── agents/ # System agents (11)
│ ├── core/ # Config, base, security
│ ├── models/ # Database models
│ ├── api/ # API endpoints
│ ├── services/ # Business logic
│ └── integrations/ # External services
├── docs/
│ ├── blocks/ # Project blocks
│ ├── design-system/ # Design tokens
│ ├── instructions/ # For AI and humans
│ ├── specs/ # Specifications
│ └── ...
├── tests/
└── CHANGELOG/
`
---
## 15. Before Starting Work
1. Read docs/blocks/00-rules.md
2. Check docs/blocks/PLAN.md for current phase
3. Check docs/instructions/ for relevant instructions
4. Update TODO list if needed
---
*Updated: 2026-05-10*
+105
View File
@@ -0,0 +1,105 @@
# Developer Instructions - VoIdea
**Date:** 2026-05-10
---
## Prerequisites
1. Python 3.12+
2. PostgreSQL (local)
3. Redis (optional for local dev)
---
## Setup
`ash
# 1. Clone repository
git clone <repo>
cd voidea
# 2. Create venv
python -m venv venv
source venv/Scripts/activate # Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Configure environment
cp .env.example .env
# Edit .env with your values
# 5. Database setup
alembic upgrade head
# 6. Run application
uvicorn app.main:app --reload --port 8020
`
---
## Key Commands
`ash
# Lint
ruff check .
# Format
ruff format .
# Type check
mypy .
# Tests
pytest
# With coverage
pytest --cov=app tests/
# Run specific test
pytest tests/unit/test_core.py -v
`
---
## Project Structure
- pp/ - Application code
- docs/ - Documentation
- ests/ - Tests
---
## Naming Conventions
- Variables/Functions: snake_case
- Classes: PascalCase
- Constants: UPPER_SNAKE_CASE
- Files: snake_case.py
---
## Adding New Feature
1. Create feature branch: git checkout -b feature/description
2. Implement code
3. Write tests
4. Update documentation
5. Create PR
6. After approval: merge to develop, then main
---
## Rules
1. Always read 00-rules.md first
2. Follow code style (ruff, mypy)
3. Write docstrings
4. Update docs on changes
5. Tests required
6. No secrets in code
---
*Updated: 2026-05-10*
+91
View File
@@ -0,0 +1,91 @@
# Tester Instructions - VoIdea
**Date:** 2026-05-10
---
## Testing Overview
### Test Types
1. **Unit Tests** - tests/unit/
- Test individual functions/methods
- Mock external dependencies
2. **Integration Tests** - tests/integration/
- Test API endpoints
- Test database operations
- Test with real services
3. **E2E Tests** - docs/specs/e2e/
- User scenarios
- Cross-module behavior
---
## Running Tests
`ash
# All tests
pytest
# Specific file
pytest tests/unit/test_services.py -v
# With coverage
pytest --cov=app --cov-report=html
# Watch mode
pytest --watch
`
---
## Writing Tests
`python
async def test_create_idea():
# Arrange
user = await create_test_user()
# Act
result = await idea_service.create(
user_id=user.id,
title="Test Idea"
)
# Assert
assert result.title == "Test Idea"
assert result.user_id == user.id
`
---
## Test Coverage Goals
- Minimum: 1 smoke test per endpoint
- Target: 80% coverage
- Critical paths: 100%
---
## Bug Reporting
Report format:
1. Description
2. Steps to reproduce
3. Expected vs actual
4. Logs/screenshots
5. Environment
---
## QA Agents
- QATesterAgent: Functional testing, temp users
- FixAgent: Bug fixes
- UITestAgent: Visual testing
---
*Updated: 2026-05-10*
+63
View File
@@ -0,0 +1,63 @@
# Admin Instructions - VoIdea
**Date:** 2026-05-10
---
## Admin Panel
Access: /admin
### Features
1. **Logs Viewer**
- Filter by type, date, severity
- Color-coded severity: red (critical), orange (warning)
- Export logs
2. **Agent Control**
- View agent status
- Start/stop agents manually
- View agent reports
3. **User Management**
- View users
- Manage roles
- Disable accounts
4. **System Health**
- Database status
- Redis status
- Server uptime
---
## Logs
Location: PostgreSQL (system_logs table) + files (logs/)
Severity levels:
- ERROR: Red + email notification
- WARNING: Orange
- INFO: No highlight
---
## Agent Commands
- "Run Test" button -> starts QATesterAgent
- "View Report" -> shows last agent report
- "Stop Task" -> cancels running agent
---
## Monitoring
Key metrics:
- API response time: < 500ms
- Database queries: < 100ms
- Uptime: > 99.9%
---
*Updated: 2026-05-10*
+44
View File
@@ -0,0 +1,44 @@
# Поэтапный план взросления проекта
## Текущий статус: Stage 2 (Production-ready)
VoIdea прошла стадии Foundation и Growth и находится на пороге Production-ready.
## Stage 0: Foundation — Ядро (✅ пройдено)
**Код:** FastAPI + PostgreSQL + базовая auth, CRUD endpoints, Pydantic схемы
**Агенты:** DocAgent, AuditAgent, EvolutionAgent, SupervisorAgent (4 core)
**Инфраструктура:** PostgreSQL, прямой вызов задач
## Stage 1: Growth — Рост (✅ пройдено)
**Код:** Полноценные сервисы, AI интеграции (YandexGPT + GigaChat), React фронтенд, тесты (125)
**Агенты:** + BacklogAgent, SpecAgent, ObserverAgent, SecurityAgent, QATesterAgent, FixAgent, UITestAgent, RolloutAgent (11 total)
**Инфраструктура:** PostgreSQL, прямой вызов, тестовое покрытие
## Stage 2: Production-ready (⬅️ текущее)
**Код:** PostgreSQL + asyncpg, Redis + Celery, мониторинг (metrics middleware + AgentMetrics), полная документация
**Агенты:** 11 агентов написаны и зарегистрированы
**Инфраструктура:** PostgreSQL, Redis + Celery, Alembic, pre-commit hooks, CI/CD, runbook
### Что осталось до Stage 2
- [x] PostgreSQL-only config
- [x] pre-commit hooks
- [x] CI/CD (lint + test)
- [x] Runbook (systemd)
- [ ] Alembic миграция на VPS
- [ ] Production .env + SSL (Let's Encrypt)
- [ ] Integration tests (36 шт)
## Stage 3: Autonomous — Саморазвитие (цель)
- Metrics dashboard на основе AgentMetrics
- Self-healing (авто-восстановление)
- A/B тестирование
## Stage 4: Evolution — Эволюция (дальняя цель)
- Агенты применяют изменения (с PR на ревью)
- ObserverAgent строит roadmap на основе метрик
- FixAgent авто-исправляет баги
+49
View File
@@ -0,0 +1,49 @@
# Производительность
## Performance budgets (p95)
| Метрика | Лимит | Примечание |
|---------|-------|------------|
| API response (без AI) | < 500ms | |
| API response (с AI) | < 5s | Fallback после таймаута |
| DB query (одиночный) | < 100ms | С индексом |
| WebUI page load | < 2s | |
| AI call | < 5s | Иначе fallback |
## Индексы БД
```sql
CREATE INDEX ix_ideas_user_id ON ideas(user_id);
CREATE INDEX ix_ideas_status ON ideas(status);
CREATE INDEX ix_ideas_created_at ON ideas(created_at);
CREATE INDEX ix_users_email ON users(email);
```
## Connection pool
```python
engine = create_async_engine(
settings.database_url,
pool_size=10,
max_overflow=20,
pool_pre_ping=True,
)
```
## Метрики
| Метрика | Тип | Описание |
|---------|-----|----------|
| `http_requests_total` | Counter | Всего запросов |
| `http_request_duration_ms` | Histogram | Время ответа (p50/p95/p99) |
| `http_errors_total` | Counter | 4xx и 5xx |
| `ai_provider_calls` | Counter | Вызовы AI провайдеров |
| `agent_execution_duration` | Histogram | Время выполнения агентов |
**Где хранить:** в БД (таблица `agent_metrics`), в перспективе — Prometheus.
## Когда оптимизировать
1. Профилировать до оптимизации. Не гадать — измерять.
2. Оптимизировать только горячие пути (90% времени на 10% кода).
3. Кэшировать только то, что реально часто читается.
+247
View File
@@ -0,0 +1,247 @@
# Quick Start - VoIdea
**Дата:** 2026-05-10
**Обновлено:** автоматически DocAgent
---
## Prerequisites
Перед началом убедитесь, что установлено:
| Компонент | Версия | Ссылка |
|-----------|--------|--------|
| Python | 3.12+ | [python.org](https://www.python.org/downloads/) |
| PostgreSQL | 14+ | [postgresql.org](https://www.postgresql.org/download/) |
| Git | 2.0+ | [git-scm.com](https://git-scm.com/) |
---
## 1. Клонирование проекта
```bash
git clone <repository_url>
cd voidea
```
---
## 2. Настройка виртуального окружения
### Windows
```bash
python -m venv venv
.\venv\Scripts\activate
```
### Linux/macOS
```bash
python -m venv venv
source venv/bin/activate
```
---
## 3. Установка зависимостей
```bash
pip install -r requirements.txt
```
---
## 4. Настройка PostgreSQL
### Windows
1. Скачайте и установите PostgreSQL с [postgresql.org](https://www.postgresql.org/download/windows/)
2. Запустите pgAdmin или psql
### Создание базы данных
```sql
-- Подключитесь к PostgreSQL (psql или pgAdmin)
CREATE USER voidea WITH PASSWORD 'your_secure_password';
CREATE DATABASE voidea OWNER voidea;
GRANT ALL PRIVILEGES ON DATABASE voidea TO voidea;
```
---
## 5. Настройка переменных окружения
```bash
cp .env.example .env
```
Откройте `.env` и заполните:
```bash
# Обязательно заполнить
DB_PASS=your_secure_password
JWT_SECRET_KEY=generate_with_python_c_secret
PROJECT_OWNER=Your Name
# Опционально (для полного функционала)
AI_YANDEX_KEY=your_yandex_gpt_key
AI_GIGACHAT_KEY=your_gigachat_key
OAUTH_YANDEX_ID=your_yandex_client_id
OAUTH_GOOGLE_ID=your_google_client_id
```
### Генерация JWT_SECRET_KEY
```bash
python -c "import secrets; print(secrets.token_hex(32))"
```
---
## 6. Миграции базы данных
```bash
# Создание миграций (если ещё нет)
alembic revision --autogenerate -m "Initial migration"
# Применение миграций
alembic upgrade head
```
---
## 7. Запуск приложения
### Локальный режим (разработка)
```bash
uvicorn app.main:app --reload --port 8020 --host 0.0.0.0
```
### Проверка работы
Откройте в браузере:
- API: http://localhost:8020
- Docs: http://localhost:8020/docs
- Health: http://localhost:8020/health
---
## 8. Тесты
```bash
# Все тесты
pytest
# С покрытием
pytest --cov=app --cov-report=html
# Конкретный файл
pytest tests/unit/test_core.py -v
```
---
## 9. Code Quality
```bash
# Линтинг
ruff check .
# Форматирование
ruff format .
# Типизация
mypy app
```
---
## 10. Генерация Design Tokens (опционально)
```bash
# После изменений в tokens.json
python -m generators css
python -m generators swift
python -m generators kotlin
```
---
## Структура проекта
```
voidea/
├── app/ # Код приложения
│ ├── agents/ # 11 системных агентов
│ ├── core/ # Конфигурация, базовые классы
│ ├── models/ # Модели данных
│ ├── api/ # API endpoints
│ ├── services/ # Бизнес-логика
│ └── integrations/ # Внешние сервисы
├── docs/ # Документация
│ ├── blocks/ # Блоки проекта
│ ├── design-system/ # Дизайн-система
│ ├── instructions/ # Инструкции
│ └── specs/ # Спецификации
├── tests/ # Тесты
├── CHANGELOG/ # История версий
├── .env.example # Пример переменных
└── requirements.txt # Зависимости
```
---
## Обновление проекта
```bash
# Переключиться на новую версию
git checkout develop
git pull origin develop
# Применить миграции
alembic upgrade head
# Обновить зависимости
pip install -r requirements.txt
```
---
## Решение проблем
### "Module not found"
```bash
pip install -r requirements.txt
```
### "Database connection refused"
1. Проверьте PostgreSQL запущен
2. Проверьте `DB_HOST`, `DB_PORT` в `.env`
3. Проверьте credentials
### "Port already in use"
```bash
# Найти процесс на порту 8020
netstat -ano | findstr :8020
# Завершить процесс
taskkill /PID <pid> /F
```
---
## Следующие шаги
1. Прочитайте `PROJECT_GUIDE.md` — обзор проекта
2. Изучите `docs/blocks/00-rules.md` — правила проекта
3. Следуйте плану в `docs/blocks/PLAN.md` — этапы разработки
---
*Обновлено: 2026-05-10*
*Этот файл поддерживается DocAgent автоматически*
+25
View File
@@ -0,0 +1,25 @@
# Runbook: Резервное копирование
## PostgreSQL
```bash
# Ручной бэкап
pg_dump -U voidea -d voidea > /backups/voidea.$(date +%Y%m%d).sql
# Восстановление
psql -U voidea -d voidea < /backups/voidea.20260511.sql
# Автоматический (cron: ежедневно в 3:00)
0 3 * * * pg_dump -U voidea -d voidea | gzip > /backups/voidea.$(date +\%Y\%m\%d).sql.gz && find /backups -name 'voidea.*.sql.gz' -mtime +30 -delete
```
## Что бэкапить
- Базу данных — ежедневно
- `.env` — отдельно, в GitHub Secrets / 1Password
## Хранение
- Последние 7 дней: локально
- Последние 30 дней: S3 / облако
- Старше 30 дней: удалять
+59
View File
@@ -0,0 +1,59 @@
# Runbook: Инциденты
## Сервис недоступен
```bash
# 1. Проверить что процесс жив
systemctl status voidea
# 2. Проверить логи
journalctl -u voidea -n 50 --no-pager
# 3. Перезапустить
systemctl restart voidea
# 4. Проверить health
curl http://localhost:8020/health
# 5. Если не помогло — rollback
cd /opt/voidea
git checkout <previous-stable-tag>
systemctl restart voidea
```
## База данных недоступна
```bash
# 1. Проверить PostgreSQL
systemctl status postgresql
# 2. Проверить логи
journalctl -u postgresql -n 50
# 3. Перезапустить
systemctl restart postgresql
# 4. Если повреждена — восстановить из backup
psql -U voidea -d voidea < /backups/voidea.20260511.sql
```
## AI провайдер недоступен
- FallbackChain автоматически пробует YandexGPT → GigaChat
- Если оба недоступны — возвращается AgentResult(success=False)
- Пользователь получает уведомление, анализ не блокируется
## Высокая загрузка CPU
```bash
# 1. Найти процесс
top -o %CPU
# 2. Проверить какие endpoint'ы нагружают
tail -n 100 /var/log/voidea/access.log
# 3. Временно ограничить: увеличить число воркеров или перезапустить
systemctl restart voidea
# 4. Разбираться после восстановления
```
+41
View File
@@ -0,0 +1,41 @@
# Runbook: Масштабирование
## Когда масштабироваться
| Метрика | Действие |
|---------|----------|
| CPU > 80% постоянно | Увеличить VPS (больше ядер) |
| RAM > 80% | Увеличить VPS (больше RAM) |
| DB > 10M записей | Индексы → шардинг |
| Response time p95 > 1s | Кэширование (Redis) → реплики БД |
## Vertical scaling (проще)
```bash
# 1. Остановить сервис
systemctl stop voidea
# 2. Увеличить ресурсы VPS (через панель управления)
# 3. Запустить
systemctl start voidea
```
## Horizontal scaling (сложнее)
```bash
# 1. Поставить Nginx как load balancer
# 2. Запустить несколько инстансов uvicorn на разных портах
# 3. Настроить shared Redis кэш
# 4. Настроить репликацию PostgreSQL
```
## Celery worker
```bash
# Запустить с большим числом воркеров
celery -A app.tasks worker --concurrency=4 -l info
# Для длительных задач — отдельная очередь
celery -A app.tasks worker -Q analysis -c 2 -l info
```
+64
View File
@@ -0,0 +1,64 @@
# Runbook: Обновление
## Стандартное обновление
```bash
# 1. Забрать новую версию
cd /opt/voidea
git pull origin main
# 2. Активировать виртуальное окружение
source venv/bin/activate
# 3. Обновить зависимости
pip install -r requirements.txt
# 4. Применить миграции БД
alembic upgrade head
# 5. Перезапустить сервис
systemctl restart voidea
# 6. Проверить health
curl http://localhost:8020/api/v1/health
```
## Обновление с минимальным даунтаймом
```bash
# 1. Запустить второй инстанс на другом порту
DATABASE_URL=... uvicorn app.main:app --port 8021 &
# 2. Проверить его health
curl http://localhost:8021/health
# 3. Переключить systemd или Nginx на новый порт
# 4. Остановить старый
```
## Откат
```bash
# 1. Откатить код
cd /opt/voidea
git revert HEAD
# 2. Откатить БД (если была миграция)
alembic downgrade -1
# 3. Перезапустить
systemctl restart voidea
```
## Миграция БД
```bash
# Сгенерировать новую миграцию
alembic revision --autogenerate -m "description"
# Применить
alembic upgrade head
# Откатить
alembic downgrade -1
```
+25
View File
@@ -0,0 +1,25 @@
# Runbook - VoIdea
**Purpose:** Operations guide for project owner
---
## Table of Contents
1. [Quick Start](01-quick-start.md)
2. [Deployment](02-deployment.md)
3. [Backup & Restore](03-backup-restore.md)
4. [Troubleshooting](04-troubleshooting.md)
5. [Monitoring](05-monitoring.md)
6. [Security](06-security.md)
---
## Overview
This runbook contains operational procedures for VoIdea project.
All procedures are maintained by system agents (DocAgent, BacklogAgent).
---
*Updated: 2026-05-10*
+53
View File
@@ -0,0 +1,53 @@
# Безопасность
## Базовые требования
- `.env` — всегда в `.gitignore`. Никогда не коммитить.
- JWT: HS256, access_token = 60 минут, refresh_token = 30 дней
- Пароли: bcrypt через passlib
- Pydantic валидация на всех входах
- RBAC: роли `user` и `admin` (`is_superuser`)
## Аутентификация
```python
# app/core/security.py
def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str
def decode_token(token: str) -> dict[str, Any] | None
def hash_password(password: str) -> str
def verify_password(plain: str, hashed: str) -> bool
```
## RBAC
| Роль | Права |
|------|-------|
| user | CRUD своих идей, запуск анализа |
| admin | Управление пользователями, просмотр логов, системные настройки |
## Sensitive data
**Никогда не логировать:**
- Пароли (даже хэш)
- JWT токены
- API keys и секреты
- Email в открытом виде (только user_id)
**Маскировать:**
- Email: `u***@mail.ru`
- IP: `195.208.*.*`
## Secrets management
| Окружение | Где хранить |
|-----------|-------------|
| Local | `.env` (в .gitignore) |
| Staging/Prod | GitHub Secrets |
Без Vault (< 10 разработчиков). JWT_SECRET_KEY менять при утечке или раз в год.
## Запланировано
- OAuth2 (Yandex, Google) — Authlib
- Rate limiting — slowapi
- CORS — FastAPI middleware (настроен)
+185
View File
@@ -0,0 +1,185 @@
# Spec: Accessibility Expert Agent
**Дата:** 2026-05-10
**Роль:** Эксперт по доступности
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Эксперт по доступности анализирует идею с точки зрения инклюзивности для людей с ограниченными возможностями (ОВЗ) и предлагает доработки для соответствия WCAG 2.1.
---
## Prompt Template
```
Ты — Эксперт по доступности команды VoIdea.
Твоя задача:
1. Проанализировать идею на соответствие WCAG 2.1
2. Выявить барьеры для людей с ОВЗ
3. Предложить доработки для инклюзивности
Релевантные стандарты:
- WCAG 2.1 (Level A, AA, AAA)
- Категории ОВЗ: слабовидящие, глухие, моторные ограничения, когнитивные
Формат ответа:
## Анализ доступности
### WCAG 2.1 соответствие
| Критерий | Статус | Рекомендация |
|----------|--------|--------------|
| 1.1.1 Non-text Content | [✓/✗/N/A] | [Рекомендация] |
| 1.2.1 Audio-only | [✓/✗/N/A] | [Рекомендация] |
| ... | ... | ... |
### Барьеры для пользователей
#### Слабовидящие
- [Барьер 1]: [Решение]
- [Барьер 2]: [Решение]
#### Глухие / слабослышащие
- [Барьер 1]: [Решение]
- ...
#### Моторные ограничения
- [Барьер 1]: [Решение]
- ...
#### Когнитивные особенности
- [Барьер 1]: [Решение]
- ...
### Доработки (приоритет)
| Приоритет | Доработка | WCAG критерий |
|-----------|-----------|---------------|
| High | [Действие] | [Критерий] |
| Medium | [Действие] | [Критерий] |
| Low | [Действие] | [Критерий] |
### Оценка соответствия
- WCAG Level A: [X]%
- WCAG Level AA: [X]%
- WCAG Level AAA: [X]%
```
---
## Входные данные
- Описание продукта/интерфейса
- Платформа (web/mobile)
---
## Выходные данные
```yaml
accessibility_analysis:
wcag_compliance:
- criterion: str
status: str # pass/fail/n/a
recommendation: str
barriers:
visual:
- barrier: str
solution: str
hearing:
- barrier: str
solution: str
motor:
- barrier: str
solution: str
cognitive:
- barrier: str
solution: str
improvements:
- priority: str # high/medium/low
action: str
wcag_criterion: str
compliance_score:
level_a: float
level_aa: float
level_aaa: float
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Web Application
**Input:** "Веб-приложение для управления задачами"
**Expected Output:**
- Проверка alt-текстов, контрастности, навигации
- Предложения для screen reader
- Клавиатурная навигация
**Validation:**
- Упомянуты основные WCAG критерии
- Есть решения для каждого типа ОВЗ
---
### TC-02: Video Platform
**Input:** "Платформа потокового видео"
**Expected Output:**
- Субтитры обязательны
- Аудио-описание
- Управление клавиатурой
**Validation:**
- Субтитры упомянуты
- Аудио-описание предложено
---
### TC-03: Mobile Banking
**Input:** "Мобильное приложение банка"
**Expected Output:**
- Высокие требования к доступности (финансы)
- Упрощённый режим для когнитивных
- Крупные кнопки для моторных
**Validation:**
- Безопасность учтена
- Крупные элементы рекомендованы
---
## Success Criteria
- WCAG критерии проверены
- Решения для всех категорий ОВЗ
- Приоритизация доработок
---
## Метрики
- analyses_completed: int
- barriers_identified: int
- improvements_implemented: float
---
*Управляется SpecAgent*
+143
View File
@@ -0,0 +1,143 @@
# Spec: Architect Agent
**Дата:** 2026-05-10
**Роль:** Архитектор решений
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Архитектор решений проектирует архитектуру системы, предлагает 2 варианта (монолит/микросервисы) с оценкой технологий и сложности.
---
## Prompt Template
```
Ты — Архитектор решений команды VoIdea.
Твоя задача:
1. Предложить 2 варианта архитектуры
2. Указать технологии (БД, бэкенд, фронтенд)
3. Оценить сложность реализации
4. Дать рекомендацию
Формат ответа:
## Архитектура системы
### Вариант A: [Монолит / Микросервисы]
#### Стек
- Бэкенд: [Технология]
- База данных: [PostgreSQL/MongoDB/...]
- Фронтенд: [Технология]
- Инфраструктура: [AWS/Yandex Cloud/...]
#### Плюсы
1. [Плюс 1]
...
#### Минусы
1. [Минус 1]
...
#### Сложность: [Низкая/Средняя/Высокая]
#### Оценка времени: [X] месяцев
### Вариант B: [Альтернативный вариант]
[Аналогично варианту A]
### Рекомендация
[Краткое обоснование]
```
---
## Входные данные
- Описание продукта
- Требования к масштабируемости
- Бюджет (если указан)
---
## Выходные данные
```yaml
architecture:
variant_a:
type: str # monolith/microservices
stack:
backend: str
database: str
frontend: str
infrastructure: str
pros: list[str]
cons: list[str]
complexity: str # low/medium/high
estimated_months: int
variant_b:
# same structure
recommendation: str
reason: str
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: SaaS Application
**Input:** "CRM-система для малого бизнеса, до 100 пользователей"
**Expected Output:**
- Вариант A: Монолит (проще)
- Вариант B: Микросервисы (масштабируемость)
- Рекомендация: Монолит для MVP
**Validation:**
- Учтено ограничение в 100 пользователей
- Монолит рекомендован для MVP
---
### TC-02: High Load System
**Input:** "Платформа потокового видео, 10K+ пользователей одновременно"
**Expected Output:**
- Вариант A: Микросервисы
- CDN, балансировка
- Рекомендация: Микросервисы
**Validation:**
- Учтена высокая нагрузка
- Упомянуты CDN, балансировка
---
## Success Criteria
- Оба варианта проработаны
- Технологии актуальные
- Сложность реалистичная
---
## Метрики
- architectures_proposed: int
- recommendations_accepted: float
---
*Управляется SpecAgent*
+136
View File
@@ -0,0 +1,136 @@
# Spec: Business Analyst Agent
**Дата:** 2026-05-10
**Роль:** Бизнес-аналитик
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Бизнес-аналитик оценивает идею с точки зрения бизнес-показателей: ROI, сроки окупаемости, целевая аудитория, конкурентные преимущества.
---
## Prompt Template
```
Ты — Бизнес-аналитик команды VoIdea.
Твоя задача:
1. Оценить ROI (%) — ожидаемая прибыль vs инвестиции
2. Оценить срок окупаемости (месяцы)
3. Определить целевую аудиторию (тыс. человек)
4. Выявить конкурентные преимущества
5. Кратко обосновать оценки
Формат ответа:
## Бизнес-анализ
### ROI
- Ожидаемый: [X]%
- Обоснование: [Краткое]
### Срок окупаемости
- [X] месяцев
- Обоснование: [Краткое]
### Целевая аудитория
- Размер: [X] тыс. человек
- Сегменты: [Список]
- Обоснование: [Краткое]
### Конкурентные преимущества
1. [Преимущество 1]
2. [Преимущество 2]
...
### Риски
- [Риск 1]
- [Риск 2]
```
---
## Входные данные
- Описание идеи
- Рынок (если указан)
- Конкуренты (если указаны)
---
## Выходные данные
```yaml
business_analysis:
roi_percentage: float
payback_months: int
target_audience_size: int # тыс.
target_segments:
- str
competitive_advantages:
- str
risks:
- str
confidence: float
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Tech Startup
**Input:** "Платформа для онлайн-курсов с ИИ-репетитором"
**Expected Output:**
- ROI оценка
- Срок окупаемости
- Целевая аудитория
- Конкуренты: Coursera, Udemy
**Validation:**
- Упомянуты основные конкуренты
- Реалистичные цифры
---
### TC-02: Local Business
**Input:** "Доставка еды в маленьком городе"
**Expected Output:**
- Локальная аудитория
- Конкуренты: местные рестораны
**Validation:**
- Аудитория < 100 тыс.
- Упомянуты локальные факторы
---
## Success Criteria
- Оценки основаны на данных
- Конкуренты идентифицированы
- Риски перечислены
---
## Метрики
- analyses_completed: int
- estimates_accuracy: float # корректировки в будущем
---
*Управляется SpecAgent*
+156
View File
@@ -0,0 +1,156 @@
# Spec: Coordinator Agent
**Дата:** 2026-05-10
**Роль:** Координатор
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Координатор управляет диалогом, распределяет задачи между агентами и обобщает результаты анализа идей.
---
## Prompt Template
```
Ты — Координатор команды ИИ-агентов для анализа идей проекта VoIdea.
Твоя задача:
1. Понять суть идеи пользователя
2. Распределить задачи между специалистами
3. Собрать и обобщить результаты
4. Представить структурированный отчёт
Правила работы:
- Отвечай кратко и по делу
- Используй структуру: Заголовок → Ключевые моменты → Рекомендации
- Если идея неполная — задай уточняющие вопросы
- Фиксируй прогресс анализа
Формат ответа:
## Анализ идеи
### Краткое резюме
[2-3 предложения]
### Ключевые аспекты
1. [Аспект 1]
2. [Аспект 2]
...
### Рекомендации
- [Рекомендация 1]
- [Рекомендация 2]
```
---
## Входные данные
- Текст идеи пользователя
- Контекст (предыдущие идеи, история)
---
## Выходные данные
```yaml
analysis:
summary: str
key_aspects:
- str
recommendations:
- str
agents_involved:
- coordinator
- organizer
- business_analyst
# и другие задействованные агенты
confidence: float # 0-1
```
---
## Fallback Chain
1. Yandex GPT → первичный провайдер
2. GigaChat → при недоступности Yandex
3. Error → вернуть сообщение об ошибке с retry suggestion
---
## Test Cases
### TC-01: Полная идея
**Input:** "Хочу создать приложение для заметок с ИИ-помощником"
**Expected Output:**
- Резюме идеи
- Распределение задач
- Краткие рекомендации
**Validation:**
- Ответ < 500 слов
- Структура соблюдена
- Все секции заполнены
---
### TC-02: Неполная идея
**Input:** "Идея для стартапа"
**Expected Output:**
- Уточняющие вопросы
- Не пытаться угадать
**Validation:**
- Заданы минимум 2 вопроса
- Не предоставлены рекомендации
---
### TC-03: Техническая идея
**Input:** "Микросервисная архитектура на Go для обработки заказов"
**Expected Output:**
- Короткое резюме
- Технические аспекты
- Рекомендации по архитектуре
**Validation:**
- Упомянуты: микросервисы, Go, заказы
---
## Success Criteria
- Отвечает в < 5 секунд
- Структура соблюдается в 95% случаев
- Fallback работает корректно
- Интеграция с другими агентами
---
## Метрики
- requests_total: int
- requests_success: int
- requests_fallback: int
- average_response_time: float
- confidence_score: float
---
## История изменений
| Дата | Изменение | Автор |
|------|-----------|-------|
| 2026-05-10 | Начальная версия | SpecAgent |
---
*Управляется SpecAgent*
+144
View File
@@ -0,0 +1,144 @@
# Spec: Financial Advisor Agent
**Дата:** 2026-05-10
**Роль:** Финансовый консультант
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Финансовый консультант рассчитывает бюджет реализации идеи, прогнозирует доходы за год и определяет точку безубыточности.
---
## Prompt Template
```
Ты — Финансовый консультант команды VoIdea.
Твоя задача:
1. Составить смету реализации (разработка, маркетинг, поддержка)
2. Прогнозировать доход за год
3. Определить точку безубыточности
Формат ответа:
## Финансовый план
### Смета реализации
| Статья | Стоимость (руб.) |
|--------|------------------|
| Разработка | XXX |
| Маркетинг | XXX |
| Поддержка (год) | XXX |
| Прочее | XXX |
| **Итого** | **XXX** |
### Прогноз доходов (год 1)
| Месяц | Ожидаемый доход |
|-------|-----------------|
| 1 | XXX |
| ... | ... |
| 12 | XXX |
| **Итого** | **XXX** |
### Точка безубыточности
- Месяц: [X]
- Выручка к этому моменту: [XXX] руб.
### Ключевые допущения
1. [Допущение 1]
2. [Допущение 2]
```
---
## Входные данные
- Описание продукта
- Ценовая политика (если известна)
- Объём рынка
---
## Выходные данные
```yaml
financial_plan:
budget:
development: int
marketing: int
support_year: int
other: int
total: int
revenue_forecast:
month_1: int
# ... до month_12
year_total: int
break_even:
month: int
revenue: int
assumptions:
- str
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Mobile App
**Input:** "Приложение для медитации с подпиской 299 руб/мес"
**Expected Output:**
- Смета: разработка, маркетинг
- Прогноз подписок
- Break-even при X подписчиках
**Validation:**
- Цена 299 руб. использована
- Реалистичные цифры
---
### TC-02: Marketplace
**Input:** "Маркетплейс услуг с комиссией 10%"
**Expected Output:**
- Смета: выше чем для SaaS
- Прогноз комиссий
- Break-even при Y транзакций
**Validation:**
- Комиссия 10% использована
- Учтены операционные расходы
---
## Success Criteria
- Смета покрывает основные статьи
- Прогноз учитывает рост
- Break-even реалистичный
---
## Метрики
- plans_generated: int
- accuracy_vs_actual: float # после запуска
---
*Управляется SpecAgent*
+138
View File
@@ -0,0 +1,138 @@
# Spec: Lawyer Agent
**Дата:** 2026-05-10
**Роль:** Юрист
**Провайдер:** GigaChat (fallback: Yandex GPT)
---
## Описание
Юрист проверяет идею на соответствие законодательству РФ (44-ФЗ, 152-ФЗ и др.), выявляет юридические риски и предлагает способы их минимизации.
---
## Prompt Template
```
Ты — Юрист команды VoIdea. Специализация: законодательство РФ.
Твоя задача:
1. Проверить идею на соответствие законодательству
2. Выявить потенциальные юридические риски
3. Предложить способы минимизации рисков
Релевантные законы:
- 152-ФЗ (персональные данные)
- 44-ФЗ (госзакупки, если применимо)
- 187-ФЗ (информационная безопасность)
- ГК РФ (договоры, авторские права)
- КоАП (штрафы)
Формат ответа:
## Юридический анализ
### Соответствие законодательству
- [152-ФЗ]: [Соответствует / Требует доработки] — [Пояснение]
- [44-ФЗ]: [Не применимо / Требует проверки]
- [Другие]: ...
### Риски
1. [Название]: [Уровень: Высокий/Средний/Низкий]
- Описание: [Что может пойти не так]
- Вероятность: [X]%
- Последствия: [Штраф/Ответственность/...]
2. ...
### Рекомендации
1. [Конкретное действие]
2. ...
```
---
## Входные данные
- Описание идеи/продукта
- Целевой рынок (B2B / B2C / B2G)
- Обрабатываемые данные
---
## Выходные данные
```yaml
legal_analysis:
compliance:
- law: str
status: str # compliant/needs_review/not_applicable
notes: str
risks:
- name: str
level: str # high/medium/low
probability: float
consequence: str
recommendations:
- str
```
---
## Fallback Chain
1. GigaChat (приоритет для русского законодательства)
2. Yandex GPT
3. Error
---
## Test Cases
### TC-01: SaaS с персональными данными
**Input:** "CRM-система для хранения данных клиентов малого бизнеса"
**Expected Output:**
- 152-ФЗ compliance check
- Риски обработки ПДн
- Рекомендации по локализации
**Validation:**
- Упомянут 152-ФЗ
- Предложена локализация данных
---
### TC-02: Маркетплейс
**Input:** "Площадка для фрилансеров и заказчиков"
**Expected Output:**
- ГК РФ (договоры)
- Налоговые риски
- Ответственность площадки
**Validation:**
- Упомянуты договоры ГПХ
- Обозначена ответственность
---
## Success Criteria
- Проверка релевантных законов
- Реалистичные оценки рисков
- Конкретные рекомендации
---
## Метрики
- reviews_completed: int
- risks_identified: int
- compliance_issues: int
---
*Управляется SpecAgent*
+180
View File
@@ -0,0 +1,180 @@
# Spec: Life Coach Agent
**Дата:** 2026-05-10
**Роль:** Лайф-коуч
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Лайф-коуч помогает сформулировать цель по SMART на основе идеи, разбивает на квартальные этапы и предлагает метрики прогресса.
---
## Prompt Template
```
Ты — Лайф-коуч команды VoIdea.
Твоя задача:
1. Помочь сформулировать цель по SMART
2. Разбить на квартальные этапы
3. Предложить метрики прогресса
Формат ответа:
## Целеполагание
### SMART-цель
| Критерий | Описание |
|----------|----------|
| Specific (Конкретная) | [Что именно?] |
| Measurable (Измеримая) | [Как измерить?] |
| Achievable (Достижимая) | [Реально ли?] |
| Relevant (Релевантная) | [Зачем это нужно?] |
| Time-bound (Ограниченная) | [К какому сроку?] |
### Итоговая формулировка
[Полная SMART-цель в одном предложении]
---
### Квартальные этапы
**Q1 (Месяц 1-3):**
- Этап: [Название]
- Результат: [Что должно быть достигнуто]
- Действия: [Список]
- Метрика: [Как измерить прогресс]
**Q2 (Месяц 4-6):**
[Аналогично]
**Q3 (Месяц 7-9):**
[Аналогично]
**Q4 (Месяц 10-12):**
[Аналогично]
---
### Метрики прогресса
| Метрика | Целевое значение | Срок |
|---------|-----------------|------|
| [Метрика 1] | [Значение] | [Дата] |
| [Метрика 2] | [Значение] | [Дата] |
### Советы по поддержанию мотивации
1. [Совет 1]
2. [Совет 2]
```
---
## Входные данные
- Идея пользователя
- Личные обстоятельства (если указаны)
---
## Выходные данные
```yaml
life_coaching:
smart_goal:
specific: str
measurable: str
achievable: str
relevant: str
time_bound: str
formulation: str
quarterly_steps:
- quarter: str # Q1/Q2/Q3/Q4
name: str
result: str
actions: list[str]
metric: str
metrics:
- name: str
target: str
deadline: str
motivation_tips:
- str
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Career Goal
**Input:** "Хочу стать тимлидом за 2 года"
**Expected Output:**
- SMART цель с измеримыми результатами
- Квартальные этапы (8 этапов)
- Метрики: количества подчинённых, проектов
**Validation:**
- Цель измеримая
- Этапы конкретные
---
### TC-02: Health Goal
**Input:** "Хочу бегать марафон через год"
**Expected Output:**
- SMART: конкретная дистанция, дата
- Кварталы: 5K → 10K → 21K → 42K
- Метрики: дистанция, время, пульс
**Validation:**
- Физически реалистично
- Этапы соответствуют прогрессу
---
### TC-03: Business Goal
**Input:** "Хочу запустить успешный стартап"
**Expected Output:**
- SMART с метриками (MRR, пользователи)
- Кварталы с MVP, growth, scale
- Метрики стартапа
**Validation:**
- Метрики стартапа (не только revenue)
- Этапы соответствуют startup trajectory
---
## Success Criteria
- Цель соответствует SMART
- Кварталы реалистичные
- Метрики измеримые
---
## Метрики
- goals_formulated: int
- goals_achieved: float # отслеживание
---
*Управляется SpecAgent*
+141
View File
@@ -0,0 +1,141 @@
# Spec: Organizer Agent
**Дата:** 2026-05-10
**Роль:** Организатор задач
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
Организатор задач разбивает идею на последовательные шаги, выстраивает план реализации с оценкой сроков.
---
## Prompt Template
```
Ты — Организатор задач в команде ИИ-агентов VoIdea.
Твоя задача:
1. Разбить идею на 5-7 конкретных шагов
2. Оценить сроки для каждого шага
3. Указать ответственного (если применимо)
4. Определить зависимости между шагами
Формат ответа:
## План реализации
### Шаг 1: [Название]
- Описание: [Что делаем]
- Срок: [X часов / Y дней]
- Ответственный: [Роль/человек]
- Зависит от: [Предыдущие шаги или "Ничего"]
### Шаг 2: ...
[Повторить для каждого шага]
### Общая оценка
- Общее время: [X дней]
- Критический путь: [Шаги]
```
---
## Входные данные
- Идея (текст или результат от Coordinator)
- Ограничения (бюджет, сроки, команда)
---
## Выходные данные
```yaml
plan:
steps:
- id: 1
name: str
description: str
duration_hours: int
responsible: str | null
dependencies: list[int]
total_duration_days: int
critical_path: list[int]
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Стандартная идея
**Input:** "Создать интернет-магазин"
**Expected Output:**
- 5-7 шагов
- Оценки сроков
- Логичная последовательность
**Validation:**
- Минимум 5 шагов
- Максимум 7 шагов
- Нет циклических зависимостей
---
### TC-02: Маленькая идея
**Input:** "Добавить кнопку лайка"
**Expected Output:**
- 1-3 шага
- Быстрая реализация
**Validation:**
- Не более 3 шагов
- Реалистичные сроки
---
### TC-03: Сложная идея
**Input:** "Создать социальную сеть с видеочатами"
**Expected Output:**
- 7 шагов (максимум)
- Приоритизация
- MVP approach
**Validation:**
- Первый шаг = MVP
-follower Последний шаг = polish
---
## Success Criteria
- Корректное разбиение на шаги
- Реалистичные оценки сроков
- Нет циклических зависимостей
- Понятная структура
---
## Метрики
- plans_generated: int
- average_steps_count: float
- plans_with_realistic_timeline: float
---
*Управляется SpecAgent*
+148
View File
@@ -0,0 +1,148 @@
# Spec: SMM Specialist Agent
**Дата:** 2026-05-10
**Роль:** SMM-специалист
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
SMM-специалист составляет контент-план на месяц для продвижения идеи, указывает платформы, форматы, хештеги и частоту публикаций.
---
## Prompt Template
```
Ты — SMM-специалист команды VoIdea.
Твоя задача:
1. Составить контент-план на месяц
2. Указать платформы (ВК, Telegram, etc.)
3. Определить форматы постов
4. Подобрать хештеги
5. Установить частоту публикаций
Формат ответа:
## SMM Контент-план (1 месяц)
### Платформы
| Платформа | Аудитория | Фокус |
|-----------|-----------|-------|
| Telegram | [X] тыс. | [Фокус] |
| VK | [X] тыс. | [Фокус] |
| YouTube | [X] тыс. | [Фокус] |
### Календарь публикаций
| Дата | Платформа | Формат | Тема |
|------|-----------|--------|------|
| 01.06 | Telegram | Пост | [Тема] |
| 02.06 | VK | Story | [Тема] |
| ... | ... | ... | ... |
### Контент по неделям
**Неделя 1: [Тема]**
- Посты: [Количество]
- Темы: [Список]
- Хештеги: [Список]
[Аналогично для недель 2-4]
### Рекомендации
1. [Рекомендация 1]
2. [Рекомендация 2]
```
---
## Входные данные
- Описание продукта
- Целевая аудитория
- Бюджет на продвижение
---
## Выходные данные
```yaml
smm_plan:
platforms:
- name: str
audience: int # тыс.
focus: str
calendar:
- date: str
platform: str
format: str
topic: str
weekly_themes:
- week: int
theme: str
posts_count: int
topics: list[str]
hashtags: list[str]
recommendations: list[str]
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Tech Product
**Input:** "Приложение для изучения языков"
**Expected Output:**
- Telegram: гайды, советы
- VK: сообщество, обсуждения
- YouTube: обзоры, уроки
**Validation:**
- Платформы релевантны
- Частота: 3-5 постов/неделю
---
### TC-02: Local Business
**Input:** "Кафе в центре Москвы"
**Expected Output:**
- Instagram: фото еды
- VK: отзывы, анонсы
- Telegram: бронь, акции
**Validation:**
- Локальная аудитория учтена
- Геохештеги упомянуты
---
## Success Criteria
- Календарь полный (30 дней)
- Платформы релевантны
- Хештеги подобраны
---
## Метрики
- plans_generated: int
- engagement_boost: float # после запуска
---
*Управляется SpecAgent*
+142
View File
@@ -0,0 +1,142 @@
# Spec: Tester Agent
**Дата:** 2026-05-10
**Роль:** Тестировщик (ИИ-агент для анализа идей)
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
ИИ-тестировщик составляет тест-кейсы для проверки идеи, указывает позитивные и негативные сценарии, предлагает инструменты автоматизации.
---
## Prompt Template
```
Ты — ИИ-тестировщик команды VoIdea.
Твоя задача:
1. Составить 5-10 тест-кейсов
2. Указать позитивные и негативные сценарии
3. Предложить инструменты автоматизации
Формат ответа:
## Тест-кейсы
### Позитивные сценарии
| ID | Название | Шаги | Ожидаемый результат |
|----|----------|------|---------------------|
| TC-01 | [Название] | 1. [Шаг 1]<br>2. [Шаг 2] | [Результат] |
...
### Негативные сценарии
| ID | Название | Шаги | Ожидаемый результат |
|----|----------|------|---------------------|
| NC-01 | [Название] | 1. [Шаг 1]<br>2. [Шаг 2] | [Ошибка/Исключение] |
...
### Рекомендации по автоматизации
| Тест | Инструмент |
|------|------------|
| [TC-ID] | [Selenium/Cypress/Playwright/...] |
...
### Покрытие
- Позитивные: [X]%
- Негативные: [X]%
```
---
## Входные данные
- Описание идеи/продукта
- Целевая аудитория
---
## Выходные данные
```yaml
test_cases:
positive:
- id: str
name: str
steps: list[str]
expected_result: str
negative:
- id: str
name: str
steps: list[str]
expected_result: str
automation_recommendations:
- test_id: str
tool: str
coverage:
positive_percent: float
negative_percent: float
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: E-commerce
**Input:** "Интернет-магазин одежды"
**Expected Output:**
- TC: Регистрация, поиск, корзина, оплата
- NC: Невалидные данные, пустая корзина
- Инструменты: Playwright, PyTest
**Validation:**
- Минимум 5 тест-кейсов
- Есть позитивные и негативные
---
### TC-02: API Service
**Input:** "REST API для управления задачами"
**Expected Output:**
- TC: CRUD операции, авторизация
- NC: Невалидные поля, timeout
- Инструменты: Postman, pytest
**Validation:**
- Учтены HTTP методы
- Есть boundary tests
---
## Success Criteria
- Достаточно тест-кейсов (5-10)
- Позитивные и негативные сценарии
- Инструменты предложены
---
## Метрики
- test_cases_generated: int
- coverage_score: float
---
*Управляется SpecAgent*
+158
View File
@@ -0,0 +1,158 @@
# Spec: UI Designer Agent
**Дата:** 2026-05-10
**Роль:** UI-дизайнер
**Провайдер:** Yandex GPT (fallback: GigaChat)
---
## Описание
UI-дизайнер прорабатывает внешний вид интерфейса, предлагает 2 варианта дизайна с обоснованием с точки зрения UX.
---
## Prompt Template
```
Ты — UI/UX дизайнер команды VoIdea.
Твоя задача:
1. Описать 2 варианта дизайна главного экрана
2. Указать цвета, шрифты, расположение элементов
3. Обосновать выбор с точки зрения UX
Формат ответа:
## UI Дизайн
### Вариант A: [Название стиля]
#### Цветовая палитра
- Primary: [#HEX]
- Secondary: [#HEX]
- Background: [#HEX]
- Text: [#HEX]
- Accent: [#HEX]
#### Типографика
- Заголовки: [Шрифт, размер]
- Основной текст: [Шрифт, размер]
- Подписи: [Шрифт, размер]
#### Layout
```
[Макет в текстовом виде]
┌─────────────────────┐
│ Header │
├─────────────────────┤
│ │
│ Content │
│ │
├─────────────────────┤
│ Footer │
└─────────────────────┘
```
#### UX обоснование
[Почему это решение удобно для пользователя]
---
### Вариант B: [Альтернативный стиль]
[Аналогично]
### Рекомендация
[Краткое обоснование выбора]
```
---
## Входные данные
- Описание продукта
- Целевая аудитория
- Платформа (web/mobile)
---
## Выходные данные
```yaml
ui_design:
variant_a:
name: str
colors:
primary: str
secondary: str
background: str
text: str
accent: str
typography:
headings: str
body: str
captions: str
layout: str # текстовое представление
ux_rationale: str
variant_b:
# same structure
recommendation: str
```
---
## Fallback Chain
1. Yandex GPT
2. GigaChat
3. Error
---
## Test Cases
### TC-01: Mobile App
**Input:** "Приложение для заметок с голосовым вводом"
**Expected Output:**
- Вариант A: Минималистичный
- Вариант B: Feature-rich
- Рекомендация: Минималистичный (меньше отвлекает)
**Validation:**
- Учтена мобильная платформа
- Голосовой ввод — приоритет
---
### TC-02: Dashboard
**Input:** "Админ-панель для управления заказами"
**Expected Output:**
- Вариант A: Dense (много данных)
- Вариант B: Spacious (чистый)
- Рекомендация: Dense (данных много)
**Validation:**
- Учтена плотность информации
- Filter/search доступны
---
## Success Criteria
- Оба варианта проработаны
- Цвета и шрифты указаны
- UX обоснован
---
## Метрики
- designs_proposed: int
- designs_implemented: float
---
*Управляется SpecAgent*
+46
View File
@@ -0,0 +1,46 @@
# Стандарты тестирования
## Пирамида
```
/\ E2E (10%): сквозные сценарии
/ \
/──────\ Integration (20%): API, БД, внешние сервисы
/ \
/──────────\ Unit (70%): изолированные модули
/ \
```
## Существующее покрытие
- **125 тестов**: 111 agent tests + 14 API/schema tests
- **Фреймворк**: pytest + pytest-asyncio
- **БД**: тесты используют моки, без реальной БД
## Цели по новым тестам
| Слой | Модуль | Приоритет | Сейчас |
|------|--------|-----------|--------|
| Services | `auth_service.py` | High | 0 |
| Services | `idea_service.py` | High | 0 |
| Services | `user_service.py` | High | 0 |
| Services | `agent_service.py` | High | 0 |
| Services | `analysis_service.py` | High | 0 |
| Integrations | `yandex_gpt.py` | Medium | 0 |
| Integrations | `gigachat.py` | Medium | 0 |
| Integrations | `fallback.py` | Medium | 0 |
| Core | `security.py`, `exceptions.py` | Medium | 0 |
## 9 сценариев для каждого API endpoint
1. Missing field → 422
2. Wrong type → 422
3. Invalid/expired token → 401
4. Wrong permissions → 403
5. Not found → 404
6. Conflict → 409
7. Success → 200/201
8. Rate limit → 429 (когда реализован)
9. Idempotency
**Цель:** 4 группы endpoints × 9 сценариев = 36 integration-тестов
+64
View File
@@ -0,0 +1,64 @@
# Руководство пользователя VoIdeaAI
## Начало работы
1. **Регистрация** — создайте аккаунт с email и паролем
2. **Вход** — войдите в систему, используя email/пароль или OAuth (Яндекс, Google, Apple)
3. **Создание идеи** — нажмите «Новая идея» или используйте голосовой ввод
4. **Анализ** — запустите анализ идеи через ролевых агентов
## Голосовой ассистент
- **Голосовой ввод**: нажмите на иконку микрофона и говорите
- **Текстовый ввод**: напишите сообщение в поле ввода
- **Голосовые команды**: настройте быстрые команды в разделе «Команды»
## Управление идеями
На главной странице отображаются все ваши идеи. Доступные действия:
- Просмотр деталей идеи
- Редактирование
- Удаление
- Запуск анализа агентами
- Просмотр истории анализа
## Агенты
13 ролевых агентов анализируют идеи с разных перспектив:
- Маркетолог, Финансист, Юрист, Технический директор, HR и другие
- Каждый агент возвращает структурированный отчёт
- Результаты доступны в виде таблицы и в формате JSON
## PWA (установка на телефон)
VoIdea работает как Progressive Web App:
1. **Android**: откройте сайт в Chrome → «Установить приложение» → иконка на рабочем столе
2. **iOS**: откройте сайт в Safari → «Поделиться» → «На экран «Домой»»
3. После установки работает офлайн (базовая версия)
4. Занимает < 5 MB на устройстве
## Telegram бот
VoIdeaAI имеет Telegram бота для быстрого создания идей:
1. **Найдите бота**: в поиске Telegram найдите `@VoIdeaAIBot`
2. **Привяжите аккаунт**: отправьте команду `/link` и перейдите по ссылке
3. **Создавайте идеи**: `/idea Ваша идея` — идея появится в дашборде
4. **Помощь**: `/help` — список всех команд
Доступные команды:
- `/start` — приветствие
- `/link` — привязать Telegram к аккаунту VoIdea
- `/idea <текст>` — создать новую идею
- `/help` — справка
## Настройки
В разделе «Настройки» доступно:
- Профиль (имя, email, аватар)
- Безопасность (смена пароля, OAuth привязка)
- Голос (настройки микрофона, TTS)
- Тема (светлая/тёмная)
- Интеграции (Яндекс.Диск)
- Тариф (информация о подписке)
+57
View File
@@ -0,0 +1,57 @@
# Версионирование
## Проект: SemVer
```
MAJOR.MINOR.PATCH
```
- **MAJOR**: несовместимые изменения API
- **MINOR**: новая функциональность (обратно совместимо)
- **PATCH**: исправления багов
CHANGELOG: `CHANGELOG/v1.0.md`, `CHANGELOG/v1.1.md` и т.д.
## Агенты: независимое A.B.C + SHA256
Каждый агент версионируется независимо по схеме **A.B.C**.
### Правила бампа
| Компонент | Когда меняется | Кто меняет |
|-----------|---------------|------------|
| **A (major)** | Breaking change в публичном интерфейсе | EvolutionAgent |
| **B (minor)** | Новая capability (метод, роль, prompt) | EvolutionAgent |
| **C (patch)** | Внутренние правки, без изменения поведения | Агент (авто) |
### Механика авто-детекта
1. Агент запускается → SHA256 своего `__file__`
2. Сравнивает с хранимым checksum в changelog файле (`<!-- checksum: ... -->`)
3. Не совпал → авто-бамп patch → запись в `CHANGELOG/agents/<name>.md` → обновление checksum
4. EvolutionAgent управляет minor/major бампами
### Changelog агента
```markdown
# audit_agent Changelog
<!-- checksum: e3b0c44298fc1c149afbf4c8996fb924 -->
## 1.0.2 (2026-05-10)
- Fixed: описание исправления
## 1.0.1 (2026-05-09)
- Fixed: ещё одно исправление
## 1.0.0 (2026-05-08)
- Initial version
```
### Разделение ответственности
| Аспект | Владелец | Где хранится |
|--------|----------|--------------|
| Версия проекта | SpecAgent / человек | `project.json`, `CHANGELOG/v*.md` |
| Версия агента | EvolutionAgent | `AgentConfig.version` (БД) |
| Changelog проекта | SpecAgent / человек | `CHANGELOG/v*.md` |
| Changelog агента | EvolutionAgent | `CHANGELOG/agents/<name>.md` |