# Schema Review & Corrections Log

> **Tanggal Review:** 15 April 2026  
> **File yang Direview:**
> - `apps/gfin/FINANCE_SCHEMA_PLANNING_GUIDE.md`
> - `apps/gwin/WAREHOUSE_SCHEMA_PLANNING_GUIDE.md`
> - `apps/glims/LIMS_OPERATIONAL_SCHEMA_GUIDE.md`

---

## A. Finance (`gfin`) — 6 Koreksi

### A1. Fix `accounting_periods.month` nullable ✅ APPLIED

**Masalah:** Ditulis `TINYINT NOT NULL` tapi keterangan bilang "null jika tahunan" — kontradiksi.

```diff
- month  TINYINT NOT NULL   -- 1–12 (null jika tahunan)
+ month  TINYINT NULL       -- 1–12 (null jika tahunan)
```

---

### A2. Tambah `NumberingSequence` module ✅ APPLIED

**Masalah:** Semua dokumen (invoice, payment, memo) butuh auto-numbering yang bisa dikonfigurasi per tahun/prefix. Sebelumnya hanya ditulis `UNIQUE NOT NULL` tanpa mekanisme generate.

**Ditambahkan:** Tabel `finance_cfg_numbering_sequences` dengan format `{PREFIX}/{YEAR}/{MONTH}/{SEQ:5}`, support year reset & month reset, atomic increment.

---

### A3. Tambah Journal Entry reversal ✅ APPLIED

**Masalah:** Tidak ada mekanisme void/reverse jurnal. Di Accurate, jurnal bisa di-void yang otomatis buat jurnal balikan.

**Ditambahkan di `finance_t_journal_entries`:**
- `is_reversal` — flag jurnal balikan
- `reversed_entry_id` — jurnal mana yang di-reverse
- `reversal_entry_id` — pointer ke jurnal reversal
- `source_type` / `source_id` — link ke transaksi asal auto-post
- `exchange_rate_diff` — selisih kurs multi-currency

---

### A4. Tambah Faktur Pajak Masukan ✅ APPLIED

**Masalah:** `TaxInvoice` hanya handle faktur pajak keluaran (SalesInvoice → customer). Untuk PurchaseInvoice juga perlu faktur pajak masukan (dari vendor) agar bisa dikreditkan.

**Ditambahkan:** Tabel `finance_t_tax_invoices_incoming` dengan field `vendor_npwp`, `dpp`, `ppn_amount`, `coretax_status`, `period_month/year`.

---

### A5. Lengkapi Posting Rules ✅ APPLIED

**Masalah:** 8 jenis transaksi belum ada di posting rule table.

**Ditambahkan:**

| Transaksi | Debet | Kredit |
|-----------|-------|--------|
| PettyCash expense | Beban | Kas Kecil |
| PettyCash replenishment | Kas Kecil | Kas/Bank |
| PurchaseCreditMemo posted | Hutang Usaha (AP) | Beban/Return |
| SalesDebitMemo posted | Piutang Usaha (AR) | Pendapatan/Koreksi |
| BankRecon bank charge | Beban Administrasi Bank | Kas/Bank |
| BankRecon bank interest | Kas/Bank | Pendapatan Bunga |
| Selisih kurs (gain) | Kas/Bank | Pendapatan Selisih Kurs |
| Selisih kurs (loss) | Beban Selisih Kurs | Kas/Bank |

---

### A6. Selisih Kurs pada Payment ✅ APPLIED

**Masalah:** Jika multi-currency, saat pembayaran (misal: invoice dalam USD, bayar di IDR) ada selisih kurs yang harus di-posting ke akun gain/loss selisih kurs.

**Solusi:** Sudah tercover lewat A3 (`exchange_rate_diff` di journal) + A5 (posting rule selisih kurs).

---

## B. Warehouse (`gwin`) — 5 Koreksi

### B1. Tambah `supplier_name` fallback di StockReceipt ✅ APPLIED

**Masalah:** `StockReceipt` punya `supplier_id` referensi ke `gfin.Vendor`, tapi saat development awal `gwin` mungkin belum terhubung ke `gfin`. Butuh fallback.

```diff
  source_type         ENUM(...)
  supplier_id         BIGINT UNSIGNED NULL
+ supplier_name       VARCHAR(200) NULL    -- snapshot nama (fallback jika belum link ke gfin)
  purchase_order_no   VARCHAR(100) NULL
```

---

### B2. Tambah `StockReturn` module ✅ APPLIED

**Masalah:** Ada `return_out` di `wh_h_stock_movements` tapi tidak ada tabel transaksi dedicated untuk retur ke supplier. Tanpa ini, flow retur tidak bisa di-track: alasan, kondisi barang, dan link ke receipt asal.

**Ditambahkan:**
- `wh_t_stock_returns` (header: nomor retur, supplier, receipt asal, status)
- `wh_t_stock_return_lines` (detail: item, batch, qty, kondisi)

---

### B3. Tambah `NumberingSequence` module ✅ APPLIED

**Masalah:** Sama seperti gfin — semua dokumen gudang butuh auto-numbering.

**Ditambahkan:** `wh_cfg_numbering_sequences` dengan format yang sama.

---

### B4. Tambah `assigned_by` di AssetAssignment ✅ APPLIED

**Masalah:** Ada `returned_by` tapi tidak ada siapa yang menyetujui peminjaman aset.

```diff
  condition_on_return ENUM(...) NULL
+ assigned_by         BIGINT UNSIGNED NULL    -- siapa yang menyetujui peminjaman
  notes_assign        TEXT NULL
```

---

