No description
  • TypeScript 96.6%
  • Shell 2.2%
  • CSS 0.9%
  • JavaScript 0.2%
Find a file
AButorov 52f4ecbb5a
Some checks failed
Deploy to Cloudflare Pages / deploy (push) Has been cancelled
Migrate deploy: GitHub Pages → Cloudflare Pages via Forgejo Actions
2026-05-20 22:39:24 +00:00
.devcontainer update libary 2026-05-20 21:21:29 +00:00
.forgejo/workflows Migrate deploy: GitHub Pages → Cloudflare Pages via Forgejo Actions 2026-05-20 22:39:24 +00:00
doc Migrate deploy: GitHub Pages → Cloudflare Pages via Forgejo Actions 2026-05-20 22:39:24 +00:00
public/data - тестовые данные 2026-05-20 20:58:33 +00:00
scripts Пороги декларирования: 2026-05-19 21:50:21 +00:00
src Migrate deploy: GitHub Pages → Cloudflare Pages via Forgejo Actions 2026-05-20 22:39:24 +00:00
.env.example add step4 - read data 2026-05-12 14:20:48 +00:00
.gitignore cluade + doc/ 2026-05-06 01:25:15 +00:00
bun.lock update libary 2026-05-20 21:21:29 +00:00
CLAUDE.md update libary 2026-05-20 21:21:29 +00:00
components.json Initial template 2026-05-04 18:59:09 +03:00
eslint.config.js Initial template 2026-05-04 18:59:09 +03:00
index.html Initial template 2026-05-04 18:59:09 +03:00
new-project.sh add new-project.sh 2026-05-04 20:25:00 +00:00
package.json update libary 2026-05-20 21:21:29 +00:00
README.md doc 2026-05-19 21:57:22 +00:00
tsconfig.app.json add step 3 - validation 2026-05-06 21:55:23 +00:00
tsconfig.json Initial template 2026-05-04 18:59:09 +03:00
tsconfig.node.json select parser 2026-05-06 20:16:36 +00:00
vite.config.ts Migrate deploy: GitHub Pages → Cloudflare Pages via Forgejo Actions 2026-05-20 22:39:24 +00:00

BrokerVergi

Веб-приложение для налогового резидента Турции. Принимает выгрузки Interactive Brokers (IBKR) в формате XML (Flex Query), рассчитывает налоговые базы по турецкому законодательству (GVK) и формирует сводную таблицу и экспортные файлы для налогового консультанта.

Статический SPA — без бэкенда, без хранения данных на сервере. Все расчёты выполняются в браузере.


Разработка

bun run dev      # Dev-сервер → http://localhost:5173
bun run build    # TypeScript check + сборка в dist/
bun run lint     # ESLint
bun run preview  # Предпросмотр production-сборки

Предварительная загрузка внешних данных

Перед сборкой рекомендуется обновить кэш курсов и индекса Yİ-ÜFE, чтобы приложение работало без API-ключа и без обращений к TCMB EVDS в браузере:

# Курсы USD/TRY (ежедневные)
bun run fetch-rates                                    # 2018-01-01 → сегодня  7 дней
bun run fetch-rates --from 2018-01-01 --to 2026-05-01  # явный диапазон
bun run fetch-rates --force                            # перезапросить все годы принудительно

# Индекс Yİ-ÜFE (ежемесячный)
bun run fetch-yuufe                                    # 2010-01-01 → сегодня  7 дней
bun run fetch-yuufe --from 2010-01-01 --to 2026-05-01  # явный диапазон
bun run fetch-yuufe --force                            # перезапросить принудительно
  • fetch-rates пропускает прошлые полные годы (≥ 200 записей); запрашивает только текущий год
  • fetch-yuufe пропускает, если файл уже содержит данные до предыдущего полного месяца
  • Оба скрипта требуют VITE_EVDS_API_KEY в .env
  • Результаты коммитятся в репозиторий и включаются в dist/ при сборке

Обновление порогов декларирования

Пороги MSİ (GVK Madde 86/1-c) хранятся в src/data/declarationThresholds.ts и обновляются вручную раз в год после публикации нового порога GİB:

bun run update-thresholds                              # показать текущие значения
bun run update-thresholds --year 2027 --amount 26000   # добавить год (помечается unofficial)
bun run update-thresholds --year 2027 --official       # подтвердить после проверки PDF GİB
  • Новые записи помечаются unofficial: true до ручной проверки по официальному PDF GİB
  • После проверки запускается --official для снятия флага
  • Изменённый src/data/declarationThresholds.ts коммитится в репозиторий

