Initial commit: VoIdeaAI - voice-first AI idea assistant
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Выбор базы данных
|
||||
|
||||
---
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Какую БД?] --> B{Многопользовательская?}
|
||||
B -->|Нет / прототип| C[SQLite]
|
||||
B -->|Да| D{Нужен JSONB?}
|
||||
D -->|Да| E[PostgreSQL]
|
||||
D -->|Нет| F{Нужен full-text search?}
|
||||
F -->|Да| E
|
||||
F -->|Нет| G[SQLite / PostgreSQL]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Варианты
|
||||
|
||||
### SQLite
|
||||
| | |
|
||||
|---|---|
|
||||
| **Когда** | Прототип, dev, однопользовательское |
|
||||
| **Плюсы** | Не требует установки, встроенная, ноль конфигурации |
|
||||
| **Минусы** | Нет конкурентной записи, нет JSONB, нет ARRAY, нет полнотекстового поиска |
|
||||
| **Драйвер** | aiosqlite |
|
||||
|
||||
### PostgreSQL
|
||||
| | |
|
||||
|---|---|
|
||||
| **Когда** | Production, многопользовательское, аналитика |
|
||||
| **Плюсы** | ACID, JSONB, ARRAY, full-text search, масштабирование |
|
||||
| **Минусы** | Требует установки, настройки, памяти |
|
||||
| **Драйвер** | asyncpg |
|
||||
|
||||
---
|
||||
|
||||
## Рекомендация
|
||||
|
||||
**SQLite для разработки, PostgreSQL для production.**
|
||||
Обе БД поддерживаются через SQLAlchemy с минимальными отличиями в моделях.
|
||||
|
||||
### Что нужно для портабельности
|
||||
|
||||
```python
|
||||
# Вместо PostgreSQL-specific типов используем универсальные:
|
||||
UUID → String(36)
|
||||
JSONB → JSON
|
||||
ARRAY → JSON
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Какая БД нужна на старте? (рекомендация: SQLite)
|
||||
- Когда переходить на PostgreSQL? (перед production)
|
||||
- Нужна ли поддержка обеих БД одновременно? (желательно — unit-тесты на SQLite быстрее)
|
||||
@@ -0,0 +1,59 @@
|
||||
# Выбор схемы аутентификации
|
||||
|
||||
---
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Схема auth?] --> B{Нужен вход через соцсети?}
|
||||
B -->|Нет| C[Email + пароль]
|
||||
B -->|Да| D{OAuth2}
|
||||
D --> E[Выбрать провайдеров]
|
||||
C --> F[Выбрать JWT или Session]
|
||||
F -->|SPA/PWA| G[JWT + refresh token]
|
||||
F -->|SSR| H[Session + cookie]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Варианты
|
||||
|
||||
### Email + пароль
|
||||
| | |
|
||||
|---|---|
|
||||
| **Плюсы** | Простота, не зависит от third-party, полный контроль |
|
||||
| **Минусы** | Пользователь должен помнить пароль, риск утечки |
|
||||
| **Хэширование** | bcrypt через passlib |
|
||||
|
||||
### OAuth2 (Яндекс, Google, GitHub, Apple)
|
||||
| | |
|
||||
|---|---|
|
||||
| **Плюсы** | Удобство для пользователя, нет паролей на нашей стороне |
|
||||
| **Минусы** | Зависимость от провайдера, нужны client_id/secret, нужен публичный URL для callback |
|
||||
| **Схема** | Один пользователь = один провайдер (нельзя привязать два) |
|
||||
|
||||
### JWT vs Session
|
||||
|
||||
| | JWT | Session |
|
||||
|---|---|---|
|
||||
| **Хранение** | На клиенте (localStorage) | На сервере (Redis/БД) |
|
||||
| **Масштабирование** | Не нужна общая session storage | Нужен Redis |
|
||||
| **Отзыв токена** | Сложно (до expire) | Мгновенно |
|
||||
| **SPA/PWA** | Идеально | Сложнее |
|
||||
|
||||
---
|
||||
|
||||
## Рекомендация
|
||||
|
||||
**Email + пароль + JWT** для старта.
|
||||
OAuth2 добавить перед production (если нужен).
|
||||
JWT с refresh token для SPA/PWA, session для SSR.
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Нужен ли вход через соцсети? (рекомендация: Яндекс для РФ, Google для международных)
|
||||
- JWT или Session? (рекомендация: JWT + refresh token)
|
||||
- Сколько провайдеров OAuth? (рекомендация: 1-2, не больше)
|
||||
@@ -0,0 +1,91 @@
|
||||
# Интеграция AI
|
||||
|
||||
---
|
||||
|
||||
## Паттерн: FallbackChain
|
||||
|
||||
```
|
||||
Запрос → Provider 1 → Успех → результат
|
||||
Ошибка → Provider 2 → Успех → результат
|
||||
Ошибка → Fallback результат
|
||||
```
|
||||
|
||||
### Реализация
|
||||
|
||||
```python
|
||||
class FallbackChain:
|
||||
def __init__(self, providers: list[AIProvider], max_retries: int = 2):
|
||||
self.providers = providers
|
||||
self.max_retries = max_retries
|
||||
|
||||
async def analyze(self, prompt: str, **kwargs) -> AIResult:
|
||||
last_error = None
|
||||
for provider in self.providers:
|
||||
for attempt in range(self.max_retries + 1):
|
||||
try:
|
||||
result = await provider.analyze(prompt, **kwargs)
|
||||
if result.success:
|
||||
return result
|
||||
last_error = result
|
||||
except Exception as e:
|
||||
last_error = AIResult(success=False, error=str(e))
|
||||
if attempt < self.max_retries:
|
||||
await asyncio.sleep(2 if attempt == 0 else 5)
|
||||
return last_error or AIResult(success=False, error="All providers failed")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Таймауты и ретраи (следуя §12 правил)
|
||||
|
||||
```
|
||||
1. Попытка (timeout: 10s)
|
||||
2. Успех → return
|
||||
3. Таймаут → retry 1 (через 2s)
|
||||
4. Таймаут → retry 2 (через 5s)
|
||||
5. 4xx → WARNING, return fallback
|
||||
6. 5xx → ERROR, retry → fallback
|
||||
7. Все retry исчерпаны → return fallback
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Хранение промптов
|
||||
|
||||
**Рекомендуемый формат:** YAML (`docs/agent_prompts.yaml`)
|
||||
|
||||
```yaml
|
||||
coordinator:
|
||||
system_prompt: "Ты — координатор проекта..."
|
||||
provider: yandex_gpt
|
||||
temperature: 0.7
|
||||
max_tokens: 2000
|
||||
|
||||
business_analyst:
|
||||
system_prompt: "Ты — бизнес-аналитик..."
|
||||
provider: yandex_gpt
|
||||
temperature: 0.5
|
||||
max_tokens: 3000
|
||||
```
|
||||
|
||||
**Альтернатива:** MD-файлы в `docs/specs/agents/` (для детальных спецификаций)
|
||||
|
||||
---
|
||||
|
||||
## Провайдеры
|
||||
|
||||
| Провайдер | Когда | Аутентификация |
|
||||
|-----------|-------|---------------|
|
||||
| Yandex GPT | РФ, хорошая русская речь | IAM token или API key |
|
||||
| GigaChat (Sber) | РФ, юридические/финансовые темы | OAuth client credentials |
|
||||
| OpenAI | Международные проекты | API key |
|
||||
| Локальная модель | Оффлайн, конфиденциальность | Не требуется |
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Какие AI провайдеры нужны? (рекомендация: минимум 2 для fallback)
|
||||
- Нужен ли fallback chain? (да — обязателен для отказоустойчивости)
|
||||
- Где хранить промпты? (рекомендация: YAML — простота редактирования)
|
||||
- Нужен ли локальный AI? (да, если конфиденциальность критична)
|
||||
@@ -0,0 +1,76 @@
|
||||
# Выбор фронтенда
|
||||
|
||||
---
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Фронтенд?] --> B{SPA или SSR?}
|
||||
B -->|SPA| C[React + Vite + TS]
|
||||
B -->|SSR| D[Next.js]
|
||||
C --> E{Нужен оффлайн?}
|
||||
E -->|Да| F[PWA + vite-plugin-pwa]
|
||||
E -->|Нет| G[Без PWA]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Варианты
|
||||
|
||||
### React + Vite + TypeScript
|
||||
| | |
|
||||
|---|---|
|
||||
| **Когда** | SPA, PWA, мобильное приложение |
|
||||
| **Плюсы** | Популярный, большая экосистема, Vite быстрый, PWA-ready |
|
||||
| **Минусы** | SPA — медленный первый заход (но PWA решает) |
|
||||
|
||||
### Next.js
|
||||
| | |
|
||||
|---|---|
|
||||
| **Когда** | SSR, SEO, контентный сайт |
|
||||
| **Плюсы** | SSR, SEO, App Router |
|
||||
| **Минусы** | Сложнее деплой, не подходит для PWA |
|
||||
|
||||
---
|
||||
|
||||
## Стили
|
||||
|
||||
| Решение | Когда |
|
||||
|---------|-------|
|
||||
| **Tailwind CSS** | Всегда (рекомендовано) |
|
||||
| CSS Modules | Если Tailwind не подходит |
|
||||
| CSS-in-JS | Не рекомендуется (производительность) |
|
||||
|
||||
---
|
||||
|
||||
## Состояние
|
||||
|
||||
| Решение | Когда |
|
||||
|---------|-------|
|
||||
| **React Context + hooks** | Маленькое приложение (< 5 страниц) |
|
||||
| **zustand** | Среднее приложение (рекомендовано) |
|
||||
| **RTK** | Большое приложение с множеством запросов |
|
||||
|
||||
---
|
||||
|
||||
## PWA
|
||||
|
||||
**Когда нужен:**
|
||||
- Приложение должно работать оффлайн
|
||||
- Пользователи на мобильных устройствах
|
||||
- Нужно push-уведомления
|
||||
|
||||
**Технологии:**
|
||||
- `vite-plugin-pwa` — генерация service worker
|
||||
- `manifest.json` — установка на домашний экран
|
||||
- IndexedDB — оффлайн-хранение
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Нужен ли фронтенд вообще? (API-first или full-stack?)
|
||||
- SPA или SSR? (SPA+PWA для приложений, SSR для контента)
|
||||
- Нужна ли PWA? (да, если мобильные пользователи и оффлайн)
|
||||
- Какой Router? (react-router-dom — стандарт)
|
||||
@@ -0,0 +1,82 @@
|
||||
# Стратегия деплоя
|
||||
|
||||
---
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Как деплоить?] --> B{Один сервер?}
|
||||
B -->|Да| C[Docker-compose]
|
||||
B -->|Нет| D{Нужна оркестрация?}
|
||||
D -->|Да| E[Kubernetes]
|
||||
D -->|Нет| F[Docker-compose + несколько серверов]
|
||||
C --> G{VPS или облако?}
|
||||
G -->|VPS| H[Ubuntu + systemd]
|
||||
G -->|Облако| I[Docker + cloud provider]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Варианты
|
||||
|
||||
### Docker-compose (рекомендован для старта)
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports: ["8020:8020"]
|
||||
env_file: .env
|
||||
db:
|
||||
image: postgres:14
|
||||
volumes: ["pgdata:/var/lib/postgresql/data"]
|
||||
redis:
|
||||
image: redis:7
|
||||
worker:
|
||||
build: .
|
||||
command: celery -A app.tasks worker -l info
|
||||
```
|
||||
|
||||
### Systemd (без Docker, VPS)
|
||||
```ini
|
||||
[Unit]
|
||||
Description=VoIdea API
|
||||
|
||||
[Service]
|
||||
ExecStart=/home/voidea/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8020
|
||||
WorkingDirectory=/home/voidea
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
**Рекомендуется:** GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with: { python-version: "3.12" }
|
||||
- run: pip install -r requirements.txt
|
||||
- run: ruff check
|
||||
- run: pytest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Docker или без Docker? (Docker для воспроизводимости)
|
||||
- VPS или облако? (VPS дешевле, облако масштабируемее)
|
||||
- CI/CD какой? (GitHub Actions — бесплатно для публичных репозиториев)
|
||||
- Нужен ли staging? (да, перед production)
|
||||
@@ -0,0 +1,49 @@
|
||||
# Мониторинг и алертинг
|
||||
|
||||
---
|
||||
|
||||
## Базовый мониторинг (нужен всегда)
|
||||
|
||||
### Health endpoints
|
||||
```python
|
||||
GET /health → {"status": "healthy", "version": "1.0.0", "db": "connected"}
|
||||
GET /api/v1/health → {"status": "healthy", "api_version": "v1"}
|
||||
```
|
||||
|
||||
### Метрики
|
||||
Собираются через middleware и хранятся в БД:
|
||||
- Время ответа (p50/p95/p99)
|
||||
- Количество запросов (всего, по endpoint'ам)
|
||||
- Количество ошибок (4xx, 5xx)
|
||||
- Статус внешних сервисов (БД, Redis, AI провайдеры)
|
||||
|
||||
---
|
||||
|
||||
## Production мониторинг
|
||||
|
||||
### Prometheus + Grafana (рекомендовано)
|
||||
|
||||
| Компонент | Метрики |
|
||||
|-----------|---------|
|
||||
| Application | Время ответа, ошибки, request rate |
|
||||
| Database | Connection pool, query time |
|
||||
| Redis | Memory, hits/misses |
|
||||
| Celery | Task queue length, execution time |
|
||||
| System | CPU, RAM, disk, network |
|
||||
|
||||
### Алерты
|
||||
|
||||
| Условие | Действие |
|
||||
|---------|----------|
|
||||
| error rate > 1% | Уведомление в Telegram/Slack |
|
||||
| API response p95 > 1s | Уведомление |
|
||||
| DB connection pool > 80% | Предупреждение |
|
||||
| Service down | PagerDuty / звонок |
|
||||
|
||||
---
|
||||
|
||||
## [ASK]
|
||||
|
||||
- Нужен ли мониторинг на старте? (базовый — да, Prometheus — перед production)
|
||||
- Отправлять ли алерты? (да, если есть кто-то кто на них реагирует)
|
||||
- Какой канал для алертов? (Telegram — простой, PagerDuty — профессиональный)
|
||||
Reference in New Issue
Block a user