xync-db 0.2.2.dev17__tar.gz → 0.3.1__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.
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/PKG-INFO +1 -1
- xync_db-0.3.1/src/xync_db/migrations/models/0006_credex_orphan.py +47 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/models/__init__.py +25 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/.gitignore +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/README.md +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/pyproject.toml +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/config.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/enums.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/exceptions.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/graph.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/i18n.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/logo.png +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/CLAUDE.md +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/0001_initial.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/0002_triggers.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/0003_files_seed.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/0004_all_seed.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/0005_credex_del.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/seed/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/seed/a_actor_seed.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/seed/a_tg_seed.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/seed/b_htx_seed.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/migrations/models/seed/xync_files.sql +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/models/CLAUDE.md +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/py.typed +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/shared.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/__init__.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/actor.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/ad.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/common.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/cred.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/order.py +0 -0
- {xync_db-0.2.2.dev17 → xync_db-0.3.1}/src/xync_db/typs/db/pm.py +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Per-CredEx exid-overwrite trigger → `credexs_orphan` channel.
|
|
2
|
+
|
|
3
|
+
`CredEx.upsert` keys on (cred, ex) and overwrites `exid`. When it overwrites a REAL (non-zero) exid
|
|
4
|
+
with a different value, the previously-registered credential keeps living on the exchange as an
|
|
5
|
+
orphaned duplicate (the DB no longer tracks it). We don't silently leak it: a BEFORE-UPDATE trigger
|
|
6
|
+
catches the change and emits `[person_id, ex_id, OLD.exid, OLD.cred_id]` so service-api can ask the
|
|
7
|
+
owner whether to delete the stale one (handler `api.handlers.creds.credex_orphan`, mirror of the
|
|
8
|
+
`is_you` consent flow). On "yes" the answer routes back through `CredEx.orphan_del` →
|
|
9
|
+
`credexs_orphan_del` → `credex_orphan_del` handler → `acl.cred_del(OLD.exid)` + a success/error report.
|
|
10
|
+
|
|
11
|
+
`OLD.cred_id` is in the payload because the orphan-consent question shows the credential's `detail`,
|
|
12
|
+
which the handler can't recover from `[person_id, ex_id, OLD.exid]` alone: post-overwrite the (cred,
|
|
13
|
+
ex) row already holds the NEW exid, and a person may own several creds on one exchange.
|
|
14
|
+
|
|
15
|
+
Fires ONLY on a genuine real→different overwrite:
|
|
16
|
+
- `OLD.exid <> 0` skips the normal publish (stub 0 → real exid in `credex_new`);
|
|
17
|
+
- `NEW.exid <> OLD.exid` skips no-op re-writes (parse re-saving the same exid).
|
|
18
|
+
The user re-registers immediately (the overwrite proceeds — `RETURN NEW`); orphan cleanup is async
|
|
19
|
+
and consent-gated. person via the parent cred; NULL ⇒ no owner to ask ⇒ skip.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from typing import ClassVar
|
|
23
|
+
|
|
24
|
+
from tortoise.migrations.migration import Migration as BaseMigration
|
|
25
|
+
from tortoise.migrations.operations import RunSQL
|
|
26
|
+
|
|
27
|
+
CREDEX_ORPHAN_SQL = """
|
|
28
|
+
CREATE OR REPLACE FUNCTION credex_orphan() returns trigger as $credex_orphan_trg$
|
|
29
|
+
DECLARE
|
|
30
|
+
pid INT;
|
|
31
|
+
BEGIN
|
|
32
|
+
IF OLD.exid <> 0 AND NEW.exid <> OLD.exid THEN
|
|
33
|
+
SELECT person_id INTO pid FROM cred WHERE id = OLD.cred_id;
|
|
34
|
+
IF pid IS NOT NULL THEN
|
|
35
|
+
PERFORM pg_notify('credexs_orphan', jsonb_build_array(pid, OLD.ex_id, OLD.exid, OLD.cred_id)::varchar);
|
|
36
|
+
END IF;
|
|
37
|
+
END IF;
|
|
38
|
+
RETURN NEW;
|
|
39
|
+
END
|
|
40
|
+
$credex_orphan_trg$ LANGUAGE plpgsql;
|
|
41
|
+
CREATE OR REPLACE TRIGGER credex_orphan BEFORE UPDATE ON "credex" FOR EACH ROW EXECUTE FUNCTION credex_orphan();
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Migration(BaseMigration):
|
|
46
|
+
dependencies: ClassVar = [("models", "0005_credex_del")]
|
|
47
|
+
operations: ClassVar = [RunSQL(CREDEX_ORPHAN_SQL)]
|
|
@@ -97,6 +97,11 @@ from xync_db.typs import HotAd, HotAds, OrderResult
|
|
|
97
97
|
# both are stubbed out until the porting cleanup decides their final shape.
|
|
98
98
|
# from xync_db.typs.db import AdNewFlatRaw
|
|
99
99
|
|
|
100
|
+
# ex_id бирж с share-hex: у их объяв обязателен MyAd.hex, иначе url-кнопку на объяву не построить, поэтому
|
|
101
|
+
# незашаренные объявы этих бирж прячем из выдачи тейкеру / алертим админу. Пока только Bybit (4); единственное
|
|
102
|
+
# место смены — на случай добавления других share-бирж.
|
|
103
|
+
SHARE_HEX_EX_IDS = [4]
|
|
104
|
+
|
|
100
105
|
|
|
101
106
|
class Country(BaseCountry):
|
|
102
107
|
cur: ForeignKeyRelation[Cur] = ForeignKeyField("models.Cur", "countries", on_update=CASCADE)
|
|
@@ -676,6 +681,11 @@ class User(TgUser, TsTrait):
|
|
|
676
681
|
) -> tuple[list[MyAd], list[MyAd], dict[int, float], dict[int, dict[int, int]]]:
|
|
677
682
|
owner = {"ad__maker__person__user_id": self.id} if mine else {"ad__maker__person__user_id__not": self.id}
|
|
678
683
|
adq = MyAd.hot_mads_query(ex_ids).filter(**owner)
|
|
684
|
+
if not mine:
|
|
685
|
+
# тейкеру прячем незашаренные объявы share-hex-бирж (hex IS NULL AND ex∈SHARE_HEX_EX_IDS): без
|
|
686
|
+
# share-hex url-кнопку не построить. Сужено до этих бирж, чтобы не зацепить hot-биржи без share-hex.
|
|
687
|
+
# Свои (mine, страница settings) оставляем — их видно для шеринга.
|
|
688
|
+
adq = adq.exclude(hex__isnull=True, ad__maker__ex_id__in=SHARE_HEX_EX_IDS)
|
|
679
689
|
bads = await adq.filter(ad__pair_side__is_sell=False)
|
|
680
690
|
# остаток каждой монеты (asset.free) у акторов персон этого юзера, по бирже и монете # noqa: RUF003
|
|
681
691
|
coin_balances: dict[int, dict[int, int]] = {}
|
|
@@ -1596,6 +1606,21 @@ class CredEx(Model):
|
|
|
1596
1606
|
`acl.cred_del(exid)`. Каскадное удаление при сносе самого Cred идёт другим путём (`creds_del`)."""
|
|
1597
1607
|
return bool(await cls.filter(cred_id=cred_id, ex_id=ex_id).delete())
|
|
1598
1608
|
|
|
1609
|
+
@classmethod
|
|
1610
|
+
async def orphan_del(cls, *, person_id: int, ex_id: int, exid: int) -> None:
|
|
1611
|
+
"""Удалить ОСИРОТЕВШИЙ exid на бирже — после согласия владельца (web-контроллер / бот-колбэк).
|
|
1612
|
+
Перезапись exid у строки (cred, ex) на другой оставляет старый реквизит висеть на бирже дубликатом;
|
|
1613
|
+
BEFORE-UPDATE триггер `credex_orphan` (миграция 0006) ловит это и шлёт `credexs_orphan` → handler
|
|
1614
|
+
спрашивает владельца. На «да» зовут СЮДА: свой канал `credexs_orphan_del` (НЕ переиспользуем
|
|
1615
|
+
`credexs_del`) — его handler `credex_orphan_del` делает `acl.cred_del(exid)` по (person, ex) И
|
|
1616
|
+
возвращает владельцу результат (успех/ошибка) тем же Notify; у обычного `credex_del` отчёта нет,
|
|
1617
|
+
поэтому каналы разделены. Строки CredEx для старого exid уже нет, и она не нужна. Единый эмиттер,
|
|
1618
|
+
чтобы канал/полезную нагрузку не дублировать в web- и bot-зонах."""
|
|
1619
|
+
await connections.get("default").execute_query(
|
|
1620
|
+
"SELECT pg_notify('credexs_orphan_del', jsonb_build_array($1::int, $2::int, $3::bigint)::varchar)",
|
|
1621
|
+
[person_id, ex_id, exid],
|
|
1622
|
+
)
|
|
1623
|
+
|
|
1599
1624
|
class Meta:
|
|
1600
1625
|
table_description = "Credential on Exchange"
|
|
1601
1626
|
unique_together = (("ex", "exid"),)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|