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_key | Level | Contoh peran |
|---|---|---|
| warehouse | 1 | Root (gudang utama) |
| storage_area | 2 | Area penyimpanan dalam gudang |
| shelf | 3 | Rak dalam area |
| bin | 4 | Baki/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:
| Field | Keterangan | Required | Contoh |
|---|---|---|---|
org_unit_id | UUID organization unit (branch) | ✅ | UUID |
location_type_key | Key dari core_location_types | ✅ | "warehouse", "storage_area" |
name | Nama lengkap lokasi | ✅ | "Main Warehouse" |
code | Kode unik dalam org unit | ✅ | "WH-001" |
category_key | Kategori lokasi | ✅ | "storage" |
is_active | Status aktif | ✅ | true |
parent_location_id | UUID parent (null = root) | - | null atau UUID |
op_unit_id | UUID operational unit | - | UUID atau null |
short_name | Nama singkat | - | "WH Main" |
address | Alamat fisik | - | "Jl. Example No. 123" |
latitude / longitude | Koordinat | - | -6.2088, 106.8456 |
attributes | JSON 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
| Operasi | Ringkasan |
|---|---|
| Create | Buat lokasi baru; path_ltree auto-generated |
| List | Daftar dengan filter (org_unit, op_unit, type, category, parent, status), search, pagination, sorting, tree mode (table_tree=1) |
| Get by ID | Detail lengkap lokasi |
| Tree | Alias list dengan format tree hierarkis |
| Search | Quick search berdasarkan keyword (name, code, short_name) |
| Get Children | Direct children dari lokasi |
| Get Parents | Chain parent dari root sampai direct parent |
| Get Usage | Statistik: inventory count, child count, active child count |
| Update | Partial update (termasuk parent); re-validate hierarchy & circular reference |
| Toggle Status | Activate/deactivate (tidak boleh deactivate jika punya active children) |
| Move | Pindah ke parent baru; rekalkulasi path untuk node + descendants |
| Soft Delete | Set is_active = false (tidak boleh jika punya active children atau inventory) |
| Hard Delete | Hapus 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 Code | Trigger |
|---|---|
location.not-found | Lokasi tidak ditemukan |
location.parent-not-found | Parent tidak ditemukan |
location.type-not-found | Location type tidak ada |
location.type-hierarchy-invalid | Level tipe tidak valid |
location.circular-reference-self | Parent = diri sendiri |
location.circular-reference-descendant | Parent adalah descendant |
location.has-active-children | Masih ada child aktif |
location.has-children | Masih ada children (hard del) |
location.code-duplicate | Code 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 / Area | Tujuan integrasi |
|---|---|
| Organization Units | Lokasi terhubung ke branch (org_unit_id) |
| Operational Units | Lokasi dapat terhubung ke op unit (opsional) |
| Inventory | Stock per lokasi, usage stats |
| Shipping / Logistics | Pick/pack by location, routing |
| Reporting | Agregasi per lokasi, hierarki |
| Authorization | Scope & 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.