Core concepts

GOLD PRO has one central record — the valuation — and everything else either feeds it or hangs off it. A customer brings ornaments; you weigh them; a gold rate per gram prices them; a certificate comes out; a loan and its repayments may follow.

This page describes the model rather than the screens. For the screens, start with the Quickstart.

Tenants

A tenant is one shop. It owns its staff, customers, valuations, gold rates, bank branches, templates, invoices and support tickets, and none of them are visible to any other tenant. Every query in the product is scoped by tenant on the server, so isolation does not depend on a hidden menu item or a filtered dropdown.

Each tenant has a slug, which becomes the subdomain its customers use to reach their portal (your-shop.goldpro.shop). The main app is where staff work; the subdomain is where customers read.

Two things are deliberately not tenant-owned:

  • The shared bank catalog. Bank entries with no owner are common to every tenant.
  • Live market gold rates. A rate fetched from the market is a public figure, so it is shared. A rate you type by hand is yours alone. See Gold rates.

Tenants do not self-register. A super admin provisions the shop and its first tenant admin, then relays the credentials by hand. The public form at /register-business only records a request for someone to do that.

A handful of tenant fields cannot be edited directly, because they affect billing identity and support routing across the whole platform: the business name and the contact phone go through an approval request instead. Your GST number, invoice footer, terms text and logo are yours to change at will — see Personalization.

Staff and roles

Four kinds of principal exist, and they are not variations on one account type. They sign in at different places and see different products.

RoleSigns in atScope
TENANT_ADMIN/loginEverything in one shop, including every Admin page
TENANT_EMPLOYEE/loginValuations and customers. Cannot open Admin at all
CUSTOMERYour subdomainA read-only portal: their own valuations, EMIs and notifications
SUPER_ADMIN/system-gatePlatform operations across all tenants. Cannot use /login

The employee restriction is enforced at the edge on every request, not by hiding links: an employee who types an Admin URL is redirected to the dashboard. See Staff and roles.

Sessions are one-device-per-class. Each person gets one web slot and one mobile slot. Signing in on a second browser evicts the first, which discovers this on its next request and is bounced to the login page with an explanation. A browser and a phone can be signed in at the same time.

An admin creates an employee by typing or generating a temporary password and passing it on out of band. Nothing is emailed, and the employee is not forced to change it — treat the first password as shared knowledge and change it deliberately.

Customers

A customer belongs to exactly one tenant. The same person at two shops is two unrelated records; there is no cross-shop identity.

Two uniqueness rules matter:

  • One record per phone per shop. This is why the valuation form refuses to create a second borrower with a phone you already hold, and why phone numbers are normalised to a canonical 10-digit form before they are compared or stored — so a number pasted as +91 98765 43210 cannot slip past as a new person.
  • One record per email per shop, if an email is set. Portal sign-in is an emailed OTP, so an address that matched two customers would lock out both. Customers with no email are unaffected by this rule.

Customers move through a lifecycle stage held on the record:

StageMeaning
NewCreated, no valuation yet. This is what an inline borrower gets
KYC PendingDocuments uploaded, identity not yet verified
ActiveKYC complete, no running loan
Loan ActiveHas a running loan or repayment schedule
OverdueAn instalment is in default
ClosedLoan settled
InactiveArchived. The only stage that blocks portal sign-in

Inactive is the one stage with teeth. Every other stage — including Overdue and Closed — keeps portal access, and only Inactive hides a borrower from the valuation form's picker. See Customers and KYC.

Valuations, ornaments and EMIs

A valuation is a priced snapshot of a set of ornaments at a moment in time. There is exactly one code path that creates one, whether the request comes from the web form, the mobile app or the API, so the arithmetic cannot differ between them.

It needs remarkably little: a customer and at least one ornament. A bank is optional as far as the record is concerned — the web form insists on one in gold loan mode, but a certificate carries none. Both the customer and the bank can be created inline as you save.

A valuation is effectively immutable. There is no edit and no delete. After saving you can attach evidence photos, set appraiser notes, issue a gold receipt and manage the repayment schedule, but the weights, rates and amounts are fixed. Value it again rather than correcting it.

What gets snapshotted, and why

A valuation stores the rate it was priced at — not a pointer to whatever the rate is now. It records the applied 22K rate per gram, which basis won (live or bank), and both the live and bank rates per gram as they stood at the time.

This is the single most important design decision in the product. A certificate may be re-rendered days later, and rates move. Without the snapshot, reprinting a certificate would quietly restate it at today's figures — a document that changes after you handed it over. It is also why per-bank rates need no history table: every valuation already carries its own.

Ornaments

An ornament is a line on a valuation: type, purity, quantity, gross weight, deduction, net weight, the value it priced at, up to two photos, how purity was tested, and whether it was verified.

  • Purity is 24K, 22K or 18K. The engine rejects anything else outright rather than pricing it at the nearest rate it has. Some internal responses mention other karats; the valuation engine does not accept them.
  • Quantity counts identical pieces weighed together. The weights on the line are already the combined total for the set and are never multiplied by the quantity.
  • Value is (gross − deduction) × the rate per gram for that purity. The deduction is stones, lac and anything else that is not gold.

