Типы транзакций
Обзор
Финапка поддерживает три типа транзакций и одну специальную категорию:
| Тип | TrnType | Описание |
|---|---|---|
| Расход | 0 | Потраченные деньги |
| Доход | 1 | Полученные деньги |
| Перевод | 2 | Перемещение денег между кошельками |
| Корректировка | 0 или 1 | Корректировка баланса (Расход или Доход с categoryId: 'adjustment') |
Расход
Обычная транзакция расхода. Уменьшает баланс кошелька.
- Требуется: кошелёк, категория, сумма
- Отображается в статистике расходов
- Сумма показывается со знаком минус
Доход
Обычная транзакция дохода. Увеличивает баланс кошелька.
- Требуется: кошелёк, категория, сумма
- Отображается в статистике доходов
- Сумма показывается со знаком плюс
Перевод
Перемещение денег между двумя кошельками. Не влияет на статистику доходов/расходов.
- Требуется: кошелёк расхода, кошелёк дохода, суммы для каждого
- Поддерживает разные валюты (например, кошелёк USD → кошелёк EUR)
- Использует системную категорию
transfer(categoryId: 'transfer') - Доступен только при наличии 2+ кошельков
Корректировка
Корректировка баланса кошелька. Влияет на баланс кошелька, но исключается из статистики доходов/расходов.
Как это работает
Корректировка - это не отдельный тип транзакции. Это обычная транзакция Расхода или Дохода с системной категорией adjustment (categoryId === 'adjustment').
- Расход + корректировка - уменьшает баланс кошелька (например, «потерянные деньги», корректировка вниз)
- Доход + корректировка - увеличивает баланс кошелька (например, «найденные деньги», корректировка вверх)
Определение
Корректировка определяется по categoryId, не по type:
const isAdjustment = trn.categoryId === 'adjustment'
Поведение
- Исключается из статистики доходов/расходов в
getTotal() - Исключается из недавних категорий в
recentCategoriesIds - Исключается из последней созданной транзакции в
lastCreatedTrnId - Включается в расчёт баланса кошелька (как отдельное поле
adjustmentв итогах) - Не показывается в дереве категорий (системная категория)
- Доступна в модальном окне выбора категории (Command Palette)
Системные категории
Две системные категории всегда присутствуют в хранилище и не могут быть изменены или удалены:
| ID | Название | Назначение |
|---|---|---|
transfer | Перевод | Используется переводами |
adjustment | Корректировка | Используется для корректировки баланса |
Эти категории:
- Автоматически добавляются в
useCategoriesStore.setCategories() - Исключены из
categoriesRootIds(не показываются в дереве категорий) - Защищены от редактирования/удаления в
saveCategory()иdeleteCategory()
Поведение при смене типа
При смене типа транзакции нормализация происходит на клиенте - в trnToRow (services/powersync/transforms.ts) при записи. Никакого серверного бэкенда для этого нет:
- → Перевод:
trnToRowустанавливаетcategoryIdв'transfer'и записываетexpenseWalletId/incomeWalletId/expenseAmount/incomeAmount; поля одного кошелька (walletId,amount) записываются какnull - → Расход/Доход:
trnToRowзаписываетwalletId/amount; поля перевода (expenseWalletId,incomeWalletId,expenseAmount,incomeAmount) записываются какnull - → Корректировка: дополнительная очистка не требуется - корректировка использует обычные поля Расхода/Дохода с
categoryId: 'adjustment'
Это гарантирует, что только поля, относящиеся к текущему типу, имеют ненулевые значения в локальной SQLite-строке и на сервере.
Статистика
getTotal() возвращает:
| Поле | Включает |
|---|---|
income | Транзакции дохода (исключая переводы и корректировки) |
expense | Транзакции расхода (исключая переводы и корректировки) |
adjustment | Транзакции корректировки (влияет на баланс кошелька) |
incomeTransfers | Сторона дохода перевода |
expenseTransfers | Сторона расхода перевода |
sum | income - expense |
sumTransfers | incomeTransfers - expenseTransfers |
Следующие шаги
- Синхронизация - как транзакции синхронизируются с сервером
- Тех. решения - обоснование ключевых решений