InfraDZ Software
ERP and point-of-sale suite for small businesses: stock, sales, purchasing, quotes and invoices, on the web and as a desktop app, with access rights per module and per role.
- My Role
- Full Stack Engineer
- Timeline
- Apr 2026 — May 2026
- Status
- Shipped

InfraDZ is a management suite for small businesses that brings stock, sales, purchasing, invoicing and a point-of-sale counter into one platform. Each company operates as a tenant, the top-level entity woven through all 74 tables of the PostgreSQL schema, and access is granted module by module.
The product ships on two surfaces from a single codebase: a React web client and a Tauri v2 desktop app that aliases the same React source. Sign-in supports email/password, OTP and Google OAuth over a hybrid cookie + Bearer scheme, and the interface reshapes itself around each user's permissions, down to a sidebar that only lists what the role is allowed to open.
The problem to solve
The hard part was serving many unrelated companies from one system without their data bleeding into each other. A tenant that only runs a cash register should not see the other modules; a cashier should not see purchasing screens; and a shop that deletes a product it sold last month must not corrupt its own history. On top of that, the product had to ship both as a web app and as an installable desktop application — which normally means maintaining two frontends.

How it was built
Tenancy is structural, not bolted on: 'tenant' is the top-level entity across the 74-table schema and throughout the code, and access rights are set module by module for each tenant. Permissions travel with the session — /auth/me returns them — and the client gates everything through a useCan hook, a <Can> component and a permission-filtered sidebar, so screens a role cannot use simply never render.
The desktop question was answered with Tauri v2: the desktop app aliases the web client's React source, so one codebase produces both builds. Data safety follows a strict soft-delete convention — master data is flipped to isActive=false and can be restored, never hard-DELETEd — which keeps historical documents pointing at records that still exist. The POS module shares a single Article master type with the rest of the suite, so a product is defined once and behaves the same at the register and in stock.
What it does
Multi-tenant core
Every table and every code path is scoped to a top-level tenant entity, isolating each company's data across the 74-table schema.
Per-module access
Stock, sales, purchasing, invoicing and POS are separate modules, and each company only gets access to the ones it uses.
Hybrid authentication
Cookie + Bearer sessions with email/password, OTP and Google OAuth sign-in.
Permission-gated interface
A useCan hook, a <Can> component and a permission-filtered sidebar hide anything the role cannot act on, driven by the permissions carried on /auth/me.
Single-source desktop app
The Tauri v2 desktop build aliases the same React source as the web client — one codebase, two platforms.
Soft delete everywhere
Master data is never hard-deleted: records flip to isActive=false and can be restored, preserving referential history.

Built with
Frontend
One React codebase renders both the web client and the Tauri v2 desktop app, so every ERP and POS screen is written once and shipped to both platforms.
Static types make the shared Article master and the permission contracts enforceable at compile time, which is what keeps one codebase safe to ship as both web and desktop builds.
Backend
Running the API on Node keeps server and client in one language, so contracts like the permission payload on /auth/me and the shared Article type stay aligned across the stack.
Data
A 74-table relational schema needs real foreign keys: PostgreSQL ties every row to its tenant and lets the soft-delete convention preserve references a hard DELETE would break.
Infrastructure
Containers pin the API and PostgreSQL to identical versions in every environment, which a multi-tenant deployment serving many companies from one stack depends on.