Цель: Запустить рабочую систему за 3-5 дней
┌─────────────────────────────────────────────────────────────┐
│ PRO.seller1 MVP │
├──────────────┬──────────────┬──────────────┬────────────────┤
│ 🔐 CORE │ 📦 CATALOG │ 🛒 ORDERS │ 🏪 OZON │
│ вход │ товары │ заказы │ синхрон │
│ меню │ остатки │ статусы │ этикетки │
└──────────────┴──────────────┴──────────────┴────────────────┘
Всё остальное — Q2+
/login — Вход (email + пароль)
/logout — Выход
/ — Главная (дашборд-заглушка)
-- Минимум для авторизации
CREATE TABLE usr_users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255),
role VARCHAR(50) DEFAULT 'manager',
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
-- Сессии (или JWT без таблицы)
┌──────────────────────────────────────────────────────────┐
│ PRO.seller1 [🔍] [User ▼] [⚙️] │
├────────────┬─────────────────────────────────────────────┤
│ │ │
│ 📦 Каталог │ Добро пожаловать! │
│ Товары │ │
│ Остатки │ Заказов сегодня: 15 │
│ │ Ожидают отгрузки: 8 │
│ 🛒 Заказы │ │
│ Список │ │
│ Отгрузки │ │
│ │ │
│ 🏪 OZON │ │
│ Синхрон │ │
│ │ │
│────────────│ │
│ ⚙️ Настр. │ │
└────────────┴─────────────────────────────────────────────┘
app/
├── main.py
├── config.py
├── database.py
├── core/
│ ├── auth/
│ │ ├── router.py # /login, /logout
│ │ ├── views.py # HTML страницы
│ │ ├── models.py # User
│ │ ├── schemas.py # LoginForm
│ │ └── service.py # verify_password, create_token
│ └── deps.py # get_current_user
└── web/
└── templates/
├── base.html # Layout + sidebar
├── login.html
└── dashboard.html
/catalog/products — Список товаров
/catalog/products/{id} — Карточка товара
/catalog/products/{id}/edit — Редактирование
/catalog/stock — Остатки по складам
Используем существующие из NocoDB:
-- Уже есть
pim_products -- 5623 товаров
pim_categories -- категории
-- Добавляем если нет
CREATE TABLE cat_stock (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES pim_products(id),
warehouse_id INTEGER,
quantity INTEGER DEFAULT 0,
reserved INTEGER DEFAULT 0,
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE cat_warehouses (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
code VARCHAR(50),
is_active BOOLEAN DEFAULT true
);
┌──────────────────────────────────────────────────────────┐
│ Каталог > Товары [+ Добавить] │
├──────────────────────────────────────────────────────────┤
│ [🔍 Поиск... ] [Категория ▼] [Бренд ▼] [Сброс] │
├──────────────────────────────────────────────────────────┤
│ □ │ Артикул │ Название │ Цена │ Остаток │ │
├───┼──────────┼────────────────────┼────────┼───────────┤ │
│ □ │ FW-001 │ Салют "Большой" │ 5 000 │ 48 │ │
│ □ │ FW-002 │ Батарея "Звёзды" │ 2 500 │ 120 │ │
│ □ │ FW-003 │ Фонтан "Золото" │ 800 │ 0 ⚠️ │ │
├──────────────────────────────────────────────────────────┤
│ Показано 1-20 из 5623 [<] [1] [2] [>] │
└──────────────────────────────────────────────────────────┘
app/modules/catalog/
├── router.py # API endpoints
├── views.py # HTML pages
├── models.py # Product, Stock, Warehouse
├── schemas.py # ProductFilter, ProductUpdate
└── service.py # get_products, update_stock
/orders — Все заказы (единый список)
/orders/{id} — Детали заказа
/orders/{id}/status — Смена статуса
/orders/shipments — Отгрузки
Используем + расширяем:
-- Уже есть
OZON_Orders -- заказы OZON
-- Универсальные заказы (агрегация)
CREATE TABLE ord_orders (
id SERIAL PRIMARY KEY,
source VARCHAR(50) NOT NULL, -- 'ozon', 'wb', 'site', 'manual'
source_id VARCHAR(100), -- ID в источнике
status VARCHAR(50) DEFAULT 'new',
customer_name VARCHAR(255),
customer_phone VARCHAR(50),
customer_email VARCHAR(255),
delivery_address TEXT,
delivery_type VARCHAR(50), -- 'pickup', 'courier', 'cdek'
total_amount DECIMAL(10,2),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE ord_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES ord_orders(id),
product_id INTEGER,
sku VARCHAR(100),
name VARCHAR(255),
quantity INTEGER,
price DECIMAL(10,2)
);
CREATE TABLE ord_shipments (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES ord_orders(id),
carrier VARCHAR(50), -- 'ozon', 'cdek', 'pochta'
tracking_number VARCHAR(100),
status VARCHAR(50),
shipped_at TIMESTAMP,
delivered_at TIMESTAMP
);
┌──────────────────────────────────────────────────────────┐
│ Заказы │
├──────────────────────────────────────────────────────────┤
│ [Все] [Новые 8] [В работе 12] [Отгружены] [Доставлены] │
├──────────────────────────────────────────────────────────┤
│ [🔍 Номер/телефон...] [Источник ▼] [Дата ▼] │
├──────────────────────────────────────────────────────────┤
│ № │ Источник │ Дата │ Клиент │ Сумма │Статус │
├───┼──────────┼────────────┼─────────────┼───────┼───────┤
│ 1 │ 🟠 OZON │ 19.12 10:30│ Иванов И.И. │ 5 200 │ 🟡 New│
│ 2 │ 🟣 WB │ 19.12 09:15│ Петров П.П. │ 3 100 │ 🟢 OK │
│ 3 │ 🔵 Сайт │ 18.12 18:00│ Сидоров С. │ 1 800 │ 🟡 New│
└──────────────────────────────────────────────────────────┘
new → 🟡 Новый
processing → 🟠 В обработке
packed → 📦 Собран
shipped → 🚚 Отгружен
delivered → 🟢 Доставлен
cancelled → ⚫ Отменён
returned → 🔴 Возврат
/ozon — Дашборд OZON
/ozon/sync — Синхронизация заказов
/ozon/orders — Заказы OZON (фильтр)
/ozon/shipments — Отгрузки
/ozon/labels/{posting} — Этикетка (PDF)
Берём из @mp1.service и @ozon.api:
@mp1.service/solution/app/
├── api/v1/orders/ → копируем логику
├── api/v1/ozon/ → копируем клиент
└── services/ → OZON API
@ozon.api/solution/scripts/
├── sync_orders.py → адаптируем
└── get_labels.py → адаптируем
┌──────────────────────────────────────────────────────────┐
│ OZON [🔄 Синхронизация]│
├──────────────────────────────────────────────────────────┤
│ Аккаунт: [O1 - Основной ▼] │
├──────────────────────────────────────────────────────────┤
│ │
│ Новых заказов: 5 Ожидают отгрузки: 8 │
│ Сегодня: 12 Просрочено: 0 │
│ │
├──────────────────────────────────────────────────────────┤
│ Последняя синхронизация: 19.12.2025 11:45 │
│ │
│ [Синхронизировать заказы] [Массовая отгрузка] │
└──────────────────────────────────────────────────────────┘
| Блок | Почему потом |
|---|---|
| CRM | Нужны заказы сначала |
| Поставщики | Работает через NocoDB |
| WB, YM | Сначала стабилизируем OZON |
| Финансы | Ведётся в Excel/1С |
| Роботы | Нужна стабильная база |
| Маркетинг | После CRM |
| Аналитика | После накопления данных |
День 1: CORE
├── Структура проекта
├── Auth (login/logout)
├── Layout (sidebar, header)
└── Dashboard (заглушка)
День 2: CATALOG
├── Модели Product, Stock
├── Список товаров
├── Карточка товара
└── Фильтры, поиск
День 3: ORDERS
├── Модели Order, OrderItem
├── Список заказов
├── Детали заказа
└── Смена статуса
День 4: OZON
├── OZON API клиент (из @mp1)
├── Синхронизация заказов
├── Этикетки
└── Отгрузка
День 5: DEPLOY
├── Docker image
├── docker-compose
├── Деплой на DEV-PROD-RF
└── Smoke test
projects/pro1/
├── CLAUDE.md
├── @pro.service/
│ ├── CLAUDE.md
│ ├── solution/
│ │ ├── app/
│ │ │ ├── main.py
│ │ │ ├── config.py
│ │ │ ├── database.py
│ │ │ │
│ │ │ ├── core/
│ │ │ │ ├── auth/
│ │ │ │ └── deps.py
│ │ │ │
│ │ │ ├── modules/
│ │ │ │ ├── catalog/
│ │ │ │ ├── orders/
│ │ │ │ └── ozon/
│ │ │ │
│ │ │ └── web/
│ │ │ ├── templates/
│ │ │ │ ├── base.html
│ │ │ │ ├── components/
│ │ │ │ └── pages/
│ │ │ └── static/
│ │ │
│ │ ├── requirements.txt
│ │ ├── Dockerfile
│ │ └── .env
│ │
│ └── docker-compose.yml
│
└── docs/
├── MVP.md ← Этот документ
└── SCHEMA.md ← Схема БД
Скажи "поехали" — создам структуру и начну с CORE.
Или нужно что-то уточнить/добавить в MVP?