--- title: Address tags: [data-model, mongoose] aliases: [Shipping Address, IAddress] --- # Address User-owned address book entry. Each row carries the recipient name, optional phone, full address text, city/state/country/zip, an address type (`Home` / `Office` / `Other`), and a `primary` flag. A pre-save hook enforces a single primary address per user by demoting the user's other addresses when the saving document is primary. > [!note] Source > `backend/src/models/Address.ts:20` — schema definition > `backend/src/models/Address.ts:89` — model export ## Schema | Field | Type | Required | Default | Validation | Index | Description | | --- | --- | --- | --- | --- | --- | --- | | `userId` | ObjectId → [[User]] | yes | — | — | yes (single + compound) | Owner. | | `name` | String | yes | — | trim | — | Recipient name. | | `phoneNumber` | String | no | — | trim | — | Recipient phone. | | `fullAddress` | String | yes | — | trim | — | Address line. | | `city` | String | yes | — | trim | — | City. | | `state` | String | yes | — | trim | — | State / province. | | `country` | String | yes | — | trim | — | Country. | | `zipCode` | String | no | — | trim | — | Postal code. | | `addressType` | String | no | `Home` | enum: `Home` / `Office` / `Other` | — | Address type label. | | `primary` | Boolean | no | `false` | — | yes (compound, desc) | Whether this is the default address. | | `createdAt` | Date | auto | — | — | — | Mongoose timestamp. | | `updatedAt` | Date | auto | — | — | — | Mongoose timestamp. | ## Virtuals None defined. ## Indexes - `{ userId: 1 }` — from field-level `index: true` at `backend/src/models/Address.ts:25`. - `{ userId: 1, primary: -1 }` — `backend/src/models/Address.ts:75`. ## Pre/Post Hooks | Hook | Behaviour | | --- | --- | | `pre('save')` (`backend/src/models/Address.ts:78`) | If the document being saved is `primary: true`, demotes (`primary: false`) every other address belonging to the same `userId`. | ## Instance Methods None defined. ## Static Methods None defined. ## Relationships - **References**: [[User]] (`userId`). - **Referenced by**: none directly. Address text is also embedded into [[PurchaseRequest]] `deliveryInfo.deliveryAddress` at request time, denormalised so historical requests do not change if the address book changes later. ## State Transitions No status field. The boolean `primary` flag follows a simple at-most-one invariant maintained by the pre-save hook. ## Common Queries ```ts // User's address book Address.find({ userId }).sort({ primary: -1, updatedAt: -1 }); // Primary address Address.findOne({ userId, primary: true }); // Set a new primary (hook handles demotion) const addr = await Address.findById(id); addr.primary = true; await addr.save(); // Delete an address Address.deleteOne({ _id, userId }); ``` Related: [[User]], [[PurchaseRequest]].