Добавление shadcn/ui компонентов

bunx --bun shadcn@latest add <component>
# Компоненты появляются в src/components/ui/

Переменные окружения

Скопировать .env.example в .env. Vite видит только переменные с префиксом VITE_.

Переменная Назначение
VITE_EVDS_API_KEY Ключ TCMB EVDS3 для загрузки курсов USD/TRY (нужен для fetch-rates и как фолбэк в браузере)
VITE_BASE_URL Base URL для GitHub Pages (прописывается в CI)

Стек

Инструмент Версия Назначение
Bun 1.x Runtime, пакетный менеджер
React 19 UI
TypeScript ~5.9 Типизация (erasableSyntaxOnly: true)
Vite 7 Dev-сервер и бандлер
React Router 7 Клиентская маршрутизация
Tailwind CSS v4 Стили
shadcn/ui latest UI-компоненты (Neutral theme)
Zustand 5 Глобальное состояние; язык (lang) сохраняется в localStorage
lucide-react latest Иконки
fast-xml-parser 5 Парсинг IBKR Flex Query XML
xlsx (SheetJS) 0.18 Генерация Excel-файлов в браузере

Локализация

Интерфейс доступен на трёх языках: RU / EN / TR. Переключатель — в правом верхнем углу шапки. Язык сохраняется в localStorage (bv_lang) и восстанавливается при следующем визите.

Строки хранятся в src/i18n/: ru.ts — эталонный файл с ключами as const; en.ts и tr.ts — явные Record<TranslationKey, string>. Компоненты используют хук useT(), сервисы — функцию t(lang, key, params?).


Прогресс реализации

Шаг Статус Описание
1 — Инструкция Ссылка на /instructions/ibkr-export
2 — Загрузка файлов File input (.xml, multiple) + тестовые данные (dev)
3 — Валидация Структурные проверки, дубли по accountId/периоду, продажи без истории покупок, статистика
4 — Загрузка данных Курсы USD/TRY (TCMB EVDS3) + Yİ-ÜFE (TÜİK, bundled fallback)
5 — Расчёт FIFO, Yİ-ÜFE индексация, дивиденды, проценты, SYEP
6 — Результаты Таблицы по разделам, итог для GİB, прогноз налога по GVK 103, проверка обязанности декларирования по GVK 86
7 — Экспорт Excel (.xlsx, 4 листа) + HTML-отчёт (.html, открыть в браузере → Ctrl+P → Save as PDF). Сводный лист/раздел включает: таблицу доходов, прогноз налога по GVK 103, блок проверки обязанности декларирования по GVK 86/1-c (статус DKİ и MSİ с суммами и ссылкой на PDF GİB), методологические примечания. Всегда формируются два файла: на языке интерфейса и на турецком (для бухгалтера). Исключение: если язык интерфейса — TR, файл один.

Именование экспортных файлов

Каждый файл содержит трёхбуквенный языковой суффикс:

Язык интерфейса Файлы Excel Файлы HTML
RU BrokerVergi-2024-RUS.xlsx + BrokerVergi-2024-TUR.xlsx BrokerVergi-2024-RUS.html + BrokerVergi-2024-TUR.html
EN BrokerVergi-2024-ENG.xlsx + BrokerVergi-2024-TUR.xlsx BrokerVergi-2024-ENG.html + BrokerVergi-2024-TUR.html
TR BrokerVergi-2024-TUR.xlsx BrokerVergi-2024-TUR.html

Deploy

Forgejo (self-hosted) → GitHub (mirror) → GitHub Pages

Push в main → GitHub Actions: bun installbun run build → deploy dist/.

Base URL берётся из переменной VITE_BASE_URL (прописана в CI).


Документация

Файл Содержимое
doc/algoritm.md Алгоритм расчёта: налоговые правила GVK, формулы, UX-флоу, открытые вопросы
doc/parser.md ТЗ модуля импорта IBKR: XML-формат, нормализация, архитектура
doc/how_make_xml.md Инструкция пользователю: выгрузка Flex Query XML из IBKR

Структура проекта