### B5. Tambah `stock_receipt_line_id` di StockBatch ✅ APPLIED

**Masalah:** Batch/lot dibuat saat penerimaan barang, tapi tidak ada FK yang menghubungkan ke receipt line asal. Ini penting untuk traceability: batch ini datang dari penerimaan mana.

```diff
  purchase_invoice_id BIGINT UNSIGNED NULL
+ stock_receipt_line_id BIGINT UNSIGNED NULL FK → wh_t_stock_receipt_lines
  status              ENUM(...)
```

---

## C. LIMS Operational (`glims`) — 7 Koreksi

### C1. Fix Circular FK di AnalysisResult ↔ AnalysisCalculation ✅ APPLIED

**Masalah:** `lims_t_analysis_results.calculation_id` FK ke `lims_t_analysis_calculations`, dan `lims_t_analysis_calculations.analysis_result_id` FK balik ke `analysis_results` — circular reference.

**Solusi:** Hapus FK `calculation_id` di `analysis_results`, cukup pakai flag `has_calculation`. Relasi dari `analysis_calculations.analysis_result_id` sudah cukup (satu arah).

```diff
  has_calculation         BOOLEAN DEFAULT false
- calculation_id          BIGINT UNSIGNED NULL FK → lims_t_analysis_calculations
+ -- calculation_id di-set setelah calculation dibuat (tidak FK karena hindari circular)
```

---

### C2. Tambah `sample_registration_id` di LHU ✅ APPLIED

**Masalah:** LHU hanya link ke PO, tapi 1 PO bisa punya banyak sampel. Tanpa link ke sampel, tidak bisa generate LHU per sampel.

```diff
  purchase_order_id       BIGINT UNSIGNED FK
+ sample_registration_id  BIGINT UNSIGNED FK → lims_t_sample_registrations  -- 1 LHU = 1 sampel
  version                 TINYINT DEFAULT 1
```

---

### C3. Tambah `purchase_order_item_id` di WorkOrder ✅ APPLIED

**Masalah:** WorkOrder link ke PO tapi tidak ke item PO. Padahal satu PO bisa punya banyak jenis pengujian (item). Tanpa ini, sulit track WO mana untuk item PO mana.

```diff
  sample_registration_id  BIGINT UNSIGNED FK  -- 1 sampel = 1 WO per divisi
  purchase_order_id       BIGINT UNSIGNED FK
+ purchase_order_item_id  BIGINT UNSIGNED NULL FK → lims_t_purchase_order_items
  lab_division            ENUM(...)
```

---

### C4. Tambah `SampleDisposal` module ✅ APPLIED

**Masalah:** ISO 17025 §7.4.4 — setelah pengujian selesai, sampel harus didispose dengan catatan: metode pemusnahan, tanggal, saksi (untuk B3), sertifikat pemusnahan.

**Ditambahkan:** `lims_t_sample_disposals` dengan field `disposal_method`, `is_hazardous`, `witness_by`, `disposal_certificate`.

---

### C5. Tambah `SubcontractedTest` module ✅ APPLIED

**Masalah:** ISO 17025 §6.6 — jika parameter tertentu tidak bisa dikerjakan sendiri (di luar lingkup akreditasi), harus ada rujukan ke lab lain yang tercatat.

**Ditambahkan:** `lims_t_subcontracted_tests` dengan field `external_lab_name`, `external_lab_accreditation`, `result_value`, `certificate_path`.

---

### C6. Tambah `Complaint` + `NonConformance` module ✅ APPLIED

**Masalah:**
- ISO 17025 §7.9 — keluhan customer harus tercatat, ditangani, dan ada corrective action
- ISO 17025 §7.10 — pekerjaan yang tidak sesuai (out-of-spec QC, pelanggaran SOP) harus dikelola

**Ditambahkan:**
- `lims_t_complaints` — pencatatan keluhan, root cause, CAPA, notifikasi customer
- `lims_t_non_conformances` — deteksi ketidaksesuaian, link ke QC batch/result/complaint, CAPA, verifikasi

---

### C7. Tambah `ProficiencyTest` module ✅ APPLIED

**Masalah:** ISO 17025 §7.7.2 — uji profisiensi (PT) dan Inter-Laboratory Comparison (ILC) wajib dilakukan secara berkala. Ini validasi eksternal bahwa lab menghasilkan data yang akurat.

**Ditambahkan:** `lims_t_proficiency_tests` dengan field `provider`, `assigned_value`, `z_score`, `en_number`, `performance_status`.

---

## Catatan yang Belum Diterapkan (Future)

Berikut item yang disadari tapi belum diterapkan karena belum prioritas:

| App | Item | Keterangan |
|-----|------|-----------|
| gfin | Approval workflow multi-level | Butuh modul approval engine (threshold-based) — bisa dibuat cross-app di `packages/` |
| gfin | SalesCreditMemo | Kebalikan dari SalesDebitMemo — retur/koreksi piutang dari customer. Bisa ditambah nanti |
| gwin | Purchase Requisition internal | Tabel internal untuk request barang sebelum dikirim ke procurement. Bisa ditambah saat integrasi `gris` |
| gwin | Barcode/QR generation service | Perlu Domain Service `QRCodeGeneratorService` — implementasi saat Phase 2 |
| glims | Customer Satisfaction Survey | ISO 17025 §8.6 — bisa diintegrasikan ke `ecustomer` |
| glims | Management Review data | ISO 17025 §8.9 — data untuk tinjauan manajemen, bisa dari reporting |
| all | Audit Trail universal | Semua perubahan data di-log, bisa pakai Laravel Auditing package di `packages/laravel-core` |
