diff --git a/backend/src/utils.ts b/backend/src/utils.ts index aa90ea1..2eb3e64 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from 'express'; export function maskAccountNumber(num: string): string { if (num.length <= 10) return num; - return num.slice(0, 6) + '*'.repeat(num.length - 10) + num.slice(-4); + return num.slice(0, 6) + '******' + num.slice(-4); } export function escapeLike(input: string): string { diff --git a/docs/agents/agent_backend.md b/docs/agents/agent_backend.md index 387c4d5..3a78f3b 100644 --- a/docs/agents/agent_backend.md +++ b/docs/agents/agent_backend.md @@ -30,7 +30,7 @@ 2 Миграции БД - Реализовать таблицы и поля строго по `db.md`, `category.md`, `edit_and_rules.md`, `analytics.md`. -- Включить все описанные CHECK/UNIQUE/FOREIGN KEY/дополнительные поля (`is_category_confirmed`, `comment`, `alias` для accounts, `budgets` и т.д.). +- Включить все описанные CHECK/UNIQUE/FOREIGN KEY/дополнительные поля (`is_category_confirmed`, `comment`, `alias` для accounts и т.д.). 3 Авторизация и сессии diff --git a/docs/backlog/analytics.md b/docs/backlog/analytics.md index b926d06..4fb9b21 100644 --- a/docs/backlog/analytics.md +++ b/docs/backlog/analytics.md @@ -136,6 +136,8 @@ ## 5.3. Задел под бюджеты (лимиты) +> **Не входит в MVP.** Этот раздел описывает будущую функциональность; таблица `budgets` и связанная логика реализуются после MVP. + Для поддержки бюджетов по категориям на будущих этапах вводится сущность `budgets`. ### Таблица `budgets` (идея) diff --git a/docs/backlog/api_import.md b/docs/backlog/api_import.md index 280ff98..991a2a5 100644 --- a/docs/backlog/api_import.md +++ b/docs/backlog/api_import.md @@ -175,7 +175,7 @@ accountNumber|operationAt|amountSigned|commission|normalizedDescription { "accountId": 1, "isNewAccount": true, - "accountNumberMasked": "408178**********5611", + "accountNumberMasked": "408178******5611", "imported": 28, "duplicatesSkipped": 3, "totalInFile": 31 @@ -197,8 +197,8 @@ accountNumber|operationAt|amountSigned|commission|normalizedDescription - Первые 6 символов остаются открытыми. - Последние 4 символа остаются открытыми. -- Промежуточные символы заменяются на `*`. -- Пример: `40817810825104025611` → `408178**********5611`. +- Промежуточные символы заменяются фиксированным набором из 6 символов `******` (количество звёздочек не раскрывает длину номера). +- Пример: `40817810825104025611` → `408178******5611`. Маскирование применяется в ответе этого эндпоинта и в `GET /api/accounts`. diff --git a/docs/backlog/db.md b/docs/backlog/db.md index ad7a37d..48bbb67 100644 --- a/docs/backlog/db.md +++ b/docs/backlog/db.md @@ -5,8 +5,10 @@ - Используется PostgreSQL, развёрнутый локально (например, на Synology). - Основные сущности: - `accounts` — банковские счета пользователя; + - `categories` — категории расходов, доходов и переводов; - `transactions` — движения средств по счетам; - - `category_rules` — правила автоматической категоризации транзакций (подготовка к SPA-редактору правил). + - `category_rules` — правила автоматической категоризации транзакций; + - `sessions` — серверные сессии авторизации. - Все суммы хранятся в минорных единицах (копейки) как `BIGINT`. - Время хранится в `TIMESTAMPTZ` (временная зона сохраняется). @@ -20,6 +22,8 @@ - `bank TEXT NOT NULL` — код/имя банка (например, `"VTB"`). - `account_number TEXT NOT NULL` — номер счёта в банке (как в выписке). - `currency TEXT NOT NULL` — код валюты счёта (например, `"RUB"`). +- `alias TEXT` — человекочитаемый алиас счёта (например, `"Текущий"`, `"Накопительный"`). + При создании счёта через импорт `alias = NULL`; пользователь задаёт его позже через SPA. Ограничения и индексы: @@ -32,21 +36,57 @@ CREATE TABLE accounts ( id BIGSERIAL PRIMARY KEY, bank TEXT NOT NULL, account_number TEXT NOT NULL, - currency TEXT NOT NULL + currency TEXT NOT NULL, + alias TEXT ); CREATE UNIQUE INDEX ux_accounts_bank_number ON accounts(bank, account_number); ``` +## Таблица `categories` + +Предназначение: хранение категорий для классификации транзакций. + +Структура: + +- `id BIGSERIAL PRIMARY KEY` — идентификатор категории. +- `name TEXT NOT NULL` — отображаемое имя категории (например, `"Продукты"`, `"ЖКХ"`). +- `type TEXT NOT NULL` — тип категории: + - `"expense"` — расходная категория; + - `"income"` — доходная категория; + - `"transfer"` — переводы между собственными счетами. +- `is_active BOOLEAN NOT NULL DEFAULT TRUE` — используется ли категория. + +Ограничения: + +- CHECK-ограничение: `type IN ('expense', 'income', 'transfer')`. + +Рекомендуемый DDL: + +```sql +CREATE TABLE categories ( + id BIGSERIAL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT TRUE +); + +ALTER TABLE categories + ADD CONSTRAINT chk_categories_type + CHECK (type IN ('expense', 'income', 'transfer')); +``` + +Начальный набор из 23 категорий заполняется seed-миграцией (см. `category.md`). + ## Таблица `transactions` -Предназначение: хранение всех операций по счетам с привязкой к `accounts`. +Предназначение: хранение всех операций по счетам с привязкой к `accounts` и `categories`. Структура: - `id BIGSERIAL PRIMARY KEY` — внутренний идентификатор транзакции. -- `account_id BIGINT NOT NULL` — внешний ключ (FK) на `accounts(id)`; +- `account_id BIGINT NOT NULL REFERENCES accounts(id)` — каждая транзакция жёстко привязана к одному счёту. - `operation_at TIMESTAMPTZ NOT NULL` — дата и время операции. - `amount_signed BIGINT NOT NULL` — сумма операции в копейках; знак отражает тип движения (приход/расход). @@ -57,31 +97,37 @@ CREATE UNIQUE INDEX ux_accounts_bank_number - `"expense"` — расход; - `"transfer"` — перевод между своими счетами / на другие свои счета. - `fingerprint TEXT NOT NULL` — вычисляемый хэш для обеспечения идемпотентности импорта. -- `category_id BIGINT` — ссылка на таблицу категорий (будет определена позже). +- `category_id BIGINT REFERENCES categories(id)` — ссылка на категорию; `NULL` для некатегоризированных транзакций. +- `is_category_confirmed BOOLEAN NOT NULL DEFAULT FALSE` — + признак того, что категория подтверждена пользователем (явно или неявно через правило без `requires_confirmation`). +- `comment TEXT` — пользовательский комментарий к транзакции. - `created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()` — время создания записи в БД. - `updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()` — время последнего обновления записи. Ограничения и индексы: -- Внешний ключ `account_id` ссылается на `accounts(id)` и обеспечивает целостность (нельзя создать транзакцию для несуществующего счёта). +- Внешний ключ `account_id` ссылается на `accounts(id)`. +- Внешний ключ `category_id` ссылается на `categories(id)`. - Уникальный индекс `(account_id, fingerprint)` обеспечивает идемпотентность: одна и та же операция не может быть загружена дважды. -- Опционально — CHECK-ограничение на поле `direction`. +- CHECK-ограничение: `direction IN ('income', 'expense', 'transfer')`. Рекомендуемый DDL: ```sql CREATE TABLE transactions ( - id BIGSERIAL PRIMARY KEY, - account_id BIGINT NOT NULL REFERENCES accounts(id), - operation_at TIMESTAMPTZ NOT NULL, - amount_signed BIGINT NOT NULL, - commission BIGINT NOT NULL, - description TEXT NOT NULL, - direction TEXT NOT NULL, - fingerprint TEXT NOT NULL, - category_id BIGINT, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + id BIGSERIAL PRIMARY KEY, + account_id BIGINT NOT NULL REFERENCES accounts(id), + operation_at TIMESTAMPTZ NOT NULL, + amount_signed BIGINT NOT NULL, + commission BIGINT NOT NULL, + description TEXT NOT NULL, + direction TEXT NOT NULL, + fingerprint TEXT NOT NULL, + category_id BIGINT REFERENCES categories(id), + is_category_confirmed BOOLEAN NOT NULL DEFAULT FALSE, + comment TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE UNIQUE INDEX ux_transactions_account_fingerprint @@ -105,7 +151,7 @@ ALTER TABLE transactions - `"starts_with"` — строка начинается с шаблона; - `"regex"` — регулярное выражение (формируется и/или проверяется в коде на основе пользовательского ввода). - MVP: при создании правила принимается только `"contains"`. Расширение до `"starts_with"` | `"regex"` запланировано. -- `category_id BIGINT NOT NULL` — ссылка на категорию (таблица категорий будет описана отдельно). +- `category_id BIGINT NOT NULL REFERENCES categories(id)` — ссылка на категорию. - `priority INT NOT NULL DEFAULT 0` — приоритет правила; чем выше число, тем раньше правило применяется при конфликте. - `requires_confirmation BOOLEAN NOT NULL DEFAULT FALSE` — если `TRUE`, транзакции, категоризированные этим правилом, получают `is_category_confirmed = FALSE` @@ -127,7 +173,7 @@ CREATE TABLE category_rules ( id BIGSERIAL PRIMARY KEY, pattern TEXT NOT NULL, match_type TEXT NOT NULL, - category_id BIGINT NOT NULL, + category_id BIGINT NOT NULL REFERENCES categories(id), priority INT NOT NULL DEFAULT 0, requires_confirmation BOOLEAN NOT NULL DEFAULT FALSE, is_active BOOLEAN NOT NULL DEFAULT TRUE, @@ -135,19 +181,46 @@ CREATE TABLE category_rules ( ); ``` +## Таблица `sessions` + +Предназначение: хранение серверных сессий авторизации с поддержкой таймаута по бездействию. + +Структура: + +- `id TEXT PRIMARY KEY` — идентификатор сессии (UUID). +- `created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()` — время создания сессии. +- `last_activity_at TIMESTAMPTZ NOT NULL DEFAULT NOW()` — время последней активности; обновляется при каждом запросе с действительной сессией. +- `is_active BOOLEAN NOT NULL DEFAULT TRUE` — флаг активности; устанавливается в `FALSE` при логауте или истечении таймаута. + +Рекомендуемый DDL: + +```sql +CREATE TABLE sessions ( + id TEXT PRIMARY KEY, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + last_activity_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + is_active BOOLEAN NOT NULL DEFAULT TRUE +); +``` + +## Таблица `budgets` (после MVP) + +> **Не входит в MVP.** Таблица запланирована для поддержки бюджетов/лимитов по категориям +> на будущих этапах. Подробности см. в `analytics.md`, секция 5.3. + ## Взаимосвязь JSON → БД при импорте 1. По полям `bank` и `statement.accountNumber` ищется или создаётся запись в `accounts`. Если счёт создан впервые, `alias = NULL`. 2. Для каждой транзакции из `transactions`: - - преобразуются суммы в копейки (`amountSigned`, `commission` → `BIGINT`); + - суммы в JSON 1.0 уже в копейках — записываются как есть; - вычисляется `fingerprint` на основе комбинации полей (например, `accountNumber + operationAt + amountSigned + commission + normalizedDescription`); - определяется `direction`: - `amountSigned > 0` → `"income"`; - `amountSigned < 0` → `"expense"`; - `"transfer"` — определяется по фиксированным ключевым фразам банка в `description` - (например, для ВТБ: "Перевод", "между счетами" и т.п.). + (например, для ВТБ: "Перевод между своими счетами", "Внутри ВТБ" и т.п.). Если ключевые фразы не сработали — остаётся `"income"` / `"expense"` по знаку суммы; - выполняется попытка вставки в `transactions`; - при срабатывании уникального ограничения `(account_id, fingerprint)` запись считается дубликатом и пропускается; diff --git a/docs/test_Statement.json b/docs/test_Statement.json index 42fbdf6..217c75a 100644 --- a/docs/test_Statement.json +++ b/docs/test_Statement.json @@ -4,227 +4,196 @@ "statement": { "accountNumber": "40817810825104025611", "currency": "RUB", - "openingBalance": 42561.67, - "closingBalance": 88459.38, + "openingBalance": 4256167, + "closingBalance": 8845938, "exportedAt": "2026-02-27T13:23:00+03:00" }, "transactions": [ { "operationAt": "2026-02-26T14:06:57+03:00", - "amountSigned": -500.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. PAVELETSKAYA. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-26T14:06:57+03:00-500.000.00Оплата товаров и услуг. PAVELETSKAYA. по карте *8214" + "amountSigned": -50000, + "commission": 0, + "description": "Оплата товаров и услуг. PAVELETSKAYA. по карте *8214" }, { "operationAt": "2026-02-26T11:46:14+03:00", - "amountSigned": -83.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. MOS.TRANSPORT. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-26T11:46:14+03:00-83.000.00Оплата товаров и услуг. MOS.TRANSPORT. по карте *8214" + "amountSigned": -8300, + "commission": 0, + "description": "Оплата товаров и услуг. MOS.TRANSPORT. по карте *8214" }, { "operationAt": "2026-02-25T23:12:10+03:00", - "amountSigned": 477.0, - "commission": 0.0, - "description": "Зачисление кешбэка за покупки у партнеров. Перечисление бонусных рублей на счета получателя за покупки у партнеров согласно реестру Z_3507_20260225_1 согласно Договору МБ-14Х/25.", - "fingerprint": "sha256:408178108251040256112026-02-25T23:12:10+03:00477.000.00Зачисление кешбэка за покупки у партнеров. Перечисление бонусных рублей на счета получателя за покупки у партнеров согласно реестру Z_3507_20260225_1 согласно Договору МБ-14Х/25." + "amountSigned": 47700, + "commission": 0, + "description": "Зачисление кешбэка за покупки у партнеров. Перечисление бонусных рублей на счета получателя за покупки у партнеров согласно реестру Z_3507_20260225_1 согласно Договору МБ-14Х/25." }, { "operationAt": "2026-02-25T16:37:47+03:00", - "amountSigned": -449.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. OZON.RU. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-25T16:37:47+03:00-449.000.00Оплата товаров и услуг. OZON.RU. по карте *2249" + "amountSigned": -44900, + "commission": 0, + "description": "Оплата товаров и услуг. OZON.RU. по карте *2249" }, { "operationAt": "2026-02-25T12:09:51+03:00", - "amountSigned": -3700.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. Lab4uru App. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-25T12:09:51+03:00-3700.000.00Оплата товаров и услуг. Lab4uru App. по карте *2249" + "amountSigned": -370000, + "commission": 0, + "description": "Оплата товаров и услуг. Lab4uru App. по карте *2249" }, { "operationAt": "2026-02-25T11:18:38+03:00", - "amountSigned": -1821.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. WILDBERRIES. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-25T11:18:38+03:00-1821.000.00Оплата товаров и услуг. WILDBERRIES. по карте *2249" + "amountSigned": -182100, + "commission": 0, + "description": "Оплата товаров и услуг. WILDBERRIES. по карте *2249" }, { "operationAt": "2026-02-24T21:49:31+03:00", - "amountSigned": -100000.0, - "commission": 0.0, - "description": "Перевод между своими счетами. Перечисление ДС для приобретения ценных бумаг. Основной рынок. Субпозиция №460827 (НДС не обл.) Канал - ВТБО. Шестеров Антон Владимирович.", - "fingerprint": "sha256:408178108251040256112026-02-24T21:49:31+03:00-100000.000.00Перевод между своими счетами. Перечисление ДС для приобретения ценных бумаг. Основной рынок. Субпозиция №460827 (НДС не обл.) Канал - ВТБО. Шестеров Антон Владимирович." + "amountSigned": -10000000, + "commission": 0, + "description": "Перевод между своими счетами. Перечисление ДС для приобретения ценных бумаг. Основной рынок. Субпозиция №460827 (НДС не обл.) Канал - ВТБО. Шестеров Антон Владимирович." }, { "operationAt": "2026-02-24T17:31:00+03:00", - "amountSigned": -214.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. STOLOVAYA 2. по карте *9058", - "fingerprint": "sha256:408178108251040256112026-02-24T17:31:00+03:00-214.000.00Оплата товаров и услуг. STOLOVAYA 2. по карте *9058" + "amountSigned": -21400, + "commission": 0, + "description": "Оплата товаров и услуг. STOLOVAYA 2. по карте *9058" }, { "operationAt": "2026-02-24T17:03:39+03:00", - "amountSigned": -26000.0, - "commission": 0.0, - "description": "Перевод между своими счетами. Перечисление средств на счет 2631", - "fingerprint": "sha256:408178108251040256112026-02-24T17:03:39+03:00-26000.000.00Перевод между своими счетами. Перечисление средств на счет 2631" + "amountSigned": -2600000, + "commission": 0, + "description": "Перевод между своими счетами. Перечисление средств на счет 2631" }, { "operationAt": "2026-02-24T17:03:24+03:00", - "amountSigned": -50000.0, - "commission": 0.0, - "description": "Перевод между своими счетами. Перечисление средств на счет 0292", - "fingerprint": "sha256:408178108251040256112026-02-24T17:03:24+03:00-50000.000.00Перевод между своими счетами. Перечисление средств на счет 0292" + "amountSigned": -5000000, + "commission": 0, + "description": "Перевод между своими счетами. Перечисление средств на счет 0292" }, { "operationAt": "2026-02-24T16:11:21+03:00", - "amountSigned": 189520.22, - "commission": 0.0, - "description": "Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_001_01 от 20.02.2026. Без НДС.", - "fingerprint": "sha256:408178108251040256112026-02-24T16:11:21+03:00189520.220.00Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_001_01 от 20.02.2026. Без НДС." + "amountSigned": 18952022, + "commission": 0, + "description": "Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_001_01 от 20.02.2026. Без НДС." }, { "operationAt": "2026-02-24T16:09:15+03:00", - "amountSigned": 72393.53, - "commission": 0.0, - "description": "Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_010_01 от 20.02.2026. Без НДС.", - "fingerprint": "sha256:408178108251040256112026-02-24T16:09:15+03:0072393.530.00Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_010_01 от 20.02.2026. Без НДС." + "amountSigned": 7239353, + "commission": 0, + "description": "Поступление заработной платы. 0726 НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ \"ВЫСША Поступление заработной платы/иных выплат Salary по реестру Z_0000005862_20260220_010_01 от 20.02.2026. Без НДС." }, { "operationAt": "2026-02-24T14:29:53+03:00", - "amountSigned": -778.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. VKUSVILL_665_2. по карте *9058", - "fingerprint": "sha256:408178108251040256112026-02-24T14:29:53+03:00-778.000.00Оплата товаров и услуг. VKUSVILL_665_2. по карте *9058" + "amountSigned": -77800, + "commission": 0, + "description": "Оплата товаров и услуг. VKUSVILL_665_2. по карте *9058" }, { "operationAt": "2026-02-24T14:20:59+03:00", - "amountSigned": -6180.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. Lab4uru App. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-24T14:20:59+03:00-6180.000.00Оплата товаров и услуг. Lab4uru App. по карте *2249" + "amountSigned": -618000, + "commission": 0, + "description": "Оплата товаров и услуг. Lab4uru App. по карте *2249" }, { "operationAt": "2026-02-24T13:05:47+03:00", - "amountSigned": -280.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. STOLOVAYA.. по карте *9058", - "fingerprint": "sha256:408178108251040256112026-02-24T13:05:47+03:00-280.000.00Оплата товаров и услуг. STOLOVAYA.. по карте *9058" + "amountSigned": -28000, + "commission": 0, + "description": "Оплата товаров и услуг. STOLOVAYA.. по карте *9058" }, { "operationAt": "2026-02-24T11:35:33+03:00", - "amountSigned": -9824.3, - "commission": 0.0, - "description": "Оплата товаров и услуг. SKLAD MSK. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-24T11:35:33+03:00-9824.300.00Оплата товаров и услуг. SKLAD MSK. по карте *8214" + "amountSigned": -982430, + "commission": 0, + "description": "Оплата товаров и услуг. SKLAD MSK. по карте *8214" }, { "operationAt": "2026-02-24T09:32:11+03:00", - "amountSigned": -800.0, - "commission": 0.0, - "description": "Внутри ВТБ. Ахмедов Али Эльдар оглы.", - "fingerprint": "sha256:408178108251040256112026-02-24T09:32:11+03:00-800.000.00Внутри ВТБ. Ахмедов Али Эльдар оглы." + "amountSigned": -80000, + "commission": 0, + "description": "Внутри ВТБ. Ахмедов Али Эльдар оглы." }, { "operationAt": "2026-02-24T09:29:30+03:00", - "amountSigned": -5132.72, - "commission": 0.0, - "description": "Оплата товаров и услуг. RNAZK MC013. по карте *9058", - "fingerprint": "sha256:408178108251040256112026-02-24T09:29:30+03:00-5132.720.00Оплата товаров и услуг. RNAZK MC013. по карте *9058" + "amountSigned": -513272, + "commission": 0, + "description": "Оплата товаров и услуг. RNAZK MC013. по карте *9058" }, { "operationAt": "2026-02-23T20:58:02+03:00", - "amountSigned": -515.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. OZON. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-23T20:58:02+03:00-515.000.00Оплата товаров и услуг. OZON. по карте *2249" + "amountSigned": -51500, + "commission": 0, + "description": "Оплата товаров и услуг. OZON. по карте *2249" }, { "operationAt": "2026-02-23T15:31:37+03:00", - "amountSigned": -1105.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. ZOOMAGAZIN CHETYRE LAP. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-23T15:31:37+03:00-1105.000.00Оплата товаров и услуг. ZOOMAGAZIN CHETYRE LAP. по карте *8214" + "amountSigned": -110500, + "commission": 0, + "description": "Оплата товаров и услуг. ZOOMAGAZIN CHETYRE LAP. по карте *8214" }, { "operationAt": "2026-02-23T15:25:53+03:00", - "amountSigned": -225.97, - "commission": 0.0, - "description": "Оплата товаров и услуг. PYATEROCHKA 6993. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-23T15:25:53+03:00-225.970.00Оплата товаров и услуг. PYATEROCHKA 6993. по карте *8214" + "amountSigned": -22597, + "commission": 0, + "description": "Оплата товаров и услуг. PYATEROCHKA 6993. по карте *8214" }, { "operationAt": "2026-02-23T13:34:47+03:00", - "amountSigned": -3926.33, - "commission": 0.0, - "description": "Оплата товаров и услуг. DOSTAVKA PEREKRESTKA_S. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-23T13:34:47+03:00-3926.330.00Оплата товаров и услуг. DOSTAVKA PEREKRESTKA_S. по карте *2249" + "amountSigned": -392633, + "commission": 0, + "description": "Оплата товаров и услуг. DOSTAVKA PEREKRESTKA_S. по карте *2249" }, { "operationAt": "2026-02-22T22:32:47+03:00", - "amountSigned": -79.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. OZON.RU. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-22T22:32:47+03:00-79.000.00Оплата товаров и услуг. OZON.RU. по карте *2249" + "amountSigned": -7900, + "commission": 0, + "description": "Оплата товаров и услуг. OZON.RU. по карте *2249" }, { "operationAt": "2026-02-22T19:59:48+03:00", - "amountSigned": -493.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. OZON.RU. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-22T19:59:48+03:00-493.000.00Оплата товаров и услуг. OZON.RU. по карте *2249" + "amountSigned": -49300, + "commission": 0, + "description": "Оплата товаров и услуг. OZON.RU. по карте *2249" }, { "operationAt": "2026-02-22T19:55:28+03:00", - "amountSigned": -536.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. OZON. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-22T19:55:28+03:00-536.000.00Оплата товаров и услуг. OZON. по карте *2249" + "amountSigned": -53600, + "commission": 0, + "description": "Оплата товаров и услуг. OZON. по карте *2249" }, { "operationAt": "2026-02-22T11:13:21+03:00", - "amountSigned": -61.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. CPPK-2000012-BPA20. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-22T11:13:21+03:00-61.000.00Оплата товаров и услуг. CPPK-2000012-BPA20. по карте *8214" + "amountSigned": -6100, + "commission": 0, + "description": "Оплата товаров и услуг. CPPK-2000012-BPA20. по карте *8214" }, { "operationAt": "2026-02-21T18:40:37+03:00", - "amountSigned": -1380.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. mkad. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-21T18:40:37+03:00-1380.000.00Оплата товаров и услуг. mkad. по карте *2249" + "amountSigned": -138000, + "commission": 0, + "description": "Оплата товаров и услуг. mkad. по карте *2249" }, { "operationAt": "2026-02-21T11:29:26+03:00", - "amountSigned": -1715.87, - "commission": 0.0, - "description": "Оплата товаров и услуг. MAGNIT MK STAROPOTAPOV. по карте *8214", - "fingerprint": "sha256:408178108251040256112026-02-21T11:29:26+03:00-1715.870.00Оплата товаров и услуг. MAGNIT MK STAROPOTAPOV. по карте *8214" + "amountSigned": -171587, + "commission": 0, + "description": "Оплата товаров и услуг. MAGNIT MK STAROPOTAPOV. по карте *8214" }, { "operationAt": "2026-02-21T10:03:16+03:00", - "amountSigned": -3700.0, - "commission": 0.0, - "description": "Оплата товаров и услуг. CP* SPIRITFIT.RU. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-21T10:03:16+03:00-3700.000.00Оплата товаров и услуг. CP* SPIRITFIT.RU. по карте *2249" + "amountSigned": -370000, + "commission": 0, + "description": "Оплата товаров и услуг. CP* SPIRITFIT.RU. по карте *2249" }, { "operationAt": "2026-02-21T09:55:24+03:00", - "amountSigned": -32.99, - "commission": 0.0, - "description": "Оплата товаров и услуг. GLOBUS KOROLEV. по карте *9058", - "fingerprint": "sha256:408178108251040256112026-02-21T09:55:24+03:00-32.990.00Оплата товаров и услуг. GLOBUS KOROLEV. по карте *9058" + "amountSigned": -3299, + "commission": 0, + "description": "Оплата товаров и услуг. GLOBUS KOROLEV. по карте *9058" }, { "operationAt": "2026-02-20T15:23:19+03:00", - "amountSigned": -1438.86, - "commission": 0.0, - "description": "Оплата товаров и услуг. DOSTAVKA IZ PYATEROCHK. по карте *2249", - "fingerprint": "sha256:408178108251040256112026-02-20T15:23:19+03:00-1438.860.00Оплата товаров и услуг. DOSTAVKA IZ PYATEROCHK. по карте *2249" + "amountSigned": -143886, + "commission": 0, + "description": "Оплата товаров и услуг. DOSTAVKA IZ PYATEROCHK. по карте *2249" } ] }