tempoweave
TempoWeave — локальное offline-first desktop-приложение поверх Kimai 2 для учёта времени, ставок, выплат, долгов, чеков НПД, налогов, загрузки и прогноза дохода.
Приложение не пытается заменить Kimai. Оно добавляет то, чего обычно не хватает индивидуальному разработчику и небольшому аутсорс-бизнесу: независимые оффлайн-таймеры, финансовую модель, графики выплат и сверку «отработано ↔ начислено ↔ выплачено ↔ подтверждено чеком».
Что уже работает
Заголовок раздела «Что уже работает»- Одновременные параллельные таймеры.
- Полностью локальная SQLite-база без отдельного сервера.
- Работа без интернета и очередь отправки в Kimai после восстановления сети.
- Идемпотентная синхронизация и дедупликация по отпечатку записи, Kimai ID и тегу
tempoweave:<uuid>. - Импорт истории из Kimai, создание новых записей и обновление уже синхронизированных через PATCH.
- Jira Cloud по email + API token и Jira Data Center по PAT.
- Локальный кэш задач Jira и оффлайн-поиск.
- Недельный календарь с часовой шкалой и разнесением параллельных интервалов по дорожкам.
- Почасовые ставки с периодами действия и приоритетами по проекту, активности, Jira-prefix и тегу.
- Фиксированные и почасовые проекты.
- Графики выплат: каждые N дней, ежемесячно, этапами в суммах/процентах и произвольным списком дат.
- Фактические выплаты с редактированием, автоматическим закрытием старых начислений, частичным распределением и явной привязкой к пункту платёжного графика.
- Долг и переплата в деньгах, а также отдельно остаток неоплаченных часов.
- Ручные денежные и часовые корректировки с обязательной причиной.
- Налог НПД с фактически полученных выплат; значение по умолчанию — 6%, с возможностью ставки по контрагенту.
- Импорт чеков НПД по публичной ссылке ФНС
/printили/json, а также из JSON/CSV. - Двусторонняя связь чека с выплатой без двойного учёта дохода; редактирование выплаты не теряет привязанный чек.
- Прогноз дохода по недавней дневной выработке, ограниченному тренду и статистическому коридору.
- Резервная копия SQLite и JSON-экспорт без токенов.
- Токены Kimai/Jira шифруются системным хранилищем Electron
safeStorage.
- Electron 43.
- Node.js 24 внутри Electron.
- Встроенный
node:sqlite, без нативных npm-модулей иelectron-rebuild. - Vanilla JavaScript, HTML и CSS без фронтенд-фреймворка.
- SQLite/WAL.
- REST API Kimai 2, Jira Cloud/Data Center и публичные JSON-представления чеков НПД.
Минимальное количество зависимостей снижает поверхность атак и упрощает сборку под Windows, Linux и macOS.
Быстрый запуск
Заголовок раздела «Быстрый запуск»Понадобятся Node.js 22.16+ и npm. Версия нужна из-за встроенной функции резервного копирования node:sqlite; само приложение работает на Node.js, входящем в Electron.
git clone https://github.com/localzet/tempoweave.gitcd tempoweavenpm installnpm testnpm startБаза создаётся автоматически в стандартном каталоге данных приложения:
- Windows:
%APPDATA%/TempoWeave/tempoweave.sqlite - Linux:
~/.config/TempoWeave/tempoweave.sqlite - macOS:
~/Library/Application Support/TempoWeave/tempoweave.sqlite
Точный путь определяется Electron через app.getPath('userData').
npm run dist:winnpm run dist:linuxnpm run dist:macАртефакты появятся в dist/.
Собирать установщик конкретной ОС надёжнее на этой же ОС. В репозитории есть workflow, который запускает тесты и собирает Windows, Linux и macOS параллельно.
Настройка Kimai 2
Заголовок раздела «Настройка Kimai 2»- В Kimai откройте профиль → API access.
- Создайте API token.
- В TempoWeave откройте Интеграции → Kimai 2.
- Укажите base URL без завершающего
/, напримерhttps://kimai.example.com. - Вставьте token и нажмите Сохранить, затем Проверить.
- Нажмите Каталоги ID, чтобы увидеть ID проектов и активностей.
- В разделе Проекты и ставки заполните
Kimai project IDиKimai activity IDдля каждого локального проекта.
TempoWeave отправляет в Kimai только завершённые записи. Запущенные оффлайн-таймеры остаются локальными до остановки.
Дедупликация Kimai
Заголовок раздела «Дедупликация Kimai»Каждая локальная запись получает UUID. При отправке в список тегов добавляется tempoweave:<uuid>. При повторном импорте используются:
- Kimai timesheet ID.
- UUID из тега.
- SHA-256 отпечаток проекта, активности, начала, конца, описания, Jira-ключа и тегов.
Перед новым POST TempoWeave дополнительно запрашивает небольшой диапазон вокруг начала записи и ищет UUID-маркер. Это закрывает случай, когда Kimai успел создать запись, но ответ потерялся из-за сетевого таймаута. Редактирование уже опубликованной записи отправляется как PATCH по сохранённому Kimai ID.
Повторный sync не должен создавать вторую запись. Локальное удаление намеренно не удаляет запись в Kimai: при следующем импорте она может появиться снова.
Настройка Jira
Заголовок раздела «Настройка Jira»Jira Cloud
Заголовок раздела «Jira Cloud»- Режим:
Cloud. - Base URL:
https://your-team.atlassian.net. - Email: email Atlassian-аккаунта.
- Token: API token Atlassian.
Jira Data Center
Заголовок раздела «Jira Data Center»- Режим:
Data Center. - Base URL: адрес Jira.
- Token: Personal Access Token.
- Email не используется.
JQL по умолчанию:
assignee = currentUser() AND resolution = Unresolved ORDER BY updated DESCПосле Обновить задачи записи сохраняются в SQLite и доступны в оффлайн-поиске.
Правила сортируются по числовому приоритету, затем по специфичности:
- Jira prefix.
- Активность.
- Тег.
- Проект.
- Глобальная ставка.
Можно задать даты С и До, поэтому изменение ставки не переписывает историю.
Примеры:
project, проект Localzet, 3500 ₽/ч.jira, значениеOPS, 5000 ₽/ч.tag, значениеsupport, 2500 ₽/ч.global, 2000 ₽/ч как резервное правило.
Выплаты, долг и часы
Заголовок раздела «Выплаты, долг и часы»TempoWeave разделяет три понятия:
- Начислено — billable-время × ставка, либо фиксированная стоимость проекта, плюс ручные денежные корректировки.
- Получено — фактические выплаты.
- Распределено — часть выплаты, которая закрыла конкретные записи времени.
При добавлении выплаты включено автораспределение: деньги закрывают самые старые неоплаченные начисления. Если выплата меньше начисления, запись закрывается частично. Если больше — остаток считается авансом/переплатой.
Формулы:
денежный долг = начислено + денежные корректировки - выплатынеоплаченные часы = отработанные часы + часовые корректировки - распределённые часыналог = сумма фактических выплат × ставка НПД / 100Денежный долг и долг в часах намеренно не смешиваются. Например, бонус или фиксированная доплата могут закрыть денежный долг, но не менять количество оплаченных часов без явного распределения.
Для фиксированного проекта договорная сумма учитывается целиком в общей аналитике, а в периодической аналитике — в периоде даты завершения проекта. Если дата завершения ещё не определена, этапные начисления удобно отражать денежными корректировками с причиной.
Графики выплат
Заголовок раздела «Графики выплат»Поддерживаются четыре режима:
- Каждые N дней — например, каждые 14 дней от опорной даты.
- Ежемесячно — заданный день месяца; для короткого месяца используется последний день.
- Этапы — строки
дата | сумма/процент | название. - Произвольно — тот же формат, но без предположения о порядке этапов.
Пример этапов:
2026-09-01 | 30% | Предоплата2026-10-15 | 50000 | Этап API2026-11-30 | 70% | Финальный расчётФактическая выплата может быть явно привязана к пункту графика либо автоматически сопоставлена с ближайшей ожидаемой датой. Частичные выплаты переводят пункт в partial, полное покрытие — в paid; редактирование и удаление выплаты пересчитывают статус заново.
Чеки НПД
Заголовок раздела «Чеки НПД»TempoWeave не хранит логин и пароль от «Мой налог» и не использует закрытую авторизацию ФНС.
Поддерживаются:
- публичная ссылка вида
.../api/v1/receipt/<ИНН>/<ID>/print; - та же ссылка с
/json; - JSON-файл;
- CSV-файл.
При загрузке /print приложение заменяет окончание на /json. Сетевой импорт разрешён только по HTTPS на nalog.ru и его поддоменах, без перехода по редиректам. Если ФНС изменит формат, остаётся импорт JSON/CSV и ручная связь с выплатой.
Чек не создаёт отдельную выплату: он связывается с уже полученной суммой и подтверждает её. Это исключает двойной доход и двойной налог.
Оффлайн-модель
Заголовок раздела «Оффлайн-модель»- Все изменения сначала фиксируются транзакцией SQLite.
- Завершённая запись времени добавляется в
outboxс уникальнымdedupe_key. - При запуске приложения и по таймеру выполняется отправка.
- Ошибка увеличивает
attemptsи назначает экспоненциальную задержку до одного часа. - Ручная синхронизация доступна всегда.
- Сбой Kimai не блокирует таймеры, календарь и финансовую аналитику.
Проверка проекта
Заголовок раздела «Проверка проекта»npm testnpm run checkТестами покрыты:
- устойчивый отпечаток и дедупликация;
- графики каждые N дней и ежемесячно;
- прогноз;
- CSV;
- формат времени Kimai;
- параллельные таймеры;
- почасовые начисления;
- частичная выплата и остаток в часах;
- налог;
- корректировки долга;
- повторный импорт Kimai и preflight-дедупликацию после сетевого таймаута;
- идемпотентное редактирование и удаление выплат в графике;
- ставку налога контрагента;
- расчёт незакрытых часов по отдельному периоду;
- нормализацию и импорт чеков НПД;
- проверку домена чеков против lookalike-хостов;
- PATCH обновлений Kimai с сохранением внутреннего маркера;
- двустороннюю связь выплаты и чека при редактировании.
Ограничения интеграций
Заголовок раздела «Ограничения интеграций»- Kimai может иметь дополнительные обязательные поля или нестандартные плагины. Проверьте
/api/docвашей установки. - Jira Cloud ориентирует публичные приложения на OAuth 2.0/Forge. Для персонального локального инструмента реализован email + API token; для Data Center — PAT.
- Формат публичного JSON чека НПД официально не позиционируется как стабильный контракт для сторонних приложений, поэтому импорт написан с несколькими вариантами названий полей и имеет файловый fallback.
Безопасность
Заголовок раздела «Безопасность»См. SECURITY.md и docs/ARCHITECTURE.md.
Лицензия
Заголовок раздела «Лицензия»MIT.
Исправления 1.0.1
Заголовок раздела «Исправления 1.0.1»- Импорт Kimai теперь передаёт диапазон дат в формате HTML5 datetime: начало дня
T00:00:00и конец дняT23:59:59. Это устраняетKimai 400: Bad Requestпри pull из календарных полей. - Base URL одинаково принимает
https://kimai.example.comиhttps://kimai.example.com/api. - Ошибки API теперь содержат HTTP-метод, путь и доступные validation details Kimai.
Исходный код · MIT