Skip to main content

Locations Module

Peruntukan: Dokumen ini adalah Product Requirements Document (PRD) untuk Locations Module — modul yang mengelola lokasi fisik (warehouse, storage area, shelf, bin, dll.) dengan struktur hierarkis, terkait organization unit dan optional operational unit. Untuk detail teknis dan API, lihat README.md dan TEKNIS.md.


Overview

Locations Module mengelola lokasi fisik dalam sistem dengan struktur hierarkis (parent-child). Setiap lokasi harus terhubung ke organization unit (branch) dan dapat dihubungkan ke operational unit (opsional). Lokasi mendukung koordinat geografis, alamat, dan atribut kustom untuk berbagai use case: pergudangan, distribusi, ritel, maupun inventori.

Modul ini menjadi single source of truth untuk struktur lokasi fisik dan menjadi basis integrasi untuk inventori, pengiriman, reporting, dan kontrol akses berbasis lokasi.

Hierarki diimplementasikan menggunakan PostgreSQL LTree extension, memungkinkan query struktur tree yang efisien untuk operasi read-heavy.


Goals

  • Menyediakan single source of truth untuk struktur lokasi fisik
  • Mendukung hierarki multi-level dengan aturan bisnis yang ketat (type-driven hierarchy)
  • Keterkaitan dengan organization unit (wajib) dan operational unit (opsional)
  • Memastikan performa tinggi untuk operasi baca (listing, tree, traversal)
  • Menjadi basis integrasi untuk inventori, pengiriman, dan reporting
  • Mendukung geografis (latitude, longitude) dan atribut kustom (JSON)
  • Spesifikasi eksplisit untuk AI-driven code generation

Core Concepts

1. Hierarchy with PostgreSQL LTree

Setiap lokasi memiliki kolom path_ltree yang menyimpan jalur lengkap dari root ke node tersebut.

Contoh:

0001.0002.0003

Makna:

  • Setiap segmen merepresentasikan satu level hierarki
  • Urutan segmen menunjukkan posisi node dalam struktur
  • Root location: 0001; child: 0001.0002, dst.

Keuntungan:

  • Query tree tanpa recursive CTE (menggunakan LTree operators)
  • Fast descendant/ancestor queries dengan GIST index
  • Performa tinggi untuk sistem read-heavy

2. Type-Driven Hierarchy

Setiap lokasi memiliki location_type_key yang mengacu ke master core_location_types. Setiap tipe memiliki level yang menentukan urutan hierarki.

Contoh tipe (dari dokumentasi):

type_keyLevelContoh peran
warehouse1Root (gudang utama)
storage_area2Area penyimpanan dalam gudang
shelf3Rak dalam area
bin4Baki/bin dalam rak (leaf)

Aturan:

  • Child type level MUST be higher than parent type level
  • Tidak boleh circular reference
  • Lokasi tidak bisa menjadi parent dirinya sendiri

Contoh valid:

  • ✅ warehouse → storage_area → shelf → bin
  • ✅ parent_id: null → warehouse (root)

Contoh invalid:

  • ❌ shelf → warehouse (level turun)
  • ❌ Location A → parent: Location A (self)
  • ❌ A → B → C, kemudian C parent ke A (circular)

3. Organization Unit & Operational Unit

  • Organization Unit (org_unit_id)Wajib. Lokasi selalu terhubung ke satu organization unit (biasanya branch). Code lokasi unik dalam scope organization unit yang sama.
  • Operational Unit (op_unit_id)Opsional. Dapat menghubungkan lokasi ke unit operasional (entity, region, area, site, dll.) untuk keperluan reporting atau kontrol akses.

4. Geographic & Attributes

  • Address — Alamat fisik (text)
  • Latitude / Longitude — Koordinat (-90 s.d. 90, -180 s.d. 180)
  • Attributes — JSONB untuk atribut kustom (mis. capacity, temperature_controlled, dll.)

Contoh Data Location

Struktur hierarki contoh (Warehouse → Storage Area → Shelf → Bin):

Main Warehouse (warehouse)
└── Storage Area A (storage_area)
└── Shelf A1 (shelf)
└── Bin A1-1 (bin)

Format isian per record:

FieldKeteranganRequiredContoh
org_unit_idUUID organization unit (branch)UUID
location_type_keyKey dari core_location_types"warehouse", "storage_area"
nameNama lengkap lokasi"Main Warehouse"
codeKode unik dalam org unit"WH-001"
category_keyKategori lokasi"storage"
is_activeStatus aktiftrue
parent_location_idUUID parent (null = root)-null atau UUID
op_unit_idUUID operational unit-UUID atau null
short_nameNama singkat-"WH Main"
addressAlamat fisik-"Jl. Example No. 123"
latitude / longitudeKoordinat--6.2088, 106.8456
attributesJSON object atribut kustom-{"capacity": 1000}

