xync-db 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .env
6
+ .venv/
7
+ venv/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ htmlcov/
13
+ dist/
14
+ build/
15
+
16
+ # uv
17
+ .uv-cache/
18
+
19
+ # Node
20
+ node_modules/
21
+ packages/xync-web/dist/
22
+ packages/xync-web/.vite/
23
+
24
+ # Env
25
+ .env
26
+ .env.local
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Generated
38
+ packages/xync-web/src/api/schema.gen.ts
39
+ openapi.json
40
+
41
+ # Claude state (board) — track this in git, but ignore live edits if user prefers:
42
+ # .claude/state/log.md # uncomment to ignore the journal
xync_db-0.0.2/PKG-INFO ADDED
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: xync-db
3
+ Version: 0.0.2
4
+ Summary: Xync DB schema: Tortoise ORM models, enums, pydantic DTOs.
5
+ Author-email: Mike Artemiev <mixartemev@gmail.com>
6
+ License: LicenseRef-EULA
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: cryptography
9
+ Requires-Dist: pillow
10
+ Requires-Dist: pydantic-settings>=2.4
11
+ Requires-Dist: pypng
12
+ Requires-Dist: python-dotenv
13
+ Requires-Dist: qrcode[pil]
14
+ Requires-Dist: tortoise-orm[asyncpg]>=1.0
15
+ Requires-Dist: xn-auth
16
+ Description-Content-Type: text/markdown
17
+
18
+ # xync-db
19
+
20
+ Tortoise ORM models, enums, pydantic DTOs, and migrations. Single source of truth for
21
+ data shape across the monorepo.
22
+
23
+ ## Migrations (native Tortoise CLI — no aerich)
24
+
25
+ ```bash
26
+ cd packages/xync-db
27
+ uv run tortoise init # only once
28
+ uv run tortoise makemigrations # detect changes
29
+ uv run tortoise migrate # apply
30
+ uv run tortoise downgrade models 0001_initial # roll back
31
+ uv run tortoise sqlmigrate models 0001_initial # preview SQL
32
+ ```
33
+
34
+ Config lives in this package's `pyproject.toml` under `[tool.tortoise]`.
@@ -0,0 +1,17 @@
1
+ # xync-db
2
+
3
+ Tortoise ORM models, enums, pydantic DTOs, and migrations. Single source of truth for
4
+ data shape across the monorepo.
5
+
6
+ ## Migrations (native Tortoise CLI — no aerich)
7
+
8
+ ```bash
9
+ cd packages/xync-db
10
+ uv run tortoise init # only once
11
+ uv run tortoise makemigrations # detect changes
12
+ uv run tortoise migrate # apply
13
+ uv run tortoise downgrade models 0001_initial # roll back
14
+ uv run tortoise sqlmigrate models 0001_initial # preview SQL
15
+ ```
16
+
17
+ Config lives in this package's `pyproject.toml` under `[tool.tortoise]`.
@@ -0,0 +1,111 @@
1
+ """PG triggers migration. Ported from the original `migrations/0003_triggers.py` and
2
+ `0008_ad_triggers.py`. These define the NOTIFY-emitting triggers that service-internal
3
+ consumes.
4
+
5
+ Channels emitted:
6
+ after_orders_new -- new order, no hot_id
7
+ hot_order_new -- order acquired hot_id (insert or update)
8
+ hot_order_upd_status -- hot order status change
9
+ after_orders_upd_status -- non-hot order status change
10
+ agents_upd_status -- agent status toggle
11
+ actor_person_needs_def_user -- new actor needs person assignment
12
+ after_users_new -- new user (also creates person + xync-actor)
13
+
14
+ Plus utility functions: _user_balance(uid, cid), _tx_pack(...).
15
+ """
16
+
17
+ from tortoise.migrations.migration import Migration as BaseMigration
18
+ from tortoise.migrations.operations import RunSQL
19
+
20
+ TRIGGERS_SQL = r"""
21
+ -- before new Actor
22
+ CREATE OR REPLACE FUNCTION actor_new() returns trigger as $actor_new_trg$
23
+ DECLARE
24
+ p_id INT;
25
+ BEGIN
26
+ IF NEW.person_id IS NULL THEN
27
+ INSERT INTO person (status) VALUES (0) RETURNING id INTO p_id;
28
+ ELSIF (SELECT status FROM person WHERE id = NEW.person_id) = -1 THEN
29
+ PERFORM pg_notify('actor_person_needs_def_user', row_to_json(NEW)::varchar);
30
+ END IF;
31
+ RETURN NEW;
32
+ END
33
+ $actor_new_trg$ LANGUAGE plpgsql;
34
+ CREATE OR REPLACE TRIGGER actor_new BEFORE INSERT ON "actor" FOR EACH ROW EXECUTE FUNCTION actor_new();
35
+
36
+ -- after new User: create person with name=user.first_name actor
37
+ CREATE OR REPLACE FUNCTION user_new() returns trigger as $user_new_trg$
38
+ DECLARE
39
+ p_id INT;
40
+ BEGIN
41
+ INSERT INTO person (user_id) VALUES (NEW.id) RETURNING id INTO p_id;
42
+ INSERT INTO actor (exid, name, ex_id, person_id) VALUES (NEW.username_id, NEW.id, 0, p_id);
43
+ PERFORM pg_notify('after_users_new', row_to_json(NEW)::varchar);
44
+ RETURN NULL;
45
+ END
46
+ $user_new_trg$ LANGUAGE plpgsql;
47
+ CREATE OR REPLACE TRIGGER user_new AFTER INSERT ON "user" FOR EACH ROW EXECUTE FUNCTION user_new();
48
+
49
+ -- after new Order: notify
50
+ CREATE OR REPLACE FUNCTION order_new() returns trigger as $order_new_trg$
51
+ BEGIN
52
+ IF NEW.hot_id IS NOT NULL THEN
53
+ PERFORM pg_notify('hot_order_new', row_to_json(NEW)::varchar);
54
+ RETURN NULL;
55
+ END IF;
56
+ PERFORM pg_notify('after_orders_new', row_to_json(NEW)::varchar);
57
+ RETURN NULL;
58
+ END
59
+ $order_new_trg$ LANGUAGE plpgsql;
60
+ CREATE OR REPLACE TRIGGER order_new AFTER INSERT ON "order" FOR EACH ROW EXECUTE FUNCTION order_new();
61
+
62
+ -- after Order status upd: notify (hot or not)
63
+ CREATE OR REPLACE FUNCTION order_upd() returns trigger as $order_upd_trg$
64
+ BEGIN
65
+ IF OLD.hot_id ISNULL AND NEW.hot_id::bool THEN
66
+ PERFORM pg_notify('hot_order_new', row_to_json(NEW)::varchar);
67
+ ELSIF OLD.status != NEW.status THEN
68
+ PERFORM pg_notify((
69
+ CASE WHEN NEW.hot_id::bool THEN 'hot_order' ELSE 'after_orders' END
70
+ ) || '_upd_status', jsonb_build_array(row_to_json(NEW), OLD.status)::varchar);
71
+ END IF;
72
+ RETURN NULL;
73
+ END
74
+ $order_upd_trg$ LANGUAGE plpgsql;
75
+ CREATE OR REPLACE TRIGGER order_upd AFTER UPDATE ON "order" FOR EACH ROW EXECUTE FUNCTION order_upd();
76
+
77
+ -- agent status toggle
78
+ CREATE OR REPLACE FUNCTION agent_upd() returns trigger as $agent_upd_trg$
79
+ BEGIN
80
+ IF OLD.status != NEW.status THEN
81
+ PERFORM pg_notify('agents_upd_status', jsonb_build_array(row_to_json(NEW), OLD.status)::varchar);
82
+ END IF;
83
+ RETURN NULL;
84
+ END
85
+ $agent_upd_trg$ LANGUAGE plpgsql;
86
+ CREATE OR REPLACE TRIGGER agent_upd AFTER UPDATE ON "agent" FOR EACH ROW EXECUTE FUNCTION agent_upd();
87
+
88
+ -- new credential
89
+ CREATE OR REPLACE FUNCTION cred_new() returns trigger as $cred_new_trg$
90
+ BEGIN
91
+ PERFORM pg_notify('creds_new', row_to_json(NEW)::varchar);
92
+ RETURN NULL;
93
+ END
94
+ $cred_new_trg$ LANGUAGE plpgsql;
95
+ CREATE OR REPLACE TRIGGER cred_new AFTER INSERT ON "cred" FOR EACH ROW EXECUTE FUNCTION cred_new();
96
+
97
+ -- user balance (cur_id) for XyncPay tx integrity
98
+ CREATE OR REPLACE FUNCTION _user_balance(uid int, cid int) RETURNS int AS $ubalance$
99
+ SELECT COALESCE(SUM(total)::int, 0)
100
+ FROM (SELECT SUM(amount) AS total FROM transaction
101
+ WHERE status = 2 AND receiver_id = uid AND cur_id = cid
102
+ UNION ALL
103
+ SELECT -SUM(amount) AS total FROM transaction
104
+ WHERE status >= 1 AND sender_id = uid AND cur_id = cid) a;
105
+ $ubalance$ LANGUAGE sql STABLE;
106
+ """
107
+
108
+
109
+ class Migration(BaseMigration):
110
+ dependencies: list = [] # populated by db agent once initial schema migration exists
111
+ operations = [RunSQL(TRIGGERS_SQL)]
@@ -0,0 +1 @@
1
+ """Tortoise native migration files live here. Generated by `tortoise makemigrations`."""
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "xync-db"
3
+ description = "Xync DB schema: Tortoise ORM models, enums, pydantic DTOs."
4
+ readme = "README.md"
5
+ license = { text = "LicenseRef-EULA" }
6
+ authors = [{ name = "Mike Artemiev", email = "mixartemev@gmail.com" }]
7
+ requires-python = ">=3.12"
8
+ dynamic = ["version"]
9
+ dependencies = [
10
+ "tortoise-orm[asyncpg]>=1.0",
11
+ "pydantic-settings>=2.4",
12
+ "cryptography",
13
+ "python-dotenv",
14
+ "qrcode[pil]",
15
+ "xn-auth",
16
+ "pillow",
17
+ "pypng",
18
+ ]
19
+
20
+ [build-system]
21
+ requires = ["hatchling", "hatch-vcs"]
22
+ build-backend = "hatchling.build"
23
+
24
+ [tool.hatch.version]
25
+ source = "vcs"
26
+ fallback-version = "0.0.0"
27
+
28
+ [tool.hatch.version.raw-options]
29
+ root = "../.."
30
+ search_parent_directories = true
31
+ tag_regex = '^xync-db-v(?P<version>\d+\.\d+\.\d+)$'
32
+ git_describe_command = ["git", "describe", "--dirty", "--tags", "--long", "--match", "xync-db-v*"]
33
+ local_scheme = "no-local-version"
34
+ version_scheme = "guess-next-dev"
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/xync_db"]
38
+
39
+ [tool.hatch.build.targets.sdist]
40
+ include = ["src/xync_db", "migrations", "README.md", "pyproject.toml"]
41
+
42
+ [tool.tortoise]
43
+ config = "xync_service.config.TORTOISE_ORM"
44
+
45
+ [dependency-groups]
46
+ dev = ["pytest>=8", "pytest-asyncio>=0.24", "testcontainers[postgres]>=4.8"]
@@ -0,0 +1,28 @@
1
+ from os import getenv as env
2
+
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+ TORM = {
8
+ "connections": {"default": env("DB_URL")},
9
+ "apps": {"models": {"models": ["xync_db.models"]}},
10
+ "use_tz": False,
11
+ "timezone": "UTC",
12
+ }
13
+
14
+
15
+ async def main():
16
+ import logging
17
+ from logging import DEBUG
18
+
19
+ from x_model import init_db
20
+
21
+ logging.basicConfig(level=DEBUG)
22
+ await init_db(TORM, create_tables=True)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ from asyncio import run
27
+
28
+ run(main())
@@ -0,0 +1,18 @@
1
+ """Tortoise ORM configuration. Used by the CLI and by service lifecycle hooks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ POSTGRES_DSN = os.getenv("POSTGRES_DSN", "postgres://xync:xync@localhost:5432/xync")
8
+
9
+ TORTOISE_ORM: dict = {
10
+ "connections": {"default": POSTGRES_DSN},
11
+ "apps": {
12
+ "models": {
13
+ "models": ["xync_db.models", "xync_db.migrations.models"],
14
+ "default_connection": "default",
15
+ "migrations": "xync_db.migrations.models",
16
+ },
17
+ },
18
+ }
@@ -0,0 +1,311 @@
1
+ from enum import IntEnum
2
+
3
+ ZERO_TS = 1770000000 # Feb 02 2026 02:40:00 (UTC)
4
+
5
+
6
+ class PersonStatus(IntEnum):
7
+ VIP = 2
8
+ DEFAULT = 1
9
+ ANONYMOUS = 0
10
+ USER_DEF = -1
11
+ BLOCKED = -2
12
+
13
+
14
+ class Side(IntEnum):
15
+ BUY = 0
16
+ SALE = 1
17
+
18
+
19
+ class PriceType(IntEnum):
20
+ FIX = 0
21
+ FLOAT = 1
22
+
23
+
24
+ class TransactionStatus(IntEnum):
25
+ request = 0 # no proof
26
+ signed = 1 # in proof: sender sign for transfer
27
+ verified = 2 # in proof: validator sign for transfer is valid
28
+
29
+
30
+ class LinkType(IntEnum):
31
+ ref = 0 # open or trusted
32
+ request = 1 # open or personalized
33
+ receipt = 2 # signed or verified
34
+ contract = 3 # todo
35
+
36
+
37
+ class UserStatus(IntEnum):
38
+ SLEEP = 0
39
+ PAY = 1
40
+ HOT_PARTNER = 2 # partner
41
+ XYNC_TEAM = 3
42
+
43
+
44
+ class AdStatus(IntEnum):
45
+ defActive = 0
46
+ active = 1
47
+ soldOut = 2
48
+ old = 3
49
+ notFound = 9
50
+
51
+
52
+ class HotStatus(IntEnum):
53
+ closed = 0
54
+ opened = 1
55
+
56
+
57
+ class OrderStatus(IntEnum):
58
+ created = 1
59
+ paid = 2
60
+ completed = 3
61
+ cancel_requested_by_seller = 4
62
+ canceled = 5
63
+ appealed_by_seller = 6
64
+ appealed_by_buyer = 7
65
+ appeal_disputed = 8
66
+ # todo: 8T - один вирт экшн на бездействие обеих сторон, а 12T и 13T - по отдельности?
67
+ # COMPLETED, PENDING, TRADING, BUYER_PAYED, DISTRIBUTING, COMPLETED, IN_APPEAL, CANCELLED, CANCELLED_BY_SYSTEM
68
+
69
+
70
+ class OrderErr(IntEnum):
71
+ ok = 0
72
+ i_wait_for_release = 1
73
+ payments_exists_on_cancel = 2
74
+ taker_balance_deficit = 3
75
+ # negative results is for agent
76
+ maker_balance_deficit = -4
77
+ uncompleted_orders = 5
78
+ wrong_status_for_hot = -6
79
+ cant_cancel = 7
80
+
81
+
82
+ class OrderAction(IntEnum):
83
+ # requested
84
+ taker_create = 1
85
+ wait_for_cancel = 0
86
+ # created
87
+ buyer_pay = 2
88
+ seller_confirm = 3
89
+ buyer_cancel = 4
90
+ # paid
91
+ wait_for_pay = 5
92
+ seller_appeal = 6
93
+ buyer_appeal = 7
94
+ # appealed by seller
95
+ buyer_dispute_appeal_s = 8
96
+ buyer_agree_appeal_s = 10 # cancel
97
+ wait_appeal_s = 12 # -> cancel
98
+ # appealed by buyer
99
+ seller_dispute_appeal_b = 9
100
+ seller_agree_appeal_b = 11 # confirm
101
+ wait_appeal_b = 13 # -> confirm
102
+ wait_disputed_appeal = 14 # ?
103
+
104
+
105
+ class CoinType(IntEnum):
106
+ normal = 1
107
+ game = 2
108
+ corp = 3
109
+ stock = 4
110
+
111
+
112
+ class ExType(IntEnum):
113
+ p2p = 1
114
+ cex = 2
115
+ main = 3 # p2p+cex
116
+ dex = 4
117
+ tg = 5
118
+ futures = 8
119
+
120
+
121
+ class DepType(IntEnum):
122
+ earn = 1
123
+ stake = 2
124
+ beth = 3
125
+ lend = 4
126
+
127
+
128
+ class AddrExType(IntEnum):
129
+ spot = 1
130
+ earn = 2
131
+ found = 3
132
+
133
+
134
+ class TradeType(IntEnum):
135
+ BUY = 0
136
+ SELL = 1
137
+
138
+
139
+ class PmType(IntEnum):
140
+ common = 0
141
+ bank_acc = 1 # no. or IBAN
142
+ emoney = 2 # QR / phone-based
143
+ cash = 3 # ваучеры / агентские
144
+ card = 4 # fintech/processing
145
+ local = 5 # региональные: bank_routing-based: IFSC(Индия), CLABE(Мексика), банк.коды ЛатАм
146
+
147
+
148
+ class TaskType(IntEnum):
149
+ invite_approve = 1
150
+ order_user_define = 2
151
+
152
+
153
+ class FileType(IntEnum):
154
+ pdf = 1
155
+ jpg = 2
156
+ png = 3
157
+ webp = 4
158
+ mov = 5
159
+ mp4 = 6
160
+ gif = 7
161
+ svg = 8
162
+ tgs = 9
163
+ jpeg = 10
164
+
165
+
166
+ class AgentStatus(IntEnum):
167
+ off = 0
168
+ race = 1
169
+ listen = 2
170
+ race_listen = 3
171
+ # ... = 4
172
+
173
+
174
+ class SynonymType(IntEnum):
175
+ name = 1
176
+ ppo = 2
177
+ from_party = 3
178
+ to_party = 4
179
+ slip_req = 5
180
+ slip_send = 6
181
+ abuser = 7
182
+ scale = 8
183
+ slavic = 9
184
+ mtl_like = 10
185
+ bank = 11
186
+ bank_side = 12
187
+ sbp_strict = 13
188
+ contact = 14
189
+
190
+
191
+ class Boundary(IntEnum):
192
+ no = 0
193
+ left_word = 1
194
+ right_word = 2
195
+ both_word = 3
196
+ left_all = 4
197
+ right_all = 5
198
+ both_all = 6
199
+
200
+
201
+ class SbpStrict(IntEnum):
202
+ no = 0
203
+ sbp = 1
204
+ card = 2
205
+
206
+
207
+ class Party(IntEnum):
208
+ fst = 0
209
+ fam = 1
210
+ lk = 2 # lk-photo/video/comment
211
+ trd = 3
212
+
213
+
214
+ class Slip(IntEnum):
215
+ no = 0
216
+ screen = 1
217
+ pdf = 2
218
+ pdf_mail = 3
219
+
220
+
221
+ class NameType(IntEnum):
222
+ no_slavic = 0
223
+ slavic = 1
224
+ fake = 2
225
+
226
+
227
+ class AbuserType(IntEnum):
228
+ no = 0
229
+ rating = 1 # рейтинг: жмет "Оплачено" сразу, "Отмена" по апелляции
230
+ fake = 2 # реклама
231
+ cash = 3 # типа кэш обменник, но хз
232
+
233
+
234
+ class ExStatus(IntEnum):
235
+ plan = 0
236
+ parted = 1
237
+ full = 2
238
+
239
+
240
+ class ExAction(IntEnum):
241
+ """Order"""
242
+
243
+ get_orders = 0 # Получение заявок за заданное время, в статусе, по валюте, монете, направлению: `get_orders(status=OrderStatus.active, coin='USDT', cur='RUB', is_sell=False) => [order]`
244
+ order_request = 1 # [T] Запрос на старт сделки
245
+ order_request_ask = -1 # [M] - Запрос мейкеру на сделку
246
+ cancel_request = 2 # [T] Отмена запроса на сделку
247
+ request_canceled = -2 # [M] - Уведомление об отмене запроса на сделку
248
+ accept_request = 3 # [M] Одобрить запрос на сделку
249
+ request_accepted = -3 # [T] Уведомление об одобрении запроса на сделку
250
+ reject_request = 4 # [M] Отклонить запрос на сделку
251
+ request_rejected = -4 # [T] Уведомление об отклонении запроса на сделку
252
+ mark_payed = 5 # [B] Перевод сделки в состояние "оплачено", с отправкой чека
253
+ payed = -5 # [S] Уведомление продавца об оплате
254
+ cancel_order = 6 # [B] Отмена сделки
255
+ order_canceled = -6 # [S] Уведомление продавцу об отмене ордера покупателем
256
+ confirm = 7 # [S] Подтвердить получение оплаты
257
+ order_completed = -7 # [B] Уведомление покупателю об успешном завершении продавцом
258
+ appeal_available = -8 # [S, B] Уведомление о наступлении возможности подать апелляцию
259
+ start_appeal = 9 # , 10 # [S, B] Подать апелляцию со скриншотом/видео/файлом
260
+ appeal_started = -9 # , -10 # [S, B] Уведомление о поданной на меня апелляции
261
+ dispute_appeal = 11 # , 12 # [S, B] Встречное оспаривание полученной апелляции со скриншотом/видео/файлом
262
+ appeal_disputed = -11 # , -12 # [S, B] Уведомление о встречном оспаривание поданной апелляции
263
+ order_completed_by_appeal = -13 # [S, B] Уведомление о завершении сделки по апелляции
264
+ order_canceled_by_appeal = -14 # [B, S] Уведомление об отмене сделки по апелляции
265
+ cancel_appeal = 15 # [B, S] Отмена апелляции
266
+ appeal_canceled = -15 # [B, S] Уведомление об отмене апелляции против меня
267
+ send_order_msg = 16 # Отправка сообщения юзеру в чат по ордеру с приложенным файлом
268
+ got_order_msg = -16 # Получение сообщения в чате по ордеру
269
+ send_appeal_msg = 17 # Отправка сообщения по апелляции
270
+ got_appeal_msg = -17 # Получение сообщения по апелляции
271
+ """ Ex: Public """
272
+ # curs = 19 # Список поддерживаемых валют тейкера
273
+ pms = 20 # Список платежных методов по каждой валюте
274
+ cur_pms_map = 21 # Мэппинг валюта => платежные методы
275
+ coins = 22 # Список торгуемых монет (с ограничениями по валютам, если есть)
276
+ pairs = 23 # Список пар валюта/монет
277
+ ads = 24 # Список объяв по покупке/продаже, валюте, монете, платежному методу (buy/sell, cur, coin, pm)
278
+ set_coins = 44 # обновление монет биржи в бд
279
+ set_curs = 19 # обновление валют и платежек биржи в бд
280
+ set_pms = 45 # обновление валют и платежек биржи в бд
281
+ set_pairs = 46 # обновление пар биржи в бд
282
+ ad = 42 # Чужая объява по id
283
+ """ Agent: Fiat """
284
+ my_creds = 25 # Список реквизитов моих платежных методов
285
+ cred_new = 26 # Создание реквизита моего платежного метода
286
+ cred_upd = 27 # Редактирование реквизита моего платежного метода
287
+ cred_del = 28 # Удаление реквизита моего платежного метода
288
+ """ Agent: Ad """
289
+ my_ads = 29 # Список моих объявлений
290
+ my_ad = 43 # Моя объява по id
291
+ ad_new = 30 # Создание объявления
292
+ ad_upd = 31 # Редактирование объявления
293
+ ad_del = 32 # Удаление объявления
294
+ ad_switch = 33 # Вкл/выкл объявления
295
+ ads_switch = 34 # Вкл/выкл всех объявлений
296
+ """ Agent: Taker """
297
+ get_user = 35 # Получить объект юзера по его id
298
+ send_user_msg = 36 # Отправка сообщения юзеру с приложенным файлом
299
+ block_user = 37 # [Раз]Блокировать пользователя
300
+ rate_user = 38 # Поставить отзыв пользователю
301
+ """ Agent: Inbound """
302
+ got_user_msg = -36 # Получение сообщения от пользователя
303
+ got_blocked = -37 # Получение уведомления о [раз]блокировке пользователем
304
+ got_rated = -38 # Получение уведомления о полученном отзыве
305
+
306
+ """ Assets """
307
+ assets = 39 # Балансы моих монет
308
+ deposit = 40 # Получить реквизиты для депозита монеты
309
+ deposited = -40 # Получена монета
310
+ withdraw = 41 # Вывести монету
311
+ withdrew = -41 # Монета выведена
@@ -0,0 +1,18 @@
1
+ from enum import IntEnum
2
+ from json import loads
3
+
4
+ from asyncpg.exceptions import RaiseError
5
+
6
+
7
+ class ExcType(IntEnum):
8
+ InsufficientBalance = 1
9
+ TxIdPackMismatch = 2
10
+
11
+
12
+ class PgRaiseError(ValueError):
13
+ typ: ExcType
14
+
15
+ def __init__(self, e: RaiseError) -> None:
16
+ typ, msg = e.args[0].split(": ")
17
+ self.typ = ExcType[typ]
18
+ super().__init__(typ, loads(msg))
@@ -0,0 +1,65 @@
1
+ from xync_db.enums import OrderAction, OrderStatus
2
+
3
+ acts = (
4
+ { # buyer
5
+ # 1
6
+ OrderStatus.created: {
7
+ OrderAction.buyer_cancel: OrderStatus.canceled,
8
+ OrderAction.buyer_pay: OrderStatus.paid,
9
+ },
10
+ # 2
11
+ OrderStatus.paid: {
12
+ OrderAction.buyer_cancel: OrderStatus.canceled,
13
+ OrderAction.buyer_appeal: OrderStatus.appealed_by_buyer,
14
+ },
15
+ # 5
16
+ OrderStatus.appealed_by_seller: {
17
+ OrderAction.buyer_cancel: OrderStatus.canceled,
18
+ OrderAction.buyer_dispute_appeal_s: OrderStatus.appeal_disputed,
19
+ },
20
+ # 6
21
+ OrderStatus.appealed_by_buyer: {
22
+ OrderAction.buyer_cancel: OrderStatus.canceled,
23
+ },
24
+ # 7
25
+ OrderStatus.appeal_disputed: {
26
+ OrderAction.buyer_cancel: OrderStatus.canceled,
27
+ },
28
+ },
29
+ { # seller
30
+ # 2
31
+ OrderStatus.paid: {
32
+ OrderAction.seller_confirm: OrderStatus.completed,
33
+ OrderAction.seller_appeal: OrderStatus.appealed_by_seller,
34
+ },
35
+ # 5
36
+ OrderStatus.appealed_by_seller: {
37
+ OrderAction.seller_confirm: OrderStatus.completed,
38
+ },
39
+ # 6
40
+ OrderStatus.appealed_by_buyer: {
41
+ OrderAction.seller_dispute_appeal_b: OrderStatus.appeal_disputed,
42
+ OrderAction.seller_confirm: OrderStatus.completed,
43
+ },
44
+ # 7
45
+ OrderStatus.appeal_disputed: {
46
+ OrderAction.seller_confirm: OrderStatus.completed,
47
+ },
48
+ },
49
+ )
50
+
51
+
52
+ waits: dict[OrderStatus, dict[OrderAction, OrderStatus]] = {
53
+ # 1
54
+ OrderStatus.created: {
55
+ OrderAction.wait_for_cancel: OrderStatus.canceled,
56
+ },
57
+ # 5
58
+ OrderStatus.appealed_by_seller: {
59
+ OrderAction.wait_appeal_s: OrderStatus.canceled,
60
+ },
61
+ # 6
62
+ OrderStatus.appealed_by_buyer: {
63
+ OrderAction.wait_appeal_b: OrderStatus.completed,
64
+ },
65
+ }