Ishtarkati — Arabic-first desktop tracker for subscriptions, renewals and account payments (Electron, offline, local SQLite)
  • TypeScript 94.5%
  • CSS 3.4%
  • JavaScript 2.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
balnaimi 24f9e3a054
All checks were successful
test / test (push) Successful in 2m20s
build-and-release / appimage (push) Successful in 2m27s
chore(release): v4.49.0
2026-09-27 23:06:59 +03:00
.forgejo/workflows feat: pause/resume, audit restore, price report, encrypted auto-backups 2026-09-27 23:06:56 +03:00
build feat: migrate Ishtarkati onto the desktop-standard contract 2026-09-11 16:43:03 +03:00
scripts feat: pause/resume, audit restore, price report, encrypted auto-backups 2026-09-27 23:06:56 +03:00
src feat: pause/resume, audit restore, price report, encrypted auto-backups 2026-09-27 23:06:56 +03:00
tests feat: pause/resume, audit restore, price report, encrypted auto-backups 2026-09-27 23:06:56 +03:00
.editorconfig chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
.gitignore chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
.prettierignore chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
.prettierrc chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
AGENTS.md chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
CHANGELOG.md chore(release): v4.49.0 2026-09-27 23:06:59 +03:00
electron-builder.yml feat: migrate Ishtarkati onto the desktop-standard contract 2026-09-11 16:43:03 +03:00
electron.vite.config.ts feat: pause/resume, audit restore, price report, encrypted auto-backups 2026-09-27 23:06:56 +03:00
eslint.config.mjs chore: tighten linting, error surfaces, performance and accessibility 2026-09-11 17:33:03 +03:00
LICENSE chore: scaffold ishtarkati from desktop-standard 2026-09-11 16:23:51 +03:00
package-lock.json chore(release): v4.49.0 2026-09-27 23:06:59 +03:00
package.json chore(release): v4.49.0 2026-09-27 23:06:59 +03:00
README.md docs: record the twelve improvements in the changelog and README 2026-09-27 23:06:56 +03:00
tsconfig.json feat: migrate Ishtarkati onto the desktop-standard contract 2026-09-11 16:43:03 +03:00
tsconfig.node.json feat: migrate Ishtarkati onto the desktop-standard contract 2026-09-11 16:43:03 +03:00
tsconfig.web.json feat: migrate Ishtarkati onto the desktop-standard contract 2026-09-11 16:43:03 +03:00
vitest.config.ts fix: oversized icons and the design-standard deviations behind them 2026-09-11 23:30:10 +03:00

Ishtarkati

اشتراكاتي · Ishtarkati

تطبيق سطح مكتب لتتبّع الاشتراكات والمدفوعات والتجديدات — يعمل محليًا بالكامل.
Offline-first desktop tracker for subscriptions, renewals and account payments.

كل البيانات في قاعدة SQLite محلية · نسخ احتياطي واستعادة · بدون حساب سحابي
Local SQLite storage · backup & restore · no cloud account required


العربية

المزايا

  • إدارة الاشتراكات والحسابات: دورة الفوترة، تاريخ التجديد، حالة الدفع، والتصنيفات والوسوم.
  • متابعة طرق الدفع: البطاقات (مع شريط انتهاء الصلاحية) والمحافظ الإلكترونية.
  • لوحة رئيسية وتقارير: المصروفات، التدفق النقدي، التنبيهات، وتقويم الاستحقاقات.
  • الميزانية الشهرية مع تنبيهات التجاوز.
  • عملات متعددة مع أسعار صرف قابلة للتحديث وتجاوزات يدوية.
  • تذكيرات سطح المكتب (مع إمكانية إسكاتها) وقفل اختياري برمز PIN.
  • نسخ احتياطي تلقائي ويدوي إلى مجلد تختاره، مع استعادة كاملة، وإمكانية تشفير الملف بكلمة مرور أو برمز قفل التطبيق.
  • نسخ استرجاع قابلة للعرض والإرجاع من الإعدادات، وتراجع فوري بعد أي حذف أو دمج.
  • تحليلات: توقع التدفق النقدي لاثني عشر شهرًا، وكشف الحسابات الخاملة، وميزانية لكل تصنيف، وتقرير بالاشتراكات المتشابهة التي قد تُدفع مرتين.
  • بحث فوري بفهرس FTS5، وقائمة حسابات تُعرض على صفحات مع التمرير.
  • تقرير تشخيصي للدعم (بلا أي بيانات شخصية).
  • إيقاف مؤقت لأي حساب (يبقى محفوظًا ويخرج من الاستحقاقات والتذكيرات)، واسترجاع أي قيمة مسجّلة في سجل التعديلات، وتقرير بتغيّر الأسعار.
  • واجهة عربية/إنجليزية كاملة (RTL/LTR)، وثيم فاتح/داكن/حسب النظام.
  • يعمل دون اتصال: الخطوط مضمّنة، والشبكة تُستخدم فقط لفحص التحديث (ويتجاهل الفشل بصمت).

