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'ом |