How We Work

“It works” is not our finish line

What matters in business software is not what it does when everything goes right, but what it protects when something goes wrong. What happens when the connection drops, when two cashiers sell the same item at the same moment, when someone wants a past record “corrected”? The rules below were settled before we wrote code — and we have never reopened them for negotiation.

Our Principles

Six rules, six reasons

Next to every rule we wrote why it is that way and what it means for your business. These are not marketing headlines; they are rules the code obeys and the tests enforce.

🧾

No deletion — only correction

Rule: Stock and money are never set by hand to “make it 50”. Every change writes a movement record: +20, −5. Movement tables only accept inserts; updates and deletes are forbidden.

Why: The moment a number is overwritten, the answer to “where did that figure come from?” is gone — and there is no way back from a wrong correction either.

For your business: When a stock count does not match, the difference can be traced. A refund does not delete the sale; it writes a counter-entry. History can always be replayed.

🗄️

Your data lives in your own database

Rule: Not a row filter over a shared table, but a separate database per company. Which database to connect to is resolved solely from verified sign-in credentials — never from the address bar, a header or the request body.

Why: In a shared table, one forgotten filter shows another company's data. With separate databases, the same mistake returns nothing at all.

For your business: Backup and restore can be performed for a single company; the boundary around your data is physical, not a technical assumption.

🎛️

Permissions live on the server, not the screen

Rule: Hiding a button is not security. Every command and every query performs its own permission check on the server before it runs; without permission the work never starts.

Why: The interface runs on the user's device — it can be modified. A server-side check cannot be bypassed.

For your business: A cashier works with a cashier's permissions, from any screen and any device. Exceptions such as comps and voids can require manager approval.

📜

Who changed what, and when

Rule: Critical operations are written to the audit trail with before/after values. In the business audit log inside your own company database, every row carries a cryptographic digest (hash) of the previous one — a chain.

Why: An audit record is only evidence if it cannot be altered afterwards. Thanks to the chain, an inserted, deleted or edited row surfaces as soon as the calculation is re-run.

For your business: “Who approved this discount?” has exactly one answer. The owner can verify the integrity of the chain from the console. Scope note: the chain is specific to the business audit log in the company database; the system/session log that records sign-in attempts and administrative actions is also append-only, but it carries no hash chain.

🔐

Two steps at sign-in

Rule: Passwords are stored irreversibly with Argon2id. When a new password is set it is checked against known breach lists and rejected on a match. Two-step verification with an authenticator app (TOTP) can be enabled on any account.

Why: Signing in to business software is opening the till. A password alone is not a sufficient door — least of all one already leaked on another site.

For your business: Staff cannot set their password to “12345”, and a departing employee's sessions can be terminated by an administrator in a single action.

📱

Browser and pocket at the same time

Rule: The mobile app is produced for both Android and iOS from a single codebase, and it talks to the same server under the same rules as the web console.

Why: Two separate mobile apps mean two separate bug lists — and over time they drift apart.

For your business: No installation, no version, no “works on my device”. While a waiter takes an order at the table, the owner sees the same data in the browser.

Process

How does a feature get shipped?

Every new feature goes through the same four steps. The order never changes: the screen comes last.

1

The rule is written first

Not the screen — the business rule. “What happens to a returned item?”, “what does a sale do when stock runs out?” are answered before any code, and the rule itself lives in one place rather than being scattered across the interface.

2

Validation happens on the server

The check in the browser is a convenience: it warns you while filling in the form. The real gate is on the server — every request passes permission and validity checks on its own.

3

No test means not finished

Each business rule gets at least one “happy path” test and one does it leak into another company's data test. If both are not green, the feature does not ship.

4

Side effects are never left half-done

A sale and its stock movement are written in a single transaction: either both or neither. Follow-on effects such as the cash entry and notifications are triggered by an event row saved in that same transaction — if the sale was recorded, so was the event; it is retried until processed and cannot be lost.

Technology

A modern and proven foundation

We do not pick what is exciting; we pick what will still be maintainable in ten years. Our choices are industry-standard, open and widely used technologies.

  • A .NET + PostgreSQL core — a separate, individually restorable database for every company.
  • A React web console and a Flutter mobile app — Android and iOS from one codebase.
  • Modules never call each other directly; they communicate through events. The event is stored in the same transaction as the business data, so “saved it but failed to trigger the side effect” cannot happen.
  • Deployment on Docker + Nginx; encrypted connections and security headers are enforced at the infrastructure layer.
  • Authorisation, tenant resolution, transaction integrity and audit writing all run on a shared pipeline — never left to individual features to remember.

What we did not add is on the record too

Adding a library makes you faster today and leaves debt tomorrow: security updates, version conflicts, abandonment risk. So we also write down the decisions not to add something, with the reasoning.

  • For background jobs, a popular scheduling library was not added; the platform's own mechanism was chosen and the reasoning was recorded in a decision record.
  • For inter-module communication, a separate message queue was not added; it was judged unnecessary complexity at this scale, and designed so it can be moved onto one later.
  • No new dependency is added before its decision is written down.

A dependency is debt to be repaid later. A few well-chosen dependencies are safer than many convenient ones.

Evidence

We measure what we claim

None of the above is a statement of intent; they are rules checked automatically on every change.

🧪

800+

automated tests — business rules, end-to-end flows and tenant isolation included.

📐

11 written

architecture decision records: the reasoning, alternatives and consequences of every major decision.

🖥️

3 platforms

web console, Android and iOS — all passing through the same build and test pipeline.

⚙️

Every change

is only merged after automated build, tests and a dependency vulnerability scan.

A fake database lies

Our integration tests do not run against an in-memory imitation but against a real PostgreSQL instance. Behaviour such as stock locking under concurrent sales, transaction rollback and uniqueness constraints can only be tested truthfully on a real database — the imitation usually just says “passed”.

Tests enforce the rule, not people

We do not leave it to code review to confirm that modules stay out of each other's internals and that no delete or update code creeps into movement records: separate architecture tests check exactly that. Code that breaks the rule turns the pipeline red before it ever reaches review.

Let's talk about your operation

Tell us what you use today and where things get stuck; we will look together at whether Business Suite, our product today, fits your business.