← All work
HAS / HE / TIPL groupIn build

Parts & Pricing System

A spare-parts master, cross-reference and pricing system built around durable identity, immutable history and human-reviewed document extraction. It is in build and not yet deployed.

Client
HAS / HE / TIPL group
Sector
Heavy earthmoving spare parts
Status
In build · not yet deployed
Live since
Stack
React 18 + TypeScript + Vite + Tailwind + TanStack Query/Table / Express + TypeScript + better-sqlite3 with FTS5, shared zod schemas, pdfjs-dist + tesseract.js
Scale
28 commits · Parts Master, Filter Cross-Reference, Customer Prices and Vendor Prices built
01

The problem

Part numbers, brand cross-references, customer prices and vendor prices lived in files and memory. Nobody could answer what a part last sold for, to whom, or when from one reliable trail.

Part numbers are corrected. Brands use different references for equivalent parts. If the visible number is treated as the database identity, fixing a typo can orphan every price already attached to it.

Vendor quotation PDFs can accelerate entry, but extraction is not clean enough to become a price without a person confirming every line.


02

What we built

The built foundation and the modules defined around it.

M-01Parts master
M-02Machine master
M-03Filter cross-reference
M-04Brand management
M-05Customer prices
M-06Vendor prices
M-07Quotations
M-08Discount engine
M-09Price history
M-10Custom fields admin
M-11Bulk import/export
M-12Master search
M-13Change log

03

The hard parts

The invariants underneath prices, identity and configurable data.

Money is integer paise, never a float

A discount carries its unit. Percentage discounts are stored in basis points, so 12% is 1200. Fixed discounts are stored in paise.

Percentage results round to the nearest paise. Every result floors at zero.

Price history is append-only, enforced by the database

Update and delete triggers raise. A back-dated entry joins the trail but never displaces the displayed last price, because “last” is max(date, then id).

Re-saving a quotation line updates rather than duplicates its price entry. A uniqueness constraint on the source line enforces that rule.

A part number is not an identity

part_identities assigns every brand-and-part-number pair a stable surrogate ID. The ID survives a correction, so fixing a typo does not orphan the price history attached to it.

One column registry drives everything

Built-in and custom fields share a single definition table. A type registry consumed by both client and server makes the grid, form, bulk-upload template, export and search behave identically.

Conditional visibility — bore dimensions only on bushes, for example — is configuration, not a hard-coded conditional.

Extraction is a draft, never a source of truth

Vendor quotation PDFs are parsed with an OCR fallback into a mandatory editable review table. A human confirms every line before it becomes a price.


04

How we know it works

Build-time invariants. This system is not yet live.

paiseinteger money end to end
append-onlyprice history enforced by database trigger
FTS5trigram search where “42 73542” matches “4273542”
0hard-coded field conditionals
← Previous caseLittle Lore ERP Next case →Hindusthan CRM

Tell us what your business runs on today.

Show us the registers, spreadsheets and hand-offs that hold the operation together. We will map where a custom system would pay for itself.