# Projection tables

Projection tables are permitted only when they provide meaningful **database-level** enforcement of an invariant that InnoDB cannot express another way (for example PostgreSQL constraint triggers that MySQL rejects with error 1442).

## Process (mandatory)

Before creating a projection:

1. Name the aggregate invariant using the **authoritative register** in `docs/PHASE1_PLAN.md` §5 (do not invent a new meaning for G1–G3).
2. State the source-of-truth tables and the projection table.
3. State how the projection is written (same transaction as the source writes).
4. State the MySQL constraints on the projection (PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY).
5. State the equivalence test.
6. Record the entry in the inventory below.
7. Only then add a migration.

## Established identifiers (do not redefine)

| ID | Meaning |
|---|---|
| **G1** | Cumulative credit-note quantity/value constraint |
| **G2** | Cumulative disposition constraint |
| **G3** | Discount/calculation cross-row constraint |
| **MLB-1** | `material_lot_balance` lockable current-balance projection (not a G-code; DB Arch does not number it) |

An earlier draft of this file listed “G1 lot quantity”. That mapping is **withdrawn**. Lot-balance is **MLB-1**.

## Phase 0 inventory

**None.** Phase 0 has no lot, challan, invoice, or IRN tables. G1–G3 and MLB-1 are not installed. Enforcement for future aggregates is transactions + deterministic `FOR UPDATE` ordering + service validation + concurrency tests, as recorded in `docs/POSTGRES_MYSQL_TRANSLATION.md`.

| ID | Invariant | Source tables | Projection | Status |
|---|---|---|---|---|
| — | — | — | — | No projections in Phase 0 |

Phase 1 projections and constraints are specified in `docs/PHASE1_PLAN.md` §5. They are **not** installed until Phase 1 implementation is approved.
