# SPECIFICATIONS/00_GLOSSARY.md

**PURPOSE:** Defines the precise meaning of domain and technical terms used across the documentation. If a term appears in multiple files with the same meaning, it is defined here once and referenced elsewhere.

---

## Domain Terms

### Contract Margin
The difference between `total_after_profit` and `purchase_amount` for a single contract. Represents the company's actual earnings from the installment sale before investor profit distribution.

```
contract_margin = total_after_profit - purchase_amount
```

**Not to be confused with:** `profit_percentage` (the rate applied to calculate the margin), `total_after_profit` (the total amount the customer pays), or `investor_profit` (the 5% distributed from the margin).

### Investor Profit
5% of the total contract margin from all active or completed contracts where the investor is the `agent_id`. Always computed dynamically — never stored.

```
investor_profit = SUM(contract_margin) × 0.05
```

### Shares Balance
The current number of active shares for an investor. Only records with `status = 'active'` are included. `deposit` transactions contribute positively, `withdraw` transactions contribute negatively. Records with `deleted` status are excluded from the calculation.

### Reference Number
A human-readable, auto-generated identifier for paper document usage. Format: `CUS-XXXXXXXXXX` for clients, `CTR-XXXXXXXXXX` for contracts (10 digits, leading zeros). Never used as a database foreign key.

### Client Type Flags
A JSONB array column on the `clients` table that stores role identifiers. Valid values: `customer`, `agent`, `investor`. A single client can hold any combination of these simultaneously. Role is inferred by checking for the presence of a flag string — O(1) operation with GIN index support.

### LIFO (Last-In, First-Out)
In the context of this system, LIFO refers exclusively to payment operations: only the most recently created payment can be modified or deleted. This preserves the integrity of the financial ledger sequence. It does NOT refer to inventory or accounting LIFO concepts.

### Narrative Independence
The principle that audit log `narrative_text` must be fully self-contained and readable without JOINing to the `payments` table. This is critical because the `payment_id` foreign key becomes `NULL` when a payment is deleted (via `ON DELETE SET NULL`), making the payment data unreachable for that audit log entry.

---

## Payment Types

### company_payout
A payment record automatically created upon contract creation (even drafts) representing the amount the company paid to acquire the product. Amount equals `purchase_amount`. Not linked to any installment. Serves for internal accounting and contract timeline display.

### initial_payment
A payment record representing the customer's down payment. Created only when `initial_payment > 0`. Not linked to any installment.

### installment_payment
A payment record representing a monthly installment payment. Always explicitly linked to a single installment via `installment_id`. This link is the sole source of truth for which payment settled which installment.

---

## Status Terms

### fully_paid
A customer list filter value indicating that all installments across the customer's active and completed contracts have been paid. Distinct from `no_installments` (customer has no contracts at all).

### overdue
An installment whose `due_date` has passed without receiving a matching payment. The transition from `pending` to `overdue` is determined by comparing `due_date` to the current date — it is not a manual status change.

---

## Architecture Terms

### State Table Pattern
Pre-generating all installments as physical database rows at contract creation time, rather than calculating them dynamically on each request. Each row has an immutable `due_date` and a mutable `status`. This enables direct index-backed filtering and sorting without complex date arithmetic at query time.

### Append-Only Ledger
The payment recording pattern where new payments are only created (appended), never modified in-place. Corrections are made by deleting the latest payment (LIFO) and creating a new one. Combined with an independent audit log, this ensures a complete and trustworthy financial history.

### Cursor Pagination
A pagination strategy that uses an opaque cursor value (derived from the last row's sort values) instead of an offset number. Unlike offset pagination (`LIMIT 20 OFFSET 100000`), cursor pagination starts reading directly at the cursor position, maintaining consistent O(1) performance regardless of dataset size. Trade-off: no "jump to page N" functionality.

### Materialized View
A PostgreSQL database object that pre-computes the result of a complex query and stores it physically. Unlike a regular view (which re-executes the query on each access), a materialized view returns data from the stored result. Must be explicitly refreshed. Used in this system for customer listing to meet sub-second response time requirements.

### Daily Snapshot Tables
Dedicated database tables that store pre-aggregated daily metrics, refreshed once per day via scheduled jobs. Used for analytics KPIs and collection trends as a lighter alternative to Materialized Views. Data is up to 24 hours stale.

### Response Builder
A service class responsible for assembling complex read responses that require data from multiple sources (multiple queries, computed fields, external state). Named `{Entity}DetailBuilder`. Output is a raw array passed to the Controller. Distinct from API Resources (which handle simple model-to-array transformation) and Services (which handle write use cases).