Savings Schemes — Detailed Requirements
The deep specification for the gold savings scheme module — expanding the module summary into a full data model, testable requirements with acceptance criteria, status lifecycles, business rules, and known gaps. Customers enrol in a scheme and pay installments over a tenure; each installment is recorded as a balanced double-entry ledger pair. Bonus tiers and maturity handling are specified but not yet implemented — flagged throughout. Derived from the live scheme module.
Scheme products
Three types (fixed / flexible / weight-based) with a purity, tenure, and tiered bonuses.
Enrolment
A customer's plan: target amount, dates, and per-installment min/max.
Installments
Double-entry installment postings against the customer and scheme accounts.
Bonus & maturity
Tiered bonuses and maturity auto-complete — specified, not yet built.
Savings Schemes · Detailed
Data model
Three entities: the scheme product, the customer enrolment, and the installment transaction (which extends the finance ledger's account-transaction).
product| Field | Type | Notes |
|---|---|---|
name | string (required) | Scheme name. |
type key | enum | FIXED_AMOUNT / FLEXIBLE_AMOUNT / WEIGHT_BASED. |
purityTypeId key | ObjectId → purity | Gold purity the scheme accrues in. |
duration | number | Tenure (months). |
schemeAccountId key | ObjectId → Account | GL account credited by each installment. |
cashAccountId | ObjectId → Account | Optional cash account. |
benefits | string[] | List of benefit lines. |
bonuses key | SchemeBonus[] | Tiered: {from, to, bonusType: AMOUNT/GRAM/PERCENT, bonusValue}. not applied Defined but no calculation logic exists. |
enrolment| Field | Type | Notes |
|---|---|---|
userId | ObjectId → User | The customer. |
schemeTypeId | ObjectId → Scheme | The scheme product. |
status | enum (default PENDING) | PENDING / ACTIVE / COMPLETED / CANCELLED. |
amount | number | Total target amount for the plan. |
startDate, endDate | number (unix) | Start and maturity. manual endDate is supplied, not derived from duration. |
minAmount, maxAmount | number | Per-installment bounds. not enforced Stored but never validated. |
installmentExtends the finance AccountTransaction; installments are posted as two linked rows.
| Field | Type | Notes |
|---|---|---|
userSchemeId | ObjectId → UserScheme | The enrolment being paid into. |
amount | number | Installment amount. |
weight, rate | number | Gold weight / rate — used for WEIGHT_BASED schemes. |
status | enum (default PENDING) | PENDING / CONFIRMED / REJECTED. |
confirmedAt, confirmedBy | number, ObjectId → User | Set when confirmed. |
accountId, type, kind, relationId | inherited | DEBIT input account; CREDIT scheme account; kind = SchemeTransaction; shared relationId links the pair. |
Savings Schemes · Detailed
Scheme products SCH-P
Administrators define the savings products — their type, purity, tenure, linked accounts, benefits, and bonus tiers.
- Create requires
name,type,purityTypeId,duration, andschemeAccountId. - Update is partial; delete is a soft delete.
- List paginates (skip / take) with a total count.
FIXED_AMOUNT, FLEXIBLE_AMOUNT, and WEIGHT_BASED.- The type is stored as an enum on the product.
- WEIGHT_BASED schemes capture
weightandrateon their installments.
AMOUNT / GRAM / PERCENT) and a value.- Each bonus tier stores
from,to,bonusType, andbonusValue. - Tiers are stored on the product (their application is specified separately — see Bonuses).
Savings Schemes · Detailed
Enrolment SCH-E
A customer's enrolment into a scheme — the target amount, the term, and the per-installment bounds.
PENDING.- Create requires
userId,schemeTypeId,amount,startDate,endDate. - Status defaults to
PENDING;minAmount/maxAmountare optional. - Listing resolves the linked customer and scheme; supports a date range filter.
PENDING → ACTIVE → COMPLETED, or to CANCELLED, administratively.- Status is settable via update.
- No state-machine guard or auto-completion is applied (see Maturity and Known gaps).
Savings Schemes · Detailed
Installment transactions SCH-T
Each installment is a balanced double-entry pair between the customer's account and the scheme account.
Posting
| Leg | Posting | Shared |
|---|---|---|
| Installment | DR Customer / payment account (input) CR Scheme account ( scheme.schemeAccountId) | same amount, same relationId, kind = SchemeTransaction |
kind = SchemeTransaction.- Creating an installment posts exactly two entries: DEBIT to the input
accountId, CREDIT toscheme.schemeAccountId. - Both rows carry the same
amountand the same generatedrelationId. - The DEBIT entry is returned to the caller.
- Missing/invalid
userSchemeId→ error "UserScheme not found". - Enrolment with no resolvable scheme → error "Scheme not found".
PENDING → CONFIRMED (or REJECTED); confirmation SHALL record who confirmed it and when.- A new installment defaults to
PENDING. - Confirming records
confirmedAtandconfirmedBy.
WEIGHT_BASED schemes, the system SHALL capture the gold weight and rate on each installment.weightandrateare stored on the transaction.
Savings Schemes · Detailed
Bonuses SCH-B not implemented
Tiered bonuses are defined on the product but their calculation and posting do not yet exist. These requirements specify the intended behaviour.
- Tier = the bonus where
from ≤ accumulated ≤ to. AMOUNT→ addbonusValue;PERCENT→ addaccumulated × bonusValue / 100;GRAM→ addbonusValuegrams valued at the prevailing rate.
- A bonus posting credits the customer's account at completion.
- The applied bonus is recorded against the enrolment for audit.
Savings Schemes · Detailed
Maturity SCH-M not implemented
Tenure handling and auto-completion at the end date are specified but not built.
endDate is supplied manually rather than derived from duration, and nothing marks a scheme COMPLETED at maturity. The requirement below is the target.startDate + duration, and at maturity auto-complete the enrolment and trigger bonus application.endDateis computed fromstartDate+durationat enrolment.- At
endDatethe enrolment moves toCOMPLETEDand bonus application (FR-SCH-B01/B02) runs.
Savings Schemes · Detailed
Statuses & key values
Scheme type
Enrolment status
Installment status
Bonus type
Savings Schemes · Detailed
Business rules
- Every installment is a balanced double-entry pair (DEBIT customer / CREDIT scheme account) sharing one
relationId. - An installment cannot be posted unless both its enrolment and the parent scheme exist.
- Deletes are soft across all three entities; all mutations are audited.
- WEIGHT_BASED schemes track gold weight and rate per installment.
Savings Schemes · Detailed
Known gaps & risks
endDate is supplied manually (not derived from duration), and nothing auto-completes a scheme at maturity (FR-SCH-M01 is target).minAmount / maxAmount are stored on the enrolment but never enforced when an installment is recorded.