التثبيت والتشغيل

npm install
npm run dev            # تشغيل التطوير
npm test               # الاختبارات
npm run typecheck      # فحص الأنواع
npm run lint           # فحص الكود
npm run gen:icon       # توليد الأيقونات
npm run dist           # بناء AppImage في release/

better-sqlite3 وحدة أصلية: npm install يبنيها لإلكترون عبر postinstall، وسكربت pretest يعيد بناءها لـ Node قبل الاختبارات ثم يعيدها لإلكترون بعدها.

التحميل

من صفحة Releases: نزّل أحدث ملف ishtarkati-<version>.AppImage ثم:

chmod +x ishtarkati-<version>.AppImage
./ishtarkati-<version>.AppImage

البيانات المحلية

تُحفظ قاعدة البيانات في app.getPath('userData')/ishtarkati.db (SQLite + WAL). حذف التطبيق لا يحذف بياناتك؛ استخدم نسخة احتياطية قبل أي إعادة تثبيت.


English

Features

  • Subscription & account management: billing cycle, renewal date, payment status, categories and tags.
  • Payment methods: credit cards (with expiry bar) and digital wallets.
  • Dashboard and insights: spend, cash flow, attention lists and a due-date calendar.
  • Monthly budget with over-budget warnings.
  • Multi-currency amounts with refreshable FX rates and manual overrides.
  • Desktop reminders (with snooze) and an optional PIN lock.
  • Automatic and manual backups to a folder of your choice, with full restore, plus optional passphrase (or app-lock PIN) encryption of the backup file.
  • Recovery copies can be listed and put back from Settings, and any delete or merge offers an undo.
  • Analytics: a rolling 12-month cash-flow projection, dormant-account detection, a monthly budget per category, and a report of look-alike accounts that may be paid twice.
  • Instant search backed by an FTS5 trigram index, and an accounts list that renders in pages.
  • A support diagnostics report that contains no personal data.
  • Pause/resume for any account (kept, but out of due lists and reminders), restoring a value straight from the account's change history, and a price-change report.
  • Complete Arabic/English UI (RTL/LTR) and a light/dark/system theme.
  • Offline-first: fonts are embedded and only the update check touches the network (it degrades silently on failure).

Install & run

npm install
npm run dev            # development
npm test               # tests
npm run typecheck      # type checking
npm run lint           # linting
npm run gen:icon       # generate app icons
npm run dist           # build the AppImage into release/
npm run lint           # ESLint (includes the React hooks rules)

Tests

npm test runs Vitest over src/**/*.test.* and tests/; npm run test:coverage does the same and enforces the thresholds in vitest.config.ts (what CI runs). npm run smoke boots the packaged app on a temporary profile and checks the database it creates — the release workflow runs it before publishing, so a build that starts broken never reaches the release page.

node scripts/gen-css.mjs regenerates the numeric helper block at the end of global.css; run it (or let the design test tell you to) after adding a helper class. scripts/ also holds the icon generator and the release script.

tests/harness/ boots the app's real SQLite schema in memory and installs a window.api backed by it, so a test can render a page and click its real buttons while asserting database state:

// @vitest-environment jsdom
const db = createTestDb()
installApi(db)
renderWithProviders(<SubscriptionsListPage />)
await userEvent.click(screen.getByRole('button', { name: text('home.markPaid') }))

better-sqlite3 is a native module: npm install rebuilds it for Electron via postinstall, while pretest rebuilds it for Node before the test run and posttest switches it back for Electron.

Download

From the Releases page, download the latest ishtarkati-<version>.AppImage, then:

chmod +x ishtarkati-<version>.AppImage
./ishtarkati-<version>.AppImage

Project layout

src/
├── main/       Electron main process (SQLite, backups, tray, IPC)
├── preload/    contextBridge API exposed as window.api
├── shared/     types, locales and constants shared by both sides
└── renderer/   React UI (components, pages, hooks, lib, styles/global.css)

Local data

The database lives at app.getPath('userData')/ishtarkati.db (SQLite with WAL). Removing the app does not delete your data — take a backup before reinstalling.


البناء على المعيار / Built on the standard

هذا التطبيق ملتزم بـ debe/desktop-standard: الستاك الثابت (Electron 44 + electron-vite 5 + React 19 + TypeScript 5.9)، ثيم متغيّرات CSS في src/renderer/src/styles/global.css (بدون Tailwind وبدون لون مكتوب في المكوّنات)، شل موحّد (قائمة جانبية + إصدار + ثيم ثلاثي + عربي/إنجليزي + إشعار تحديث من Forgejo)، وبدون إيموجي.

