Почему 2 недели - это идеальный срок для первого запуска
Мы регулярно видим одну и ту же историю. Основатель стартапа приходит с идеей. Команда 6 месяцев разрабатывает продукт: продумывает каждую деталь, добавляет фичу за фичей, полирует дизайн. Тратит бюджет. А после запуска оказывается, что пользователям это не нужно. Или нужно, но совсем по-другому.
6 месяцев работы. Сотни тысяч рублей. И всё мимо.
MVP (Minimum Viable Product - "минимально жизнеспособный продукт") - это противоядие от этой болезни. MVP - это не "кривой прототип" и не "бета-версия с багами". Это минимальный продукт, который решает одну конкретную проблему и позволяет проверить вашу гипотезу на реальных пользователях.
Две недели - это не магическое число, а разумный срок, который заставляет фокусироваться на главном и отсекать лишнее. Если вы не можете запустить MVP за 2 недели - скорее всего, вы пытаетесь сделать слишком много.
День 1: Приоритизация фич (самый важный день)
Первый день - самый критичный. Здесь вы решаете, что войдёт в MVP, а что подождёт. Метод MoSCoW помогает разделить все фичи на 4 категории:
Must have (обязательно) - без этого продукт бессмыслен. Если вы делаете маркетплейс - это каталог товаров, корзина и оформление заказа. Без каталога маркетплейс не маркетплейс.
Should have (важно, но не критично) - добавим через неделю после запуска. Фильтры, поиск, личный кабинет. Продукт может работать без них.
Could have (было бы круто) - добавим, когда появятся пользователи. Рекомендации, отзывы, избранное.
Won't have (не сейчас) - мобильное приложение, программа лояльности, AI-ассистент. Когда-нибудь, но не в MVP.
// Пример: приоритизация для маркетплейса хендмейд-товаров
// Используем метод MoSCoW
const features = {
// MUST HAVE - без этого продукт не может работать
// Это и есть ваш MVP. Только это. Ничего больше.
mustHave: [
'Каталог товаров с фото и описанием', // Пользователи видят, что продаётся
'Страница товара с подробностями', // Можно рассмотреть товар
'Корзина', // Можно собрать заказ
'Оформление заказа (имя, телефон, адрес)', // Можно сделать покупку
'Уведомление продавцу о заказе (Telegram)', // Продавец узнает о заказе
'Лендинг с объяснением "что это за сайт"', // Новые посетители понимают суть
],
// SHOULD HAVE - важно, но можно добавить после запуска
shouldHave: [
'Регистрация/авторизация покупателей',
'Личный кабинет продавца (добавление товаров)',
'Фильтрация по категориям',
'Поиск по названию',
],
// COULD HAVE - было бы круто, но не критично
couldHave: [
'Отзывы о товарах',
'Избранное (wishlist)',
'История заказов',
'Оплата онлайн (Юкасса, Stripe)',
],
// WON'T HAVE - не в этот раз, даже не думаем об этом
wontHave: [
'Мобильное приложение',
'Чат между покупателем и продавцом',
'Рекомендательная система ("Вам также может понравиться")',
'Программа лояльности и бонусы',
'Мультиязычность (английская версия)',
],
}
// ПРАВИЛО: если сомневаетесь, куда отнести фичу - относите НИЖЕ
// Лучше запустить с 6 фичами, чем не запустить с 60
День 1 (продолжение): Выбор технологий для скорости
Для MVP выбирайте инструменты, которые дают максимум "из коробки". Не время для экспериментов с новыми фреймворками.
// Рекомендуемый стек для быстрого MVP
// Каждая технология выбрана по одному критерию: скорость разработки
const mvpStack = {
frontend: 'Next.js 15 (App Router)',
// Почему: встроенный серверный рендеринг (хорошо для SEO),
// файловая маршрутизация (создал файл page.tsx = создал страницу),
// встроенные API-эндпоинты (не нужен отдельный сервер),
// деплой на Vercel одной кнопкой
ui: 'Tailwind CSS + shadcn/ui',
// Почему: shadcn/ui - готовые красивые компоненты (кнопки, формы, модалки)
// Не нужно писать CSS с нуля. Выглядит профессионально "из коробки"
database: 'Supabase (PostgreSQL)',
// Почему: бесплатный тариф для начала,
// готовая авторизация (Google, email),
// REST API из коробки (не нужно писать backend для простых CRUD),
// хранилище файлов (для фото товаров)
orm: 'Prisma',
// Почему: пишете TypeScript-код вместо SQL,
// автоматические миграции базы данных,
// типобезопасность - меньше ошибок
deploy: 'Vercel',
// Почему: сделали git push - сайт обновился. Бесплатно для малых проектов
analytics: 'Yandex Metrika',
// Почему: бесплатно, вебвизор (записи экрана), карта кликов.
// Понимаете, что делают пользователи на сайте
}
День 2: Схема базы данных
Для MVP схема должна быть минимальной. Не проектируйте "на вырост" - это ловушка, из-за которой MVP превращается в 6-месячный проект.
// prisma/schema.prisma - схема базы данных для маркетплейса
// Prisma - ORM (Object-Relational Mapping)
// Вместо SQL вы описываете структуру данных в простом формате
// Настройки Prisma
generator client {
provider = "prisma-client-js" // Генерировать TypeScript-клиент
}
datasource db {
provider = "postgresql" // Используем PostgreSQL
url = env("DATABASE_URL") // Адрес базы данных из переменной окружения
}
// model - описание таблицы в базе данных
// Каждый model = одна таблица
// Пользователи (и покупатели, и продавцы)
model User {
id String @id @default(cuid()) // Уникальный ID (генерируется автоматически)
email String @unique // Email (не может повторяться)
name String // Имя
role Role @default(BUYER) // Роль: покупатель или продавец
products Product[] // Список товаров (если продавец)
orders Order[] // Список заказов (если покупатель)
createdAt DateTime @default(now()) // Дата регистрации
}
// enum - перечисление возможных значений
enum Role {
BUYER // Покупатель
SELLER // Продавец
ADMIN // Администратор
}
// Товары
model Product {
id String @id @default(cuid())
title String // Название товара
description String // Описание
price Int // Цена в КОПЕЙКАХ (не рублях!)
// Почему в копейках? Потому что числа с плавающей точкой (Float)
// дают ошибки: 0.1 + 0.2 = 0.30000000000000004
// А целые числа (Int) точные: 100 + 200 = 300 (копеек = 3 рубля)
images String[] // Массив ссылок на фото
category String // Категория
seller User @relation(fields: [sellerId], references: [id])
sellerId String // ID продавца
active Boolean @default(true) // Товар активен (виден в каталоге)
orderItems OrderItem[] // В каких заказах есть этот товар
createdAt DateTime @default(now())
}
// Заказы
model Order {
id String @id @default(cuid())
buyer User @relation(fields: [buyerId], references: [id])
buyerId String
items OrderItem[] // Список товаров в заказе
total Int // Общая сумма (в копейках)
status OrderStatus @default(NEW) // Статус заказа
name String // Имя получателя
phone String // Телефон
address String // Адрес доставки
createdAt DateTime @default(now())
}
// Позиция заказа (конкретный товар в заказе)
model OrderItem {
id String @id @default(cuid())
order Order @relation(fields: [orderId], references: [id])
orderId String
product Product @relation(fields: [productId], references: [id])
productId String
quantity Int // Количество
price Int // Цена НА МОМЕНТ ЗАКАЗА
// Почему цена дублируется? Потому что продавец может изменить цену
// после заказа, но заказ должен сохранить оригинальную цену
}
// Статусы заказа
enum OrderStatus {
NEW // Новый (только оформлен)
CONFIRMED // Подтверждён продавцом
SHIPPED // Отправлен
DELIVERED // Доставлен
CANCELLED // Отменён
}
План по дням: две недели от идеи до запуска
Дни 1-2: Фундамент
- Приоритизация фич (MoSCoW) - что входит в MVP
- Создание проекта (Next.js + Prisma + Supabase)
- Схема базы данных + первая миграция
- Базовый layout (шапка, навигация, подвал - общий каркас)
- Авторизация (вход через email + Google)
Дни 3-5: Ядро продукта (самое важное)
- Каталог товаров (список с карточками)
- Страница товара (фото, описание, цена, кнопка "В корзину")
- Форма добавления товара для продавцов
- Загрузка фото (Supabase Storage)
Дни 6-8: Заказы
- Корзина (хранится в localStorage - не нужна авторизация для добавления)
- Страница оформления заказа (имя, телефон, адрес)
- Уведомление продавцу (Telegram-бот или email)
- Страница "Спасибо за заказ"
Дни 9-10: Лендинг и SEO
- Главная страница: заголовок, преимущества, призыв к действию
- Мета-теги для поисковиков (title, description)
- Open Graph (красивые превью в соцсетях)
- sitemap.xml и robots.txt
Дни 11-12: Полировка
- Мобильная версия (адаптивная вёрстка)
- Страницы ошибок (404, 500)
- Пустые состояния ("Каталог пуст", "Корзина пуста")
- Loading-скелетоны (индикаторы загрузки)
Дни 13-14: Запуск!
- Деплой на Vercel (или VPS)
- Подключение домена
- SSL-сертификат (HTTPS - бесплатный от Let's Encrypt)
- Аналитика (Yandex Metrika)
- Тест на реальных людях (5-10 друзей/знакомых)
- Исправление критичных багов
Авторизация за 30 минут
С NextAuth.js настройка авторизации - буквально один файл. Вход через Google и по email (magic link - пользователь получает ссылку на почту):
// src/app/api/auth/[...nextauth]/route.ts
// Настройка авторизации с NextAuth.js
import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import EmailProvider from 'next-auth/providers/email'
import { PrismaAdapter } from '@auth/prisma-adapter'
import { prisma } from '@/lib/prisma'
const handler = NextAuth({
// PrismaAdapter - автоматически сохраняет пользователей в вашу БД
adapter: PrismaAdapter(prisma),
providers: [
// Вход через Google
// Для этого нужно зарегистрировать приложение в Google Cloud Console
// и получить clientId и clientSecret
GoogleProvider({
clientId: process.env.GOOGLE_ID!,
clientSecret: process.env.GOOGLE_SECRET!,
}),
// Вход по email (magic link)
// Пользователь вводит email, получает ссылку, кликает - и он авторизован
EmailProvider({
server: process.env.EMAIL_SERVER, // SMTP-сервер для отправки писем
from: process.env.EMAIL_FROM, // От чьего имени ([email protected])
}),
],
pages: {
signIn: '/auth/signin', // Кастомная страница входа
},
})
export { handler as GET, handler as POST }
// Использование в любом серверном компоненте:
// import { getServerSession } from 'next-auth'
// const session = await getServerSession()
// if (!session) redirect('/auth/signin')
// console.log(session.user.email) // email авторизованного пользователя
5 главных ошибок при создании MVP
Ошибка 1: Overengineering (переусложнение)
"Нам нужна микросервисная архитектура, Kubernetes, очереди сообщений и CI/CD с 50 шагами". Нет. Вам нужен ОДИН сервер и ОДНА база данных. Масштабировать будете, когда придут пользователи. А чтобы они пришли - нужно сначала запуститься.
Ошибка 2: Идеальный дизайн
"Дизайнер ещё не утвердил третий вариант кнопки". Shadcn/ui + Tailwind дают профессионально выглядящий интерфейс за минуты. Для MVP этого более чем достаточно. Кастомный дизайн от дизайнера - после того, как убедитесь, что продукт нужен.
Ошибка 3: Фичи, которые никто не просил
"Давайте сразу добавим чат, рейтинги, программу лояльности и рекомендации". Каждая лишняя фича - это дни разработки, новые баги и будущая поддержка. Запустите с минимумом, послушайте реальных пользователей, добавляйте то, что они просят.
Ошибка 4: Преждевременная оптимизация
"Нужно сделать кэширование Redis, потому что будет 100 000 пользователей". У вас пока 0 пользователей. PostgreSQL на минимальном сервере выдержит тысячи запросов в секунду. Оптимизируйте, когда появится реальная проблема, а не воображаемая.
Ошибка 5: Нет аналитики с первого дня
Это единственное, что НЕЛЬЗЯ отложить. Без аналитики вы слепы: не знаете, кто приходит на сайт, что делает, где уходит. Yandex Metrika - 5 минут на установку, бесплатно, вебвизор (запись экрана) показывает каждое действие пользователя. Добавьте события на ключевые действия: регистрация, добавление в корзину, оформление заказа.
Лендинг: как объяснить посетителю, зачем ему ваш продукт
MVP без лендинга - это продукт, о котором никто не узнает. Минимальная структура:
- Hero - главный экран: что это (заголовок), для кого (подзаголовок), кнопка "Попробовать бесплатно"
- Проблема - опишите боль вашего пользователя (2-3 предложения)
- Решение - как ваш продукт решает эту боль (скриншоты, видео)
- Преимущества - 3-4 ключевых фичи с иконками
- Социальное доказательство - отзывы, цифры, логотипы партнёров (если есть)
- CTA (призыв к действию) - ещё одна кнопка "Начать сейчас" или "Оставить заявку"
После запуска: что делать в первую неделю
MVP запущен. Поздравляем! Теперь начинается самое интересное:
- Дни 1-2: Мониторьте ошибки. Если есть Sentry - смотрите отчёты. Если нет - хотя бы смотрите логи сервера. Исправляйте критичные баги
- Дни 3-5: Смотрите аналитику. Откуда приходят пользователи? На какой странице уходят? Какие кнопки нажимают? Yandex Metrika покажет всё
- Дни 5-7: Поговорите с 5-10 первыми пользователями. Что неудобно? Чего не хватает? Что непонятно? Эта обратная связь на вес золота
- По результатам - планируйте следующий спринт (ещё 2 недели). Добавляйте фичи из "Should have", которые реально просят пользователи
API за 15 минут: как сделать корзину и оформление заказа
Корзина - это одна из Must Have фич для любого магазина. Вот минимальная реализация, которую можно сделать за 15 минут:
// src/app/api/orders/route.ts
// API-endpoint для создания заказа
// Next.js App Router - каждый файл route.ts автоматически становится API
import { prisma } from '@/lib/prisma'
import { NextRequest, NextResponse } from 'next/server'
// POST /api/orders - создать новый заказ
export async function POST(request: NextRequest) {
try {
// Получаем данные из тела запроса
const body = await request.json()
const { items, name, phone, address } = body
// Проверяем обязательные поля
// Без имени и телефона мы не сможем связаться с покупателем
if (!items || items.length === 0) {
return NextResponse.json(
{ error: 'Корзина пуста' },
{ status: 400 }
)
}
if (!name || !phone) {
return NextResponse.json(
{ error: 'Укажите имя и телефон' },
{ status: 400 }
)
}
// Получаем актуальные цены товаров из базы данных
// ВАЖНО: не доверяйте ценам от клиента!
// Пользователь может изменить цену в DevTools браузера
const productIds = items.map((item: any) => item.productId)
const products = await prisma.product.findMany({
where: { id: { in: productIds } }
})
// Считаем реальную сумму заказа
let total = 0
const orderItems = items.map((item: any) => {
const product = products.find(p => p.id === item.productId)
if (!product) throw new Error(`Товар ${item.productId} не найден`)
total += product.price * item.quantity
return {
productId: product.id,
quantity: item.quantity,
price: product.price, // Цена из базы, не от клиента!
}
})
// Создаём заказ в базе данных
const order = await prisma.order.create({
data: {
name,
phone,
address: address || '',
total,
items: {
create: orderItems // Prisma создаст все OrderItem автоматически
}
},
include: { items: true } // Вернуть заказ вместе с товарами
})
// Отправляем уведомление продавцу в Telegram
// (Telegram-бот настраивается за 10 минут через @BotFather)
await sendTelegramNotification(
`Новый заказ #${order.id}!\n` +
`Имя: ${name}\n` +
`Телефон: ${phone}\n` +
`Сумма: ${(total / 100).toFixed(2)} руб.\n` +
`Товаров: ${orderItems.length} шт.`
)
return NextResponse.json({ data: order }, { status: 201 })
} catch (error) {
console.error('Ошибка создания заказа:', error)
return NextResponse.json(
{ error: 'Ошибка сервера' },
{ status: 500 }
)
}
}
// Функция отправки уведомления в Telegram
async function sendTelegramNotification(text: string) {
const botToken = process.env.TELEGRAM_BOT_TOKEN
const chatId = process.env.TELEGRAM_CHAT_ID
if (!botToken || !chatId) return // Если не настроено - пропускаем
await fetch(
`https://api.telegram.org/bot${botToken}/sendMessage`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, text }),
}
)
}
Корзина на фронтенде: без базы данных
Для MVP корзину можно хранить в localStorage (локальное хранилище браузера). Это позволяет добавлять товары без авторизации - очень удобно для пользователей:
// lib/cart.ts - работа с корзиной через localStorage
// localStorage - хранилище в браузере, данные сохраняются даже после закрытия вкладки
// Тип для элемента корзины
interface CartItem {
productId: string // ID товара
name: string // Название (для отображения)
price: number // Цена (в копейках)
quantity: number // Количество
image: string // Фото (URL)
}
// Получить все товары из корзины
export function getCart(): CartItem[] {
// Читаем из localStorage
// localStorage хранит только строки, поэтому JSON.parse
const data = localStorage.getItem('cart')
return data ? JSON.parse(data) : []
}
// Добавить товар в корзину
export function addToCart(product: CartItem) {
const cart = getCart()
// Проверяем, есть ли уже этот товар в корзине
const existing = cart.find(item => item.productId === product.productId)
if (existing) {
// Если есть - увеличиваем количество
existing.quantity += 1
} else {
// Если нет - добавляем с количеством 1
cart.push({ ...product, quantity: 1 })
}
// Сохраняем обратно в localStorage
localStorage.setItem('cart', JSON.stringify(cart))
}
// Удалить товар из корзины
export function removeFromCart(productId: string) {
const cart = getCart().filter(item => item.productId !== productId)
localStorage.setItem('cart', JSON.stringify(cart))
}
// Изменить количество товара
export function updateQuantity(productId: string, quantity: number) {
const cart = getCart()
const item = cart.find(i => i.productId === productId)
if (item) {
item.quantity = Math.max(1, quantity) // Минимум 1
}
localStorage.setItem('cart', JSON.stringify(cart))
}
// Посчитать общую сумму
export function getCartTotal(): number {
return getCart().reduce(
(sum, item) => sum + item.price * item.quantity,
0
)
}
// Очистить корзину (после оформления заказа)
export function clearCart() {
localStorage.removeItem('cart')
}
Реальная стоимость MVP: сколько это стоит
Вот честный расчёт затрат на MVP маркетплейса за 2 недели:
Если делаете сами (0 руб + ваше время):
- Vercel (хостинг) - бесплатный тариф
- Supabase (база данных) - бесплатный тариф (500 MB, 50 000 запросов)
- Домен (.ru) - 200-500 руб/год
- SSL-сертификат - бесплатно (Let's Encrypt или Vercel)
- Yandex Metrika - бесплатно
- Итого: 200-500 руб + 2 недели вашего времени
Если заказываете у нас:
- Проектирование + дизайн + разработка + деплой
- Настройка аналитики и SEO
- Обучение работе с админ-панелью
- 3 месяца гарантийной поддержки
- От 150 000 руб за полный MVP
- Вы экономите 2 недели своего времени и получаете профессиональный продукт
Итого
MVP за 2 недели - это реально, если фокусироваться на главном. Приоритизируйте жёстко (MoSCoW), выбирайте стек для скорости (Next.js + Supabase + Prisma), не поддавайтесь соблазну "а давайте ещё добавим...".
Цель MVP - не идеальный продукт, а проверенная гипотеза. Если идея подтвердилась реальными пользователями - масштабируйте. Если нет - вы потеряли 2 недели, а не 6 месяцев. В любом случае вы в плюсе.
Нужна помощь с разработкой MVP? Напишите нам - мы специализируемся на быстром запуске продуктов. Первая консультация бесплатно.