Есть свое видение, как это реализовать. Но хотел услышать ваши замечания и если кто с таким сталкивался, то поделитесь опытом.
Представим что есть некий магазин, где можно купить услуги разного рода. Некий аналог AppStore.
Есть 3 вида пользователей:
1. клиент
2. компания,которая предоставляет услугу
3. исполнитель или сотрудник этой компании
Клиент покупает у компании услугу, а компания разбивает услугу на разные работы, которых делают исполнители.
Получается есть несколько видов движений денежной массы:
1. пополнение счета клиентом
2. оплата за услуги
3. полный/частичный возврат денег клиенту
4. оплата за работу сотрудника
5. вывод денег клиентом/сотрудником
Основная задача: отследить, что за деньги выводит клиент/сотрудник.
Идея была следующая:
1. любое движение фиксируем в некий базе, в которую можно только добавлять
2. вводим операции объединить и разделить. допустим клиент пополнил баланс на 100,а потом на 200 руб, и купил услугу за 250. Соответственно делаем операцию разъединения 100 на 50 и 50. Далее операция объединения 50 и 200. И оплата этой суммой за услуги.
3. любое объединение/разъединение имеет родителей, т.е. на кого то ссылается. это должны сохранить.
4. при операции оплата, происходит смена владельца этих денег
Продолжая так логику, получаю такой результат. Если пользователь решил вывести деньги, то по базе смотрим все строки, у которых владелец данный пользователь. Суммируем и показываем какую сумму он может выводить.
После того как он указал определенную сумму, менеджер, который ответственен за обналичивание, смотрит всю цепочку, удостоверяется, что деньги реальные, а не кто-то достал их из воздуха. Дает добро. И у этих денег владелец удаляется, т.е. они из системы исчезают.
При таком подходе можно и программно проверить, не появились ли виртуальные деньги, в результате некого взлома сайта/БД.
ТЗ на курсовик по БД похоже.
Если же это действительно для бизнеса нужно, то скорее всего такой велосипед кто-то уже реализовал - наверняка у какого-нибудь 1с есть подходящее решение.
AigizK Согласно вашей логике, любая сумма попавшая в БД через ввод денег(пометка "пополнение счета клиентом") считается "нормальными деньгами". Особой разницы с черным ящиком нет, по сути вы описываете транзакции виртуального счета.
"При таком подходе можно и программно проверить, не появились ли виртуальные деньги, в результате некого взлома сайта/БД."
Проверить можно, только если текущий баланс пофиксили, а если себе несколько новых цепочек транзакций нарисовали или увели с чужого счета - то уже нет.
"Дает добро. И у этих денег владелец удаляется, т.е. они из системы исчезают." - Т.е. виртуальный счет закрывается и связанные с ним транзакции удаляются.
А что делать в случае сбоя, когда деньги "зависают" т.е. с виртуального счета списались, а на реальном остались?
Не совсем так. Во первых я использую не реляционную БД, а список событий(Event Store). Пополнение счета - это событие. Я могу сделать отдельную таблицу из событий, когда кем были пополнены счета и сравнить их с таблицей,которую могу получить из банка. Соответственно при выводе денег я и должен знать, откуда она появилась. Мне достаточно знать общую сумму, которую перечислили на счет в банке и сравнить его с суммами, которых внесли на счет клиентов. Как только появится разница, можно запустить проверку и найти "не правильные деньги".
Проверка опять же осуществляется легко, т.к. у меня изначально все события сохраняются и их не возможно удалить. Тут возможен другой случай: увели деньги клиента. Но деньги клиента может снять либо сама компания, либо сотрудники. У клиента будет история всех списаний, поэтому он может пожаловаться, мы проведем проверку и если услуга никакая не была выполнена, то компания эта и возместит ущерб.
По поводу зависаний. Перевод на другой счет - это одно событие. Поэтому если событие в базу записали, значит у кого то спишется, а у кого то прибавятся эти деньги.
Теперь по поводу "черного ящика". В моем случае ее и не должно быть. У каждого события есть уникальный ИД. Поэтому это будет работать примерно так:
1. клиент пополнил баланс на 100 руб - создали событие "баланс пополнен"
2. клиент заказал услугу на 50 руб -
а)пробегаемся по всем событиям и ищем,есть ли отдельная сумма у клиента 50 руб, таких нет
б)создали событие "разделить сумму", у события указываем родительское событие, и два числа, на которых разбили
в)создаем событие "заказана услуга", указываем ИД услуги, сумму и ИД события из п.А, т.е. оттуда сняли одно из чисел.
3.клиент заказал еще раз услугу за 50 руб -
а)пробегаемся по всем событиям и видм что есть отдельная сумма на 50 руб,которую получили в 2Б.
б)создаем событие "заказана услуга", указываем ИД услуги, сумму и ИД события из п.А
4.работники выполнили задачу и менеджер отмечает выполнено
а)создаем событие "задача выполнена", указываем сумму, ИД события с оплатой за эту работу
5.сотрудник хочет обналичивать деньги - пробегаемся по все событиям "задача выполнена" и для каждого создаем событие "деньги выданы", указав ИД события "задача выполнена". И эту сумму выдаем.
При этом менеджер по ИД может проследить всю цепочку, вплоть до пополнения счета.
И я какую-то часть программно могу проверить, не появились ли "левые" события.Например если за услугу деньги перевели 1 раз сотруднику и эту же операцию пытаются повторить еще раз.
Единственный случай, когда не смогу, это если взломщик восстановит всю цепочку, с момента покупки услуги до вывода денег разработчику. Но в этом случае клиент сам может заметить, что были списания с его счета и после проверок деньги свои он получит.
Да нет. В 1С в студенческие годы программировал. Так что, как работает бух.программы, я знаю. Там нет возможности отследить, откуда именно эта сумма получилась. Там грубо говоря в черный ящик кидают деньги, которые пришли в систему и оттуда вытаскивают случайном образом нужную сумму.
В какой-то степени мне нужно реализовать то, что есть у биткоина. А именно взяв любую строку из денежной массы, мог получить все связанные предыдущие операции и тем самым мог выяснить, нормальные деньги или нет.