Спецификация персистентного слоя экосистемы FoodLifeCycle

Часть 1: Схемы баз данных IAD, MDM и финансового контура

Author

Database Administrator / Lead Systems Architect

Published

July 13, 2026

1. СУБД Контура Авторизации: Auth_db (PostgreSQL)

База данных обслуживает сервис auth-service. Хранит данные пользователей, связки мультитендентных групп и локализованные справочники ошибок для мобильного АРМ.

-- Таблица учетных записей пользователей
CREATE TABLE users (
    user_id VARCHAR(50) PRIMARY KEY, -- usr-991
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL, -- Argon2 hash
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Таблица мультитендентных групп (Семья / Компания)
CREATE TABLE groups (
    group_id VARCHAR(50) PRIMARY KEY, -- group-office-corporate-4
    space_type VARCHAR(20) NOT NULL CHECK (space_type IN ('HOME', 'OFFICE')),
    is_verified BOOLEAN DEFAULT FALSE, -- Статус ЕСИА верификации B2B
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Таблица связей пользователей и орг-групп (Многие-к-Одному)
CREATE TABLE group_members (
    user_id VARCHAR(50) REFERENCES users(user_id) ON DELETE CASCADE,
    group_id VARCHAR(50) REFERENCES groups(group_id) ON DELETE CASCADE,
    role VARCHAR(30) DEFAULT 'MEMBER', -- LEADER, MEMBER
    joined_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    PRIMARY KEY (user_id, group_id)
);

-- Динамический справочник ИИ-ошибок (Для холодного старта App)
CREATE TABLE error_directory (
    error_code VARCHAR(50) PRIMARY KEY, -- INSUFFICIENT_STOCK, SECURITY_PROFANITY_BAN
    http_status INTEGER NOT NULL, -- 422, 403
    grpc_status_code INTEGER NOT NULL, -- 9, 7
    app_lang VARCHAR(10) NOT NULL, -- ru, en
    localized_message TEXT NOT NULL,
    is_active BOOLEAN DEFAULT TRUE
);

2. СУБД Финансового Контура: Billing_db (PostgreSQL)

База данных обслуживает сервис billing-service. Хранит информацию о затратах, покупках и фискальных данных ОФД.

-- Таблица зарегистрированных фискальных чеков
CREATE TABLE store_receipts (
    receipt_id VARCHAR(50) PRIMARY KEY, -- rec-00125
    group_id VARCHAR(50) NOT NULL, -- Сквозной ключ Partition Key
    shop_id VARCHAR(50) NOT NULL,
    total_amount NUMERIC(12, 4) NOT NULL,
    currency VARCHAR(10) DEFAULT 'RUB',
    x_request_id VARCHAR(50) NOT NULL,
    purchased_at TIMESTAMP WITH TIME ZONE NOT NULL
);

-- Таблица детализации позиций чека (Цены магазинов)
CREATE TABLE receipt_items (
    item_id SERIAL PRIMARY KEY,
    receipt_id VARCHAR(50) REFERENCES store_receipts(receipt_id) ON DELETE CASCADE,
    raw_input_name TEXT NOT NULL, -- Название из чека ОФД
    resolved_product_id VARCHAR(50), -- Ссылка на эталонный ID из MDM
    quantity NUMERIC(10, 4) NOT NULL,
    price_per_unit NUMERIC(12, 4) NOT NULL
);

3. СУБД Мастер-Данных и Каталогов: Mdm_db (PostgreSQL)

База данных обслуживает recipes-service и хранит неизменяемые физико-химические константы, БЖУ и кулинарную книгу.

-- Периодическая система эталонных продуктов
CREATE TABLE product_catalog (
    product_id VARCHAR(50) PRIMARY KEY, -- mdm-prod-102
    element_symbol VARCHAR(10) NOT NULL, -- St (Strawberries), Wt (Water)
    canonical_name VARCHAR(255) NOT NULL, -- Клубника свежая
    proteins NUMERIC(6, 2) DEFAULT 0.00,
    fats NUMERIC(6, 2) DEFAULT 0.00,
    carbohydrates NUMERIC(6, 2) DEFAULT 0.00,
    calories NUMERIC(8, 2) DEFAULT 0.00,
    storage_mode VARCHAR(20) DEFAULT 'CHILLED' -- FROZEN, CHILLED, DRY
);

-- Таблица штрих-кодов номенклатур
CREATE TABLE product_barcodes (
    barcode VARCHAR(50) PRIMARY KEY,
    product_id VARCHAR(50) REFERENCES product_catalog(product_id) ON DELETE CASCADE
);

-- Таблица технологических карт (Кулинарная Книга)
CREATE TABLE recipe_book (
    recipe_id SERIAL PRIMARY KEY,
    dish_name VARCHAR(255) NOT NULL, -- Компот Ягодный
    total_portions INTEGER DEFAULT 1,
    instructions TEXT NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Ингредиенты технологических карт (Связь Многие-ко-Многим)
CREATE TABLE recipe_ingredients (
    recipe_id INTEGER REFERENCES recipe_book(recipe_id) ON DELETE CASCADE,
    product_id VARCHAR(50) REFERENCES product_catalog(product_id),
    required_weight_g NUMERIC(10, 4) NOT NULL,
    PRIMARY KEY (recipe_id, product_id)
);

4. СУБД Контура Склада и Холодильника: Fridge_db (PostgreSQL)

База данных обслуживает сервис fridge-service. Это самое высоконагруженное OLTP-ядро системы. Она хранит физические остатки продуктов (в граммах/литрах/порциях), разбитые на изолированные партии для обеспечения работы каскадного алгоритма FIFO, контроля сроков годности и считывания IoT смарт-меток.

-- Таблица складского инвентаря (Партионный учет FIFO)
CREATE TABLE fridge_inventory (
    batch_id VARCHAR(50) PRIMARY KEY, -- batch-uuid-111
    group_id VARCHAR(50) NOT NULL, -- Сквозной ключ Partition Key арендатора
    product_id VARCHAR(50) NOT NULL, -- Ссылка на эталонный ID из Mdm_db
    quantity NUMERIC(12, 4) NOT NULL, -- Текущий остаток (грамм/литр). Может быть < 0 для HOME
    initial_volume NUMERIC(12, 4) NOT NULL, -- Объем при зачислении из чека
    storage_mode VARCHAR(20) DEFAULT 'CHILLED', -- FROZEN, CHILLED, DRY
    is_cooked BOOLEAN DEFAULT FALSE, -- TRUE для готовых блюд (Блинчики, Борщ)
    status VARCHAR(20) DEFAULT 'READY', -- READY, EXPIRED (при авто-списании планировщиком)
    expired_at TIMESTAMP WITH TIME ZONE NOT NULL, -- Жесткий дедлайн таймера свежести
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -- Используется для: ORDER BY created_at ASC (FIFO)
);

-- Индекс для мгновенной выборки старых партий по FIFO-стратегии
CREATE INDEX idx_fridge_fifo_flow ON fridge_inventory (group_id, product_id, created_at ASC) 
WHERE quantity > 0;

-- Индекс для извлечения virtual-shortages (Для контура HOME)
CREATE INDEX idx_fridge_virtual_shortages ON fridge_inventory (group_id) 
WHERE quantity < 0;

-- Таблица IoT смарт-меток и весовых датчиков контейнеров
CREATE TABLE fridge_smart_tags (
    tag_id VARCHAR(50) PRIMARY KEY, -- tag-rfid-555
    batch_id VARCHAR(50) REFERENCES fridge_inventory(batch_id) ON DELETE SET NULL,
    current_weight_g NUMERIC(10, 2) NOT NULL,
    battery_level INTEGER CHECK (battery_level BETWEEN 0 AND 100),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

5. СУБД Сквозного Аудита Процессов: Bupar_db (PostgreSQL)

База данных обслуживает аналитический сервис bupar-audit-service. Работает в режиме накопления бизнес-метрик. Агрегирует сырые события из топика №14 (bpds.pma.out.process.event) для склеивания сквозных цепочек жизненного цикла еды и визуализации D3.js графов.

-- Таблица сквозного лога событий симуляции (Event Log для bupar)
CREATE TABLE bupar_event_log (
    event_id VARCHAR(50) PRIMARY KEY, -- evt-uuid-8830
    case_id VARCHAR(50) NOT NULL, -- Сквозной маркер жизненного цикла конкретной еды
    x_request_id VARCHAR(50) NOT NULL, -- Технический UUID трейсинга логов (trace_id)
    home_group_id VARCHAR(50) NOT NULL, -- Контекст орг-группы симулятора
    activity_name VARCHAR(100) NOT NULL, -- PRODUCT_BATCH_PURCHASED, MANUAL_DISH_COOKED, FOOD_CONSUMED, FOOD_WASTED, SHORTAGE_RECONCILED
    payload_snapshot JSONB NOT NULL, -- Сырой слепок параметров (вес, причины утилизации, коды ошибок)
    timestamp TIMESTAMP WITH TIME ZONE NOT NULL
);

-- Индексы для высокоскоростной сборки Process Mining цепочек и вызовов BFF дашборда
CREATE INDEX idx_bupar_case_mining ON bupar_event_log (case_id, timestamp ASC);
CREATE INDEX idx_bupar_trace_search ON bupar_event_log (x_request_id);
CREATE INDEX idx_bupar_group_analytics ON bupar_event_log (home_group_id, activity_name);

6. СУБД Сервиса Уведомлений: Notification_db (PostgreSQL)

База данных обслуживает сервис notification-service. Хранит локализованные шаблоны пушей и лог отправленных через Google FCM нотификаций.

-- Таблица локализованных шаблонов всплывающих уведомлений
CREATE TABLE notification_templates (
    template_code VARCHAR(50) NOT NULL, -- EXPIRED_ALERT, PROFANITY_BAN_ALERT
    app_lang VARCHAR(10) NOT NULL, -- ru, en
    title VARCHAR(150) NOT NULL,
    body_text TEXT NOT NULL,
    PRIMARY KEY (template_code, app_lang)
);

-- Лог отправленных пуш-уведомлений пользователям (Для аудита сбоев ИИ)
CREATE TABLE push_delivery_log (
    delivery_id SERIAL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL,
    template_code VARCHAR(50) NOT NULL,
    x_request_id VARCHAR(50) NOT NULL, -- Трейсинг причины пуша (например, ID забаненной сессии)
    status VARCHAR(20) DEFAULT 'SENT', -- SENT, DELIVERED, FAILED
    delivered_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);