[2026-06-25] taiga-vault: family/how-to/htpc-emulators-setup.md family/how-to/htpc-gaming-plans.md family/how-to/kraken-access.md family/how-to/openmediavault-rpi5.md family/how-to/time-machine.md family/how-to/wireguard-vpn.md personal/documents/todo-list.md personal/plans/extract-stable-prompt-blocks.md personal/plans/hermes-whale-system-prompt.md personal/plans/thread-scoped-memory.md
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
# Импорт банковских выписок за последний год
|
||||
|
||||
**Создано:** 2026-06-23
|
||||
**Цель:** Получить все транзакции за последний год (середина 2025 — июнь 2026) в Budget App, автоматизируя импорт банковских выписок как можно полнее.
|
||||
|
||||
## Проблема
|
||||
|
||||
В `Budget.xlsx` данные заканчиваются в **середине 2025** (май-июнь 2025, в зависимости от счёта). Последние ~12 месяцев транзакций не внесены в Excel. Вручную вспомнить каждую трату за год — нереалистично.
|
||||
|
||||
## Существующий инструмент: budget-bank-statement-converter
|
||||
|
||||
**Путь:** `~/Developer/budget-bank-statement-converter/`
|
||||
**Язык:** Swift (macOS command-line tool)
|
||||
**Формат вывода:** CSV с колонками `[дата, сумма, дебет, кредит, категория, комментарий, курс]` — совпадает с форматом Excel.
|
||||
|
||||
### Поддерживаемые банки
|
||||
|
||||
| Банк | Формат входа | Конфиг | Статус |
|
||||
|------|-------------|--------|--------|
|
||||
| Demir | CSV (из PDF → Adobe Extract → CSV) | `demir-config.json` | ✅ Работает |
|
||||
| Сбер | CSV (выгрузка из СберБизнес) | `sber-config.json` | ✅ Работает |
|
||||
| Тинькофф | CSV (выгрузка из Тинькофф) | `tinkoff-config.json` | ✅ Работает |
|
||||
| ВТБ | CSV (из PDF → Adobe Extract → CSV) | `vtb-config.json` | ✅ Работает |
|
||||
| Альфа | — | — | ❌ `fatalError("Alfa not implemented")` |
|
||||
|
||||
### Как работает
|
||||
|
||||
1. **PDF → CSV**: использует Adobe PDF Extract API (`pdfservices-api-credentials.json`) — загружает PDF, получает ZIP с CSV-таблицами.
|
||||
2. **CSV → формат App**: разбирает CSV, маппит категории через regex-конфиг, нормализует double-entry (дебет/кредит/конверсии).
|
||||
3. Если нужно — автоматически конкатенирует `fileoutpart0001.csv`… файлы.
|
||||
4. Использует OpenAI GPT-3.5-turbo для AI-категоризации (закомментировано, `aiMaxTokens = 80`).
|
||||
|
||||
### Что нужно для использования
|
||||
|
||||
- Xcode (для сборки Swift-проекта)
|
||||
- `OPENAI_API_KEY` в env (не обязательно, выключено)
|
||||
- `pdfservices-api-credentials.json` для Adobe Extract
|
||||
- JSON config для каждого банка: `Сбер config`, `Tinkoff config`, `Demir config`, `VTB config`
|
||||
|
||||
## План импорта
|
||||
|
||||
### Шаг 1: Получить выписки из банков
|
||||
|
||||
**Что нужно выгрузить за июнь 2025 — июнь 2026:**
|
||||
|
||||
| Счёт | Банк | Как получить выписку |
|
||||
|------|------|---------------------|
|
||||
| Нал RUB | Наличные | Ручной ввод (см. ниже про наличные) |
|
||||
| Нал KGS | Наличные | Ручной ввод |
|
||||
| Нал USD | Наличные | Ручной ввод |
|
||||
| Нал KZT | Наличные | Ручной ввод |
|
||||
| Demir ИП | Demir | CSV (интернет-банк/моб. приложение) |
|
||||
| Demir ИП USD | Demir | CSV (интернет-банк/моб. приложение) |
|
||||
| Demir KGS | Demir | CSV (интернет-банк/моб. приложение) |
|
||||
| Demir USD | Demir | CSV (интернет-банк/моб. приложение) |
|
||||
| Тинькофф Black | Тинькофф | CSV (выгрузка из Тинькофф) |
|
||||
| Тинькофф Кредитка | Тинькофф | CSV (выгрузка из Тинькофф) |
|
||||
| Сбер | Сбер | CSV (СберБизнес / PDF) |
|
||||
| Сбер Кредитка | Сбер | CSV (СберБизнес / PDF) |
|
||||
| Альфа | Альфа | CSV — но конвертер Альфу не поддерживает |
|
||||
| Альфа Кредитка | Альфа | — |
|
||||
| ВТБ | ВТБ | PDF → Adobe Extract → CSV |
|
||||
| ВТБ Кредитка | ВТБ | PDF → Adobe Extract → CSV |
|
||||
|
||||
### Шаг 2: Конвертировать выписки в CSV формата App
|
||||
|
||||
Запуск для каждого банка:
|
||||
```bash
|
||||
./budget-bank-statement-converter --bank <bank> --account <account> <input.csv>
|
||||
```
|
||||
|
||||
Выход: `_processed.csv` с колонками `дата, сумма, дебет, кредит, категория, комментарий, курс`.
|
||||
|
||||
### Шаг 3: Написать Python импортёр CSV → Budget App DB
|
||||
|
||||
Существующий `xlsx_import.py` читает из Excel. Нужен новый: `csv_bank_import.py`, который:
|
||||
|
||||
- Читает CSV в формате App (колонки из `csvHeaders` в `Common.swift`)
|
||||
- Привязывает `дебет`/`кредит` к существующим счетам в БД (по имени)
|
||||
- Маппит категории из CSV на существующие категории в БД (по имени подкатегории)
|
||||
- Игнорирует дубликаты (hash по `date + amount + source + dest + comment`)
|
||||
- Поддерживает несколько CSV-файлов за раз (много выписок)
|
||||
- Выводит отчёт: сколько добавлено, сколько пропущено (дубликаты), какие категории не найдены
|
||||
|
||||
### Шаг 4: Импортировать в Budget App
|
||||
|
||||
```bash
|
||||
cd ~/Developer/budget-app
|
||||
uv run python src/budget/importers/csv_bank_import.py <output1.csv> <output2.csv> ...
|
||||
```
|
||||
|
||||
### Шаг 5: Дописать недостающее в Swift-конвертере
|
||||
|
||||
- **AlfaToCSV**: реализовать парсер для Альфа-банка (CSV выгрузка из моб. банка/СберБизнес)
|
||||
- **AI-категоризация**: раскомментировать и обновить (GPT-3.5 → DeepSeek/local LLM?)
|
||||
|
||||
## Наличные расходы — проблема и решение
|
||||
|
||||
### Проблема
|
||||
Наличные траты не трекались последний год. У нас есть конечный остаток налички на руках сейчас, но нет истории по категориям.
|
||||
|
||||
### Подходы
|
||||
|
||||
#### A. Снять остаток наличных сейчас → счёт в БД (простой)
|
||||
- Посчитать физическую наличку сейчас → записать как `initial_balance` для `Нал RUB`, `Нал KGS`, `Нал USD`, `Нал KZT`.
|
||||
- Все траты наличными за год никогда не будут зафиксированы.
|
||||
- **Минус:** дыра в данных большого объёма (вероятно значительная часть расходов).
|
||||
|
||||
#### B. Экстраполяция по историческим трендам (средний)
|
||||
- Взять помесячные тренды наличных трат по категориям за 2023–первую половину 2025.
|
||||
- Экстраполировать на июнь 2025 — июнь 2026 с учётом сезонности.
|
||||
- Создать транзакции-плейсхолдеры с пометкой `import_id = 'cash_estimate'`.
|
||||
- **Минус:** неточность, может не отражать реальные изменения.
|
||||
|
||||
#### C. Ретроспектива через месяц-два + экстраполяция (предпочтительный)
|
||||
- **Сейчас:** начать трекать наличные расходы (вручную или через мобильный интерфейс Budget App).
|
||||
- **Через 1–2 месяца:** по собранным данным наличных трат вычислить реальные помесячные паттерны.
|
||||
- Экстраполировать на пропущенный год с этими паттернами.
|
||||
- **Плюс:** база для экстраполяции будет основана на реальных данных, а не на исторических.
|
||||
|
||||
#### D. None of the above — принять дыру
|
||||
- Сделать только безналичный импорт. Наличные начинаем трекать с сегодня.
|
||||
- В аналитике отмечать периоды как "без наличных".
|
||||
- **Плюс:** не надо ничего выдумывать.
|
||||
|
||||
### Рекомендация: C+D combined
|
||||
1. Трекать наличку вручную через UI Budget App начиная с сегодня.
|
||||
2. Через 2 месяца посчитать реальные тренды и решить, стоит ли экстраполировать на прошлый год.
|
||||
3. Если нет — просто принять дыру и жить с хорошей аналитикой начиная с 2026-06.
|
||||
|
||||
## Что уже реализовано в Budget App для импорта
|
||||
|
||||
- ✅ `xlsx_import.py` — полный импорт из Budget.xlsx (34k строк)
|
||||
- ✅ Все счета, категории, курсы, транзакции — в БД
|
||||
- ✅ Идемпотентный UPSERT для счетов и курсов
|
||||
- ✅ Транзакции добавляются обычным insert (без import_hash после фикса)
|
||||
|
||||
## Реализованный скрипт: bank_scraper
|
||||
|
||||
**Путь:** `~/Developer/budget-app/scripts/bank_scraper/`
|
||||
|
||||
Структура:
|
||||
```
|
||||
scripts/bank_scraper/
|
||||
├── __init__.py
|
||||
├── .gitignore # config.yaml + data/imports/ не коммитятся
|
||||
├── config.example.yaml # шаблон для копирования в config.yaml
|
||||
├── base_driver.py # base class BankDriver + load_config()
|
||||
├── orchestrator.py # entry point (н.п.)
|
||||
└── drivers/
|
||||
└── demir.py # Demir IB драйвер (н.п.)
|
||||
```
|
||||
|
||||
**Статус:** ✅ base + Demir driver написаны, Playwright установлен. **НО — Demir требует QR-логин через мобильное приложение**, не логин/пароль на сайте.
|
||||
|
||||
## Реальность Demir IB
|
||||
|
||||
Сайт `93.171.215.109` (и `apps.demirbank.kg/ib/`) — **Flutter web SPA** с QR-аутентификацией. Нет формы логина с паролем — нужно сканировать QR мобильным приложением Demir.
|
||||
|
||||
**Варианты решения:**
|
||||
|
||||
### A. Продолжить с Playwright + session persistence
|
||||
- Один раз залогиниться руками (QR → моб. приложение)
|
||||
- Сохранить session cookies/storage в persistent context
|
||||
- Дальше переиспользовать сессию для выгрузок (пока не протухнет)
|
||||
- **Плюс:** минимум кода
|
||||
- **Минус:** сессия рано или поздно протухнет, нужен ручной ре-логин
|
||||
|
||||
### B. Appium / ADB — эмуляция мобильного приложения
|
||||
- Демонстратор Android/iOS эмулятора с мобильным приложением Demir
|
||||
- Appium для UI automation внутри приложения
|
||||
- **Плюс:** полный контроль
|
||||
- **Минус:** сложно, накладно
|
||||
|
||||
### C. Заменить Demir на первый банк с логином/паролем
|
||||
- Тинькофф имеет API для разработчиков (OAuth)
|
||||
- Сбер — есть API SberBusinessAPI (хотя для юрлиц)
|
||||
- Можно начать с Тинькофф: Tinkoff API → выписка без браузера
|
||||
- **Плюс:** самый простой tech-wise
|
||||
- **Минус:** Demir пока под вопросом
|
||||
|
||||
### D. Парсить CSV выписки, которые уже есть в mobile/email
|
||||
- Возможно Demir присылает выписки на email
|
||||
- Или можно скачать через мобильное приложение → экспорт → AirDrop/email себе
|
||||
- Это полу-ручной подход (но быстрее чем QR scraping)
|
||||
|
||||
## Решение
|
||||
|
||||
**Рекомендация: A + D**
|
||||
1. Самый ценный банк — **Тинькофф** (есть API) — начинаем с него
|
||||
2. Demir — разово выгрузить через мобильное приложение (Export CSV/email)
|
||||
3. Если сессия Demir долго живёт — Playwright persistent context отработает
|
||||
|
||||
### Новый порядок разработки
|
||||
|
||||
1. ✅ Demir driver (написан, но упирается в QR)
|
||||
2. **Tinkoff API driver** — следующий приоритет (без браузера, REST API)
|
||||
3. **Сбер / ВТБ / Альфа** — Playwright или Tinkoff-style API
|
||||
4. **Parse Demir CSV** — Python-версия DemirToCSV для уже скачанных файлов
|
||||
|
||||
## Файл вывода Swift-конвертера
|
||||
|
||||
```
|
||||
csvHeaders = ["дата", "сумма", "дебет", "кредит", "категория", "комментарий", "курс"]
|
||||
```
|
||||
|
||||
- `дата` — `dd.MM.yyyy HH:mm` (формат EUR)
|
||||
- `сумма` — строка с суммой (±знак)
|
||||
- `дебет` — имя счёта-источника (пусто = доход извне)
|
||||
- `кредит` — имя счёта-получателя (пусто = расход вовне)
|
||||
- `категория` — имя подкатегории
|
||||
- `комментарий` — очищенный текст
|
||||
- `курс` — кросс-курс при внутреннем переводе между валютами
|
||||
|
||||
## Автоматизация выгрузки выписок из банков
|
||||
|
||||
### 1. Browser automation libraries (CV-driven)
|
||||
|
||||
| Библиотека | Язык | Браузеры | CV | 2FA/SMS |
|
||||
|-----------|------|----------|----|---------|
|
||||
| **Playwright** (MS) | Python, JS, Java, .NET ⭐ | Chromium, Firefox, WebKit | Есть (locator screenshots) | `page.wait_for_selector` на поле ввода кода |
|
||||
| **Puppeteer** (Google) | JS (Python через pyppeteer) | Chromium | Есть | — |
|
||||
| **Selenium** | Python, Java, JS и др. | Все major | Через сторонние утилиты | — |
|
||||
|
||||
**Рекомендация: Playwright Python** — де-факто стандарт в 2025, cross-browser, async, видит элементы даже в SPA, встроенные ожидания. Подходит и для РФ-банков (Сбер, Тинькофф, Альфа-клик — все на SPA).
|
||||
|
||||
### 2. Готовые решения на GitHub
|
||||
|
||||
**AploBankParsers** ([github.com/Zaurrex1/AploBankParsers](https://github.com/Zaurrex1/AploBankParsers)):
|
||||
- Парсер выписок **СберБизнес** (production-ready) — читает xlsx/сsv из уже выгруженного файла
|
||||
- Заглушки для Альфа, ВТБ, Тинькофф
|
||||
- Это парсер **уже скачанных файлов**, не скрапер
|
||||
|
||||
**bank_scrapers** ([github.com/eebette/bank_scrapers](https://github.com/eebette/bank_scrapers)):
|
||||
- Playwright-based для scraping bank websites
|
||||
- Generic, не специфичен под РФ-банки
|
||||
|
||||
**Sber API** — официальный REST API Сбера:
|
||||
- `developers.sber.ru/docs/ru/sber-api/specifications/statement/transactions`
|
||||
- Получение выписки по счёту за 5 лет
|
||||
- **Требует** корпоративного доступа (SberBusinessAPI / ДБО), не подойдёт для личного СберБанк
|
||||
|
||||
**Готового решения "под ключ" для РФ-банков** (Playwright → bank login → 2FA → CSV выписка) **нет** в открытом доступе. Каждый банк — свой уникальный UI и flow. Придётся писать самим.
|
||||
|
||||
### 3. Архитектура скрипта
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Telegram Bot (Hermes/кит) │ ← запрашивает SMS-код
|
||||
├─────────────────────────────────┤
|
||||
│ Orchestrator (Python) │ ← запускает по крону / кнопке
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Playwright browser │ │ ← drives bank login page
|
||||
│ │ - headless=false │ │ (visible для отладки)
|
||||
│ │ - persistent context │ │ (сессия не слетает)
|
||||
│ └─────────────────────────┘ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Bank drivers: │ │
|
||||
│ │ - tinkoff.py │ │
|
||||
│ │ - sber.py │ │
|
||||
│ │ - alfa.py │ │
|
||||
│ │ - demir.py │ │
|
||||
│ │ - vtb.py │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Output: CSV в формате │ │
|
||||
│ │ budget-bank-statement- │ │
|
||||
│ │ converter │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4. Flow для каждого банка
|
||||
|
||||
```
|
||||
1. Запустить headless Playwright (или visible=False для отладки)
|
||||
2. Открыть страницу логина банка
|
||||
3. Ввести credentials (из конфига, НЕ скрипта)
|
||||
4. Если запрошен SMS-код:
|
||||
→ отправить в Telegram: "Код из смс для {bank}:"
|
||||
→ ждать ответа (polling/async)
|
||||
→ ввести полученный код
|
||||
5. Дождаться загрузки дашборда
|
||||
6. Перейти на страницу выписок/истории
|
||||
7. Указать период: 2025-06-01 — 2026-06-23
|
||||
8. Скачать CSV/Excel
|
||||
9. Сохранить в ~/Developer/budget-app/data/imports/{bank}/{date}.csv
|
||||
10. Конвертировать через budget-bank-statement-converter (или Python-версию)
|
||||
11. Импортировать в БД
|
||||
12. Закрыть браузер
|
||||
```
|
||||
|
||||
### 5. Обработка SMS-кодов (Telegram)
|
||||
|
||||
Скрипт не должен хранить сессию банка, каждый запуск — новая авторизация.
|
||||
|
||||
**Варианты:**
|
||||
1. **Telegram Bot (inline keyboard)**: скрипт ждёт сообщение, когда нужен код — присылает кнопку "Отправить код для {bank}", пользователь вводит → скрипт вставляет
|
||||
2. **Hermes-агент**: крон-джоб спрашивает в Telegram нужный код, ждёт ответа через webhook
|
||||
3. **Простой stdin**: скрипт пишет "Введите код для Тинькофф:" и ждёт ввод (если запуск из терминала)
|
||||
|
||||
**Рекомендация: вариант 1** — TG bot минимальная зависимость, полный контроль.
|
||||
|
||||
Для реализации: существующий Hermes/Zulip может служить relay. Или простой скрипт на Python + python-telegram-bot с `await incoming_message`.
|
||||
|
||||
### 6. Чувствительность данных — ограничения
|
||||
|
||||
Скрипт будет:
|
||||
- Знать **логины/пароли** банков (хранятся в локальном конфиге, НЕ в коде)
|
||||
- Открывать **браузер на машине Алекса** (никаких VPN/прокси)
|
||||
- Передавать только SMS-коды через TG — пароли не передаются
|
||||
- Работать **локально**, без LLM/агентов в browser automation
|
||||
|
||||
Код пишем так, чтобы ни одна строка credentials не была в скрипте:
|
||||
```python
|
||||
# config.yaml (chmod 600)
|
||||
banks:
|
||||
tinkoff:
|
||||
login: "7999..."
|
||||
password: "..."
|
||||
phone: "7999..."
|
||||
sber:
|
||||
login: "..."
|
||||
password: "..."
|
||||
```
|
||||
|
||||
### 7. Альтернатива: API банков (без browser)
|
||||
|
||||
| Банк | REST API для личных счетов | Комментарий |
|
||||
|------|---------------------------|-------------|
|
||||
| Тинькофф | Есть (Tinkoff API для разработчиков) | Требует регистрации приложения, OAuth |
|
||||
| Сбер | Sber API для юрлиц, нет для личных | Не подходит |
|
||||
| Альфа | Альфа-Бизнес API (юрлица) | Не подходит |
|
||||
| Demir | Нет публичного API | — |
|
||||
| ВТБ | Нет публичного API | — |
|
||||
|
||||
Тинькофф — единственный из списка, у кого есть адекватный API для физлиц (Tinkoff API / Tinkoff Invest API). Можно получить выписку через API, без browser. Остальные — только SPA scraping.
|
||||
|
||||
**Код:** 10 swift-файлов, ~2 400 строк.
|
||||
|
||||
**Что хорошо:**
|
||||
- Хорошая архитектура: каждый банк = отдельный struct с чётким интерфейсом
|
||||
- Конфиги вынесены из кода (JSON)
|
||||
- Regex-маппинг категорий гибкий
|
||||
- Умеет объединять multi-part CSV и извлекать из PDF через Adobe API
|
||||
- Формат вывода совпадает со структурой Excel/Budget App
|
||||
|
||||
**Чего не хватает:**
|
||||
- Парсер Альфа-банка (только заглушка)
|
||||
- AI-категоризация закомментирована (GPT-3.5, устарела)
|
||||
- Нет интеграции с Budget App (только → CSV, не → БД)
|
||||
- Нет обработки для Demir ИП USD / Demir USD / Demir KGS отдельно (DemirToCSV один конфиг на все)
|
||||
- PDF-парсер привязан к Adobe PDF Extract API (платный сервис, credentials нужны)
|
||||
- Нет обработки для Сбер Кредитка как отдельного счёта (SberToCSV один конфиг)
|
||||
- Нет автоматического определения новых форматов CSV от банков
|
||||
Reference in New Issue
Block a user