Contoh payload Create:

{
"org_unit_id": "550e8400-e29b-41d4-a716-446655440000",
"location_type_key": "warehouse",
"parent_location_id": null,
"name": "Main Warehouse",
"short_name": "WH Main",
"code": "WH-001",
"category_key": "storage",
"is_active": true,
"address": "Jl. Example No. 123",
"latitude": -6.2088,
"longitude": 106.8456,
"attributes": { "capacity": 1000, "temperature_controlled": true }
}

Supported Operations

OperasiRingkasan
CreateBuat lokasi baru; path_ltree auto-generated
ListDaftar dengan filter (org_unit, op_unit, type, category, parent, status), search, pagination, sorting, tree mode (table_tree=1)
Get by IDDetail lengkap lokasi
TreeAlias list dengan format tree hierarkis
SearchQuick search berdasarkan keyword (name, code, short_name)
Get ChildrenDirect children dari lokasi
Get ParentsChain parent dari root sampai direct parent
Get UsageStatistik: inventory count, child count, active child count
UpdatePartial update (termasuk parent); re-validate hierarchy & circular reference
Toggle StatusActivate/deactivate (tidak boleh deactivate jika punya active children)
MovePindah ke parent baru; rekalkulasi path untuk node + descendants
Soft DeleteSet is_active = false (tidak boleh jika punya active children atau inventory)
Hard DeleteHapus permanen (harus sudah soft-deleted, tidak punya children)

Data Integrity Rules

  • Organization unit harus ada dan valid
  • Location type harus ada di core_location_types
  • Parent (jika ada) harus exist dan active
  • Type hierarchy: child level > parent level
  • Code unik dalam organization unit yang sama
  • Circular reference: parent bukan self, bukan descendant
  • Deactivate: tidak boleh jika masih ada active children
  • Soft delete: tidak boleh jika ada active children atau inventory
  • Hard delete: hanya setelah soft delete, dan tidak ada children

Error Codes (Ringkasan)

Reason CodeTrigger
location.not-foundLokasi tidak ditemukan
location.parent-not-foundParent tidak ditemukan
location.type-not-foundLocation type tidak ada
location.type-hierarchy-invalidLevel tipe tidak valid
location.circular-reference-selfParent = diri sendiri
location.circular-reference-descendantParent adalah descendant
location.has-active-childrenMasih ada child aktif
location.has-childrenMasih ada children (hard del)
location.code-duplicateCode duplikat dalam org unit

Detail error response format dan validation rules ada di README.md (Error Responses) dan validation-rule.json (jika digunakan).


Integrasi

Modul / AreaTujuan integrasi
Organization UnitsLokasi terhubung ke branch (org_unit_id)
Operational UnitsLokasi dapat terhubung ke op unit (opsional)
InventoryStock per lokasi, usage stats
Shipping / LogisticsPick/pack by location, routing
ReportingAgregasi per lokasi, hierarki
AuthorizationScope & access control berbasis lokasi

Technical Characteristics

  • Identifier: UUID
  • Hierarchy: PostgreSQL LTree extension
  • Pattern: CQRS (Commands & Queries terpisah)
  • API base: /api/v1/locations
  • Auth: Bearer token + X-LANYA-TID (tenant)
  • Row-Level Security (RLS) untuk tenant isolation

Typical Use Cases

  • Struktur gudang: Warehouse → Storage Area → Shelf → Bin
  • Manajemen lokasi ritel (outlet, rak, zona)
  • Distribusi dan pengiriman berdasarkan lokasi
  • Inventori dan stock count per lokasi
  • Reporting dan agregasi per hierarki lokasi
  • Kontrol akses berbasis lokasi fisik

Referensi

  • API & Endpoints: README.md
  • Technical (arsitektur, schema, validators, LTree): TEKNIS.md
  • MCP / Machine-readable spec: locations-api.mcp.json (jika ada)

Summary

Locations Module adalah modul fondasional untuk mengelola lokasi fisik dengan hierarki (warehouse → storage area → shelf → bin), terhubung ke organization unit dan optional operational unit. Dengan PostgreSQL LTree, type-driven hierarchy, code uniqueness per org unit, dan aturan integritas yang ketat, modul ini cocok untuk sistem enterprise yang butuh performa tinggi, integritas data, dan integrasi dengan inventori, pengiriman, serta reporting.