feat(sources): контракт источников, worker и синк ZenMoney + ЦБ

Source.sync(ctx) -> SyncResult пишет только raw_* и возвращает курсор; локи,
журнал, ошибки и продвижение курсора берёт на себя worker/runner.

ZenMoney читается единственным доступным способом — POST /v8/diff/ по
serverTimestamp; токен живёт сутки, поэтому worker ротирует refresh_token через
source_credential. Маппер всегда пересобирает core из полных raw_*, так что
удаление в ZenMoney исчезает и у нас.

ЦБ ходит мимо прокси (trust_env=False) и отдаёт cp1251 с делением на Nominal.
Курсы только по рабочим дням — протяжку по календарю делает аналитика.

Планировщик — APScheduler в отдельном процессе, на источник advisory-лок
sync:<name>, чтобы ручной запуск не пересёкся с плановым.
This commit is contained in:
Dmitry
2026-09-18 13:43:49 +03:00
parent 3fc7a954b9
commit c55fe19e48
31 changed files with 3713 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
{
"serverTimestamp": 1750001000,
"account": [
{
"id": "aaaaaaaa-0000-0000-0000-000000000001",
"changed": 1750000900,
"user": 555,
"instrument": 2,
"type": "ccard",
"title": "Карта Т-Банк",
"syncID": ["4377"],
"balance": 24000.5,
"startBalance": 0,
"creditLimit": 100000,
"inBalance": true,
"savings": false,
"archive": false,
"enableCorrection": false,
"enableSMS": true
}
],
"deletion": [
{
"id": "dddddddd-0000-0000-0000-000000000006",
"object": "transaction",
"stamp": 1750000950,
"user": 555
}
]
}