Happy House - Ecommerce Docs
Developer ResourcesGeo

Geo Backend Documentation

Backend architecture, data model, services, seeding, and operational behavior for the Geo module.

Geo - Backend Documentation

1. Documentation Evidence

AreaFiles InspectedVerified Details
Module wiringapps/api/src/modules/geo/ (module files)Leaf composition, mobile registration
Controllerscustomer/geo-customer.controller.tsRoutes, guards, rate limits
Servicescustomer/geo-customer.service.ts, shared lookup serviceOrdering, filter, FK conversion
Schemapackages/db/src/schema/geo/{province,district,municipality,enums}.tsTables, codes, empty municipality reference
Seedpackages/db/src/seed/seed-geo.ts, seed.tsIdempotent seeding, wiring

2. Backend Scope and Boundaries

Owns

  • Province and district reference tables.
  • The two public read routes.
  • GeoLookupService — the single place a district uuid becomes a foreign key.

Does Not Own

  • The municipality reference — the table ships empty by design; municipality.name is free text on addresses.
  • Shipping rates, addresses, or any customer data — geo only names places; other modules attach prices and addresses to them.

Source of Truth

ConcernSource of TruthNotes
Reference dataPostgreSQL (province, district)Seeded, never edited via API
District→id resolutionGeoLookupServiceSingle code path

3. Module Composition

ModuleTypePathControllersProvidersExportsResponsibility
GeoCustomerModuleLeafcustomer/GeoCustomerControllerService + lookupServicePublic reads + lookup
(mobile composition)mobile.module.tsMounted under /api/mobile/geo

4. File and Directory Map

apps/api/src/modules/geo/
  customer/
    geo-customer.controller.ts
    geo-customer.service.ts
    geo-lookup.service.ts        # the single FK-conversion path
    dto/
packages/db/src/schema/geo/
  province.ts  district.ts  municipality.ts  enums.ts  index.ts
packages/db/src/seed/seed-geo.ts

Key files:

FilePurposeKey ExportsNotes
customer/geo-customer.service.tsList readsGeoCustomerServiceOfficial order for provinces, name order for districts
customer/geo-lookup.service.tsFK conversionGeoLookupServiceShared by shipping and address
seed/seed-geo.tsIdempotent seedseedGeo()db:seed:geo

5. Data Model

5.1 Schema Source

packages/db/src/schema/geo/
  province.ts  district.ts  municipality.ts  enums.ts

5.2 Tables

TablePurposeKey points
province7 provincescode (stable, e.g. bagmati), name (a label — renames happen), displayOrder (official order)
district77 districtscode unique (incl. the four merge-trap codes), province_id FK, name unique nationwide
municipalityEmpty by design753 names are not reproduced from memory; addresses store municipality_name as free text, municipality_id is always null

5.3 Relationship Diagram

6. Services and Responsibilities

6.1 GeoCustomerService

MethodCalled ByReadsWritesSide EffectsErrors
listProvinces()controllerprovince
listDistricts()controllerdistrictGEO_PROVINCE_NOT_FOUND

6.2 GeoLookupService

MethodCalled ByReadsWritesSide EffectsErrors
resolveDistrict()shipping, addressdistrictGEO_DISTRICT_NOT_FOUND

The lookup is the single place a district uuid becomes an internal integer id. A new module that needs a district resolves it here — never by querying district directly.

7. Runtime Flows

7.1 District resolution

8. Cache

No geo read is Redis-cached — 84 rows do not justify it. The cost of a miss is a single indexed lookup.

9. Jobs and Workers

None. Geo is synchronous reads plus a seed script; there is no queue involvement.

10. Security and Authorization

  • Public routes (@Public()) throttled at PUBLIC_READ (60/min per IP) — for load, not secrecy.
  • No admin surface, no permissions, no writes through the API.

11. Seeding and Operations

  • seed-geo.ts is idempotent: re-running never duplicates rows.
  • Runs with the normal db:seed; standalone via pnpm --filter @happy-shop/db db:seed:geo.
  • New environments must be seeded before address/shipping surfaces are exercised — an unseeded database returns empty lists, and GeoLookupService cannot resolve anything until districts exist.