Rechvix Documentation
This page covers the product and architecture at a level useful for evaluating Rechvix. For the full, always-current technical detail — module boundaries, ADRs, the exact test matrix — go straight to the repository's own docs/ folder on GitHub; the marketing site intentionally doesn't try to duplicate it.
Introduction
Rechvix
Self-hosted billing, inventory, accounting and GST-compliance platform for Indian businesses. Go backend, PostgreSQL 18, AGPL-3.0.
What is Rechvix?
Rechvix is a production-grade, multi-company, multi-branch, multi-warehouse billing, inventory, accounting, and tax-management platform — India GST / e-Invoice / e-Way Bill capable today, built to extend to other countries' tax regimes without a rewrite. It is not a CRUD demo: it's built for double-entry accounting correctness, tenant isolation, and 10-year maintainability from the first commit.
It runs as a single Go binary (apps/server) backed by PostgreSQL 18, self-hosted on your own hardware by default — no mandatory cloud dependency, no phone-home telemetry. The only things that ever reach the internet are integrations you explicitly turn on and that inherently require it: GST e-Invoice/e-Way Bill submission (a government API, required by Indian law for those documents), WhatsApp/email sharing, and optional cloud object storage.
Where things actually stand
Stages 0 through 10 — research, architecture, foundation, catalogue/contacts/pricing, inventory, sales/GST, accounting, reporting, government integrations, other integrations, packaging, and the full web app — are complete and independently verified. Stage 11 (hardening: security review, load testing, accessibility audit) is the one remaining phase before a v1.0 production-readiness claim, and is already partially underway. See docs/TODO.md on GitHub for exactly what's done versus in progress right now, and the wiki for a narrative walkthrough.
Browse the documentation
Self-Hosting Quick Start
Requires Go 1.27+ (or let Go's toolchain auto-download it) and a PostgreSQL 18 instance.
git clone https://github.com/Raktim94/rechvix.git cd rechvix # Point at your own Postgres 18 instance export DATABASE_DSN="postgres://user:pass@localhost:5432/rechvix?sslmode=disable" export DATABASE_AUTO_MIGRATE=true # applies pending migrations on startup go build ./... go run ./apps/server
See internal/platform/config/config.go in the repository for the full list of environment variables (session cookie settings, Argon2id tuning, OTel exporter target, CORS allow-list, etc.) — every required value fails fast at startup with a clear message rather than a nil-pointer panic later.
./install.sh + Docker Compose setup — matching nodedr-pos's "clone and run, no manual config editing" install experience — is available today. Building against a local Go/Postgres setup, as above, is the path for development.Running the test suite
go test ./... # unit tests go test -tags=integration ./... # integration tests (needs Docker — real postgres:18 via Testcontainers)
Why Self-Hosted by Default
Self-hosted by default, no external connection required to run your business.
Same philosophy as this project's sibling, nodedr-pos: core billing, inventory, and accounting work entirely on your own machine — your own PostgreSQL, no mandatory cloud dependency, no phone-home telemetry. Everything else — creating invoices, tracking stock, running reports, closing the books — works fully offline.
Billing & Invoicing
Quotations through to finalized tax invoices, plus the returns and adjustments a real billing counter needs.
Quotations, proforma/tax/cash/credit invoices, POS billing, credit/debit notes, sales & purchase returns — across multiple companies, branches and warehouses in a single deployment, with document numbering scoped correctly per legal entity.
Inventory
Perpetual multi-warehouse inventory with batch/lot/serial tracking and unit conversion.
Stock balance is a materialized projection of an append-only stock-movement ledger, never a directly-editable number — so at any point it can be reconciled back to every movement that produced it. Batch, lot, and serial tracking, with unit conversion, across as many warehouses as the business runs.
Accounting
Full double-entry accounting with customer/supplier ledgers, ageing, and GSTR-oriented reporting.
Double-entry is enforced at three separate layers: an app-level sum check on every posting, a deferred database constraint trigger that rejects an unbalanced journal at commit time, and no UPDATE grant on posted journal rows at the database-permission level. A bug in any one layer still can't post an unbalanced or silently-edited journal.
GST & Compliance
CGST/SGST/IGST, HSN, place-of-supply, e-Invoice (IRN/QR) and e-Way Bill generation.
Modeled through a generic tax-document engine — tax_document / tax_line / tax_component tables and a TaxEngine interface, with IndiaGSTEngine as the first concrete plugin — rather than hardcoded cgst/sgst columns, so a second country's tax regime is additive rather than a rewrite. Government integrations for e-Invoice and e-Way Bill go through directory-versioned adapters (einvoice/v1, .../vNext) — when GSTN changes the schema, as it did on 2026-08-01, that's a new adapter directory, not an emergency rewrite.
Security & RBAC
Branch/warehouse-scoped permissions, TOTP MFA, and Row-Level Security as defense-in-depth.
RBAC with branch- and warehouse-scoped permissions, Argon2id password hashing (parameters documented in ADR 0001), TOTP multi-factor authentication, and a full audit trail. Every tenant table is scoped by organisation_id both in application code and via PostgreSQL Row-Level Security — a bug in one layer isn't automatically a cross-tenant data leak.
Tech Stack
| Layer | Choice |
|---|---|
| Backend | Go 1.27, net/http + chi, pgx |
| Database | PostgreSQL 18 — NUMERIC for money/rates, Row-Level Security, UUIDv7 primary keys |
| Migrations | golang-migrate, plain versioned SQL |
| Money | shopspring/decimal wrapped in an internal Money type — never float32/float64 |
| Auth | Argon2id, server-managed sessions, TOTP MFA |
| Observability | log/slog (structured JSON) + OpenTelemetry |
| Frontend | TypeScript, React 19, Vite, TanStack Query/Router, React Hook Form, Zod, Apache ECharts |
| Desktop (planned) | Tauri 2 — thin shell only, all business logic stays server-side; not started yet |
Architecture
A modular monolith — module boundaries enforced by convention, one database, one deployable.
apps/ server, worker, web, desktop entrypoints
internal/
platform/ cross-cutting: config, database, auth, permissions, audit, money, http...
modules/ domain modules: identity, organisation, catalogue, inventory, sales,
accounting, gstindia, einvoice...
api/openapi/ OpenAPI 3.1 spec (source of truth for API clients)
migrations/ versioned SQL migrations
deploy/ docker, compose, casaos deployment manifests
docs/ architecture, research, ADRs, API/operations/security docs
tests/ integration and end-to-end testsEach internal/modules/* package follows domain/ (pure business rules, no I/O) → app/ (use-case orchestration) → pg/ (repository implementation) layering.
Core Design Decisions
The reasoning behind the choices that are easy to get wrong in billing software.
| Decision | Why |
|---|---|
| Modular monolith, not microservices | Invoice finalization touches inventory, ledger, tax, and numbering atomically — that needs one transaction, not a distributed saga. |
| NUMERIC, never float, for money | Floats can't represent ₹0.01 exactly; a tax/accounting system that rounds wrong is a compliance and trust problem, not a bug ticket. |
| Append-only stock ledger | Stock balance is a materialized projection of immutable movements, never a directly-editable number — so it's always reconcilable. |
| Double-entry, enforced at 3 layers | App-level sum check, a deferred DB constraint trigger, and no UPDATE grant on posted journal rows — a bug in any one layer still can't post an unbalanced journal. |
| Generic tax model | tax_document / tax_line / tax_component, not hardcoded cgst/sgst columns — a TaxEngine interface with an IndiaGSTEngine plugin, so a second country is additive. |
| Versioned government adapters | GSTN changed the e-Invoice/e-Way Bill schema on 2026-08-01 with weeks' notice — adapters are versioned by directory, so that's a new adapter, not a scramble. |
| RLS as defense-in-depth | Every tenant table is scoped by organisation_id at the application layer and PostgreSQL Row-Level Security — a bug in one layer isn't a cross-tenant data leak. |
| No bundled reverse proxy | Self-hosted (CasaOS) and most cloud deployments already have one; TLS termination is the operator's documented job, not a second proxy fighting the first. |
Full reasoning, threat model, ERD shape, and the staged build plan live in docs/architecture.md on GitHub.
API & MCP
OpenAPI 3.1 is the source of truth; a real, read-only-by-default MCP server for AI access ships today.
The REST API is specified in api/openapi/ (OpenAPI 3.1) — the source of truth for API clients, not documentation reverse-engineered from the code after the fact. A read-only-by-default MCP server (apps/mcp) ships today: 10 tools, each calling the same permission-checked application-layer method a REST endpoint would, with no tool's input schema even carrying an organisation_id field — org scope comes only from the API key resolved once at process startup, so cross-tenant access isn't just disallowed, it's structurally impossible to request.
Roadmap
Built in explicit, gated stages — see the homepage roadmap section for the full stage-by-stage status.
Research → architecture → foundation → catalogue → inventory → sales/GST → accounting → reporting → government integrations → other integrations → packaging → hardening. A stage isn't marked done until it has real passing unit and integration tests. See the homepage roadmap or docs/TODO.md for the live, stage-by-stage checklist.
Scope & Limitations
What's intentionally not built yet, stated plainly.
The Go backend and the full web app (apps/web) are both built, wired, and tested today — this isn't an API-only product waiting on a UI. What's genuinely not available yet: a managed-cloud version, the Tauri 2 desktop shell (needs a Rust toolchain, not started), live WhatsApp/email/SMS sending (interface and mock only — no adapter shipped), and the Stage 11 hardening pass (security review, load testing at scale, and an accessibility audit) that should land before treating this as a v1.0 production guarantee. Nothing on this site claims otherwise; check docs/TODO.md for the exact, current line between shipped and in progress.
Contributing
AGPL-3.0-only. Bug reports and pull requests are welcome.