# SellerCopilot — Production-Ready Roadmap (Closed Pilot)

> Provenance: user-команда «распиши полный план до продакшн реди и следуй ему» (2026-05-30).
>
> Цель: **closed pilot 3-5 продавцов** работает end-to-end на stable URL: bookmarklet → SQLite → analyzer → recommendations.

## Definition of «Production-Ready»

| Критерий | Метрика | Owner |
|---|---|---|
| Stable URL | `https://<domain>` отвечает 200 на `/api/health` | claude (deploy) + user (домен) |
| Bookmarklet works | 5 топ-маркетов (Ozon/WB/Yandex Market/Amazon/AliExpress) → ≥4 fields per click | claude |
| Real-card analyzer | Parsed card → analyze pipeline → seller-facing recommendations | claude |
| Admin UI | User видит список карточек, фильтрует по seller_session_id | claude |
| Legal | pilot-agreement подписан 3-5 тестерами | user (Q-4/Q-5/Q-6 closed) |
| Health monitoring | `/api/health` показывает Anthropic spend + parsed_cards count | claude |
| Pilot kickoff | 3-5 тестеров получили bookmarklet + первый seller-facing report | user (Q-1/Q-2 closed) |

## Фазы (sequenced)

### Phase A — Bookmarklet Distribution UI (claude, ~1 час)

**Source**: user-команда «client-side parsing работает, но user должен знать как поставить bookmarklet».

**Что сделать**:
1. Создать страницу `/install-bookmarklet/index.html` на frontend SellerCopilot
2. Drag-and-drop link `📦 Распарсить (SellerCopilot)` который user перетягивает в bookmark bar
3. 5-шаговая инструкция с скриншотами (или text-only mockup)
4. Test page для проверки что bookmarklet работает: статичный mock-marketplace с og:title и JSON-LD
5. Mobile fallback: «Mobile bookmarklets requires X — open SellerCopilot on desktop»

**DONE_GATE**: User открывает `localhost:3000/install-bookmarklet/`, перетягивает закладку, тестирует на mock-странице → видит alert «✓ saved id=N».

**Files**: `install-bookmarklet/index.html`, `install-bookmarklet/test-card.html`, `server/index.js` (static serve), `docs/log.md`.

### Phase B — Per-marketplace selector overrides (claude, ~2 часа)

**Source**: universal bookmarklet извлекает только OG+JSON-LD. Per-marketplace дают больше fields.

**Что сделать**:
1. Расширить bookmarklet с per-marketplace JS блоками для Ozon/WB/Yandex Market
2. **Ozon**: `[data-widget="webPrice"]` для price, `[data-widget="webProductHeading"]` для title, `[data-widget="webGallery"] img` для photos
3. **Wildberries**: SPP card.json endpoint через fetch (same-origin, cookies), `salePriceU/100` → price RUB
4. **Yandex Market**: `data-auto="snippet-price-current"` selectors
5. Fallback на universal если per-mp нашёл < 3 fields
6. Smoke test: 3 fixture HTML файла + assertions on extracted fields

**DONE_GATE**: Прогон bookmarklet на 3 fixture marketplace-страницах → каждый ≥5 fields extracted.

**Files**: `install-bookmarklet/bookmarklet.js`, `server/evals/bookmarklet-fixtures-smoke.js`, fixtures.

### Phase C — Parsed_cards → Analyzer integration (claude, ~2 часа)

**Source**: parsed_cards row есть, но analyzer пока не использует их. Нужно `/api/analyze-from-parsed/:cardId`.

**Что сделать**:
1. Endpoint `POST /api/analyze-from-parsed` — body `{cardId: 21}` → читает parsed_cards row → конвертирует fields в analyze request → запускает analysis-service
2. Маппинг полей: `parsed_cards.title` → `analyze.title`, `parsed_cards.price_value/price_currency` → `analyze.price`, etc.
3. Auto-trigger: после `receiveFromBrowser` сохранения → optional flag `analyze: true` → автоматический analyze
4. Save analyze result в `history` table linked by `source_card_id`
5. Smoke: real parsed card (Ozon row id=21 / Yandex Market row id=1) → analyze → response valid shape

**DONE_GATE**: `POST /api/analyze-from-parsed {cardId: 21}` → 200 + analyze envelope с diagnostics/improvements/score.

**Files**: `server/parse-to-analyze.js`, `server/index.js` (endpoint), `server/storage/schema.sql` (add `source_card_id` column to history if missing), smoke test.

### Phase D — Admin UI «Мои карточки» (claude, ~3 часа)

**Source**: user должен видеть какие карточки parsed + результаты analyze.

**Что сделать**:
1. Страница `/cards/` показывает SQLite parsed_cards (filter by marketplace_id, status, дата)
2. Per-row: title, marketplace, price, status, кнопка «Запустить анализ» (если ещё не запущен) или «Открыть отчёт» (если есть history row)
3. Bulk action «Анализировать все pending»
4. Live update через polling `/api/cards/list?since=ID` каждые 30 сек
5. Empty state: «Перетяните bookmarklet, откройте карточку → она появится здесь»

**DONE_GATE**: открыть `/cards/` → видеть 20+ row'ов из SQLite, кликнуть «Запустить анализ» → 30 сек → report появляется.