EMIs

Selecting a repayment schedule on a loan valuation generates the instalments at save time, spaced 30 days apart. The arithmetic is simple interest over the tenure, quoted per annum:

interest      = principal × (rate / 100) × (months / 12)
total payable = principal + interest + valuation fee
instalment    = total payable / number of instalments

The last instalment absorbs the rounding remainder, so the schedule sums exactly to the total payable. With no schedule selected the loan collapses to a single bullet repayment and interest accrues for a full year. Instalments carry a status of Upcoming, Due Soon, Overdue or Paid. See EMI tracking.

Gold rates

Always think of a gold rate as a figure per gram. Rates are entered, stored, derived and printed per gram throughout, and the most common data-entry error is a per-10-gram figure typed into a per-gram field. The system guards against exactly that: a rate whose karats are implausible relative to each other is rejected on entry rather than stored and priced from.

Two different things are both called a rate, and they are not interchangeable.

The market rate

The market rate is a running history per tenant. Each row is either manual (an admin typed it) or online (fetched from the market). When a valuation needs a rate, it resolves in three tiers:

OrderSourceWhen it applies
1Your own latest rateYou have ever recorded a rate, by hand or by sync
2The newest online rate from anywhere on the platformYou have none of your own
3A live fetch from the marketNothing is stored anywhere yet

Tier 2 is why a brand-new shop can value on day one. It is deliberately restricted to online rows: a market rate is a public figure and safe to share, but a rate you typed by hand is a commercial judgement and never leaks to another tenant. Setting your own rate is recommended, not required — Gold rates covers manual entry and auto-sync.

The 24K, 22K and 18K figures are validated as a set: they must descend in that order, and each must sit in a plausible band relative to 24K.

Per-bank rates

Banks publish their own gold-loan rate per gram, which trails the market. A report bound for a bank is normally priced at that bank's rate, and the appraiser picks the basis per valuation.

A per-bank rate stores only the 22K figure, because that is the one number banks actually publish. The 24K and 18K figures are derived from it on read, using the same fixed purity ratios as everything else. One stored figure per bank means the karats cannot drift apart.

Unlike the market rate, a per-bank rate has no cross-tenant fallback. It is a privately negotiated commercial term, not a market figure — your rate with a bank is never visible to another shop, and a bank with no rate configured for you falls back to the live market rate.

Banks and branches

Three models sit behind the word "bank", and the shape of each is a deliberate answer to a real-world fact.

The bank catalog is a central, shared list — one entry per bank, managed by the platform. A tenant admin cannot create one from the admin pages. Your shop gets its own entry only when someone types a genuinely new name on the valuation form, and even then the name is matched against the catalog first so a near-duplicate resolves to the existing bank.

A branch is your own directory entry for one branch of one bank: its name, IFSC, and the manager's email a report is dispatched to, plus optional per-branch email wording. Branches are private to your shop.

A per-bank rate is your gold-loan rate per gram with that bank, described above.

The asymmetry between the last two is the point:

ModelRows per (tenant, bank)Why
BranchManyOne bank has many branches across many cities, each with its own manager and email address
Per-bank rateExactly oneA bank publishes one gold-loan rate per gram. Branches do not set their own

So an edit to a per-bank rate overwrites the existing figure rather than adding a row — it is audited, not versioned, and past certificates stay reproducible because each one carries its own snapshot.

A valuation records which branch its report was dispatched to, and that is set when you send, not when you save. See Banks and branches.

Plans and entitlements

A plan is a row in a catalog, not a name in the code, so prices and capabilities can change without a deploy. What a tenant may actually do is resolved from the plan its plan ID points at, through a set of features.

A tenant carries a plan name as well, and it is a display snapshot only. It exists so older badges keep rendering, and it can lag behind reality. Never treat it as an answer to "what is this shop allowed to do" — the plan ID is the source of truth.

Features come in two kinds:

KindMeansNote
BooleanA capability is on or off
LimitA numeric allowance, such as monthly scansNo value means unlimited. Zero means none — the two are opposites, not synonyms

A feature can also be marked not enforced, which means it is marketing copy on the pricing table and no code gates on it. That distinction is explicit so a bullet point can never be mistaken for a real entitlement. A tenant with no plan at all gets nothing.

Subscription status is derived, never stored. It is computed from the expiry date each time it is read, so it cannot go stale: Active, Expiring Soon within seven days, Expired, No Subscription, or Suspended when the shop is deactivated.

Today, an expired subscription does not revoke access. Expiry drives the status badge and nothing else, behind a switch that is off by default. This is a business decision rather than an oversight: turning it on before self-serve payment is live would strand tenants with no way back in.

New shops are provisioned onto whichever plan is flagged as the default trial, for that plan's trial length. A trial is marked as such — a lapsed trial and a lapsed paid subscription are otherwise indistinguishable — and a shop that has used its trial cannot start another. See Billing and plans and the Billing API.