xync-db 0.5.5.dev31__tar.gz → 0.5.5.dev82__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.
Files changed (42) hide show
  1. xync_db-0.5.5.dev82/.gitignore +39 -0
  2. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/PKG-INFO +6 -12
  3. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/README.md +5 -11
  4. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/enums.py +31 -15
  5. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/i18n.py +1 -1
  6. xync_db-0.5.5.dev82/src/xync_db/migrations/CLAUDE.md +21 -0
  7. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/0001_initial.py +111 -27
  8. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/0002_triggers.py +116 -33
  9. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/0003_seed.py +3 -5
  10. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/a_actor_seed.py +13 -1
  11. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/a_bin_seed.py +1 -1
  12. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/a_country_seed.py +2 -6
  13. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/a_tg_seed.py +32 -1
  14. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/b_htx_seed.py +1 -1
  15. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/models/CLAUDE.md +21 -21
  16. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/models/__init__.py +196 -56
  17. xync_db-0.5.5.dev31/.gitignore +0 -48
  18. xync_db-0.5.5.dev31/src/xync_db/migrations/CLAUDE.md +0 -129
  19. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/pyproject.toml +0 -0
  20. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/__init__.py +0 -0
  21. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/config.py +0 -0
  22. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/exceptions.py +0 -0
  23. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/graph.py +0 -0
  24. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/login_store.py +0 -0
  25. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/logo.png +0 -0
  26. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/__init__.py +0 -0
  27. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/__init__.py +0 -0
  28. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/__init__.py +0 -0
  29. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/c_net_seed.py +0 -0
  30. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/countries.json +0 -0
  31. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/ranges.csv +0 -0
  32. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/migrations/models/seed/xync_files.sql +0 -0
  33. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/py.typed +0 -0
  34. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/shared.py +0 -0
  35. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/__init__.py +0 -0
  36. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/__init__.py +0 -0
  37. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/actor.py +0 -0
  38. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/ad.py +0 -0
  39. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/common.py +0 -0
  40. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/cred.py +0 -0
  41. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/order.py +0 -0
  42. {xync_db-0.5.5.dev31 → xync_db-0.5.5.dev82}/src/xync_db/typs/db/pm.py +0 -0
@@ -0,0 +1,39 @@
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
+ *.log*
16
+
17
+ # uv
18
+ .uv-cache/
19
+
20
+ # Node
21
+ node_modules/
22
+ *.tsbuildinfo
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
+
38
+ packages/xync-web
39
+ packages/xync-chrome-ext
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: xync-db
3
- Version: 0.5.5.dev31
3
+ Version: 0.5.5.dev82
4
4
  Summary: Xync DB schema: Tortoise ORM models, enums, pydantic DTOs.
5
5
  Author-email: Mike Artemiev <mixartemev@gmail.com>
6
6
  License: LicenseRef-EULA
@@ -56,7 +56,7 @@ Single source of truth for data shape across the monorepo.
56
56
  classDiagram
57
57
  direction BT
