База: PostgreSQL (NocoDB)
Схема: pt7k98pv0fwi1el (существующая) или pro_seller1 (новая)
| Префикс | Модуль | Описание |
|---|---|---|
usr_ |
CORE | Пользователи, роли, настройки |
cat_ |
CATALOG | Товары, категории, склады |
ord_ |
ORDERS | Заказы, позиции |
shp_ |
SHIPMENTS | Отгрузки, доставка |
prc_ |
PROCUREMENT | Закупки, поставщики |
mp_ |
MARKETPLACES | Маркетплейсы (общее) |
ozon_ |
OZON | OZON данные |
wb_ |
WB | Wildberries данные |
ym_ |
YM | Яндекс.Маркет данные |
crm_ |
CRM | Клиенты, сегменты |
mkt_ |
MARKETING | Реклама, акции |
fin_ |
FINANCE | Финансы, транзакции |
int_ |
INTEGRATIONS | Интеграции (1С, банки) |
bot_ |
AUTOMATION | Роботы, триггеры |
log_ |
LOGS | Логи, аудит |
CREATE TABLE usr_users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255),
phone VARCHAR(50),
avatar_url VARCHAR(500),
role_id INTEGER REFERENCES usr_roles(id),
is_active BOOLEAN DEFAULT true,
last_login TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_usr_users_email ON usr_users(email);
CREATE TABLE usr_roles (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL, -- 'admin', 'manager', 'operator'
name VARCHAR(100) NOT NULL,
permissions JSONB DEFAULT '[]', -- ['orders.view', 'orders.edit']
created_at TIMESTAMP DEFAULT NOW()
);
-- Предустановленные роли
INSERT INTO usr_roles (code, name, permissions) VALUES
('admin', 'Администратор', '["*"]'),
('manager', 'Менеджер', '["orders.*", "catalog.view", "crm.*"]'),
('operator', 'Оператор', '["orders.view", "catalog.view"]'),
('warehouse', 'Кладовщик', '["catalog.*", "shipments.*"]');
CREATE TABLE usr_sessions (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES usr_users(id) ON DELETE CASCADE,
token VARCHAR(500) NOT NULL,
ip_address VARCHAR(50),
user_agent TEXT,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_usr_sessions_token ON usr_sessions(token);
CREATE INDEX idx_usr_sessions_user ON usr_sessions(user_id);
CREATE TABLE usr_settings (
id SERIAL PRIMARY KEY,
key VARCHAR(100) UNIQUE NOT NULL,
value JSONB,
description TEXT,
updated_at TIMESTAMP DEFAULT NOW()
);
-- Примеры настроек
INSERT INTO usr_settings (key, value) VALUES
('company_name', '"PRO.seller1"'),
('default_warehouse', '1'),
('ozon_sync_interval', '15'),
('notification_email', '"admin@example.com"');
CREATE TABLE cat_categories (
id SERIAL PRIMARY KEY,
parent_id INTEGER REFERENCES cat_categories(id),
name VARCHAR(255) NOT NULL,
slug VARCHAR(255),
sort_order INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_cat_categories_parent ON cat_categories(parent_id);
CREATE TABLE cat_products (
id SERIAL PRIMARY KEY,
sku VARCHAR(100) UNIQUE, -- Внутренний артикул
name VARCHAR(500) NOT NULL,
description TEXT,
category_id INTEGER REFERENCES cat_categories(id),
brand VARCHAR(255),
-- Цены
cost_price DECIMAL(12,2), -- Себестоимость
base_price DECIMAL(12,2), -- Базовая цена продажи
-- Габариты
weight_g INTEGER, -- Вес в граммах
length_mm INTEGER,
width_mm INTEGER,
height_mm INTEGER,
-- Статус
is_active BOOLEAN DEFAULT true,
-- Мета
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_cat_products_sku ON cat_products(sku);
CREATE INDEX idx_cat_products_category ON cat_products(category_id);
CREATE INDEX idx_cat_products_brand ON cat_products(brand);
CREATE TABLE cat_product_images (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES cat_products(id) ON DELETE CASCADE,
url VARCHAR(500) NOT NULL,
sort_order INTEGER DEFAULT 0,
is_main BOOLEAN DEFAULT false
);
CREATE TABLE cat_warehouses (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
address TEXT,
is_active BOOLEAN DEFAULT true,
is_default BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE cat_stock (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES cat_products(id) ON DELETE CASCADE,
warehouse_id INTEGER REFERENCES cat_warehouses(id),
quantity INTEGER DEFAULT 0, -- Всего на складе
reserved INTEGER DEFAULT 0, -- Зарезервировано
available INTEGER GENERATED ALWAYS AS (quantity - reserved) STORED,
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(product_id, warehouse_id)
);
CREATE INDEX idx_cat_stock_product ON cat_stock(product_id);
CREATE INDEX idx_cat_stock_warehouse ON cat_stock(warehouse_id);
CREATE TABLE cat_prices (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES cat_products(id) ON DELETE CASCADE,
channel VARCHAR(50) NOT NULL, -- 'ozon', 'wb', 'site', 'wholesale'
price DECIMAL(12,2) NOT NULL,
min_price DECIMAL(12,2),
max_price DECIMAL(12,2),
is_active BOOLEAN DEFAULT true,
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(product_id, channel)
);
CREATE TABLE ord_orders (
id SERIAL PRIMARY KEY,
order_number VARCHAR(50) UNIQUE, -- Внутренний номер
-- Источник
source VARCHAR(50) NOT NULL, -- 'ozon', 'wb', 'site', 'manual'
source_id VARCHAR(100), -- ID в источнике
source_number VARCHAR(100), -- Номер в источнике
-- Статус
status VARCHAR(50) DEFAULT 'new',
substatus VARCHAR(50),
-- Клиент
customer_id INTEGER REFERENCES crm_clients(id),
customer_name VARCHAR(255),
customer_phone VARCHAR(50),
customer_email VARCHAR(255),
-- Доставка
delivery_type VARCHAR(50), -- 'pickup', 'courier', 'cdek', 'pochta'
delivery_address TEXT,
delivery_city VARCHAR(255),
delivery_price DECIMAL(10,2) DEFAULT 0,
delivery_date DATE,
delivery_time_from TIME,
delivery_time_to TIME,
-- Суммы
items_amount DECIMAL(12,2), -- Сумма товаров
discount_amount DECIMAL(10,2) DEFAULT 0,
total_amount DECIMAL(12,2), -- Итого к оплате
-- Оплата
payment_type VARCHAR(50), -- 'prepaid', 'cod', 'card'
payment_status VARCHAR(50), -- 'pending', 'paid', 'refunded'
paid_at TIMESTAMP,
-- Комментарии
customer_comment TEXT,
manager_comment TEXT,
-- Мета
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_ord_orders_source ON ord_orders(source, source_id);
CREATE INDEX idx_ord_orders_status ON ord_orders(status);
CREATE INDEX idx_ord_orders_customer ON ord_orders(customer_id);
CREATE INDEX idx_ord_orders_created ON ord_orders(created_at);
CREATE TABLE ord_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES ord_orders(id) ON DELETE CASCADE,
product_id INTEGER REFERENCES cat_products(id),
sku VARCHAR(100),
name VARCHAR(500),
quantity INTEGER NOT NULL,
price DECIMAL(12,2) NOT NULL, -- Цена за единицу
discount DECIMAL(10,2) DEFAULT 0,
total DECIMAL(12,2), -- quantity * price - discount
-- Для маркетплейсов
source_sku VARCHAR(100), -- SKU в источнике
source_item_id VARCHAR(100) -- ID позиции в источнике
);
CREATE INDEX idx_ord_items_order ON ord_items(order_id);
CREATE INDEX idx_ord_items_product ON ord_items(product_id);
CREATE TABLE ord_status_history (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES ord_orders(id) ON DELETE CASCADE,
status VARCHAR(50) NOT NULL,
comment TEXT,
user_id INTEGER REFERENCES usr_users(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_ord_history_order ON ord_status_history(order_id);
CREATE TABLE shp_shipments (
id SERIAL PRIMARY KEY,
shipment_number VARCHAR(50) UNIQUE,
-- Связь с заказом
order_id INTEGER REFERENCES ord_orders(id),
-- Служба доставки
carrier VARCHAR(50) NOT NULL, -- 'ozon', 'cdek', 'pochta', 'own'
carrier_service VARCHAR(100), -- Тариф/услуга
-- Трекинг
tracking_number VARCHAR(100),
tracking_url VARCHAR(500),
-- Статус
status VARCHAR(50) DEFAULT 'pending',
-- Отправка
warehouse_id INTEGER REFERENCES cat_warehouses(id),
shipped_at TIMESTAMP,
delivered_at TIMESTAMP,
-- Стоимость
shipping_cost DECIMAL(10,2),
-- Документы
label_url VARCHAR(500), -- Этикетка
waybill_url VARCHAR(500), -- Накладная
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_shp_shipments_order ON shp_shipments(order_id);
CREATE INDEX idx_shp_shipments_tracking ON shp_shipments(tracking_number);
CREATE TABLE shp_carriers (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(50), -- 'courier', 'post', 'pvz'
api_enabled BOOLEAN DEFAULT false,
api_config JSONB, -- API credentials
is_active BOOLEAN DEFAULT true
);
INSERT INTO shp_carriers (code, name, type) VALUES
('cdek', 'СДЭК', 'courier'),
('pochta', 'Почта России', 'post'),
('dpd', 'DPD', 'courier'),
('boxberry', 'Boxberry', 'pvz'),
('own', 'Своя доставка', 'courier');
CREATE TABLE shp_couriers (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
phone VARCHAR(50),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE shp_delivery_zones (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
cities TEXT[], -- Список городов
delivery_days INTEGER, -- Срок доставки
delivery_price DECIMAL(10,2),
free_from DECIMAL(12,2), -- Бесплатно от суммы
is_active BOOLEAN DEFAULT true
);
CREATE TABLE prc_suppliers (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE,
name VARCHAR(255) NOT NULL,
contact_name VARCHAR(255),
phone VARCHAR(50),
email VARCHAR(255),
address TEXT,
payment_terms TEXT, -- Условия оплаты
delivery_days INTEGER, -- Срок поставки
min_order_amount DECIMAL(12,2),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE prc_price_lists (
id SERIAL PRIMARY KEY,
supplier_id INTEGER REFERENCES prc_suppliers(id),
product_id INTEGER REFERENCES cat_products(id),
supplier_sku VARCHAR(100), -- Артикул поставщика
supplier_name VARCHAR(500), -- Название у поставщика
price DECIMAL(12,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'RUB',
min_quantity INTEGER DEFAULT 1,
in_stock BOOLEAN DEFAULT true,
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(supplier_id, product_id)
);
CREATE INDEX idx_prc_prices_supplier ON prc_price_lists(supplier_id);
CREATE INDEX idx_prc_prices_product ON prc_price_lists(product_id);
CREATE TABLE prc_price_history (
id SERIAL PRIMARY KEY,
supplier_id INTEGER REFERENCES prc_suppliers(id),
product_id INTEGER REFERENCES cat_products(id),
price DECIMAL(12,2) NOT NULL,
recorded_at TIMESTAMP DEFAULT NOW()
);
-- Партиционирование по месяцам для больших объёмов
CREATE INDEX idx_prc_history_date ON prc_price_history(recorded_at);
CREATE TABLE prc_purchases (
id SERIAL PRIMARY KEY,
purchase_number VARCHAR(50) UNIQUE,
supplier_id INTEGER REFERENCES prc_suppliers(id),
status VARCHAR(50) DEFAULT 'draft', -- draft, sent, confirmed, received, cancelled
-- Суммы
total_amount DECIMAL(12,2),
-- Даты
ordered_at TIMESTAMP,
expected_at DATE,
received_at TIMESTAMP,
-- Связь с заказами клиентов
related_orders INTEGER[], -- ID заказов под которые закупаем
comment TEXT,
created_by INTEGER REFERENCES usr_users(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE prc_purchase_items (
id SERIAL PRIMARY KEY,
purchase_id INTEGER REFERENCES prc_purchases(id) ON DELETE CASCADE,
product_id INTEGER REFERENCES cat_products(id),
supplier_sku VARCHAR(100),
quantity INTEGER NOT NULL,
price DECIMAL(12,2) NOT NULL,
received_quantity INTEGER DEFAULT 0,
total DECIMAL(12,2)
);
CREATE TABLE mp_accounts (
id SERIAL PRIMARY KEY,
marketplace VARCHAR(50) NOT NULL, -- 'ozon', 'wb', 'ym'
code VARCHAR(50) NOT NULL, -- 'O1', 'O2', 'WB1'
name VARCHAR(255),
client_id VARCHAR(100),
api_key VARCHAR(500),
api_secret VARCHAR(500),
is_active BOOLEAN DEFAULT true,
last_sync_at TIMESTAMP,
settings JSONB,
UNIQUE(marketplace, code)
);
CREATE TABLE mp_product_mapping (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES cat_products(id),
account_id INTEGER REFERENCES mp_accounts(id),
external_sku VARCHAR(100), -- SKU на маркетплейсе
external_id VARCHAR(100), -- ID на маркетплейсе
external_url VARCHAR(500),
is_active BOOLEAN DEFAULT true,
UNIQUE(product_id, account_id)
);
CREATE INDEX idx_mp_mapping_external ON mp_product_mapping(account_id, external_sku);
CREATE TABLE ozon_orders (
id SERIAL PRIMARY KEY,
account_id INTEGER REFERENCES mp_accounts(id),
order_id INTEGER REFERENCES ord_orders(id),
posting_number VARCHAR(100) UNIQUE,
order_number VARCHAR(100),
-- OZON специфичные поля
in_process_at TIMESTAMP,
shipment_date DATE,
delivering_date DATE,
analytics_data JSONB, -- Аналитика OZON
financial_data JSONB, -- Финансы OZON
raw_data JSONB, -- Полный ответ API
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_ozon_orders_posting ON ozon_orders(posting_number);
CREATE TABLE ozon_products (
id SERIAL PRIMARY KEY,
account_id INTEGER REFERENCES mp_accounts(id),
product_id INTEGER REFERENCES cat_products(id),
ozon_product_id BIGINT,
ozon_sku BIGINT,
ozon_fbo_sku BIGINT,
ozon_fbs_sku BIGINT,
-- Статус на OZON
visibility VARCHAR(50),
status VARCHAR(50),
-- Цены
price DECIMAL(12,2),
old_price DECIMAL(12,2),
min_price DECIMAL(12,2),
-- Остатки
fbo_stock INTEGER DEFAULT 0,
fbs_stock INTEGER DEFAULT 0,
raw_data JSONB,
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE crm_clients (
id SERIAL PRIMARY KEY,
-- Основное
name VARCHAR(255),
phone VARCHAR(50),
email VARCHAR(255),
-- Тип
type VARCHAR(50) DEFAULT 'retail', -- retail, wholesale, vip
-- Сегментация
segment VARCHAR(50), -- 'new', 'active', 'sleeping', 'lost'
tags TEXT[],
-- Статистика (обновляется триггером)
orders_count INTEGER DEFAULT 0,
orders_total DECIMAL(12,2) DEFAULT 0,
last_order_at TIMESTAMP,
avg_order_value DECIMAL(12,2),
-- Лояльность
loyalty_points INTEGER DEFAULT 0,
loyalty_level VARCHAR(50),
-- Источник
source VARCHAR(50), -- 'ozon', 'site', 'manual'
source_id VARCHAR(100),
-- Согласия
consent_sms BOOLEAN DEFAULT false,
consent_email BOOLEAN DEFAULT false,
consent_whatsapp BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_crm_clients_phone ON crm_clients(phone);
CREATE INDEX idx_crm_clients_email ON crm_clients(email);
CREATE INDEX idx_crm_clients_segment ON crm_clients(segment);
CREATE TABLE crm_communications (
id SERIAL PRIMARY KEY,
client_id INTEGER REFERENCES crm_clients(id),
channel VARCHAR(50) NOT NULL, -- 'call', 'sms', 'email', 'whatsapp'
direction VARCHAR(10), -- 'in', 'out'
subject VARCHAR(255),
content TEXT,
status VARCHAR(50), -- 'sent', 'delivered', 'read', 'failed'
user_id INTEGER REFERENCES usr_users(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_crm_comm_client ON crm_communications(client_id);
CREATE TABLE crm_segments (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
code VARCHAR(50) UNIQUE,
description TEXT,
-- Правила сегментации (JSON)
rules JSONB, -- {"orders_count": {"gte": 3}, "last_order_days": {"lte": 30}}
clients_count INTEGER DEFAULT 0, -- Обновляется периодически
is_auto BOOLEAN DEFAULT true, -- Автоматическое обновление
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE mkt_campaigns (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(50), -- 'email', 'sms', 'push', 'ads'
status VARCHAR(50) DEFAULT 'draft',
-- Аудитория
segment_id INTEGER REFERENCES crm_segments(id),
clients_count INTEGER,
-- Контент
subject VARCHAR(255),
content TEXT,
template_id INTEGER,
-- Расписание
scheduled_at TIMESTAMP,
sent_at TIMESTAMP,
-- Статистика
sent_count INTEGER DEFAULT 0,
delivered_count INTEGER DEFAULT 0,
opened_count INTEGER DEFAULT 0,
clicked_count INTEGER DEFAULT 0,
created_by INTEGER REFERENCES usr_users(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE mkt_promotions (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
code VARCHAR(50) UNIQUE, -- Промокод
type VARCHAR(50), -- 'percent', 'fixed', 'gift'
-- Условия
discount_value DECIMAL(10,2),
min_order_amount DECIMAL(12,2),
max_discount DECIMAL(10,2),
-- Применимость
applicable_to VARCHAR(50), -- 'all', 'category', 'product'
applicable_ids INTEGER[],
-- Период
starts_at TIMESTAMP,
ends_at TIMESTAMP,
-- Лимиты
usage_limit INTEGER,
usage_count INTEGER DEFAULT 0,
per_client_limit INTEGER DEFAULT 1,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE fin_transactions (
id SERIAL PRIMARY KEY,
type VARCHAR(50) NOT NULL, -- 'income', 'expense', 'transfer'
category VARCHAR(100), -- 'order_payment', 'supplier_payment', 'salary'
amount DECIMAL(12,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'RUB',
-- Связи
order_id INTEGER REFERENCES ord_orders(id),
purchase_id INTEGER REFERENCES prc_purchases(id),
supplier_id INTEGER REFERENCES prc_suppliers(id),
account VARCHAR(50), -- 'cash', 'bank', 'ozon', 'wb'
description TEXT,
transaction_date DATE NOT NULL,
created_by INTEGER REFERENCES usr_users(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_fin_trans_date ON fin_transactions(transaction_date);
CREATE INDEX idx_fin_trans_order ON fin_transactions(order_id);
CREATE TABLE fin_accounts (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(50), -- 'cash', 'bank', 'marketplace'
balance DECIMAL(12,2) DEFAULT 0,
currency VARCHAR(3) DEFAULT 'RUB',
is_active BOOLEAN DEFAULT true
);
INSERT INTO fin_accounts (code, name, type) VALUES
('cash', 'Касса', 'cash'),
('bank_main', 'Расчётный счёт', 'bank'),
('ozon', 'OZON баланс', 'marketplace'),
('wb', 'WB баланс', 'marketplace');
CREATE TABLE int_1c_queue (
id SERIAL PRIMARY KEY,
direction VARCHAR(10) NOT NULL, -- 'to_1c', 'from_1c'
entity_type VARCHAR(50) NOT NULL, -- 'order', 'product', 'client'
entity_id INTEGER,
status VARCHAR(50) DEFAULT 'pending',
payload JSONB,
response JSONB,
error_message TEXT,
attempts INTEGER DEFAULT 0,
processed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_int_1c_status ON int_1c_queue(status);
CREATE TABLE bot_robots (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(50), -- 'price', 'stock', 'order', 'notification'
is_active BOOLEAN DEFAULT true,
schedule VARCHAR(100), -- Cron expression
config JSONB, -- Настройки робота
last_run_at TIMESTAMP,
last_run_status VARCHAR(50),
last_run_message TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE bot_logs (
id SERIAL PRIMARY KEY,
robot_id INTEGER REFERENCES bot_robots(id),
status VARCHAR(50), -- 'started', 'success', 'error'
message TEXT,
details JSONB,
duration_ms INTEGER,
records_processed INTEGER,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_bot_logs_robot ON bot_logs(robot_id);
CREATE INDEX idx_bot_logs_date ON bot_logs(created_at);
CREATE TABLE log_audit (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES usr_users(id),
action VARCHAR(50) NOT NULL, -- 'create', 'update', 'delete'
entity_type VARCHAR(50) NOT NULL,
entity_id INTEGER,
old_values JSONB,
new_values JSONB,
ip_address VARCHAR(50),
user_agent TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_log_audit_user ON log_audit(user_id);
CREATE INDEX idx_log_audit_entity ON log_audit(entity_type, entity_id);
CREATE INDEX idx_log_audit_date ON log_audit(created_at);
-- Партиционирование по месяцам
-- CREATE TABLE log_audit_2024_12 PARTITION OF log_audit FOR VALUES FROM ('2024-12-01') TO ('2025-01-01');
┌─────────────┐
│ usr_users │
└──────┬──────┘
│
┌───────────────────────────────┼───────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ cat_products│◄───────────────│ ord_orders │───────────────►│ crm_clients │
└──────┬──────┘ └──────┬──────┘ └─────────────┘
│ │
┌─────┴─────┐ ┌─────┴─────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐
│cat_stock│ │cat_prices│ │ord_items │ │shp_ship. │
└─────────┘ └─────────┘ └──────────┘ └──────────┘
│ │
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│prc_suppliers │ │ mp_accounts │
│prc_purchases │ │ ozon_orders │
└──────────────┘ └──────────────┘
Эти таблицы уже есть, можно использовать или мигрировать:
-- Товары (5623)
pim_products → cat_products (миграция)
-- Категории
pim_categories → cat_categories
-- Заказы OZON
OZON_Orders → ozon_orders
-- Аккаунты
OZON_Accounts → mp_accounts
-- Цены поставщиков (4126)
Prices_History → prc_price_history
Продолжаем?