**Files**: `cards/index.html`, `cards/cards.css`, `cards/cards.js`, `server/index.js` (endpoint `/api/cards/list`).

### Phase E — Health & Cost observability (claude, ~1 час)

**Source**: Q-7 + production blocker из review_2026-04-29.

**Что сделать**:
1. Расширить `server/health-service.js` — добавить `sqliteHealth` (count tables, parsed_cards count, latest parsed_at), `anthropicBudget` (daily_spend_usd / monthly_spend_usd / remaining_budget из budget_state table)
2. `/api/health` теперь возвращает + storage block + budget block
3. Dashboard в admin UI: блок «Health» с health-service output rendered nicely
4. Error log: SQLite `request_logs` показывает последние 50 errors

**DONE_GATE**: `/api/health` возвращает full report, admin UI показывает live стату.

**Files**: `server/health-service.js`, `cards/health-dashboard.js`.

### Phase F — Deploy на production (claude + user, ~2 часа)

**Source**: stable URL = production-ready criterion.

**Что сделать**:
1. Vercel config уже в `vercel.json` (D-034 accepted)
2. Migrate SQLite → Vercel KV или **deploy на VPS** ($5/mo DigitalOcean / Hetzner / Beget) — потому что Vercel serverless НЕ supports persistent SQLite
3. **Recommendation**: VPS (Hetzner $5/mo) с Node.js + SQLite file + systemd service + caddy reverse proxy с автоматическим Let's Encrypt
4. Domain: user покупает (`sellercopilot.ru` $5/year .ru или `sellercopilot.app` $20/year .app)
5. Environment: ANTHROPIC_API_KEY + SELLERCOPILOT_PROXY_* (optional) + базовый rate-limit per IP
6. Deploy script `scripts/deploy.sh` (rsync + systemctl restart)

**DONE_GATE**: `https://<domain>/api/health` отвечает 200 + bookmarklet работает на real Ozon → row в production SQLite.

**Files**: `scripts/deploy.sh`, `infra/systemd/sellercopilot.service`, `infra/caddy/Caddyfile`, docs.

**user блокеры**: домен + VPS account credentials + Anthropic billing setup.

### Phase G — Legal + Pilot kickoff (user-driven, claude assists, ~1 неделя календарно)

**Source**: Q-1/Q-2/Q-4/Q-5/Q-6, D-036 финализация.

**Что сделать**:
1. Юрист review pilot-agreement (или пользователь решает «GDPR-style без юриста» для пилота, Q-5)
2. Финализировать `legal/pilot-agreement.md` + `legal/privacy-quick-summary.md` (промоция из `drafts/legal/`)
3. Контакты 3-5 тестеров (Q-2)
4. Дата demo MVP v1 (Q-1)
5. Onboarding flow: тестер получает ссылку на `https://<domain>/install-bookmarklet/` + личное письмо

**DONE_GATE**: 3 тестера подписали agreement + дали первый feedback.

**Files**: `legal/pilot-agreement/index.html`, `legal/privacy/index.html`, send-out email template.

### Phase H — Iteration on real feedback (claude, continuous)

**Source**: первые 3 тестера обязательно найдут баги + улучшения.

**Что сделать**:
1. Track bugs in `docs/log.md` + `POSTMORTEM.md` для повторных
2. Issue list: что seller сказал не работает / что хотят
3. Priority queue: critical (нет работы) → important (UX) → nice-to-have

**DONE_GATE**: «Test seller использует SellerCopilot 3 раза подряд без вашей помощи».

## Sequencing

```
Phase A (UI bookmarklet)
   ↓
Phase B (per-mp selectors) ─┐
   ↓                        │
Phase C (analyzer integration) ── parallel:
   ↓                        └─ Phase E (health/cost)
Phase D (admin UI)
   ↓
Phase F (deploy production) ←── user: домен + VPS
   ↓
Phase G (legal + pilot kickoff) ←── user: юрист + тестеры
   ↓
Phase H (iteration on feedback) — continuous
```

## Critical user blockers (без них production не запустить)

| Q-# | Что | Status |
|---|---|---|
| Q-1 | Таргет-дата demo | OPEN |
| Q-2 | Контакты 3-5 тестеров | OPEN |
| Q-4 | Юр.форма Оператора | OPEN |
| Q-5 | Юрист на review | OPEN |
| Q-6 | РКН уведомление | OPEN |
| Q-7 | Cost observability sink | будет CLOSED в Phase E |
| Q-9 | Снять freeze в CLAUDE.md | OPEN |
| (новый) | Домен (sellercopilot.ru или .app) | OPEN |
| (новый) | VPS provider + credentials | OPEN |
| (новый) | Anthropic API billing setup в production | OPEN |

## Estimate

- **Phase A-E** (claude autonomous): ~9 часов работы (можно за 1-2 сессии)
- **Phase F** (claude + user setup): ~2 часа моих + 1 час user'а
- **Phase G** (user-driven): 1 неделя календарно
- **Phase H**: continuous

**Реалистичный pilot launch**: **2 недели от сегодня** если user закроет блокеры Q-1/Q-2/Q-4/Q-5 в течение первой недели.

## Что начну сейчас

**Phase A** — Bookmarklet Distribution UI. Это в моём control, не требует user-блокеров.
