Initial commit from Specify template

This commit is contained in:
2026-01-29 08:34:11 -03:00
commit fe2c861007
74 changed files with 22234 additions and 0 deletions

398
MVP-SPEC.md Normal file
View File

@@ -0,0 +1,398 @@
# YouTube Thumbnail A/B Preview Tool
## MVP Specification
**Название проекта:** ThumbnailTest / ThumbPreview
**Цель:** Помочь YouTube-креаторам увидеть, как их превью выглядит в поисковой выдаче рядом с конкурентами ДО публикации видео.
---
## Проблема
YouTube-креаторы не могут визуализировать, как их превью будет выглядеть:
- В результатах поиска рядом с конкурентами
- На главной странице YouTube
- На мобильных устройствах
- В разных размерах (большой/маленький превью)
Они загружают видео, надеются на лучшее, и только потом видят результат.
---
## Решение (MVP)
Веб-приложение где пользователь:
1. Загружает свой thumbnail (или несколько для сравнения)
2. Вводит поисковый запрос
3. Видит свой thumbnail рядом с реальными конкурентами из YouTube
---
## Основные функции MVP
### 1. Загрузка Thumbnail
- Drag & drop или выбор файла
- Поддержка форматов: JPG, PNG, WebP
- Рекомендуемый размер: 1280x720
- Превью загруженного изображения
### 2. Поиск конкурентов
- Поле ввода поискового запроса
- Получение топ-10 видео по запросу через YouTube Data API
- Отображение их thumbnails, заголовков, названий каналов
### 3. Превью в контексте
- **Search Results View:** Имитация страницы поиска YouTube
- **Sidebar View:** Имитация рекомендованных видео справа
- **Mobile View:** Мобильный вид результатов
### 4. A/B сравнение
- Загрузка 2-3 вариантов thumbnail
- Быстрое переключение между вариантами
- Сохранение сессии для возврата
---
## Технический стек
### Frontend
```
- React 18+ с TypeScript
- Tailwind CSS для стилей
- Vite как сборщик
- React Query для API запросов
- Zustand для state management (легковесный)
```
### Backend
```
- NestJS с TypeScript
- PostgreSQL для хранения данных
- Redis для кеширования YouTube API ответов (опционально)
- Multer для загрузки файлов
- Sharp для обработки изображений
```
### Внешние API
```
- YouTube Data API v3 (search.list, videos.list)
```
---
## База данных (PostgreSQL)
### Таблицы
```sql
-- Пользователи (для будущего)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Проекты/Сессии превью
CREATE TABLE preview_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
search_query VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Загруженные thumbnails
CREATE TABLE thumbnails (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID REFERENCES preview_sessions(id) ON DELETE CASCADE,
file_path VARCHAR(500) NOT NULL,
original_name VARCHAR(255),
title VARCHAR(255), -- Пользовательский заголовок для превью
position INTEGER DEFAULT 0, -- Порядок в списке
created_at TIMESTAMP DEFAULT NOW()
);
-- Кеш YouTube результатов
CREATE TABLE youtube_cache (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
search_query VARCHAR(255) NOT NULL,
results JSONB NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP NOT NULL
);
CREATE INDEX idx_youtube_cache_query ON youtube_cache(search_query);
CREATE INDEX idx_youtube_cache_expires ON youtube_cache(expires_at);
```
---
## API Endpoints
### Backend API
```
POST /api/thumbnails/upload - Загрузка thumbnail
DELETE /api/thumbnails/:id - Удаление thumbnail
GET /api/youtube/search - Поиск видео (с кешированием)
?q=query&maxResults=10
POST /api/sessions - Создание сессии
GET /api/sessions/:id - Получение сессии
PUT /api/sessions/:id - Обновление сессии
```
---
## YouTube Data API
### Настройка
1. Создать проект в Google Cloud Console
2. Включить YouTube Data API v3
3. Создать API ключ
4. Настроить ограничения (HTTP referrers)
### Квоты
- Бесплатно: 10,000 units/день
- search.list = 100 units за запрос
- ~100 поисков в день бесплатно
- Кеширование обязательно!
### Пример запроса
```typescript
// GET https://www.googleapis.com/youtube/v3/search
{
part: 'snippet',
q: 'react tutorial',
type: 'video',
maxResults: 10,
key: YOUTUBE_API_KEY
}
// Ответ содержит:
// - videoId
// - title
// - channelTitle
// - thumbnails.medium.url (320x180)
// - thumbnails.high.url (480x360)
```
---
## Структура проекта
```
thumbnail-preview-tool/
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── ThumbnailUploader.tsx
│ │ │ ├── SearchInput.tsx
│ │ │ ├── PreviewGrid.tsx
│ │ │ ├── YouTubeSearchResult.tsx
│ │ │ ├── UserThumbnail.tsx
│ │ │ ├── ViewSwitcher.tsx
│ │ │ └── MobilePreview.tsx
│ │ ├── hooks/
│ │ │ ├── useYouTubeSearch.ts
│ │ │ └── useThumbnails.ts
│ │ ├── store/
│ │ │ └── previewStore.ts
│ │ ├── api/
│ │ │ └── client.ts
│ │ ├── types/
│ │ │ └── index.ts
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── package.json
│ └── vite.config.ts
├── backend/
│ ├── src/
│ │ ├── modules/
│ │ │ ├── thumbnails/
│ │ │ │ ├── thumbnails.controller.ts
│ │ │ │ ├── thumbnails.service.ts
│ │ │ │ └── thumbnails.module.ts
│ │ │ ├── youtube/
│ │ │ │ ├── youtube.controller.ts
│ │ │ │ ├── youtube.service.ts
│ │ │ │ └── youtube.module.ts
│ │ │ └── sessions/
│ │ │ ├── sessions.controller.ts
│ │ │ ├── sessions.service.ts
│ │ │ └── sessions.module.ts
│ │ ├── entities/
│ │ │ ├── thumbnail.entity.ts
│ │ │ ├── session.entity.ts
│ │ │ └── youtube-cache.entity.ts
│ │ ├── app.module.ts
│ │ └── main.ts
│ ├── uploads/ # Загруженные файлы
│ ├── package.json
│ └── .env
├── docker-compose.yml # PostgreSQL для разработки
├── MVP-SPEC.md
└── README.md
```
---
## UI/UX Дизайн (MVP)
### Главная страница
```
┌─────────────────────────────────────────────────────────┐
│ [Logo] ThumbnailTest [Login] [Try Free] │
├─────────────────────────────────────────────────────────┤
│ │
│ See how your thumbnail looks before publishing │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [Drag & drop your thumbnail here] │ │
│ │ or click to upload │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Search query: [_________________________] [Search] │
│ │
└─────────────────────────────────────────────────────────┘
```
### Страница превью
```
┌─────────────────────────────────────────────────────────┐
│ [← Back] Query: "react hooks tutorial" [Desktop ▼]│
├─────────────────────────────────────────────────────────┤
│ │
│ Your thumbnails: [A] [B] [+Add] │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ YouTube Search Results Simulation │ │
│ │ │ │
│ │ ┌──────┐ React Hooks Tutorial for Beginners │ │
│ │ │ YOUR │ Your Channel Name │ │
│ │ │THUMB │ 125K views • 2 days ago │ │
│ │ └──────┘ ← YOUR THUMBNAIL (highlighted) │ │
│ │ │ │
│ │ ┌──────┐ Learn React Hooks in 30 Minutes │ │
│ │ │ img │ Fireship │ │
│ │ └──────┘ 1.2M views • 1 year ago │ │
│ │ │ │
│ │ ┌──────┐ React Hooks Crash Course │ │
│ │ │ img │ Traversy Media │ │
│ │ └──────┘ 890K views • 2 years ago │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
---
## План разработки MVP (5-7 дней)
### День 1: Настройка проекта
- [ ] Инициализация frontend (Vite + React + TypeScript + Tailwind)
- [ ] Инициализация backend (NestJS)
- [ ] Docker compose для PostgreSQL
- [ ] Настройка YouTube Data API ключа
### День 2: Backend - загрузка файлов
- [ ] Модуль thumbnails с upload endpoint
- [ ] Обработка изображений (Sharp)
- [ ] Хранение в файловой системе
- [ ] Базовые entities и миграции
### День 3: Backend - YouTube интеграция
- [ ] Модуль youtube с поиском
- [ ] Кеширование результатов в БД
- [ ] Rate limiting
### День 4: Frontend - загрузка и поиск
- [ ] Компонент ThumbnailUploader
- [ ] Компонент SearchInput
- [ ] API клиент
- [ ] Базовый state management
### День 5: Frontend - превью
- [ ] Компонент PreviewGrid (имитация YouTube)
- [ ] Стили максимально похожие на YouTube
- [ ] Переключение между вариантами thumbnail
- [ ] ViewSwitcher (Desktop/Mobile)
### День 6: Полировка
- [ ] Мобильная адаптивность
- [ ] Обработка ошибок
- [ ] Loading states
- [ ] Базовая аналитика
### День 7: Деплой
- [ ] Деплой backend (Railway/Render)
- [ ] Деплой frontend (Vercel)
- [ ] Тестирование production
- [ ] Лендинг с ценами
---
## Монетизация
### Free Tier
- 3 превью сессии в месяц
- Водяной знак "Made with ThumbnailTest"
- Только desktop view
### Pro - $9/месяц
- Безлимитные сессии
- Без водяного знака
- Desktop + Mobile + Sidebar views
- Сохранение истории сессий
- A/B сравнение до 5 вариантов
### Будущие фичи (после MVP)
- AI оценка кликабельности
- Тепловая карта внимания
- Интеграция с Canva
- Chrome расширение
- Командный доступ
---
## Конкуренты
| Инструмент | Цена | Особенности | Наше преимущество |
|------------|------|-------------|-------------------|
| Clickpilot | $9/mo | Похожий функционал | Проще UX, быстрее |
| TubeBuddy | $9-49/mo | Много фич, сложно | Фокус на одной задаче |
| VidIQ | $7.50-49/mo | Аналитика, сложно | Простота |
---
## Метрики успеха MVP
- [ ] 100 уникальных пользователей за первую неделю
- [ ] 10 регистраций email для Pro
- [ ] 2 платных подписки
- [ ] NPS > 7 от первых пользователей
---
## Риски и решения
| Риск | Решение |
|------|---------|
| YouTube API квоты | Агрессивное кеширование (24 часа) |
| Низкий трафик | Постинг на r/NewTubers, Product Hunt |
| Сложность YouTube стилей | Использовать скриншоты как референс |
| Юридические вопросы | Только публичные данные, no scraping |
---
## Следующие шаги
1. **Сейчас:** Создать YouTube API ключ
2. **Сегодня:** Инициализировать проекты frontend/backend
3. **Завтра:** Первый рабочий прототип загрузки + поиска