க
கnaQ?formerly Ledgerstone

The books for a builder running many sites at once

கnaQ? is a financial management system for construction companies. It tracks project budgets and profit, vendors, labour, materials, loans and EMIs, and reconciles the bank statement against everything recorded, with role-based access and reporting on top.

12modules in the sidebar, each one switchable per company
216permissions (27 modules × 8 actions) behind every screen
Multi-companyone installation, fully separated companies
₹ INRlakh/crore grouping, April–March financial year
Why it exists

Every rupee counted once

Recording expenses is the easy part. The hard part is keeping three views of the same money in agreement: what a project has cost, what each vendor is owed, and what the bank says. When they drift apart, someone spends a week working out why.

Project C says ₹30,000 is owed. The vendor statement says ₹28,500. Which one is right? கnaQ? is built so that question never comes up.
Project outstanding
₹1,15,000.00
Vendor outstanding
₹1,15,000.00
Bank, after reconciliation
₹1,15,000.00

✓ All three are calculated from the same ledger entries, so they cannot disagree.

How money flows

Owing money and paying it are separate things

The data model keeps the record of a debt apart from the record of a payment. A purchase creates what is owed. A payment settles it. An allocation connects the two and says which project the money belongs to. Each step writes to an append-only ledger, and every report reads from that ledger.

Obligation Money owed: vendor purchase, labour work, EMI due, donation, contract value Settlement Money moving: vendor payment, client receipt, labour payment Allocation Links a payment to what it pays and to one or more projects Ledger Append-only. Never edited. Reports Balances, P&L, dashboards Bank statement Imported, then reconciled matched to
Obligation raises an expense or receivable and increases what is outstanding. Settlement reduces what is outstanding and moves cash. It never creates an expense.

Green means money in

Receipts and credits. The colour is used for nothing else anywhere in the app.

Red means money out

Payments, purchases and debits.

Amber needs attention

Unreconciled bank lines, pending approvals, EMIs falling due.

Modules

What is in the app

The sidebar follows the navigation the client signed off. Each item is tied to a permission, so people only see the parts their role allows. An administrator can also switch off whole modules the company does not use.

Dashboard

The whole business at a glance: money in, money out, what is owed and what needs attention.

Company dashboardProject dashboardNotificationsApprovals

Projects

Each site, created together with its budget. Budget revisions, BOQ, income, expenses, P&L and a full project ledger.

BudgetBudget vs actualBOQP&LLedger

Vendors

Suppliers, what you owe each one, purchase orders that need a Manager's approval, and quotations with price trends.

Purchase ordersQuotationsPaymentsPayment allocationStatements

Field Officers

Staff who spend money on site and are reimbursed later, with or without a project attached.

PaymentsProject paymentsNo-project billsStatement

Labour & Subcontractors

Teams grouped by department, the work they do, what they are paid and what is still due.

DepartmentsTeamsWork entriesStatements

Materials

The items you buy, grouped into categories, and the purchases made against each project.

Item masterCategoriesPurchases

Donations

Donations committed per project, such as to a temple, as a fixed amount or a share of the contract value.

Donation masterProject donationsReports

Loans

Borrowings, their EMI schedules, payments made and what is still outstanding.

Loan masterEMI scheduleEMI paymentsOutstanding

Other Expenses

Costs outside a single project: office, personal and savings, plus shared overheads spread across active projects.

OfficePersonalSavingsCommon allocationCustomized work

Accounts

The cash and bank accounts money moves through, bank statement upload and the reconciliation queue.

CashBankPayment modesStatement uploadReconciliation

Reports

Every report in one explorer, with filters, column choice and export to Excel or PDF.

ProjectVendorLoanCash/BankP&LOutstandingBudget vs actual

Administration

Users, roles and permissions, module configuration, masters, audit logs, an integrity check and notification channels.

UsersRolesModulesAudit logsIntegrity check

Every main page also has a How it works guide in its top-right corner that explains what the page is for and the usual steps.

Bank reconciliation

From bank statement to agreed books

Payments are usually recorded before the bank statement arrives. Reconciliation matches each bank line to what was already recorded, so nothing is booked twice and nothing is missed.

  1. Upload the statementThe file becomes a draft batch. Lines that are already in the system are flagged as duplicates.
  2. Review the draftFix parse errors, drop unwanted rows, and optionally say which project each line belongs to. A debit can be split across projects; a credit cannot.
  3. CommitAccepted rows become bank transactions, all pending. Nothing is posted to the ledger at this stage.
  4. Work the queueEach line shows suggested matches with a confidence score. Accept a suggestion, match by hand, or exclude the line with a reason.
  5. DoneMatched lines are reconciled. Excluded lines stay on record so a later import still recognises them.
Pending In review Reconciled Excluded Internal transfer
Ground rules

Decisions that keep the numbers right

These are built into the database and the code, so they do not depend on anyone remembering them.

Projects

Budget first

