Engineering

Six architecture decisions behind NovaDesk

The operations platform we built for ourselves runs on one process, one database and one file volume. Here is why, decision by decision.

Published
Reading time
3 min
Written by
Tensly Solutions
NovaDesk project board in dark mode, with tasks spread across columns
NovaDesk, shown with demonstration data.

NovaDesk is the platform we use to run Tensly: clients, projects, tasks, quotes, invoices, payments, expenses and email in one self-hosted application. It is also where we test, on ourselves, the way we build for others.

What follows are six decisions that shaped it, with the reason behind each. The reasons matter more than the choices: they are what another team needs in order to carry on.

1. One deployable, no internal API

NovaDesk is a single Next.js application using the App Router. Pages read the database directly through server components, and every write goes through a server action.

The alternative was a separate REST API serving a separate front end: two deployments, two sets of types, and a serialisation layer to maintain — for an application with one client, its own interface.

The public API still exists, under /api/v1, for n8n, Make and Zapier. It is a product in its own right, authenticated with API keys, and not the plumbing of the interface.

2. Permissions are decided on the server, every time

Every server action follows the same sequence: identify the user, check the permission, validate the input, write, record the action in the audit log, then refresh the affected pages.

The interface hides what a user cannot do, but that is a courtesy, not a control. Removing the hiding in the browser grants nothing: the permission check runs on the server, in every action and every route.

3. Money is stored in whole cents

Every amount is an integer number of cents. There are no floating-point numbers anywhere in the financial code.

The rounding rule is written once: discount, then rounding line by line, VAT rounded line by line, totals as the sum of the rounded lines. The total on a document is therefore always exactly the sum of the lines shown on it — which is what a client checks first. A quote converted into an invoice goes through the same code, so its amount cannot drift.

4. One renderer for the preview and the PDF

Quotes and invoices are designed in a visual template editor with a live preview. There were two ways to build it: a PDF drawing library plus a separate HTML preview, or a single HTML renderer.

We chose the second. A pure function turns a document into HTML. The template editor calls it in the browser and refreshes the preview on every keystroke; the PDF route passes the same output to headless Chromium. What you see in the editor is what the client receives.

The cost is known and accepted: a larger container image and about a second per document. The browser is started once and reused.

5. No infrastructure the product does not need

A single instance does not need Redis, so there is none. Rate limiting runs in memory, behind an interface that would accept a Redis implementation without touching its callers. The few long tasks — PDF generation and mail synchronisation — run through routes called on a schedule rather than through a queue.

The result is one process, one database and one file volume. It runs on a modest server and backs up with a script, with a written procedure for a full restore.

6. Charts that everyone can read

The chart palette was not chosen by eye. It was checked by computation: luminance band, minimum chroma, separation under the common forms of colour-vision deficiency, and contrast against the background — in light mode and in dark mode.

Every chart also has a table view. It makes the data readable with a screen reader, printable, and easy to copy into a spreadsheet.

What comes next

The project keeps a written roadmap that is candid about what remains: two-factor authentication for administrators, a client portal for quotes and invoices, and electronic invoicing. The architecture already allows the last one — controlled numbering, locked documents, traceability — but the format and the connection to an approved platform are still to be built.

A white-label edition of NovaDesk is also planned. If that interests you, tell us.

Have something worth building?

Tell us what you’re building. We reply within two working days with an honest first view on feasibility, scope and order of magnitude.