# 4. Требования к данным и сущностям ## 4.1 Общие требования к данным Основное хранилище данных программного продукта реализуется на `PostgreSQL`. Прикладной доступ к данным осуществляется через `Prisma ORM`. Система должна обеспечивать хранение: - пользователей и ролей - компаний и профилей контрагентов - адресов доставки - каталога и складских остатков - корзины и ее позиций - заказов и расчетных заявок - событий изменения статусов - подключений мессенджеров - бонусных и реферальных сущностей В прикладной реализации должны использоваться фактические сущности базы данных, определенные в `schema.prisma`. Наименование сущностей в документации и в базе данных должно сопоставляться однозначно. ## 4.2 Справочник сущностей базы данных | Модель в базе данных | Русское наименование | Назначение | | --- | --- | --- | | `Company` | Компания | Клиентская организация | | `User` | Пользователь | Учетная запись клиента, менеджера или суперменеджера | | `DeliveryAddress` | Адрес доставки | Справочник адресов доставки клиента | | `CounterpartyProfile` | Профиль контрагента | Юридические и банковские реквизиты клиента | | `RegistrationRequest` | Заявка на подключение | Самостоятельная заявка клиента на подключение | | `Invitation` | Приглашение | Менеджерское приглашение на регистрацию | | `MessengerConnection` | Подключение мессенджера | Связка пользователя с Telegram или MAX | | `Product` | Товар | Карточка товарной позиции каталога | | `CatalogProductTypeSetting` | Настройки типа товара | Правила параметров и кастомизации по товарному направлению | | `Cart` | Корзина | Корзина клиента | | `CartItem` | Позиция корзины | Конкретный выбранный товар в корзине | | `Warehouse` | Склад | Справочник складов | | `ProductStock` | Складской остаток | Остаток товара на складе | | `Order` | Заказ / заявка | Единая заказная сущность для готовой продукции и расчета | | `OrderItem` | Позиция заказа | Состав заказа | | `OrderStatusEvent` | Событие статуса заказа | История изменения статусов | | `ReferralLink` | Реферальная связь | Связь между рекомендателем и приглашенным клиентом | | `BonusTransaction` | Бонусная транзакция | Начисление или списание бонусов | | `RewardWithdrawalRequest` | Заявка на вывод бонусов | Заявка клиента на использование или вывод бонусов | ## 4.3 Служебные перечисления и статусы В модели данных используются следующие перечисления: - `UserRole`: `CLIENT`, `MANAGER`, `SUPER_MANAGER` - `RegistrationStatus`: `PENDING`, `APPROVED`, `REJECTED` - `MessengerType`: `TELEGRAM`, `MAX` - `OrderKind`: `READY`, `CALCULATION` - `OrderStatus`: `NEW`, `MANAGER_PROCESSING`, `WAITING_DOUBLE_CONFIRM`, `CLIENT_REJECTED`, `MANAGER_REJECTED`, `MANAGER_BLOCKED`, `CONFIRMED`, `IN_PROGRESS`, `COMPLETED` - `WithdrawalStatus`: `PENDING`, `APPROVED`, `REJECTED` ## 4.4 Пользователи и компании ### 4.4.1 Company Русское наименование: `Компания` Назначение: - хранение клиентской организации - объединение пользователей одной компании Основные поля: - `id` - `name` - `inn` - `createdAt` - `updatedAt` Связи: - одна компания связана со многими пользователями ### 4.4.2 User Русское наименование: `Пользователь` Назначение: - хранение клиентской, менеджерской или административной учетной записи - связывание пользователя с заказами, корзиной, бонусами и адресами Основные поля: - `id` - `email` - `fullName` - `role` - `companyId` - `defaultDeliveryAddressId` - `createdAt` - `updatedAt` Связи: - пользователь может быть связан с компанией - пользователь может иметь профиль контрагента - пользователь может иметь адреса доставки - пользователь может иметь корзину - пользователь может выступать клиентом или менеджером в заказах - пользователь может иметь бонусные операции и заявки на вывод ### 4.4.3 DeliveryAddress Русское наименование: `Адрес доставки` Назначение: - хранение адресов доставки клиента - выбор адреса по умолчанию для корзины и заказов Основные поля: - `id` - `userId` - `label` - `address` - `unrestrictedValue` - `fiasId` - `createdAt` - `updatedAt` ### 4.4.4 CounterpartyProfile Русское наименование: `Профиль контрагента` Назначение: - хранение полных реквизитов клиента для договоров, счетов и поставки Основные поля: - `id` - `userId` - `companyName` - `companyFullName` - `inn` - `kpp` - `ogrn` - `legalAddress` - `bankName` - `bik` - `correspondentAccount` - `checkingAccount` - `signerFullName` - `signerPosition` - `signerBasis` - `createdAt` - `updatedAt` ### 4.4.5 RegistrationRequest Русское наименование: `Заявка на подключение` Назначение: - хранение самостоятельной заявки клиента на подключение Основные поля: - `id` - `companyName` - `inn` - `contactName` - `email` - `status` - `rejectionReason` - `requesterId` - `reviewedById` - `createdAt` - `updatedAt` ### 4.4.6 Invitation Русское наименование: `Приглашение` Назначение: - хранение менеджерского приглашения клиента на регистрацию Основные поля: - `id` - `token` - `email` - `companyName` - `managerId` - `acceptedById` - `expiresAt` - `acceptedAt` - `createdAt` ### 4.4.7 MessengerConnection Русское наименование: `Подключение мессенджера` Назначение: - хранение подключенного Telegram или MAX-канала пользователя Основные поля: - `id` - `userId` - `type` - `channelId` - `displayName` - `username` - `avatarFileId` - `avatarFileUniqueId` - `isActive` - `createdAt` ## 4.5 Каталог и складской контур ### 4.5.1 Product Русское наименование: `Товар` Назначение: - хранение карточки товарной позиции каталога - хранение параметров товара и признаков кастомизации Основные поля: - `id` - `sku` - `name` - `productType` - `widthMm` - `lengthM` - `thicknessMicron` - `sleeveBrand` - `quantityPerBox` - `tags` - `description` - `isCustomizable` - `isActive` - `createdAt` - `updatedAt` ### 4.5.2 CatalogProductTypeSetting Русское наименование: `Настройки типа товара` Назначение: - хранение правил параметров по товарному направлению - хранение разрешений на кастомизацию Основные поля: - `id` - `productType` - `showQuantityPerBox` - `allowCustomLength` - `customLengthMinM` - `customLengthMaxM` - `customLengthStepM` - `allowCustomSleeveBrand` - `allowCustomLabel` - `widthOptionsMm` - `lengthOptionsM` - `thicknessOptionsMicron` - `sleeveOptions` - `colorOptions` - `labelOptions` - `createdAt` - `updatedAt` ### 4.5.3 Warehouse Русское наименование: `Склад` Назначение: - хранение справочника складов Основные поля: - `id` - `code` - `name` - `createdAt` - `updatedAt` ### 4.5.4 ProductStock Русское наименование: `Складской остаток` Назначение: - хранение остатка товара на конкретном складе Основные поля: - `id` - `productId` - `warehouseId` - `availableQty` - `updatedAt` ## 4.6 Корзина, заявки и заказы ### 4.6.1 Cart Русское наименование: `Корзина` Назначение: - хранение текущего набора выбранных клиентом позиций Основные поля: - `id` - `userId` - `deliveryAddressId` - `createdAt` - `updatedAt` ### 4.6.2 CartItem Русское наименование: `Позиция корзины` Назначение: - хранение одной выбранной клиентом позиции с параметрами и количеством Основные поля: - `id` - `cartId` - `productId` - `productName` - `sku` - `isCustomizable` - `quantity` - `parameters` - `createdAt` - `updatedAt` ### 4.6.3 Order Русское наименование: `Заказ / заявка` Назначение: - хранение готовой заказной заявки и расчетной заявки в единой сущности - хранение согласованных менеджером условий и статуса работы Основные поля: - `id` - `code` - `kind` - `customerId` - `deliveryAddressId` - `deliveryAddress` - `managerId` - `status` - `clientApproved` - `managerApproved` - `blockReason` - `deliveryTerms` - `deliveryFee` - `totalPrice` - `calculationPayload` - `createdAt` - `updatedAt` Комментарий к модели: - `kind = READY` означает сценарий заказа готовой продукции - `kind = CALCULATION` означает сценарий расчета индивидуальной продукции - поле `calculationPayload` хранит параметры расчетной заявки ### 4.6.4 OrderItem Русское наименование: `Позиция заказа` Назначение: - хранение состава заказа Основные поля: - `id` - `orderId` - `productId` - `productName` - `quantity` - `unitPrice` - `createdAt` ### 4.6.5 OrderStatusEvent Русское наименование: `Событие статуса заказа` Назначение: - хранение истории изменения статусов заказа или заявки Основные поля: - `id` - `orderId` - `status` - `actorUserId` - `note` - `createdAt` ## 4.7 Бонусный и реферальный контур ### 4.7.1 ReferralLink Русское наименование: `Реферальная связь` Назначение: - фиксация связи между рекомендателем и приглашенным клиентом Основные поля: - `id` - `referrerId` - `refereeId` - `createdById` - `bonusPercent` - `createdAt` ### 4.7.2 BonusTransaction Русское наименование: `Бонусная транзакция` Назначение: - хранение начисления или списания бонусов Основные поля: - `id` - `userId` - `amount` - `reason` - `orderId` - `referralLinkId` - `createdAt` ### 4.7.3 RewardWithdrawalRequest Русское наименование: `Заявка на вывод бонусов` Назначение: - хранение заявки клиента на использование или вывод бонусов Основные поля: - `id` - `requesterId` - `amount` - `status` - `reviewedById` - `reviewComment` - `createdAt` - `updatedAt` ## 4.8 Основные связи между сущностями Укрупненная структура связей определяется следующими правилами: - `Company` объединяет пользователей одной клиентской организации - `User` связан с `CounterpartyProfile`, `DeliveryAddress`, `MessengerConnection`, `Cart`, `Order`, `BonusTransaction` и `RewardWithdrawalRequest` - `Cart` содержит набор `CartItem`, привязанных к конкретным `Product` - `Order` содержит набор `OrderItem` и историю `OrderStatusEvent` - `Product` связан с остатками `ProductStock`, распределенными по сущностям `Warehouse` - настройки параметров по товарному направлению хранятся в `CatalogProductTypeSetting` - реферальные связи реализуются через `ReferralLink`, связывающий одного пользователя с другим пользователем ## 4.9 Структура хранения и модель базы данных ![Укрупненная модель базы данных](/diagrams/database-model.svg) Модель базы данных должна обеспечивать: - уникальность ключевых идентификаторов - хранение дат создания и изменения сущностей - хранение параметров товарных позиций в структурированном виде - хранение истории статусов и действий - хранение интеграционных идентификаторов для связи с внешними системами - расширение состава параметров товаров без разрушения базовой структуры ролей и заказов