# SPECIFICATIONS/03_ARCHITECTURE/02_STATE_MACHINES.md

**PURPOSE:** Defines the valid states and transitions for contracts and installments. This file answers "what states exist and how do entities move between them?" — it contains zero implementation logic.

> **Business rules that govern these transitions:** `../01_BUSINESS_CONTEXT/03_BUSINESS_RULES.md` → BR-002, BR-003, BR-004
> **Algorithms that execute these transitions:** `../05_ALGORITHMS/03_PAYMENT_ENGINE.md`

---

## Contract State Machine

### States

| State | Description |
|:---|:---|
| **draft** | Initial state. Contract data is modifiable. |
| **active** | Signed. All contract data becomes immutable. Only payment operations allowed. |
| **completed** | All installments paid. No further operations. |

### Transitions

```
┌─────────┐      sign()      ┌─────────┐   last payment  ┌───────────┐
│  draft  │ ───────────────> │ active  │ ──────────────> │ completed │
└─────────┘                  └─────────┘                 └───────────┘
     │
     │ delete() (draft only)
     ▼
 [DELETED — no trace remains]
```

### Transition Rules

| From | To | Trigger | Guard |
|:-----|:---|:--------|:------|
| — | `draft` | Create contract | None |
| `draft` | `active` | Sign contract | Status must be `draft` |
| `active` | `completed` | Pay last installment | No pending or overdue installments remain |
| `draft` | [DELETED] | Delete contract | Status must be `draft` |

### Immutable State
Once `active`:
- All contract fields become read-only
- Only payment recording, modification (LIFO), and deletion (LIFO) are allowed
- Deletion is completely blocked

---

## Installment State Machine

### States

| State | Description |
|:---|:---|
| **pending** | Awaiting payment. Not yet due, or due in the future. |
| **overdue** | Past due date. Not yet paid. |
| **paid** | Payment received matching exact amount. |

### Transitions

```
┌──────────┐ due_date < today ┌──────────┐
│ pending  │ ─────────────────> │ overdue  │
└──────────┘                    └──────────┘
     │                               │
     │ payment (exact match)         │ payment (exact match)
     ▼                               ▼
┌──────────┐                    ┌──────────┐
│   paid   │                    │   paid   │
└──────────┘                    └──────────┘
     │                               │
     └──────────┬────────────────────┘
                │ LIFO reversal (payment deleted)
                ▼
          ┌──────────┐
          │ pending  │  (if due_date >= today)
          │    or    │
          │ overdue  │  (if due_date < today)
          └──────────┘
```

### Transition Rules

| From | To | Trigger | Notes |
|:-----|:---|:--------|:------|
| — | `pending` | Contract creation | Initial state |
| `pending` | `overdue` | Scheduled check | When `due_date` passes without payment |
| `pending` | `paid` | Payment received | Amount must exactly match |
| `overdue` | `paid` | Payment received | Amount must exactly match |
| `paid` | `pending` | LIFO reversal | If `due_date >= today` |
| `paid` | `overdue` | LIFO reversal | If `due_date < today` |

### Overdue Detection
Installments transition from `pending` to `overdue` when their `due_date` is earlier than the current date. This check runs on a scheduled basis.

### Contract Completion Trigger
When any installment transitions to `paid`, the system checks whether the contract has any remaining pending or overdue installments. If none remain, the contract automatically transitions to `completed`.