58
58
  class Actor {
59
- uint8 exid
59
+ uint16 exid
60
60
  uint1 ex_id
61
61
  varchar(63) name
62
62
  integer person_id
@@ -335,13 +335,7 @@ user --> username : username_id->username.id
335
335
  - а в `Order` соответственно через `ad_id` получаем `ad.actor.ex_id`
336
336
 
337
337
 
338
- ## Migrations (native Tortoise CLI — no aerich)
339
- ```bash
340
- cd packages/xync-db
341
- tortoise init # only once
342
- tortoise makemigrations # detect changes
343
- tortoise migrate # apply
344
- tortoise downgrade models 0001_initial # roll back
345
- tortoise sqlmigrate models 0001_initial # preview SQL
346
- ```
347
- Config lives in this package's `pyproject.toml` under `[tool.tortoise]`.
338
+ ## Миграции
339
+ Ровно три: `0001_initial` (схема), `0002_triggers`, `0003_seed`; изменение схемы — правкой `0001`, новых миграций
340
+ не заводим (`src/xync_db/migrations/CLAUDE.md`). Применить: `tortoise migrate` (конфиг — `[tool.tortoise]` в
341
+ `pyproject.toml`).
@@ -38,7 +38,7 @@ Single source of truth for data shape across the monorepo.
38
38
  classDiagram
39
39
  direction BT
40
40
  class Actor {
41
- uint8 exid
41
+ uint16 exid
42
42
  uint1 ex_id
43
43
  varchar(63) name
44
44
  integer person_id
@@ -317,13 +317,7 @@ user --> username : username_id->username.id
317
317
  - а в `Order` соответственно через `ad_id` получаем `ad.actor.ex_id`
318
318
 
319
319
 
320
- ## Migrations (native Tortoise CLI — no aerich)
321
- ```bash
322
- cd packages/xync-db
323
- tortoise init # only once
324
- tortoise makemigrations # detect changes
325
- tortoise migrate # apply
326
- tortoise downgrade models 0001_initial # roll back
327
- tortoise sqlmigrate models 0001_initial # preview SQL
328
- ```
329
- Config lives in this package's `pyproject.toml` under `[tool.tortoise]`.
320
+ ## Миграции
321
+ Ровно три: `0001_initial` (схема), `0002_triggers`, `0003_seed`; изменение схемы — правкой `0001`, новых миграций
322
+ не заводим (`src/xync_db/migrations/CLAUDE.md`). Применить: `tortoise migrate` (конфиг — `[tool.tortoise]` в
323
+ `pyproject.toml`).
@@ -176,12 +176,9 @@ class AgentStatus(IntEnum):
176
176
 
177
177
 
178
178
  class SynonymType(IntEnum):
179
- name = 1
180
179
  ppo = 2
181
- from_party = 3
182
- to_party = 4
183
- slip_req = 5
184
- slip_send = 6
180
+ from_party = 3 # с чьего лица платит покупатель: sell — какое мейкер требует, buy — с какого шлёт сам
181
+ slip = 5 # sell-объява: какой чек мейкер требует, buy: какой шлёт (бывш. slip_req/slip_send)
185
182
  abuser = 7
186
183
  scale = 8
187
184
  slavic = 9
@@ -203,15 +200,14 @@ class Boundary(IntEnum):
203
200
 
204
201
 
205
202
  class SbpStrict(IntEnum):
206
- no = 0
207
203
  sbp = 1
208
204
  card = 2
209
205
 
210
206
 
211
- class Party(IntEnum):
207
+ class FromParty(IntEnum):
212
208
  fst = 0
213
209
  fam = 1
214
- lk = 2 # lk-photo/video/comment
210
+ lk = 2
215
211
  trd = 3
216
212
 
217
213
 
@@ -222,17 +218,37 @@ class Slip(IntEnum):
222
218
  pdf_mail = 3
223
219
 
224
220
 
225
- class NameType(IntEnum):
226
- no_slavic = 0
227
- slavic = 1
228
- fake = 2
229
-
230
-
231
221
  class AbuserType(IntEnum):
232
- no = 0
233
222
  rating = 1 # рейтинг: жмет "Оплачено" сразу, "Отмена" по апелляции
234
223
  fake = 2 # реклама
235
224
  cash = 3 # типа кэш обменник, но хз
225
+ long = 4 # ждать дольше 15 мин (оплату/отпуск)
226
+ add_vrf = 5 # сверх чека — видео из лк/выписка и т.п.
227
+ fee = 6 # доплата/комиссия сверх суммы ордера
228
+ rate = 7 # цена объявления не совпадает с реальным (сделка будет по другому курсу)
229
+
230
+
231
+ class CredType(
232
+ IntEnum
233
+ ): # требование к реквизитам (искл: foreign — предупреждение мейкера-продавца о своей зарубежной карте)
234
+ no_llc = 1 # не ИП/юрлицо: «с ип не работаю»
235
+ rus_num = 2 # только российские, обычно номер телефона: «только на номера рф»
236
+ foreign = 3 # продавец просит платёж на зарубежную (не российскую) карту/номер: «перевод на зарубежную карту»
237
+
238
+
239
+ class GeminiModel(
240
+ IntEnum
241
+ ): # модель Gemini (`GeminiReq`); имя в API, порядок силы и квоты — `cond_ai.providers.gemini.MODELS`
242
+ lite_3_5 = 5
243
+ lite_3_1 = 6
244
+
245
+
246
+ class GeminiRes(IntEnum): # исход запроса к Gemini (`GeminiReq`)
247
+ ok = 0
248
+ minute = 1 # прочие 429 (…PerMinute…, отказ без квоты): ключ на минуту мимо этой модели
249
+ day = 2 # 429 …PerDay…: ключ выбыл по этой модели до сброса квоты (`GeminiKey.pick`)
250
+ bad_key = 4 # 401/403/API_KEY_INVALID: ключ выбыл по всем моделям на сутки
251
+ fail = 5 # прочие сбои (таймаут; 5xx — перегружена модель: условие — к следующей)
236
252
 
237
253
 
238
254
  class ExStatus(IntEnum):
@@ -1,4 +1,4 @@
1
- """Bilingual text selector for user-facing strings (D-026).
1
+ """Bilingual text selector for user-facing strings (D-08).
2
2
 
3
3
  Usage::
4
4
 
@@ -0,0 +1,21 @@
1
+ # migrations — три миграции (D-09)
2
+
3
+ Конфиг — `xync_service.config.TORTOISE_ORM`; `make migrate` / `make makemigrations` из корня.
4
+
5
+ 1. **`0001_initial`** — полная финальная схема (`ops.CreateModel`). **Любое изменение схемы — правкой этого
6
+ файла**: `0003_seed` пишет через ORM по финальной модели, поздняя миграция с новой колонкой уронит засев.
7
+ Новых миграций не заводим; на прод (ledger фейковый) — DDL руками.
8
+ 2. **`0002_triggers`** — все триггеры и функции (`CREATE OR REPLACE`): NOTIFY-каналы (`contracts/events.md`),
9
+ гарды (`tx_before`, `tx_no_delete`, `ad_exid_ex_uniq`, `ad_cond_side_uniq`, `cond_txt_side_uniq`), GC условий
10
+ (`ad_cond_gc`, `cond_new_gc`), утилиты `_user_balance`, `_tx_pack`. Идёт до засева — сид полагается на
11
+ `user_new`.
12
+ 3. **`0003_seed`** — засев по зависимостям: файлы PM-логотипов → `a_actor_seed` (биржи, 56 базовых валют, монеты,
13
+ XyncPay, эл. кошельки, origin user id=0) → `a_tg_seed` (DC/App, `pm_rep`) → `a_country_seed` (страны+валюты
14
+ из `seed/countries.json`) → `a_bin_seed` (BIN/банки из `seed/ranges.csv`) → `b_htx_seed` (валюты/монеты/пары
15
+ HTX) → `c_net_seed` (web3-сети).
16
+
17
+ Засев, зависящий от Pm (`set_pms` с логотипами, `refine_pms`), — в `xync-script`, не здесь: миграции не
18
+ импортируют `pyro_client`.
19
+
20
+ Дев-БД пересобирать только с нуля (`DROP`/`CREATE` + `make migrate`); таблицы, созданные заранее
21
+ `generate_schemas`, ломают `0001` (DuplicateTable).
@@ -10,7 +10,7 @@ from tortoise.fields.db_defaults import Now
10
10
  from tortoise.migrations import operations as ops
11
11
  from tortoise.migrations.constraints import CheckConstraint
12
12
  from x_auth.enums import Lang, PeerType, Role
13
- from x_model.field import DatetimeSecField, UInt1Field, UInt2Field, UInt4Field, UInt8Field, UniqBinaryField
13
+ from x_model.field import DatetimeSecField, UInt1Field, UInt2Field, UInt4Field, UInt8Field, UInt16Field, UniqBinaryField
14
14
 
15
15
  from xync_db.enums import (
16
16
  AbuserType,
@@ -19,14 +19,17 @@ from xync_db.enums import (
19
19
  AgentStatus,
20
20
  Boundary,
21
21
  CoinType,
22
+ CredType,
22
23
  DepType,
23
24
  ExAction,
24
25
  ExStatus,
25
26
  ExType,
26
27
  FileType,
28
+ FromParty,
29
+ GeminiModel,
30
+ GeminiRes,
27
31
  HotStatus,
28
32
  OrderStatus,
29
- Party,
30
33
  PersonStatus,
31
34
  PmType,
32
35
  SbpStrict,
@@ -70,12 +73,97 @@ class Migration(migrations.Migration):
70
73
  ("id", fields.IntField(generated=True, primary_key=True, unique=True, db_index=True)),
71
74
  ("created_at", DatetimeSecField(db_default=Now(), auto_now=False, auto_now_add=True)),
72
75
  ("updated_at", DatetimeSecField(db_default=Now(), auto_now=True, auto_now_add=False)),
73
- ("raw_txt", fields.CharField(unique=True, max_length=4095)),
76
+ ("raw_txt", fields.CharField(db_index=True, max_length=4095)),
74
77
  ("last_ver", fields.CharField(null=True, max_length=4095)),
75
78
  ],
76
79
  options={"table": "cond", "app": "models", "pk_attr": "id"},
77
80
  bases=["Model", "TsTrait"],
78
81
  ),
82
+ ops.CreateModel(
83
+ name="CondPrompt",
84
+ fields=[
85
+ ("id", fields.IntField(generated=True, primary_key=True, unique=True, db_index=True)),
86
+ ("txt", fields.TextField(unique=False)),
87
+ ("is_jev", fields.BooleanField(db_default=False)),
88
+ (
89
+ "cond",
90
+ fields.ForeignKeyField(
91
+ "models.Cond",
92
+ source_field="cond_id",
93
+ null=True,
94
+ db_constraint=True,
95
+ to_field="id",
96
+ related_name="prompts",
97
+ on_delete=OnDelete.SET_NULL,
98
+ ),
99
+ ),
100
+ ("remark", fields.TextField(null=True, unique=False)),
101
+ ("note", fields.TextField(null=True, unique=False)),
102
+ ("created_at", DatetimeSecField(db_default=Now(), auto_now=False, auto_now_add=True)),
103
+ ],
104
+ options={
105
+ "table": "cond_prompt",
106
+ "app": "models",
107
+ "pk_attr": "id",
108
+ "table_description": "Версия промпта разбора условий (`xync_service.common.cond_ai`): системного промпта Gemini или вопросов JEV",
109
+ },
110
+ bases=["Model"],
111
+ ),
112
+ ops.CreateModel(
113
+ name="GeminiKey",
114
+ fields=[
115
+ ("id", fields.IntField(generated=True, primary_key=True, unique=True, db_index=True)),
116
+ ("key", fields.CharField(unique=True, max_length=63)),
117
+ ],
118
+ options={
119
+ "table": "gemini_key",
120
+ "app": "models",
121
+ "pk_attr": "id",
122
+ "table_description": "Ключ Gemini API free tier (разбор условий, `xync_service.common.cond_ai`). Квота своя на каждую модель, расход и",
123
+ },
124
+ bases=["Model"],
125
+ ),
126
+ ops.CreateModel(
127
+ name="GeminiReq",
128
+ fields=[
129
+ ("id", fields.IntField(generated=True, primary_key=True, unique=True, db_index=True)),
130
+ (
131
+ "key",
132
+ fields.ForeignKeyField(
133
+ "models.GeminiKey",
134
+ source_field="key_id",
135
+ db_constraint=True,
136
+ to_field="id",
137
+ related_name="reqs",
138
+ on_delete=OnDelete.CASCADE,
139
+ ),
140
+ ),
141
+ (
142
+ "model",
143
+ fields.IntEnumField(
144
+ description="lite_3_5: 5\nlite_3_1: 6",
145
+ enum_type=GeminiModel,
146
+ generated=False,
147
+ ),
148
+ ),
149
+ (
150
+ "res",
151
+ fields.IntEnumField(
152
+ description="ok: 0\nminute: 1\nday: 2\nbad_key: 4\nfail: 5",
153
+ enum_type=GeminiRes,
154
+ generated=False,
155
+ ),
156
+ ),
157
+ ("created_at", DatetimeSecField(db_default=Now(), auto_now=False, auto_now_add=True)),
158
+ ],
159
+ options={
160
+ "table": "gemini_req",
161
+ "app": "models",
162
+ "pk_attr": "id",
163
+ "table_description": "Запрос к Gemini (`cond_ai._generate`) — история за сутки (старше удаляет `CondAi` на входе): по ней",
164
+ },
165
+ bases=["Model"],
166
+ ),
79
167
  ops.CreateModel(
80
168
  name="CondSim",
81
169
  fields=[
@@ -507,7 +595,7 @@ class Migration(migrations.Migration):
507
595
  options={"table": "pm_group", "app": "models", "pk_attr": "id"},
508
596
  bases=["Model"],
509
597
  ),
510
- # `bank` — раньше `Bank`/`Bin`/`Card` (D-038), т.к. на него ссылается `pm.bank_id`
598
+ # `bank` — раньше `Bank`/`Bin`/`Card` (D-17), т.к. на него ссылается `pm.bank_id`
511
599
  ops.CreateModel(
512
600
  name="Bank",
513
601
  fields=[
@@ -621,27 +709,21 @@ class Migration(migrations.Migration):
621
709
  on_delete=OnDelete.CASCADE,
622
710
  ),
623
711
  ),
624
- (
625
- "to_party",
626
- fields.IntEnumField(
627
- null=True, description="fst: 0\nfam: 1\nlk: 2\ntrd: 3", enum_type=Party, generated=False
628
- ),
629
- ),
630
712
  (
631
713
  "from_party",
632
714
  fields.IntEnumField(
633
- null=True, description="fst: 0\nfam: 1\nlk: 2\ntrd: 3", enum_type=Party, generated=False
715
+ null=True, description="fst: 0\nfam: 1\nlk: 2\ntrd: 3", enum_type=FromParty, generated=False
634
716
  ),
635
717
  ),
636
- ("ppo", UInt1Field(null=True)),
637
718
  (
638
- "slip_req",
719
+ "to_party",
639
720
  fields.IntEnumField(
640
- null=True, description="no: 0\nscreen: 1\npdf: 2\npdf_mail: 3", enum_type=Slip, generated=False
721
+ null=True, description="fst: 0\nfam: 1\nlk: 2\ntrd: 3", enum_type=FromParty, generated=False
641
722
  ),
642
723
  ),
724
+ ("ppo", UInt1Field(null=True)),
643
725
  (
644
- "slip_send",
726
+ "slip",
645
727
  fields.IntEnumField(
646
728
  null=True, description="no: 0\nscreen: 1\npdf: 2\npdf_mail: 3", enum_type=Slip, generated=False
647
729
  ),
@@ -649,27 +731,28 @@ class Migration(migrations.Migration):
649
731
  (
650
732
  "abuser",
651
733
  fields.IntEnumField(
652
- description="no: 0\nrating: 1\nfake: 2\ncash: 3",
653
- db_default=AbuserType.no,
734
+ null=True,
735
+ description="rating: 1\nfake: 2\ncash: 3\nlong: 4\nadd_vrf: 5\nfee: 6\nrate: 7",
654
736
  enum_type=AbuserType,
655
737
  generated=False,
656
738
  ),
657
739
  ),
658
740
  ("slavic", fields.BooleanField(null=True)),
741
+ (
742
+ "cred",
743
+ fields.IntEnumField(
744
+ null=True, description="no_llc: 1\nrus_num: 2\nforeign: 3", enum_type=CredType, generated=False
745
+ ),
746
+ ),
659
747
  ("mtl_like", fields.BooleanField(null=True)),
660
748
  ("scale", fields.SmallIntField(null=True)),
661
749
  ("bank_side", fields.BooleanField(null=True)),
662
750
  (
663
751
  "sbp_strict",
664
- fields.IntEnumField(
665
- description="no: 0\nsbp: 1\ncard: 2",
666
- db_default=SbpStrict.no,
667
- enum_type=SbpStrict,
668
- generated=False,
669
- ),
752
+ fields.IntEnumField(null=True, description="sbp: 1\ncard: 2", enum_type=SbpStrict, generated=False),
670
753
  ),
671
754
  ("contact", fields.CharField(null=True, max_length=127)),
672
- ("done", fields.BooleanField(db_index=True, db_default=False)),
755
+ ("is_intermediary", fields.BooleanField(null=True)),
673
756
  (
674
757
  "banks",
675
758
  fields.ManyToManyField(
@@ -930,7 +1013,7 @@ class Migration(migrations.Migration):
930
1013
  "typ",
931
1014
  fields.IntEnumField(
932
1015
  db_index=True,
933
- description="name: 1\nppo: 2\nfrom_party: 3\nto_party: 4\nslip_req: 5\nslip_send: 6\nabuser: 7\nscale: 8\nslavic: 9\nmtl_like: 10\nbank: 11\nbank_side: 12\nsbp_strict: 13\ncontact: 14",
1016
+ description="ppo: 2\nfrom_party: 3\nslip: 5\nabuser: 7\nscale: 8\nslavic: 9\nmtl_like: 10\nbank: 11\nbank_side: 12\nsbp_strict: 13\ncontact: 14",
934
1017
  enum_type=SynonymType,
935
1018
  generated=False,
936
1019
  ),
@@ -1361,7 +1444,7 @@ class Migration(migrations.Migration):
1361
1444
  name="Actor",
1362
1445
  fields=[
1363
1446
  ("id", fields.IntField(generated=True, primary_key=True, unique=True, db_index=True)),
1364
- ("exid", UInt8Field()),
1447
+ ("exid", UInt16Field()),
1365
1448
  ("name", fields.CharField(max_length=63)),
1366
1449
  (
1367
1450
  "ex",
@@ -1379,6 +1462,7 @@ class Migration(migrations.Migration):
1379
1462
  fields.ForeignKeyField(
1380
1463
  "models.Person",
1381
1464
  source_field="person_id",
1465
+ null=True,
1382
1466
  db_constraint=True,
1383
1467
  to_field="id",
1384
1468
  related_name="actors",
@@ -2607,7 +2691,7 @@ class Migration(migrations.Migration):
2607
2691
  options={"table": "vpn", "app": "models", "pk_attr": "id", "table_description": "VPNs"},
2608
2692
  bases=["Model"],
2609
2693
  ),
2610
- # ── Cards / BINs (D-038; засев — `0003_seed` → a_bin_seed из binlist/data; `Bank` создан выше — на него ссылается `pm`) ──
2694
+ # ── Cards / BINs (D-17; засев — `0003_seed` → a_bin_seed из binlist/data; `Bank` создан выше — на него ссылается `pm`) ──
2611
2695
  ops.CreateModel(
2612
2696
  name="Bin",
2613
2697
  fields=[