IP / 02 · Operational finance · Indian project businesses
Project costs, cash flow, approvals, taxes, and profitability in one system.
acntnt is a multi-tenant operational-finance system for architecture, construction, and project-management practices in India. It connects scope, BOQ, measured work, approvals, costs, invoices, payments, bank movement, GST, TDS, project health, and client reporting without pretending to be the statutory ledger.
- Role
- Product owner · technical architect · full-stack engineer
- Period
- Independent product · active development
Product overview
The problem, users, and product decisions.
I designed acntnt for the financial decisions that happen while work is still moving. The product sits between project delivery and statutory accounting: close enough to the project to explain cost, scope, approval, and collection; disciplined enough to hand a clean, accountable record to the systems and professionals responsible for filing.Project businesses often distribute one financial reality across BOQs, measurement sheets, site bills, WhatsApp approvals, bank statements, payroll files, client invoices, and an accounting package updated after the decision. Each fragment may be locally correct while the principal still cannot explain what the project has earned, spent, committed, collected, or exposed the practice to today.
acntnt makes the project—not the chart of accounts—the first unit of navigation. Organisation, office, phase, scope, cost, revenue, tax, approval, bank movement, and reporting remain linked so a change in project health can be traced to the record and decision that produced it.
Who uses it and what they need.
Each team gets the information and actions needed for its part of the same workflow.
Principals and studio leads
Read project health, cash exposure, profitability, commitments, collections, and office-level position before the month closes.
Project managers
Connect scope, BOQ, progress, vendors, expenses, invoices, and approvals to the work they are responsible for delivering.
Site and delivery teams
Capture operational costs and evidence without needing to understand the statutory chart of accounts.
Finance and approvers
Validate expenses, payables, invoices, payments, tax treatment, bank effects, and exception history.
CA and accounting collaborators
Receive compliance-ready evidence and structured exports while retaining authority for statutory books and filings.
Clients
Read deliberately shared project reports and PDFs without gaining access to the organisation’s internal application.
What the product does—and does not do.
- 01
acntnt is operational finance for project-based work; it does not impersonate statutory accounting, a CA, or a filing system.
- 02
Every business record belongs to a tenant and an explicit office scope. Switching office changes both what is read and where new work is written.
- 03
The browser cannot use Supabase as a shortcut around business rules. All business data passes through the NestJS API.
- 04
Money is decimal data with transactional side effects. It is not floating-point interface state and it is not allowed to commit in fragments.
- 05
Public client reporting is a separate, revocable projection of approved material—not an anonymous doorway into the authenticated product.
Key product decisions.
Organise finance around the project.
Projects and phases hold BOQ, estimate, cost, revenue, resource, and progress context so profitability can be explained in the same structure in which delivery decisions are made.
Keep compliance inside the workflow, not at the centre of the brand.
GST, TDS, ITC, and MSME obligations appear where they affect an invoice, payment, vendor, or due date; final books and filings remain outside the product boundary.
Make approval a state machine.
Draft, pending, approved, paid, rejected, and auto-approved paths create permission and consequence. Approval is not a comment attached to a mutable expense.
Share a projection, never the internal application.
Client reports are generated artifacts with private storage, explicit sharing state, token validation, expiry, revocation, and audit history.
How it works
From project definition to accountable readback.
The workflow follows the financial life of project delivery. It begins with organisational and scope context, records the work and its resource effects, governs commitments and collections, then produces views suitable for principals, clients, and accounting collaborators.- 1.0
Admin · principal
Define the operating frame
tenant / office / role / projectOrganisation, active office, team, permissions, service types, project phases, categories, clients, vendors, bank accounts, BOQ, and estimates establish the legal context for every later write.
ProducesA project and permission boundary that every workflow can resolve. - 2.0
Project · site teams
Measure and commit
BOQ / progress / expense / payableMeasured work, scope changes, bills, attachments, inventory use, manpower, machinery, and overheads record what delivery has consumed or committed.
ProducesA cost and commitment picture attached to work—not to an orphan ledger line. - 3.0
Approvers · finance
Approve consequence
draft / pending / approved / paidRules, roles, admin auto-approval, notifications, duplicate checks, and linked evidence determine which financial actions may proceed.
ProducesAn accountable decision history and the next valid financial action. - 4.0
Finance · project lead
Bill and collect
invoice / receivable / paymentInvoices, additions and deductions, GST treatment, receipts, third-party payers, TDS, bank charges, and ageing record the commercial side of delivery.
ProducesProject revenue and cash movement that can be reconciled to the bank. - 5.0
Finance · CA
Govern obligations
GST / TDS / ITC / MSMETax and vendor obligations are carried beside the source transaction so they can be reviewed, exported, and acted on before filing.
ProducesCompliance-ready evidence without collapsing operational and statutory responsibilities. - 6.0
Principal · client · accountant
Read and disclose
report / PDF / export / scheduled jobProject health, client reports, receivable ageing, bank views, exports, notifications, and scheduled reports turn the record into bounded decisions and hand-offs.
ProducesA legible financial narrative with a controlled audience.
Product modules
Six connected parts of the product.
Each module serves a different task, but all of them use the same underlying business record.Tenancy control plane
Organisation, office, and access
Admins · principals · every authenticated userResolve tenant, active office, roles, page access, actions, preferences, alerts, and scheduled-report context before business data is exposed.
What it does
Multi-office is not a filter on a dashboard. It changes the boundary of every read and write, and therefore belongs in the product’s core grammar.
How it works
- 01
Supabase Auth provides the identity token; the NestJS API validates it and resolves organisation, user, role, and explicit office scope.
- 02
Controllers remain thin: guards and permissions establish access, while services own the business operation.
- 03
Office scope is supplied deliberately rather than guessed or backfilled from an unrelated record.
Safety checks
- Every business query is tenant-scoped.
- Office context is explicit for reads and writes.
- Unsafe scope fallback is rejected instead of silently widening access.
Commercial definition
Projects, BOQ, and estimation
Principals · project managers · financeConnect client, phase, service, estimate, BOQ, measured progress, and financial summary as the common frame for delivery.
What it does
The project is where design and construction teams recognise the work. Financial information becomes usable when it is arranged in that same vocabulary.
How it works
- 01
Project and phase records anchor scope, people, client, office, and the financial surfaces that follow.
- 02
BOQ and estimation establish the expected quantities and value against which later cost and billing can be read.
- 03
Project summaries derive payments and balance due from authoritative financial records rather than independent display totals.
Safety checks
- Project identity persists across modules.
- Derived totals use consistent payment semantics.
- Soft-deleted records remain excluded from operational readback without erasing audit history.
Commitment control
Expenses, payables, and approvals
Site · project · finance · approversMove costs from capture through evidence, review, approval, payment, bank effect, and exception handling.
What it does
An expense is a claim on project resources. Its useful record includes evidence, category, project and office context, approval state, linked invoice, payment status, and who authorised the consequence.
How it works
- 01
Approval finalisation is a service concern and does not depend on whichever HTTP request happened to trigger it.
- 02
Admin auto-approval follows the same finalisation path, keeping financial side effects consistent.
- 03
Expenses linked to invoices are validated for duplicates and cross-invoice conflicts before the relationship is accepted.
Safety checks
- State transitions are permission-controlled.
- Organisation admins receive the right operational notifications.
- Duplicate and cross-invoice evidence is challenged before commit.
Revenue and cash authority
Invoices, payments, and bank ledger
Finance · project leads · principalsConnect invoices, receivables, direct project payments, bank accounts, TDS, bank charges, third-party payers, and balance due.
What it does
Collection is not a checkbox on an invoice. A payment may have tax withheld, bank charges, a payer different from the client, and a bank movement that must be reversed if the payment is removed.
How it works
- 01
Invoice numbering remains unique across active and soft-deleted history so a cancelled record cannot create a future collision.
- 02
Non-GST invoices zero GST inputs at the UI and server boundary; post-GST additions and deductions change the grand total without corrupting the tax fields.
- 03
Deleting a payment transactionally reverses the bank credit and soft-deletes linked TDS receivable effects.
Safety checks
- Money stored as NUMERIC(15,2).
- Bank charges remain distinct from TDS.
- Payment deletion reverses every linked financial side effect together.
Compliance-ready layer
Tax and operating obligations
Finance · principals · accounting collaboratorsSurface GST, TDS, ITC, MSME, and due-date consequences alongside the transactions that created them.
What it does
Compliance becomes useful before filing when the project team can see which invoice, payment, vendor, or delay created the obligation.
How it works
- 01
Tax attributes remain attached to source transactions and calculated through server-owned rules.
- 02
GST-disabled invoices cannot retain stale tax percentages or amounts behind the visible total.
- 03
Exports prepare the operational record for Tally, Zoho, and professional accounting workflows without claiming statutory authority.
Safety checks
- Server validation mirrors the visible tax mode.
- Compliance records retain their source transaction.
- The product boundary is explicit: prepare and reconcile, do not file.
Decision and disclosure surface
Reports and controlled sharing
Principals · project managers · clientsProduce internal project views, client reports, PDF and spreadsheet exports, ageing, notifications, and scheduled readback with deliberate access.
What it does
Reporting is where the product explains the project. A client-facing artifact must be useful without leaking the studio’s internal records or becoming a permanent public URL by accident.
How it works
- 01
Report generation uses server templates and job-backed production for PDF and spreadsheet artifacts.
- 02
Client PDFs live in private storage. A public route validates share token, sharing state, deletion state, and expiry before returning a signed URL or streamed file.
- 03
Sharing is unavailable until the report artifact exists and can be revoked without deleting the internal report.
Safety checks
- Private bucket by default.
- Token, expiry, revocation, and deleted-state checks on every public read.
- Share and access events remain auditable and tenant-isolated.
Technical architecture
How the system is built and keeps data reliable.
I treated the application boundary as a financial control. The web client can compose an interaction, but it cannot own tenant scope, approval finalisation, tax semantics, or money movement. Those rules live in a typed NestJS service layer over an explicit Postgres model, with transactions at every consequential edge.- L1 / Work surfacesNext.js PWA · React · HeroUI · Tailwind↓
Responsive project, office, approval, expense, invoice, payment, tax, report, and administration views for studio and field use.
- L2 / API boundaryNestJS controllers · guards · permissions↓
JWT validation, tenant and office scope, input contracts, access decisions, and thin transport handlers precede every business operation.
- L3 / Domain servicesProject-finance rules and transaction orchestration↓
Services own approvals, invoice and GST behaviour, payment reversals, bank effects, report sharing, notifications, and cross-record validation.
- L4 / PersistenceDrizzle ORM · Supabase Postgres↓
Explicit schemas, NUMERIC money, tenant-keyed queries, soft deletion, uniqueness, audit state, and transactional writes form the durable financial record.
- L5 / Identity and filesSupabase Auth · private Storage↓
Supabase provides JWT identity and file storage; it does not become a parallel business API for the browser.
- L6 / Asynchronous productionPostgres-backed jobs · schedules · document generation
Notifications, scheduled reports, PDF rendering, spreadsheet exports, and longer work execute outside the request lifecycle with durable state.
Technical rules.
Rules every part of the system must follow.
One business boundary.
Every business read and write crosses the NestJS API. The web application does not query the database directly or use Supabase as an alternate API layer.
Scope precedes query.
Tenant and explicit office context are resolved before repository access. Missing context fails closed rather than being inferred from unrelated rows.
Money is decimal and transactional.
Financial values use NUMERIC(15,2), and operations that affect invoices, payments, taxes, or bank state commit all linked consequences together.
Controllers transport; services decide.
Permission checks and thin controllers route validated commands. Domain services own the rule, state transition, and side effects.
Public means projected and revocable.
A shared report is a specific generated artifact behind an expiring token—not authenticated application data with its guard removed.
Technology and responsibilities.
The main technologies and what each layer is responsible for.
Turborepo · pnpm · shared packages
Web, API, database schema, and shared contracts evolve together without becoming one runtime.
Next.js App Router · React 19 · PWA · HeroUI · Tailwind · TanStack Query
One installable, responsive client with explicit server-state handling.
NestJS · JWT validation · guards · controllers · domain services
Access, workflow, and financial rules remain authoritative outside the browser.
Supabase Postgres · Drizzle ORM · NUMERIC(15,2)
Typed schemas and decimal arithmetic support auditable, tenant-scoped financial state.
Supabase Auth · private Supabase Storage
Identity and artifacts share managed infrastructure without bypassing the API’s business boundary.
Postgres-backed queue · Nest schedules
Reports and notifications remain durable beyond a single request or process restart.
PDFKit · Handlebars · ExcelJS
Client reports and accounting hand-offs become reproducible artifacts rather than browser printouts.
How the system handles failure.
What happens when data is missing, incorrect, or only partly saved.
The browser bypasses tenant or money rules.
Business data is unavailable through direct client-side database access; authenticated requests enter through the API, guards, permissions, and scoped services.
A request is written into the wrong office.
The active office is explicit. Missing or invalid scope fails instead of being backfilled from a project or user guess.
A non-GST invoice retains hidden GST values.
The UI clears those inputs and the server independently zeroes GST rates and amounts before persistence.
A payment is deleted but the bank or TDS effect remains.
One database transaction reverses the bank credit and soft-deletes the linked TDS receivable effect with the payment.
An old invoice number is reused after soft deletion.
Uniqueness covers historical soft-deleted records as well as the active set.
A shared client report exposes internal or expired data.
The public route validates token, sharing state, report state, deletion, expiry, and tenant isolation before returning a private artifact.
Sources
What this case study is based on.
- 01
The acntnt monorepo and its explicit web, API, database, storage, job, and shared-package boundaries.
- 02
The implemented project, office, BOQ, expense, approval, invoice, payable, payment, bank, tax, report, notification, inventory, overhead, loan, client, and vendor workflows.
- 03
Service-level corrections for payment semantics, tenant and office scope, non-GST invoices, GST additions and deductions, approval finalisation, invoice uniqueness, and transactional payment reversal.
- 04
The controlled-report-sharing design: generated PDF requirement, private storage, token validation, expiry, revocation, deleted-state checks, audit logging, and tenant isolation.