Перейти к содержанию

P2P Service

Назначение

P2P — сервис одноранговой торговли платформы Univex: размещение объявлений, создание и выполнение ордеров, разрешение споров, обмен сообщениями, управление методами оплаты и отзывами.

Транспорт: gRPC. Количество RPC: 43. Дополнительно: Redis (pub/sub, кэш), Temporal (workflow ордеров), PostgreSQL (31 миграция).


Архитектура

┌──────────────────────────────────────────────────┐
│                  gRPC Server                     │
│               43 RPC методов                     │
└────────────────────┬─────────────────────────────┘
┌────────────────────▼─────────────────────────────┐
│               Domain Layer                       │
│  Бизнес-логика P2P-торговли                      │
└────────┬─────────────────────────┬───────────────┘
         │                         │
┌────────▼────────┐  ┌─────────────▼────────────┐
│  Storage Layer  │  │   Redis                  │
│  PostgreSQL     │  │   (pub/sub, очереди)     │
│  31 миграция    │  └──────────────────────────┘
└─────────────────┘
┌────────▼────────────────────────────────────────┐
│   Temporal Workflows                            │
│   (жизненный цикл ордера)                       │
└─────────────────────────────────────────────────┘

База данных

Миграции (31)

Таблицы охватывают все домены P2P-сервиса:

Группа Таблицы
Объявления advertisements, advertisement_events
Ордера orders, order_events, order_roles
Споры disputes, dispute_events
Чат messages, message_files
Методы оплаты payment_methods, global_payment_methods, account_payment_methods, advertisement_payment_methods, order_payment_methods
Отзывы feedback
Чёрный список blacklist
Статистика account_stats
Индексы Дополнительные индексы производительности

gRPC-контракт

Прото-файл: proto/p2p.proto

Полный список RPC (43)

