83 lines
2.8 KiB
Markdown
83 lines
2.8 KiB
Markdown
---
|
|
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]].
|