A project cannot be created without a budget by cost category. Its estimated cost is the budget total, and each later change is saved as a new revision.

Balances

Calculated, never stored

Outstanding amounts, bank balances and project costs are summed from the ledger each time they are shown. There is no balance column that could go stale.

History

Nothing is deleted

Financial records are reversed or voided, never removed. A reversal writes a mirror entry, and the ledger refuses edits and deletes outright.

Audit

Every change is logged

Who changed what, when, and the old and new values, written in the same transaction as the change. Audit rows cannot be edited.

Money

Exact decimals, Indian format

Amounts are stored as fixed decimals, never floating point, and shown as ₹1,15,000.00. When an amount is split, the last share takes the rounding remainder so the parts always add up.

Safety

No double posting

Every action that moves money confirms its effect in words and numbers first and rejects a repeated request, so a double click cannot pay a vendor twice.

Approvals

A Manager signs off

Purchase orders and BOQ revisions wait in the Approvals queue until a Manager approves them, and orders are checked against the project's BOQ.

Dates

Indian financial year

Business dates carry no time or timezone, so an entry on the 1st never slips to the 31st. Reports include This FY and Previous FY presets (April to March).

Users & access

Who sees what

A user has one role, and a role is a set of module.action permissions such as vendors.edit or bank_reconciliation.reconcile. The server checks every request. Hiding a menu item is a convenience, not the security boundary.

RoleDefault access
Super administratorBelongs to no company. Adds and deactivates companies, creates their first administrator, and can open any company with full access.
AdministratorEverything inside their own company, including users, roles, module configuration and audit logs.
Accounts TeamView, add, edit, export and print on the financial modules; approve on projects, expenses and payments; reconcile bank statements. No delete anywhere.
Project ManagerDay-to-day project work, limited to the projects they are assigned to.
ManagementRead and export only.
Data Entry UserView and add on the transaction entry screens.

Project scoping

Give a user access to specific projects and every list and report is filtered to them. Users with no project grants see all projects.

Separate companies

Each company has its own projects, masters, ledger, users, roles and settings. Every database query is filtered to the signed-in company.

Editable roles

Administrators can add roles and change permissions at runtime. The code never checks a role by name.

Architecture

How it is built

A Next.js frontend talks to an ASP.NET Core API over /api/v1. The API is split into layers so that business rules have no dependency on the database or the web framework.

FrontendNext.js (App Router), React 19, TypeScript strict, Tailwind CSS with shadcn/ui, TanStack Query, React Hook Form + Zod, AG Grid for data grids, Recharts for dashboards, Excel and PDF export.
APIASP.NET Core Web API on .NET 10. Layers: Api → Application → Domain, with Infrastructure for EF Core, file storage and importers. FluentValidation, Serilog, problem+json errors.
AuthJWT access token with a rotating refresh token in httpOnly cookies. Permissions are carried as claims; passwords hashed with PBKDF2.
DatabaseMySQL / MariaDB through EF Core 9 and Pomelo. Money as DECIMAL(18,2), optimistic concurrency stamps, migrations checked into source.
Testing & CIxUnit and FluentAssertions for the backend, Vitest with React Testing Library and MSW for the frontend, Playwright end-to-end. GitHub Actions runs everything on each push and pull request.
HostingOne Ubuntu 24.04 VPS, no Docker. Nginx with TLS in front of two systemd services. Each release goes into its own folder and goes live by switching a symlink, so a bad deploy can be rolled back at once.
Browser Nginx TLS, ports 80/443 Next.js web app domain · :3000 ASP.NET Core API api domain · :5095 MariaDB localhost · :3306
Running it

Local setup and demo data

Needs the .NET 10 SDK, Node.js 20+, and MySQL/MariaDB on localhost:3306 (XAMPP works). The full steps are in README.md.

# API  (http://localhost:5095)
cd backend
dotnet tool restore
dotnet ef database update \
  -p src/Ledgerstone.Infrastructure \
  -s src/Ledgerstone.Api
dotnet run --project src/Ledgerstone.Api \
  --urls "http://localhost:5095"

# Web  (http://localhost:3000)
cd frontend
npm install
npm run dev
# With the API running, fill an empty database:

# 5 construction projects with budgets, vendors,
# labour, purchases, payments, a loan and a donation
node scripts/seed-demo.mjs

# a few entries dated this month, for the
# monthly dashboard on demo day
node scripts/seed-demo.mjs --recent-only

# a second company: ANSS Uns Crafters,
# an interior design and fit-out firm
node scripts/seed-anss.mjs
Development sign-inEmailPassword
Administratoradmin@ledgerstone.localAdmin!23456
Super administratorsuperadmin@ledgerstone.localSuperAdmin!23456
ANSS administratoradmin@unscrafters.localCrafters!23456

These accounts exist only in development. A production install seeds no users; the first administrator is created with the Ledgerstone.SeedAdmin tool (see README.md and docs/deployment.md).