service P2P {

    // Объявления (6)
    rpc CreateAdvertisement(CreateAdvertisementRequest) returns (CreateAdvertisementResponse);
    rpc ListAdvertisements(ListAdvertisementsRequest) returns (ListAdvertisementsResponse);
    rpc ListAdvertisementsByAccount(ListAdvertisementsByAccountRequest) returns (ListAdvertisementsByAccountResponse);
    rpc GetAdvertisement(GetAdvertisementRequest) returns (GetAdvertisementResponse);
    rpc UpdateAdvertisement(UpdateAdvertisementRequest) returns (UpdateAdvertisementResponse);
    rpc DeleteAdvertisement(DeleteAdvertisementRequest) returns (DeleteAdvertisementResponse);

    // Ордера (11)
    rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
    rpc ListOrders(ListOrdersRequest) returns (ListOrdersResponse);
    rpc GetOrder(GetOrderRequest) returns (GetOrderResponse);
    rpc GetPlainOrder(GetPlainOrderRequest) returns (GetPlainOrderResponse);
    rpc ListPlainOrders(ListPlainOrdersRequest) returns (ListPlainOrdersResponse);
    rpc ListOrderEvents(ListOrderEventsRequest) returns (ListOrderEventsResponse);
    rpc AcceptOrder(AcceptOrderRequest) returns (AcceptOrderResponse);
    rpc RejectOrder(RejectOrderRequest) returns (RejectOrderResponse);
    rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
    rpc CompletePayment(CompletePaymentRequest) returns (CompletePaymentResponse);
    rpc ConfirmPayment(ConfirmPaymentRequest) returns (ConfirmPaymentResponse);

    // Споры (6)
    rpc StartDispute(StartDisputeRequest) returns (StartDisputeResponse);
    rpc ListDisputes(ListDisputesRequest) returns (ListDisputesResponse);
    rpc AcceptDispute(AcceptDisputeRequest) returns (AcceptDisputeResponse);
    rpc DisputeDecision(DisputeDecisionRequest) returns (DisputeDecisionResponse);
    rpc GetDisputeByOrderId(GetDisputeByOrderIdRequest) returns (GetDisputeByOrderIdResponse);
    rpc GetDisputesByOrderIds(GetDisputesByOrderIdsRequest) returns (GetDisputesByOrderIdsResponse);

    // Статистика (1)
    rpc GetStatsByAccounts(GetStatsByAccountsRequest) returns (GetStatsByAccountsResponse);

    // Сообщения (4)
    rpc SendText(SendTextRequest) returns (SendTextResponse);
    rpc SendFile(SendFileRequest) returns (SendFileResponse);
    rpc GetMessages(GetMessagesRequest) returns (GetMessagesResponse);
    rpc GetNewMessages(GetNewMessagesRequest) returns (GetNewMessagesResponse);

    // Методы оплаты — глобальные (2)
    rpc CreateGlobalPaymentMethod(CreateGlobalPaymentMethodRequest) returns (CreateGlobalPaymentMethodResponse);
    rpc ListGlobalPaymentMethods(ListGlobalPaymentMethodsRequest) returns (ListGlobalPaymentMethodsResponse);

    // Методы оплаты — аккаунта (3)
    rpc CreateAccountPaymentMethod(CreateAccountPaymentMethodRequest) returns (CreateAccountPaymentMethodResponse);
    rpc ListAccountPaymentMethods(ListAccountPaymentMethodsRequest) returns (ListAccountPaymentMethodsResponse);
    rpc DeleteAccountPaymentMethod(DeleteAccountPaymentMethodRequest) returns (DeleteAccountPaymentMethodResponse);

    // Методы оплаты — объявления (2)
    rpc SetAdvertisementPaymentMethods(SetAdvertisementPaymentMethodsRequest) returns (SetAdvertisementPaymentMethodsResponse);
    rpc ListAdvertisementPaymentMethods(ListAdvertisementPaymentMethodsRequest) returns (ListAdvertisementPaymentMethodsResponse);

    // Методы оплаты — ордера (3)
    rpc SetOrderPaymentMethod(SetOrderPaymentMethodRequest) returns (SetOrderPaymentMethodResponse);
    rpc GetOrderPaymentMethod(GetOrderPaymentMethodRequest) returns (GetOrderPaymentMethodResponse);
    rpc ListOrderPaymentMethods(ListOrderPaymentMethodsRequest) returns (ListOrderPaymentMethodsResponse);

    // Отзывы (5)
    rpc CreateFeedback(CreateFeedbackRequest) returns (CreateFeedbackResponse);
    rpc GetFeedback(GetFeedbackRequest) returns (GetFeedbackResponse);
    rpc GetFeedbackByAccount(GetFeedbackByAccountRequest) returns (GetFeedbackByAccountResponse);
    rpc CountFeedbackByAccount(CountFeedbackByAccountRequest) returns (CountFeedbackByAccountResponse);
    rpc DeleteFeedback(DeleteFeedbackRequest) returns (DeleteFeedbackResponse);

    // Чёрный список (4)
    rpc AddToBlacklist(AddToBlacklistRequest) returns (AddToBlacklistResponse);
    rpc GetBlacklist(GetBlacklistRequest) returns (GetBlacklistResponse);
    rpc RemoveFromBlacklist(RemoveFromBlacklistRequest) returns (RemoveFromBlacklistResponse);
    rpc CheckBlacklist(CheckBlacklistRequest) returns (CheckBlacklistResponse);
}

Группы RPC

Объявления (6)

RPC Описание
CreateAdvertisement Создаёт объявление на покупку или продажу.
ListAdvertisements Публичный список объявлений с фильтрацией (актив, валюта, тип, метод оплаты).
ListAdvertisementsByAccount Объявления конкретного аккаунта.
GetAdvertisement Данные конкретного объявления.
UpdateAdvertisement Обновляет параметры объявления (цена, лимиты, методы оплаты).
DeleteAdvertisement Удаляет объявление.

Ордера (11)

