architect/arh/design/PRO_SELLER1_MVP.md

PRO.seller1 MVP — Быстрый старт

Цель: Запустить рабочую систему за 3-5 дней


MVP = 4 БЛОКА

┌─────────────────────────────────────────────────────────────┐
│                      PRO.seller1 MVP                         │
├──────────────┬──────────────┬──────────────┬────────────────┤
│   🔐 CORE    │  📦 CATALOG  │  🛒 ORDERS   │  🏪 OZON      │
│   вход       │  товары      │  заказы      │  синхрон      │
│   меню       │  остатки     │  статусы     │  этикетки     │
└──────────────┴──────────────┴──────────────┴────────────────┘

Всё остальное — Q2+


БЛОК 1: CORE (день 1)

Что делаем

/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 без таблицы)

UI

┌──────────────────────────────────────────────────────────┐
│ 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

БЛОК 2: CATALOG (день 2)

Что делаем

/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
);

UI: Список товаров

┌──────────────────────────────────────────────────────────┐
│ Каталог > Товары                        [+ Добавить]     │
├──────────────────────────────────────────────────────────┤
│ [🔍 Поиск...        ] [Категория ▼] [Бренд ▼] [Сброс]   │
├──────────────────────────────────────────────────────────┤
│ □ │ Артикул  │ Название           │ Цена   │ Остаток   │ │
├───┼──────────┼────────────────────┼────────┼───────────┤ │
│ □ │ 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

БЛОК 3: ORDERS (день 2-3)

Что делаем

/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
);

UI: Список заказов

┌──────────────────────────────────────────────────────────┐
│ Заказы                                                   │
├──────────────────────────────────────────────────────────┤
│ [Все] [Новые 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   → 🔴 Возврат

БЛОК 4: OZON (день 3-4)

Что делаем

/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      адаптируем

UI: OZON дашборд

┌──────────────────────────────────────────────────────────┐
│ OZON                                    [🔄 Синхронизация]│
├──────────────────────────────────────────────────────────┤
│ Аккаунт: [O1 - Основной ▼]                               │
├──────────────────────────────────────────────────────────┤
│                                                          │
│   Новых заказов: 5          Ожидают отгрузки: 8         │
│   Сегодня: 12               Просрочено: 0               │
│                                                          │
├──────────────────────────────────────────────────────────┤
│ Последняя синхронизация: 19.12.2025 11:45               │
│                                                          │
│ [Синхронизировать заказы]  [Массовая отгрузка]          │
└──────────────────────────────────────────────────────────┘

НЕ ВХОДИТ В MVP (Q2+)

Блок Почему потом
CRM Нужны заказы сначала
Поставщики Работает через NocoDB
WB, YM Сначала стабилизируем OZON
Финансы Ведётся в Excel/1С
Роботы Нужна стабильная база
Маркетинг После CRM
Аналитика После накопления данных

ПЛАН НА 5 ДНЕЙ

День 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

СТРУКТУРА ПРОЕКТА MVP

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?