Happy House - Ecommerce Docs
Developer ResourcesAddress

Address API Reference

Complete API contracts for the Address module, including routes, auth, DTOs, responses, errors, examples, and integration notes.

Address - API Reference

Audience: Frontend engineers, mobile engineers, backend engineers, QA, and API consumers. Scope: The customer address book — seven customer-facing endpoints. There is no admin surface.

1. Documentation Evidence

AreaFiles InspectedWhat Was Verified
Controllersapps/api/src/modules/address/customer/address-customer.controller.tsRoutes, methods, guards, idempotency scopes, status codes
DTOscustomer/dto/*.tsValidation, defaults
Servicescustomer/address-customer.service.tsBehavior, default invariant, errors
Schemapackages/db/src/schema/address/customer-address.tsCHECKs, partial unique default, CASCADE
Error registryapps/api/src/common/types/error-codes.ts (// CUSTOMER ADDRESS)CUSTOMER_ADDRESS_* codes

2. Module Summary

FieldValue
Module nameaddress
Module slugaddress
Primary actorscustomer
API surfacesmobile only
Base route prefixes/api/mobile/addresses
Auth modelJwtAuthGuard
PersistencePostgreSQL (customer_address), Redis (shipping serviceability cache, read)
Runtime source of truthcustomer_address rows
Sibling docsBackend, Features and flows

3. Concepts and Terminology

TermMeaningSource FileUsed By
isDefaultThe customer's one default delivery addressschemaCreate/list/default routes
archivedSoft-deleted; readable and restorable, not writableschemaAll routes
serviceableLive shipping availability for the address's district — computed per read, never storedserviceAll responses
municipality.idAlways null — reference table ships empty by design; municipality.name is free textschemaResponses
recipientPhoneLocal numbers accepted; stored and returned as E.164 (+977…)phone utilCreate/update

4. API Surface Map

SurfaceMethodPathActorAuth/GuardPermissionControllerPurpose
MobilePOST/api/mobile/addressesCustomerJWT + IpThrottleAddressCustomerControllerCreate (201; idempotent)
MobileGET/api/mobile/addressesCustomerJWT + IpThrottlesameList mine
MobileGET/api/mobile/addresses/:idCustomerJWT + IpThrottlesameRead one (archived readable)
MobilePATCH/api/mobile/addresses/:idCustomerJWT + IpThrottlesameUpdate (active only)
MobileDELETE/api/mobile/addresses/:idCustomerJWT + IpThrottlesameArchive (active only; 200)
MobilePOST/api/mobile/addresses/:id/restoreCustomerJWT + IpThrottlesameRestore (archived only; 200; idempotent)
MobilePUT/api/mobile/addresses/:id/defaultCustomerJWT + IpThrottlesameSet default (active only)

Row-state requirement per route: GET :id works on any state (a customer must see what to restore); PATCH, DELETE and PUT /default require active (409 on archived); restore requires archived (409 on active).

5. Auth, Identity, and Permissions

SurfaceGuard/DecoratorIdentity ShapePermissionGuest AllowedNotes
AllJwtAuthGuard, IpThrottlerGuardreq.user.idNoEvery WHERE is scoped to req.user.id

Rate limits, keyed on the account (keyStrategy: "user"): CUSTOMER_READ 60/min (list/read), CUSTOMER_WRITE 20/min (create/update/archive/restore/default). Idempotency: Idempotency-Key required on create (scope customer-address-create) and restore (scope customer-address-restore).

6. DTO and Model Reference

6.1 CreateAddressDto

FieldTypeRequiredDefaultValidationExampleSource
recipientNamestringYesN/A"Sita Sharma"create-address.dto.ts
recipientPhonestringYesN/Amust normalize to E.164 (NP region)"9812345678"
districtIdUUID v7YesN/A@IsUUID("7")0198…
municipalityNamestringYesN/A"Kathmandu Metropolitan City"
wardnumberYesN/Aint 1..4016
street / landmark / postalCodestringNoNULL"Jhamsikhel Marg"
latitude / longitudenumberNoNULLboth or neither; inside Nepal (26.0–30.6, 79.9–88.3)27.6789 / 85.3123
deliveryInstructionsstringNoNULL"call on arrival"
isDefaultbooleanNofalsetrueonly matters from the second address

6.2 UpdateAddressDto

Same fields, all optional; omitted fields unchanged; an explicit null clears a nullable field. Changing the district may change serviceability, which the response reflects.

6.3 Query DTO

ListAddressesQueryDto: status (active default / archived / all), districtId, provinceId, + QueryDto base (pagination, page, size).

6.4 Response DTO

{
  "id": "0198…",
  "recipient": { "fullName": "Sita Sharma", "phoneNumber": "+9779812345678" },
  "location": {
    "province": { "id": "0198…", "code": "bagmati", "name": "Bagmati" },
    "district": { "id": "0198…", "code": "kathmandu", "name": "Kathmandu" },
    "municipality": { "id": null, "name": "Kathmandu Metropolitan City" },
    "ward": 16, "street": "Jhamsikhel Marg", "landmark": "opposite the bakery",
    "postalCode": "44600", "latitude": 27.6789, "longitude": 85.3123,
    "deliveryInstructions": "call on arrival"
  },
  "status": { "default": true, "archived": false, "serviceable": true },
  "timestamps": { "createdAt": "…", "updatedAt": "…", "archivedAt": null }
}

7. Enum Reference

None — address state is archived_at + is_default columns.

8. Endpoint Reference

8.1 POST /api/mobile/addresses

Purpose

Add a delivery address. The first address becomes the default automatically. Retries with the same Idempotency-Key never create a duplicate.

Auth and Permissions

JwtAuthGuard, IpThrottlerGuard; CUSTOMER_WRITE 20/min (account-keyed); Idempotency-Key required (scope customer-address-create).

Request

Body per §6.1 — local phone accepted (9812345678+9779812345678).

Response

201 — address response per §6.4.

Side Effects

customer_address row; auto-default when it is the first active address; serviceability computed from shipping.

Error Cases

HTTPCodeCondition
400CUSTOMER_ADDRESS_RECIPIENT_PHONE_INVALIDPhone will not normalize to E.164
400CUSTOMER_ADDRESS_COORDINATES_INCOMPLETEOne coordinate without the other
400CUSTOMER_ADDRESS_COORDINATES_OUT_OF_RANGEOutside Nepal — usually latitude/longitude swapped
400IDEMPOTENCY_KEY_REQUIREDMissing header
404CUSTOMER_ADDRESS_DISTRICT_NOT_FOUNDDistrict uuid names nothing
409CUSTOMER_ADDRESS_LIMIT_REACHED20 active addresses already
409idempotency conflictsKey replayed differently / in flight

8.2 GET /api/mobile/addresses

Purpose

List my addresses — default first, then newest. Unpaginated by default (the active set is capped at 20).

Request

?status=active|archived|all&districtId=&provinceId=&pagination=&page=&size

Response

200 — array of address responses.

8.3 GET /api/mobile/addresses/:id

Purpose

Read one address — archived rows are readable, so a customer can see what to restore.

Error Cases

HTTPCodeCondition
404CUSTOMER_ADDRESS_NOT_FOUNDNo such address for this customer — also the answer for someone else's address (a 403 would be an existence oracle)

8.4 PATCH /api/mobile/addresses/:id

Purpose

Update an address. Omitted fields are unchanged; explicit null clears a nullable field.

Error Cases

HTTPCodeCondition
409CUSTOMER_ADDRESS_ALREADY_ARCHIVEDWrite attempted on an archived row — offer restore
404CUSTOMER_ADDRESS_NOT_FOUNDNot this customer's address

8.5 DELETE /api/mobile/addresses/:id

Purpose

Archive (soft delete). Archiving the default promotes the newest remaining active address. Restorable via 8.6.

Response

200 message-only.

Error Cases

HTTPCodeCondition
409CUSTOMER_ADDRESS_ALREADY_ARCHIVEDAlready archived
404CUSTOMER_ADDRESS_NOT_FOUNDNot this customer's address

8.6 POST /api/mobile/addresses/:id/restore

Purpose

Restore an archived address. The default flag is recomputed, never carried over — it becomes the default only if the customer has no other active addresses. Idempotency-Key required (scope customer-address-restore).

Response

200 — address response.

Error Cases

HTTPCodeCondition
409CUSTOMER_ADDRESS_NOT_ARCHIVEDRestore attempted on an active row
404CUSTOMER_ADDRESS_NOT_FOUNDNot this customer's address

8.7 PUT /api/mobile/addresses/:id/default

Purpose

Make this my default address. Clears the previous default in the same transaction; archived addresses cannot be made default. Concurrent calls are serialized per customer.

Response

200 — address response.

Error Cases

HTTPCodeCondition
409CUSTOMER_ADDRESS_ALREADY_ARCHIVEDArchived row
404CUSTOMER_ADDRESS_NOT_FOUNDNot this customer's address

9. Flow Diagrams

9.1 Route Ownership

9.2 Request Sequence (create)

9.3 Error Branch (write on archived)

EndpointPagination TypeDefault SizeMax SizeSort FieldsFiltersResult Cap
GET /api/mobile/addressesoffset (opt-in)20100default first, then newest (fixed)status, districtId, provinceId20 active / unbounded with status=all

11. Caching, Jobs, and External Integrations

IntegrationUsed?Details
Redis cacheRead-onlyShipping serviceability (one key in the shipping domain); address rows never cached (PII)
BullMQNo
External APINo

13. Mandatory Deep API Documentation Pack

13.1 Route-by-Route Completeness Matrix

RouteController MethodDTOsService MethodGuardsPermissionsCacheJobsDB TouchesErrorsDocumented?
POST /api/mobile/addressescreateCreateAddressDtoAddressCustomerService.createJWT+IpThrottle+Idempotencycustomer_address, district, shipping400/404/409Yes
GET /api/mobile/addresseslistListAddressesQueryDto…listJWT+IpThrottleshipping (read)customer_address, shippingYes
GET /api/mobile/addresses/:idfindOneAddressParamsDto…findOneJWT+IpThrottlecustomer_address404Yes
PATCH /api/mobile/addresses/:idupdateUpdateAddressDto…updateJWT+IpThrottlecustomer_address404/409Yes
DELETE /api/mobile/addresses/:idarchiveAddressParamsDto…archiveJWT+IpThrottlecustomer_address (default promotion)404/409Yes
POST /:id/restorerestoreAddressParamsDto…restoreJWT+IpThrottle+Idempotencycustomer_address (flag recompute)404/409Yes
PUT /:id/defaultsetDefaultAddressParamsDto…setDefaultJWT+IpThrottlecustomer_address (lock + flags)404/409Yes

13.2 Request/Response Exhaustiveness

Covered in §8: minimal/full create payloads (§6.1/8.1), success responses (§8.1/8.6), the municipality.id: null response shape (§6.4), domain errors per endpoint (§8 error tables), rate-limit behavior (account-keyed 429), permission-free surface (403 impossible — JWT only).

13.3 API Diagram Pack

Route ownership (§9.1), sequence per endpoint family (§9.2, backend §7), error decision tree (§9.3), serviceability flow (backend §7.2).

13.4 Consumer Integration Notes

ConsumerRequired KnowledgeFailure HandlingContract Stability
Web frontendmunicipality.id always null; render municipality.name; phone always E.164 in responses409 on archived → offer restoreStable
Mobile appIdempotency-Key on create/restore; account-keyed rate limits429 → back off; retry create with same keyStable
QADefault-flag recompute, zero-active = legal, serviceability-on-readReproduce via exact codesStable
Orders (future)Snapshot the address, never FK to itCASCADE erases addresses with the customerStable
Admin panelNo admin surface existsStable

13.5 API Tradeoffs and Rationale

DecisionChosen BehaviorAlternatives ConsideredWhy This TradeoffRiskMitigation
CASCADE + snapshot ruleAddresses die with the customerNo-cascadePII must not outlive ownerOrders lose referencesSnapshot contract documented
Default invariantPartial unique index + advisory lockApplication check onlyConcurrent set-default safeRare contentionLock is per-customer
Restore flag recomputeNever carry the old flagRestore as-wasDefault is a choice, not historySurprise restoresDocumented
municipality.id nullFree-text nameFull referenceNo 753-row memory gameNo idsDocumented
Local phone acceptedNP default regionStrict E.164Easier entryAmbiguityDocumented

13.6 API Change Impact

ChangeAffected ConsumersBackend ImpactData ImpactMigration Needed?Compatibility Plan
Serviceability changeAny consumer caching itNoneNoneNoNever stored — computed per read
Repricing a districtAddress listsNoneNoneNoShipping cache domain

14. Zero-Omission API Checklist

  • Every controller route is documented (§4, §8, §13.1).
  • Every parent route prefix and runtime URL is documented (§2, §4).
  • Every DTO field, enum, default, transform and validator is documented (§6).
  • Every response field and nullable field is documented (§6.4, §8).
  • Every auth, guard, permission and guest identity branch is documented (§5).
  • Every success, validation, not-found, conflict, rate-limit and server-error branch is documented (§8).
  • Every DB read/write, cache read and external call is documented (§11, backend §8).
  • Every route has examples for minimal request, success response and representative failures (§8).
  • Every endpoint family has route, sequence and error diagrams (§9, backend §7).
  • Every tradeoff and compatibility risk is documented (§13.5, §13.6).
  • The API doc links to backend and features/flows (§1, See Also).

15. Integration Checklist

  • Every route from controllers is documented.
  • Every DTO field is documented.
  • Every response envelope is documented.
  • Every error code is documented.
  • Every auth guard and permission is documented.
  • Every cache key, queue job and external call is documented.
  • Every diagram matches the current code.
  • The API doc links to backend and features/flows.

See Also