scripts/
├── fetch-rates.ts          # Bun-скрипт: курсы USD/TRY с TCMB EVDS3 → public/data/usd_try_rates.json
├── fetch-yuufe.ts          # Bun-скрипт: индекс Yİ-ÜFE с TCMB EVDS3 → public/data/yuufe.json
└── update-thresholds.ts    # Bun-скрипт: обновление порогов MSİ в src/data/declarationThresholds.ts

public/
├── data/
│   ├── usd_try_rates.json  # Предварительно загруженные курсы USD/TRY (генерируется скриптом, коммитится)
│   └── yuufe.json          # Предварительно загруженный индекс Yİ-ÜFE (генерируется скриптом, коммитится)
└── samples/                # Тестовые IBKR XML (dev-режим)

src/
├── i18n/
│   ├── ru.ts               # Русские строки — эталон, все ключи as const
│   ├── en.ts               # Английский перевод (Record<TranslationKey, string>)
│   ├── tr.ts               # Турецкий перевод (Record<TranslationKey, string>)
│   └── index.ts            # Lang, t(lang, key, params?), useT() хук
├── components/
│   ├── Layout.tsx              # Sticky header (логотип, версия, LanguageSwitcher, nav) + Outlet + footer
│   ├── LanguageSwitcher.tsx    # Переключатель RU / EN / TR в шапке
│   ├── TaxResultsView.tsx      # Результаты: год, 3 раздела, итог, прогноз налога
│   ├── ExportPanel.tsx         # Шаг 7: Excel + HTML кнопки по годам, двойной экспорт
│   └── ui/                     # shadcn/ui (генерируется через CLI)
├── data/
│   ├── yuufe.ts                # Bundled TÜİK Yİ-ÜFE (2018-01  2025-04, база 2010=100)
│   ├── taxBrackets.ts          # GVK Madde 103 прогрессивная шкала 20222026
│   └── declarationThresholds.ts # GVK Madde 86 пороги MSİ 20202026; обновляется скриптом
├── pages/
│   ├── HomePage.tsx
│   ├── CalculatorPage.tsx      # 7-шаговый stepper (всё реализовано)
│   ├── InstructionsPage.tsx
│   ├── instructions/           # Вложенные страницы раздела Инструкции
│   ├── ContactsPage.tsx
│   └── NotFoundPage.tsx
├── services/
│   ├── ibkr/
│   │   ├── parser.ts           # parseIBKRXml() → ParsedStatement | error
│   │   ├── validator.ts        # validateFiles() → ValidationResult + FileStats[]
│   │   └── types.ts            # IBKR domain-интерфейсы
│   ├── tax/
│   │   ├── types.ts            # CapitalGainLine, DividendLine, TaxYearResult, TaxResult
│   │   ├── normalize.ts        # RawAttrs[] → NormalizedOrder / NormalizedCashTx
│   │   ├── calculator.ts       # calculateTax() — FIFO + Yİ-ÜFE + дивиденды
│   │   └── estimator.ts        # estimateTax() — прогрессивный налог по GVK 103
│   ├── export/
│   │   ├── excel.ts            # exportYearToExcel(yr, est, lang) — SheetJS, 4 листа
│   │   └── pdf.ts              # downloadHtmlReport(yr, est, lang) — скачивает .html файл
│   ├── evds.ts                 # EvdsClient, evdsDateToIso, extractDailyRates/MonthlyIndex
│   ├── tcmb.ts                 # fetchRatesForYear (localStorage → static file → EVDS), parseTcmbCsv
│   ├── tuik.ts                 # fetchYiUfe (localStorage → static file → EVDS → bundled), mergeYiUfe
│   └── cache.ts                # cacheGet/Set/Clear — localStorage TTL
├── store/
│   └── appStore.ts             # Zustand: loadedFiles, tcmbRates, yiufeData, calcResult, lang
├── lib/
│   └── utils.ts                # cn() утилита
├── env.d.ts                    # declare __APP_VERSION__, __APP_BUILD_DATE__ (Vite define)
├── App.tsx                     # createBrowserRouter + маршруты
├── main.tsx
└── index.css                   # Tailwind v4 + shadcn CSS-переменные

Маршруты

Путь Страница
/ Главная
/calculator Расчёт (7 шагов)
/instructions/ibkr-export Выгрузка отчётов IBKR
/instructions/calculator-guide Режим расчёта
/instructions/results-guide Использование результатов
/instructions/other Прочие инструкции
/contacts Контакты