RPC Описание
CreateOrder Создаёт ордер на основе объявления. Замораживает активы maker'а.
ListOrders Список ордеров с фильтрацией (статус, роль, период).
GetOrder Данные ордера с полной информацией.
GetPlainOrder Упрощённые данные ордера (без вложенных объектов).
ListPlainOrders Список упрощённых ордеров.
ListOrderEvents История событий по ордеру (смены статуса).
AcceptOrder Maker принимает ордер.
RejectOrder Maker отклоняет ордер.
CancelOrder Отмена ордера (taker или maker до принятия).
CompletePayment Taker подтверждает отправку оплаты.
ConfirmPayment Maker подтверждает получение оплаты → ордер завершается, активы размораживаются.

Споры (6)

RPC Описание
StartDispute Открывает спор по ордеру (доступно после CompletePayment).
ListDisputes Список всех споров (для арбитров).
AcceptDispute Арбитр принимает спор в работу.
DisputeDecision Арбитр выносит решение по спору.
GetDisputeByOrderId Получить спор по ID ордера.
GetDisputesByOrderIds Получить споры по нескольким ID ордеров.

Статистика (1)

RPC Описание
GetStatsByAccounts Статистика P2P-активности по аккаунтам (количество ордеров, оборот, рейтинг).

Сообщения (4)

RPC Описание
SendText Отправляет текстовое сообщение в чат ордера.
SendFile Отправляет файл (скриншот оплаты и т.д.) в чат ордера.
GetMessages Возвращает историю сообщений ордера с пагинацией.
GetNewMessages Возвращает новые сообщения (с момента последней проверки).

Методы оплаты (10)

RPC Группа Описание
CreateGlobalPaymentMethod Глобальные Создаёт глобальный метод оплаты (справочник).
ListGlobalPaymentMethods Глобальные Список глобальных методов оплаты.
CreateAccountPaymentMethod Аккаунта Добавляет метод оплаты к аккаунту (реквизиты).
ListAccountPaymentMethods Аккаунта Список методов оплаты аккаунта.
DeleteAccountPaymentMethod Аккаунта Удаляет метод оплаты аккаунта.
SetAdvertisementPaymentMethods Объявления Устанавливает методы оплаты для объявления.
ListAdvertisementPaymentMethods Объявления Список методов оплаты объявления.
SetOrderPaymentMethod Ордера Устанавливает выбранный метод оплаты для ордера.
GetOrderPaymentMethod Ордера Получить метод оплаты ордера.
ListOrderPaymentMethods Ордера Доступные методы оплаты для ордера.

Отзывы (5)

RPC Описание
CreateFeedback Оставить отзыв о контрагенте после завершения ордера.
GetFeedback Получить отзыв по ID.
GetFeedbackByAccount Список отзывов об аккаунте.
CountFeedbackByAccount Количество положительных/отрицательных отзывов.
DeleteFeedback Удалить отзыв (администратором).

Чёрный список (4)

RPC Описание
AddToBlacklist Добавить пользователя в чёрный список (не показывать объявления).
GetBlacklist Список заблокированных пользователей.
RemoveFromBlacklist Удалить из чёрного списка.
CheckBlacklist Проверить, заблокирован ли пользователь.

Перечисления

AdvertisementType

enum AdvertisementType {
    ADVERTISEMENT_TYPE_UNSPECIFIED = 0;
    BUY                            = 1;  // Покупка криптовалюты
    SELL                           = 2;  // Продажа криптовалюты
}

OrderStatus (15 состояний)

