Архитектура сделок
Архитектура сделок в FirstWork построена вокруг сущности work_processed, которая описывает состояние конкретной сделки между двумя пользователями в контексте покупки работы. Каждая сделка проходит через набор стадий, а все ключевые операции выполняются внутри транзакций базы данных с блокировками строк, что исключает гонки и повторные действия.
Создание сделки начинается в момент покупки работы. При оформлении покупки выполняется проверка доступного баланса, запрет на покупку собственной работы, запрет на одновременное ведение нескольких заказов у одного и того же исполнителя, а также защита от повторной покупки той же работы. Если все проверки проходят успешно, создается запись в таблице works_transact_orders с уникальным ключом сделки и солью, а также запись в work_processed со стадией один. На этом этапе деньги списываются с баланса покупателя, создаются транзакции для покупателя и исполнителя, рассчитывается комиссия и профит, а также отправляется служебное сообщение в диалог. Средства фактически блокируются в системе и становятся объектом дальнейшей логики сделки.
Стадия один означает, что сделка активна и ожидает результата. На этом этапе возможны два ключевых сценария. Первый сценарий — подтверждение успешного выполнения работы. Второй — открытие спора. Подтверждение выполнения сделки или её завершение всегда привязано к ключу сделки из works_transact_orders. Этот ключ используется как защита от подмены параметров. Дополнительно предусмотрена возможность принудительного управления сделкой через флаг manage_deal у системных ролей, что позволяет арбитру или модератору завершать сделку независимо от ключа.
При подтверждении успешного выполнения сделки выполняется переход в стадию два. Операция проводится внутри транзакции с блокировкой строки сделки. Проверяется, что стадия сделки позволяет выполнить действие и что сумма сделки положительна. Затем проверяется валидность ключа или наличие права управления сделкой. После этого рассчитывается комиссия и профит, пользователю-исполнителю начисляется его доля, а комиссия проекта фиксируется в транзакциях и добавляется в общую прибыль проекта. Если по сделке был открыт спор, он закрывается. В таблице транзакций обновляются записи, отражающие финальное распределение средств. Стадия сделки обновляется на два, фиксируется время закрытия, ключ сделки удаляется, а в чат отправляется служебное сообщение о подтверждении выполнения заказа.
Открытие спора возможно только из стадии один. При открытии спора создается запись в таблице disputes, где фиксируется инициатор, связанная сделка и текст причины. После этого в чат отправляется сообщение с указанием суммы, номера сделки и причины спора, а стадия сделки переводится в состояние четыре. Стадия четыре обозначает, что сделка находится в споре и дальнейшие действия должны выполняться либо через арбитраж, либо через подтверждение или отмену с учетом прав и ключа.
Завершение сделки с отказом от выполнения или отменой возможно из стадии четыре. В этом случае выполняется проверка валидности действия по ключу сделки или по правам управления. При успешной проверке деньги возвращаются на баланс соответствующей стороны, спор закрывается, транзакции обновляются так, чтобы отразить возврат средств, а стадия сделки переводится в три с фиксацией времени закрытия. Стадия три обозначает завершенную сделку, по которой произведен возврат или отмена. Ключ сделки удаляется, а в чат отправляется служебное сообщение о том, что заказ отменен и деньги возвращены.
Отдельно реализован сценарий возврата средств после подтверждения сделки. Он применяется, когда сделка уже была переведена в стадию два, но требуется откат с перераспределением средств. В этом случае выполняется проверка стадии, проверка кулдауна, пересчет комиссии и прибыли, корректировка общей прибыли проекта, списание средств с одной стороны и возврат другой, обновление транзакций и перевод сделки в стадию три. Этот механизм позволяет арбитру корректно завершать спорные ситуации даже после формального завершения сделки.
Во всех операциях с деньгами и стадиями сделок используется явное начало транзакции, блокировка строки сделки через select for update, проверки текущей стадии и обязательный commit или rollback. Это гарантирует целостность данных, предотвращает повторные действия по одной и той же сделке и исключает расхождения между балансами пользователей, транзакциями и состоянием сделки. Архитектура сделок таким образом представляет собой строго детерминированную модель с фиксированными стадиями, жесткими проверками и явным управлением денежными потоками через транзакции и таблицу транзакций.