Back home
Product Built and operated by us

taktiko: a multi-tenant ERP platform we built and run

Problem

A back office for a small business is deceptively wide: accounting, payroll, leave, invoicing, bank reconciliation, and tax filing all have to agree on the same numbers. Kosovo adds its own constraints: ATK e-deklarimi, KKRF contributions, and bank salary files in a specific CSV format. Stitching that together from generic tools leaves gaps that show up as filing errors and manual rework. The platform problem is keeping one tenant fully isolated from another while every tenant gets the same correct engine underneath.

What we did

taktiko is multi-tenant from the ground up. A Clerk middleware proxy maps each customer subdomain to a tenant-internal route, and every backend call goes through a tenantQuery/tenantMutation layer that enforces tenant scope, checks permissions, and writes an audit row. Permissions are a single source of truth: 19 permissions across 8 roles, evaluated on the server, not trusted from the client. The tax engine computes Kosovo VAT and withholding and exports ATK and KKRF filings directly. Banking automation generates Kosovo CSV salary files and matches statement lines back to ledger entries. Gemini reads receipts into draft expenses, and a token-gated ICS feed exposes a tenant calendar without opening the data model. The stack is Next.js 16, React 19, and a typed Convex backend with crons, HTTP endpoints, and storage.

Result

taktiko is a large, mature codebase: roughly 132,000 lines of TypeScript across 669 files, split between a typed Convex backend and the frontend. The data model spans 72 tables and the app exposes 111 page routes. The test suite runs about 5,000 cases across 397 files, covering payroll, VAT, the ledger, and reconciliation. 12 cron jobs run recurring operations: invoice generation, reminders, leave reset, and year close. Every mutation auto-writes an audit row, so the system is accountable by construction rather than by convention.

Key highlights

  • Multi-tenant SaaS: per-customer subdomains mapped through a Clerk middleware proxy to tenant-internal routes
  • Server-authoritative RBAC: 19 permissions, 8 roles, single source of truth, every mutation writes an audit row
  • Kosovo tax engine emits real ATK e-deklarimi and KKRF filing exports, plus bank salary CSV and a statement matcher
  • About 5,000 tests cover payroll, VAT, withholding, ledger, and reconciliation; 12 crons automate recurring ops
  • Gemini receipt OCR drafts expenses; token-gated ICS calendar feed exposes data without widening the model

Tech stack

Next.js 16React 19ConvexClerkTypeScriptGeminiBunTurbo