Model: EmailAuthentication¶
Authenticates a User by email address. Owned by exactly one User; one User may own many.
Fields¶
| Field | Type | Constraints | Notes |
|---|---|---|---|
Id |
uuid |
PK, generated | |
CreatedAt |
timestamp with time zone |
NOT NULL, default now() UTC |
|
Address |
text |
NOT NULL, UNIQUE | Stored normalized: trimmed, lowercase. The unique constraint applies to the normalized value directly — no citext, no functional index. Application-level normalization at the controller boundary is the contract. |
UserId |
uuid |
NOT NULL, FK → User.Id ON DELETE RESTRICT, ON UPDATE RESTRICT |
Invariants¶
Addressis globally unique. One address authenticates one User.Addressis stored normalized (lowercase, trimmed, no surrounding whitespace). Inputs are normalized at the controller boundary before any DB lookup or write.- The FK to
UserisRESTRICTon both delete and update — the row must be removed explicitly before deleting the User. (Project policy: no cascade.)
Relationships¶
- Many-to-one with
User. See User's Relationships section for the FK behavior.
Notes¶
- Uniqueness is enforced on the pre-normalized lowercase string — a plain
UNIQUEconstraint onAddress. Per ADR 0004, the database collation isC.UTF-8(byte-order), so no functional index orcitextextension is needed. Normalization (trim + lowercase) happens at the controller boundary; the database is told the truth and indexes the truth. - This table holds only the address. Sign-in flows resolve
Address → User → PasswordHash; the password lives onUser, not here.