[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:
Taiga
2026-06-25 05:23:46 +00:00
parent ac0d753ec0
commit 16987d69f3
26 changed files with 2656 additions and 457 deletions
@@ -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 от банков