# Batasan Komponen & Dependency Graph Dokumen ini mendefinisikan batas-batas arsitektur (*architectural boundaries*) dan aturan dependensi dalam monorepo KeluargaMart. --- ## 1. Aturan Batasan Arsitektur (*Boundary Rules*) Untuk mencegah spaghetti code, kopling yang tidak diinginkan (*tight coupling*), dan siklus dependensi (*circular dependencies*), monorepo ini menerapkan aturan ketat: ### Rule 1: Isolasi Antar-Aplikasi (No Cross-App Imports) - **Dilarang keras**: Aplikasi di dalam `apps/*` mengimpor file secara langsung dari aplikasi lain di `apps/*`. - Contoh terlarang: `import { helper } from '../../pos/src/...'` di dalam `apps/erp`. - **Solusi**: Jika ada kode atau logika yang dibutuhkan oleh lebih dari satu aplikasi, kode tersebut harus diekstrak ke dalam shared package di `packages/*`. ### Rule 2: Arah Dependensi Satu Arah (Unidirectional Dependency) - `apps/*` **dapat** mengimpor dari `packages/*` melalui package name `@keluargamart/*`. - `packages/*` **dilarang keras** mengimpor dari `apps/*`. Shared packages harus bersifat murni (*pure/agnostic*) terhadap konteks aplikasi spesifik. ### Rule 3: Tingkat Dependensi Antar-Package (Package-to-Package) - Package dasar (`@keluargamart/contracts`, `@keluargamart/permissions`, `@keluargamart/utils`) adalah *leaf packages* (tidak bergantung pada package lain). - Package tingkat lanjut (`@keluargamart/api-client`) dapat bergantung pada *leaf packages* (misalnya `@keluargamart/contracts` atau `@keluargamart/utils`), tetapi tidak boleh sebaliknya. - Siklus dependensi antar-package dilarang keras. --- ## 2. Dependency Matrix ```mermaid classDiagram class Apps_ERP["apps/erp"] class Apps_POS["apps/pos"] class Apps_B2B["apps/b2b"] class Pkg_Contracts["packages/contracts"] class Pkg_Perms["packages/permissions"] class Pkg_Utils["packages/utils"] class Pkg_ApiClient["packages/api-client"] Apps_ERP --> Pkg_Contracts : uses Apps_ERP --> Pkg_Perms : uses Apps_ERP --> Pkg_Utils : uses Apps_ERP --> Pkg_ApiClient : uses Apps_POS --> Pkg_Contracts : uses Apps_POS --> Pkg_Perms : uses Apps_POS --> Pkg_Utils : uses Apps_POS --> Pkg_ApiClient : uses Apps_B2B --> Pkg_Contracts : uses Apps_B2B --> Pkg_Perms : uses Apps_B2B --> Pkg_Utils : uses Apps_B2B --> Pkg_ApiClient : uses Pkg_ApiClient --> Pkg_Contracts : optional types ``` --- ## 3. Konvensi Import Semua consumer di dalam `apps/` harus menggunakan resolusi workspace pnpm standar (`workspace:*`): ### 1. Kontrak Rute API (`@keluargamart/contracts`) ```javascript // Import rute terpusat import { BACKEND_ROUTES, BACKEND_ROUTE_SET, isValidRoute } from '@keluargamart/contracts/routes'; // Validasi saat runtime atau compile-time if (!isValidRoute('/api/v1/pos/orders')) { throw new Error('Invalid endpoint'); } ``` ### 2. Otorisasi RBAC (`@keluargamart/permissions`) ```javascript // Import permission catalog & helper import { PERMISSIONS, can, isSuperAdmin } from '@keluargamart/permissions'; // Pengecekan otorisasi pengguna const allowed = can(user.permissions, PERMISSIONS.POS_ORDERS_CREATE, user.role); if (!allowed) { notify('Akses ditolak'); } ``` ### 3. Utilitas Bisnis (`@keluargamart/utils`) ```javascript // Import formatters & helpers import { formatRupiah, formatNumber, formatDate, newIdempotencyKey } from '@keluargamart/utils'; const displayPrice = formatRupiah(150000); // "Rp 150.000" const idempotencyToken = newIdempotencyKey(); // "km-1729134567890-a1b2c3d4" ``` ### 4. API Client (`@keluargamart/api-client`) ```javascript import { createApiClient, ApiError } from '@keluargamart/api-client'; const client = createApiClient({ baseURL: import.meta.env.VITE_API_URL, getAccessToken: () => authStore.token, onUnauthorized: () => authStore.logout() }); ``` --- ## 4. Validasi Batasan pada CI/CD Batasan ini diverifikasi secara otomatis pada tahap build & test di GitHub Actions: - `pnpm turbo run test`: Menjalankan suite pengujian di seluruh workspace. - `pnpm turbo run build`: Memastikan bundling tidak mengalami kebocoran pathing atau circular references. - `pnpm drift:check`: Memastikan tidak ada consumer yang tertinggal dalam sinkronisasi kontrak rute dan permission.