Address Features and Flows
Developer Resources Address Address Features and Flows Complete feature list, actor journeys, state flows, business rules, edge cases, and diagrams for the Address module.
Use this page for the address-book domain: what it does for customers and systems, and how each flow behaves from start to finish.
Source Type Files or Docs What Was Extracted API apps/api/src/modules/address/customer/address-customer.controller.tsRoutes, guards, idempotency scopes, status codes Backend address-customer.service.tsDefault handling, advisory lock, serviceability-on-read Schema packages/db/src/schema/address/customer-address.tsWard/coordinate CHECKs, partial unique default, CASCADE Phone apps/api/src/utils/phone/phone.util.tsNP region, E.164 normalization Error registry apps/api/src/common/types/error-codes.ts (// CUSTOMER ADDRESS)CUSTOMER_ADDRESS_* codes
Field Value Module addressSubmodule N/A Primary user value A customer's own delivery addresses with one default, restorable archive, and live serviceability Actors Customer (signed in), internal systems (shipping serviceability, future orders) Main entry points /api/mobile/addresses (7 routes)Main outputs Address responses with grouped recipient/location/status Related docs API , Backend
Actor Can Do Cannot Do Auth Requirement Notes Customer Create, list, read, update, archive, restore, set-default their own addresses Touch another customer's address (404, never 403 — no existence oracle), write to an archived address (409) JWT CUSTOMER_READ 60/min, CUSTOMER_WRITE 20/min — both keyed on the accountAdmin — Read or write any address — No admin surface, by design (PII) Orders (future) Read an address at checkout to snapshot it Hold a foreign key to it Internal Snapshot rule — see backend §2
Capability Surface Actor Route/Trigger State Read State Written Linked API Section Create address Customer Customer POST /api/mobile/addressesactive count, default address row API §4 List addresses Customer Customer GET /api/mobile/addressesown rows — API Read one Customer Customer GET /:idany state — API Update Customer Customer PATCH /:idactive row fields API Archive Customer Customer DELETE /:idactive row archived_atAPI Restore Customer Customer POST /:id/restorearchived row archived_at clearedAPI Set default Customer Customer PUT /:id/defaultactive rows default flag API
A customer adds a delivery address. The first address becomes the default automatically; the response includes live serviceability computed from the shipping configuration.
Branch Condition Behavior Error/Result First address No active rows Becomes default automatically status.default: true20 active already Cap reached Reject 409 CUSTOMER_ADDRESS_LIMIT_REACHED Local phone 9812345678Normalized to +977… E.164 in response Bad phone Will not normalize Reject 400 CUSTOMER_ADDRESS_RECIPIENT_PHONE_INVALID Swapped coordinates Longitude in latitude's range Reject 400 CUSTOMER_ADDRESS_COORDINATES_OUT_OF_RANGE Retry after timeout Same Idempotency-Key No duplicate Same response (idempotency interceptor)
PUT /:id/default clears the previous default and sets the new one in the same transaction. Concurrent calls are serialized per customer so two set-defaults cannot race.
Branch Condition Behavior Error/Result Archived target Row archived 409 CUSTOMER_ADDRESS_ALREADY_ARCHIVEDConcurrent set-default Two calls Serialized per customer Second sees committed state No previous default Zero active New one becomes default Legal state
Archiving the default promotes the newest remaining active address. Restore never restores the old default flag — the flag is recomputed (default only if the customer has no active addresses).
None. There is no admin surface over the address table — it holds PII, and a cross-customer read path should not exist until something concretely needs one.
Entity From Event/Action To Guard Condition Side Effects customer_address— create active< 20 active; district resolves Auto-default if first; serviceability computed customer_addressactivearchive archivedMust be active (409 otherwise) If it was default: newest active promoted customer_addressarchivedrestore activeMust be archived (409 otherwise) Default only if no other active customer_addressactiveset-default activeMust be active Previous default cleared, same tx
Flow DB Writes Cache Effects Jobs Realtime Analytics Notifications Create address row — — — — — Update fields — — — — — Archive/restore archived_at (+ default promotion)— — — — — Set default default flags — — — — — Any read — shipping serviceability cache (read) — — — —
Scenario Trigger User/System Experience Recovery Source Address cap 20 active 409 Archive one first service Write on archived PATCH/DELETE/default 409 Offer restore service Restore on active Restore active row 409 Refresh service Someone else's id Cross-customer 404 (no existence oracle) Refresh list service WHERE Idempotent retry Client retry Same response — interceptor Serviceability change Admin edits district Next read reflects it — computed on read
Actor capability diagram — §3/§4.
Sequence diagram per major flow — §5.1/§5.2.
State machine diagram — §5.3/§7.
Data side-effect diagram — §9.
Error branch diagram — §10.
Feature Minor Behavior Actor Trigger User/System Result Backend Side Effect Source Create Auto-default first Customer POST default true — service Create Idempotency Customer Retry with key No duplicate interceptor Create Local phone Customer 9812345678E.164 stored NP region phone util Create Coordinates pair rule Customer One coordinate 400 both-or-neither dto List Default first ordering Customer GET Ordering — service List Status filter Customer ?status=archivedSubset — dto Read Archived readable Customer GET archived Restore discovery — service Archive Default promotion Customer Archive default Newest active default — service Restore Flag recompute Customer Restore Not default unless alone — service Set default Concurrent safety Customer Parallel calls Serialized advisory lock service All reads Serviceability live Customer Any read Current flag shipping read service
Rule Business Reason Actor Impact Enforced In API Impact Backend Impact Tests At most one default per customer One unambiguous delivery target UI shows one default Partial unique index PUT /default index + advisory lock spec Zero active = no default legal Archive-all is fine UI must not assume default Service — — spec Restore never restores flag Default is a choice, not history Restored address not default Service — recompute spec CASCADE from customers PII must not outlive owner Addresses vanish with customer Schema FK — Orders must snapshot schema Ward 1–40 Generous bound Validation error beyond CHECK 400 probe Coordinates in Nepal Swap detection 400 on swap CHECK/dto — probe Cap 20 active Bounded list 409 Service — archived don't count spec Serviceability never stored Live truth Reads reflect edits Service design — shipping read spec
Product Decision User Benefit Engineering Benefit Alternative Tradeoff Risk CASCADE + snapshot rule Privacy by deletion Orders stay truthful No-cascade rule Orders must copy fields Snapshot contract documented Municipality id null Free-text name No 753-row memory game Full reference No ids Documented Advisory lock per customer Safe concurrent defaults Serialized writes Optimistic retry Rare contention Accepted Serviceability computed Always current No sync job Stored flag Read cost Batched + cached Local phone accepted Easy entry NP default region Strict E.164 only Ambiguity Documented
Flow Edge Case Trigger Expected Behavior User/System Feedback Source Create 21st active Cap 409 LIMIT_REACHED Create Unknown district Bad uuid 404 DISTRICT_NOT_FOUND Create One coordinate Missing pair 400 COORDINATES_INCOMPLETE Create Out-of-range pair Swapped 400 COORDINATES_OUT_OF_RANGE Update Archived row PATCH 409 ALREADY_ARCHIVED Update Null clear explicit null Field cleared — dto Default Archived row PUT 409 ALREADY_ARCHIVED Restore Active row POST 409 NOT_ARCHIVED Read Others' address Any 404 NOT_FOUND (no oracle) Any write Duplicate idempotent Retry Same response —
Flow Reads Writes Cache Jobs/Events Response Fields Create count, district address row — — grouped response List/read address rows + shipping — shipping (read) — grouped array Update row fields — — grouped Archive/restore row archived_at (+ default) — — message / grouped Set default rows default flags — — grouped