Unreleased
Accountant handoff packages
- India, Spain, UK and US tax workpapers, source registers, review checks and downloadable ZIP/XLSX; scoped permissions and reconciliation.
- Spain IVA/recargo corrections and Modelo 303 workpapers; UK VAT boxes; eligible Indian offline-tool CSVs; separate US state schedules. Unknown statutory inputs stay blank for the accountant.
- No government submission credentials required for exports. See docs/accountant-exports.md for supported cases and remaining accountant work.
Invoice language, currency and credit-note follow-up
- Settings: interface language, company invoice-language default, and scoped browser preference for new-invoice currency.
- Invoice screen: explicit language/currency/rate controls; exact-decimal conversion of catalogue prices at the invoice rate.
- Hindi browser-print invoices with embedded Devanagari font, safe HTML and scoped CSP; migration 0048 enables Hindi. Print-copy overrides do not change saved choices.
- Sales summaries subtract credit notes/returns; product/category grouping no longer repeats document totals.
- Compliance limits remain explicit; no return filing, VERI*FACTU, UK MTD submission, local US tax/nexus or automatic FX revaluation added.
Added
- Tax: Spain (IVA incl. recargo de equivalencia), United Kingdom and all 27 EU member states (VAT, intra-EU B2B reverse charge, exports), and US state sales tax, behind a country dispatcher; India GST is unchanged (docs/tax-regimes.md). Migrations 0044-0046.
- All 165 ISO 4217 currencies and 250 countries; reference endpoints; first-run setup chooses country, currency and timezone.
- Eight UI languages (en, es, fr, de, it, pt, nl, hi) with locale-aware money/date formatting; locale parity check in CI.
- Invoice PDFs outside India itemise tax, show tax IDs, the currency and legal notes; Unicode text support.
- Scheduled, verified, encrypted backups with retention (worker, opt-in).
- Historical cost snapshots on stock movements (
stock_movements.base_unit_cost) for accurate gross profit.
Added (tax readiness for India, Spain, UK, US)
- Input VAT on domestic purchases (Spain, UK, EU); credit notes, tax summary report and Tax page; country-specific tax account names; readable tax errors; tax-inclusive pricing; invoice labels, tax names, dates and legal notes in the seller's language; customer address and tax ID on invoices; IBAN/BIC; country-aware contacts, inventory and settings screens. See docs/tax-regimes.md for what is and is not ready per country.
Fixed
- Accounting and reports labelled every amount "INR" regardless of the company's currency.
- Gross profit counted quotations/orders/challans as revenue and added credit notes instead of subtracting them.
- Invoice PDFs printed accented letters and the euro sign incorrectly.
- Mobile layout: the page scrolled sideways below ~1196px; topbar and 320px reflow; table scroll regions are keyboard-focusable; contrast of sidebar group labels.
- Purchases silently skipped tax for any company outside India, so input VAT was never recorded.
- Tax-rule errors reached users as "An unexpected error occurred" (HTTP 500).
- Setup country select could show a different country from the one the form held.
- Dependency vulnerabilities: excelize, vite, and the Go toolchain/standard library (1.27.1 -> 1.27.3, covering net/http, net/http/internal/http2 and crypto/x509 advisories) plus golang.org/x/net. CI's govulncheck job had been failing since 9 October; it now reports 0 affecting vulnerabilities.
Staged per docs/architecture.md §16 / docs/TODO.md. A stage is listed here once it has real passing unit and integration tests — see docs/TODO.md for exactly what's built vs. in progress within a stage.
Stage 15 — Catalogue pagination, a11y regression suite, backup/MSIX docs (2026-09-19)
- Fixed a real scale bug: the product catalogue list loaded every product for an organisation into the browser on every visit, with no server-side limit.
ProductRepo.ListByOrganisationnow takeslimit/offsetand returns a total count;CataloguePagesends paginated requests (50/page) with Previous/Next controls. Proven with a new integration test (TestCatalogue_ListProducts_Paginates), not just a UI change — this matters for any customer with a large SKU count, which this platform explicitly targets (distributors, multi-branch retailers). - Added a real, CI-wired accessibility regression suite (
tests/e2e, Playwright + axe-core): an axe scan of the login page (zero serious/critical violations — two pre-existing moderate landmark issues are flagged, not silently hidden) and a keyboard-only tab-order smoke test. Runs on every PR and push tomainalongside the existing Go/frontend/Docker jobs.tests/e2ewas previously an empty placeholder. - Documented backup/restore properly for the first time (
docs/operations/backup-restore.md): the feature itself already existed and was CI-tested, but had no operator-facing runbook. Added a concrete restore-drill procedure (spin up a scratch Postgres, restore into it, verify row counts and the trial-balance invariant), a scheduled-export script, and the real upgrade/migration mechanism. Also surfaced a real gap while writing it: API keys have nobackup.managescope mapping, so only session-cookie auth can actually call export/restore today. - Drafted
apps/desktop/msix/TERMS_AND_PRIVACY.mdfor the Microsoft Store submission (Store ID9NMPSP7CR5RW) — none existed, and Partner Center requires one. Marked as a draft pending legal review. - Fixed
gofmtdrift inapps/server/main.go,ewaybill/portal/v1/mapper.go, andorganisation/domain/domain.gothat had been silently failing CI's go-static job across several prior commits. - Known, not fixed this stage:
govulnchecknow flagsgithub.com/xuri/excelize/v2(GO-2026-6452, XLSX import path) — a newly-disclosed third-party CVE, unrelated to this stage's changes; and 5 pre-existingewaybill_free_portal_test.gointegration test failures (HSN/PIN-code eligibility) predate this stage too, confirmed against the unmodified baseline.
Stage 14 — Phone validation/search, WhatsApp PDF share, receivables reminders (2026-09-13)
- Party (customer/supplier) phone numbers must now be exactly 10 digits and unique within an organisation (DB partial unique index + app-level check); the sale-counter/Contacts search box, which already claimed to search "by name or phone", now actually matches on phone too.
- Sales documents can be shared via WhatsApp as the real PDF file (native OS/browser share sheet), alongside the existing signed-link share.
- The "Receivables (who owes you)" report gained a proper panel: customer name, phone, a one-click WhatsApp reminder button, and first/last reminder-sent tracking (
receivable_reminderstable) — previously the report only rendered a raw party UUID with no name at all. - Bulk e-Way Bill preparation now shows each invoice's amount.
- The Tax Rates screen gained a CSV import that bulk-creates HSN/SAC rates and, given a
sku_codecolumn, can also update that product's HSN/SAC code and stock on hand in the same pass — catalogue's existing product importer only ever creates brand-new products, never updates one that already exists.
Stage 13 — First-run activation flow (2026-09-07)
- A fresh install landed on a bare Sign-in page with no discoverable path to
/setup, even though the full bootstrap form already existed there — the root route always bounced an unauthenticated visitor straight to/login, and nothing linked to setup. AddedGET /auth/bootstrap(unauthenticated, mirrors the existingPOST), returning whether first-run setup is still open; the Sign-in page now checks it on load and shows a persistent "New to Rechvix? Set up your business" link when it's open, the same always-visible-link pattern this project's siblingnodedr-restaurant-posalready uses on its own login page ("New restaurant? Create an account"), rather than a silent redirect away from the login form. - Bootstrap availability now also auto-closes once any organisation exists, on top of the existing
ENABLE_BOOTSTRAPenv gate — belt and suspenders against an operator forgetting to disable it post-setup, since that endpoint has no permission check by design. Addedorganisation.Service.Exists, checked once at server startup. BootstrapPagenow redirects to/login?created=trueon success, which shows a "Business created — sign in to continue" banner instead of silently dropping the new owner back at a bare form.- Verified end-to-end against a real Postgres container (not just unit tests): fresh DB reports
{"available":true}, a real bootstrap call succeeds, and restarting the server against the now-non-empty database correctly reports{"available":false}and 405sPOST /auth/bootstrap.
Stage 12 — Team members, forgot-password UI, real brand assets (2026-09-06)
- Owner/Admin can add additional logins to their own organisation (
POST /users,identity.manage_users/identity.view_users) — the account-creation gap Bootstrap deliberately never covered, since it only ever provisions the single first-run owner. Settings > Team lists members and adds new ones. - Wired the frontend to the password-reset endpoints that already existed on the backend but had no screen (
/forgot-password,/reset-password), plus a "Forgot password?" link on the login page. - Replaced the placeholder rupee-glyph mark (in-app header/login, favicon, CasaOS icon) with the real Rechvix logo.
Stage 10b-2 — Frontend feature screens (2026-09-03)
- Sales screen (barcode/keyboard-driven billing, list, detail), e-Way Bill card, inventory/purchases/contacts/catalogue/accounting/GST/reports screens, global search + quick-create, code-split routing
- Fixed nil-slice list endpoints crashing fresh-organisation list screens (Go
nilslice serializes as JSONnull, not[]) - WCAG 2.2 AA accessibility pass: contrast-ratio fixes, ARIA role corrections, keyboard/Escape handling, skip link, table header scope, chart text alternative
Stage 10a — Docker / Compose / CasaOS packaging (2026-09-03)
- Multi-stage server/worker Dockerfiles, docker-compose with migrate/app/ worker services, CasaOS manifest
- Split migrator vs. runtime Postgres roles so RLS isn't silently bypassed by table ownership
Stage 10b-1 — Frontend foundation (2026-09-03)
apps/webscaffolded (Vite, React 19, TypeScript strict, TanStack Query/ Router, React Hook Form, Zod, ECharts), design system, auth flow, app shell, dashboard wired to real reporting endpoints
Stage 9 — Integrations (2026-09-03)
- Notification provider interfaces (email/SMS/WhatsApp), signed share links, scoped API keys, HMAC-signed webhooks with outbox-backed retry, read-only MCP server (10 tools)
Stage 8c — Free-first e-Way Bill portal workflow (2026-09-03)
- Canonical e-Way Bill snapshot model, versioned eligibility rules, portal export mapper, logistics module (vehicles/transporters), manual import/verify flow, API-failure → free-portal fallback
Stage 8 — Government integrations, sandbox only (2026-09-03)
- Transactional outbox +
apps/worker, e-Invoice provider interface (mock - NIC sandbox adapter), e-Way Bill generate/retrieve/cancel/Part-B
Stage 7 — Reports / dashboard (2026-09-03)
- Sales/purchases/inventory/accounting/tax reports, 8-card dashboard, CSV/XLSX/JSON/PDF export
Stage 6 — Accounting (2026-09-03)
- Chart of accounts, double-entry journals enforced at 3 layers, auto- posting from sales/purchases, customer/supplier ledger + ageing, fiscal period locking
Stage 5b — Sales documents & printing (2026-09-03)
- Quotation/proforma/order/challan/invoice/credit-debit-note/return document family, document numbering, PDF templates
Stage 5a — Tax engine (2026-09-03)
- Generic
TaxEngineinterface +IndiaGSTEngineplugin, golden tax fixtures across GST rate slabs
Stage 4 — Inventory & purchases (2026-09-03)
- Append-only stock ledger, weighted-average costing, batches/serials, purchase order → GRN → invoice → return flow
Stage 3 — Catalogue, contacts, pricing (2026-09-02)
- Products/variants/SKUs, units of measure with conversions, parties, price lists, CSV/XLSX import scaffolding
Stage 0-2 — Research, architecture, foundation (2026-09-02)
- Verified Go/PostgreSQL/GST API version facts, module architecture and ERD shape,
internal/platformcross-cutting packages, identity + organisation modules, Argon2id-based auth with TOTP MFA
Rendered from the repository at commit f27eb2b. Original on GitHub (opens in a new tab)