This app follows the debe/desktop-standard contract: fixed stack (Electron 44 + electron-vite 5 + React 19 + TypeScript 5.9), a CSS-variable theme in src/renderer/src/styles/global.css (no Tailwind, no hardcoded colours in components), the required shell (sidebar with version, tri-state theme, ar/en toggle, Forgejo update notice) and no emoji.

التحقّق / Verify:

node path/to/desktop-standard/scripts/check-standard.mjs .

ملاحظات على الالتزام / Compliance notes

النقاط التالية مقصودة وموثّقة (كل الفحوص في check-standard.mjs ناجحة):

  • الإعدادات تُحفظ في قاعدة SQLite الخاصة بالتطبيق، لذا لا تُستخدم وحدتا store.ts/paths.ts من القالب — مصدر واحد للإعدادات بدلًا من ملف JSON منفصل.

  • مسارات إضافية ضرورية للتطبيق فوق الهيكل الثابت: src/renderer/src/{pages,hooks,lib,db,types} وsrc/shared/{locales,locale.ts,settingsKeys.ts,backupIPC.ts}. تبقى مكوّنات الواجهة في components/ كما في المعيار.

  • react-router-dom مُبقى عليه للمسارات العميقة (تفاصيل الاشتراك، التعديل…).

  • سكربتات إضافية للوحدة الأصلية: rebuild:native (من postinstall)، وpretest/posttest لتبديل بناء better-sqlite3 بين Node (الاختبارات) وإلكترون (التشغيل والتغليف).

  • test.yml يشغّل npm run test:coverage (لا npm test) ليفرض حدود التغطية، ويضيف خطوة npm run lint بعدها (المعيار يذكر الاختبارات وفحص الأنواع فقط).

  • global.css أكبر من قالب المعيار (2742 سطرًا و429 فئة، منها 141 فئة مساعدة مولَّدة آليًا مقابل 86 فئة في القالب). التطبيق يستخدم فئات المعيار القياسية للهيكل والأزرار والبطاقات والنوافذ والتنبيهات، ويضيف فوقها طبقة مساعدة رقمية للتخطيط (صفوف/أعمدة/شبكات/مسافات/أحجام/أنماط نصية) ترث قيمها من متغيرات المعيار ولا تحمل أي لون خاص. الطبقة مولَّدة بـ _migration/gen-css.py ولا تُكتب يدويًا، واختبار tests/design-standard.test.ts يفشل إذا استعمل أي مكوّن فئة غير معرّفة (وهو الخطأ الذي جعل الأيقونات تظهر بحجم كبير).

  • خمس فئات من قالب المعيار لا تنطبق على شاشات هذا التطبيق ولم تُضف عن قصد: detail-grid وdetail-item (صفحة التفاصيل هنا بطاقات لا جدول حقول)، وnotes-preview وcell-email (لا يوجد جدول ملاحظات/بريد)، وsettings-content (الإعدادات تمرّر مع الصفحة لا في حاوية مستقلة). الفئتان المناسبتان filter-select وexport-grid مُضافتان ومستعملتان.

  • Settings persist in the app's SQLite database, so the template's store.ts/paths.ts are not used — one source of configuration instead of a separate JSON file.

  • Extra directories beyond the fixed skeleton are required by the app: src/renderer/src/{pages,hooks,lib,db,types} and src/shared/{locales,locale.ts,settingsKeys.ts,backupIPC.ts}. UI components stay under components/ as in the standard.

  • react-router-dom is kept for the app's deep routes (subscription detail, edit, …).

  • Extra npm scripts handle the native module: rebuild:native (from postinstall) and pretest/posttest to switch the better-sqlite3 build between Node (tests) and Electron (dev + packaging).

  • test.yml runs npm run test:coverage (not npm test) so the coverage thresholds are enforced, and adds an npm run lint step after it (the standard's template only lists tests and type checking).

  • global.css is larger than the standard's template (2742 lines and 429 classes, of which 141 are generated helpers, against the template's 86 classes). The app uses the standard component classes for the shell, buttons, cards, modals and notices, and adds a numeric layout helper layer on top (rows, stacks, grids, spacing, sizes, text tones); every value resolves to a standard CSS variable and carries no brand colour of its own. The layer is generated by _migration/gen-css.py, never hand-written, and tests/design-standard.test.ts fails if any component references a class global.css does not define — the mistake that made the icons render huge.

  • Five classes from the standard's template deliberately do not exist here because this app has no screen they fit: detail-grid / detail-item (the detail screen is a set of cards, not a field table), notes-preview and cell-email (there is no notes/e-mail table), and settings-content (settings scroll with the page rather than in their own pane). The two that do apply, filter-select and export-grid, are defined and used.

الترخيص / License

هذا العمل مرخّص تحت CC BY-NC-SA 4.0 — استخدام غير تجاري مع مشاركة بالمثل.

This work is licensed under CC BY-NC-SA 4.0 — non-commercial, share-alike.