enum OrderStatus {
    ORDER_STATUS_UNSPECIFIED         = 0;
    CREATED                          = 1;   // Ордер создан, ожидает принятия
    ACCEPTED                         = 2;   // Maker принял ордер
    PROCESSING                       = 3;   // В обработке
    PAYMENT_COMPLETED                = 4;   // Taker подтвердил оплату
    PAYMENT_CONFIRMED                = 5;   // Maker подтвердил получение
    SUCCESS                          = 6;   // Ордер завершён
    CANCELLED                        = 7;   // Отменён
    REJECTED                         = 8;   // Отклонён maker'ом
    DISPUTE_START                    = 9;   // Спор открыт
    DISPUTE_DECISION_AWAITING        = 10;  // Арбитр принял спор, ждёт решения
    DISPUTE_DECIDED                  = 11;  // Решение вынесено
    EXPIRED                          = 12;  // Истёк срок ожидания
    FAILED                           = 13;  // Ошибка выполнения
    FROZEN                           = 14;  // Активы заморожены (AML)
}

OrderRole

enum OrderRole {
    ORDER_ROLE_UNSPECIFIED = 0;
    MAKER                  = 1;  // Создатель объявления
    TAKER                  = 2;  // Инициатор ордера
}

DisputeDecision

enum DisputeDecision {
    DISPUTE_DECISION_UNSPECIFIED = 0;
    ACCEPTED                     = 1;  // Решение в пользу открывшего спор
    REJECTED                     = 2;  // Решение в пользу противоположной стороны
}

MessageType

enum MessageType {
    MESSAGE_TYPE_UNSPECIFIED = 0;
    TEXT                     = 1;  // Текстовое сообщение
    FILE                     = 2;  // Файл (изображение)
}

Жизненный цикл P2P-ордера

stateDiagram-v2
    [*] --> CREATED : CreateOrder

    CREATED --> ACCEPTED : AcceptOrder (maker)
    CREATED --> REJECTED : RejectOrder (maker)
    CREATED --> CANCELLED : CancelOrder (taker)
    CREATED --> EXPIRED : Timeout

    ACCEPTED --> PROCESSING : Taker выбирает метод оплаты
    ACCEPTED --> CANCELLED : CancelOrder

    PROCESSING --> PAYMENT_COMPLETED : CompletePayment (taker)
    PROCESSING --> CANCELLED : CancelOrder

    PAYMENT_COMPLETED --> PAYMENT_CONFIRMED : ConfirmPayment (maker)
    PAYMENT_COMPLETED --> DISPUTE_START : StartDispute

    PAYMENT_CONFIRMED --> SUCCESS : Активы разморожены

    DISPUTE_START --> DISPUTE_DECISION_AWAITING : AcceptDispute (арбитр)

    DISPUTE_DECISION_AWAITING --> DISPUTE_DECIDED : DisputeDecision (арбитр)

    DISPUTE_DECIDED --> SUCCESS : Решение в пользу taker
    DISPUTE_DECIDED --> CANCELLED : Решение в пользу maker

    SUCCESS --> [*]
    CANCELLED --> [*]
    REJECTED --> [*]
    EXPIRED --> [*]
    FAILED --> [*]

Temporal Workflows

Workflow Описание
OrderWorkflow Управляет жизненным циклом ордера: тайм-ауты, переходы состояний, автоматические действия.
OrderExpiryWorkflow Отслеживает истечение времени ожидания принятия/оплаты.
DisputeWorkflow Управляет жизненным циклом спора: уведомления арбитров, дедлайн решения.

Redis

Redis используется для:

  • Pub/Sub: оповещение Gateway о новых сообщениях в ордерах (WebSocket push).
  • Кэш активных ордеров: быстрый доступ к состоянию текущих ордеров.
  • Счётчики: статистика онлайн-пользователей в P2P.

Конфигурация

Параметр Описание
DATABASE_URL DSN для подключения к PostgreSQL
REDIS_URL Адрес Redis
GRPC_PORT Порт gRPC-сервера
TEMPORAL_HOST Адрес Temporal-сервера
TEMPORAL_NAMESPACE Namespace в Temporal
LEDGER_GRPC_ADDR Адрес Ledger gRPC (для заморозки/разморозки активов)
ORDER_ACCEPT_TIMEOUT Тайм-аут принятия ордера maker'ом
PAYMENT_TIMEOUT Тайм-аут оплаты taker'ом