﻿# 📘 Blueprint Master Data — GMP GLIMS (v2 — Gabungan Lama + Baru)

> Dokumen ini adalah cetak biru (blueprint) untuk seluruh **master data** pada aplikasi GMP GLIMS.
> Semua penamaan tabel mengikuti [ARCHITECTURE_GUIDE.md](../../ARCHITECTURE_GUIDE.md) §19.
>
> **v2:** Hasil penggabungan struktur lama (`persadal_lims.sql`) dengan desain baru.
> Lihat [COMPARISON_OLD_VS_NEW.md](./COMPARISON_OLD_VS_NEW.md) untuk detail perbandingan.

---

## Daftar Isi

1. [Ringkasan Tabel](#1-ringkasan-tabel)
2. [ERD (Entity Relationship Diagram)](#2-erd-entity-relationship-diagram)
3. [Flow Data Master](#3-flow-data-master)
4. [Detail Struktur Tabel](#4-detail-struktur-tabel)
   - 4.1  [glims_m_sample_type_categories](#41-glims_m_sample_type_categories)
   - 4.2  [glims_m_sample_types](#42-glims_m_sample_types)
   - 4.3  [glims_m_sample_type_fields](#43-glims_m_sample_type_fields)
   - 4.4  [glims_m_parameter_categories](#44-glims_m_parameter_categories)
   - 4.5  [glims_m_parameters](#45-glims_m_parameters)
   - 4.6  [glims_m_parameter_aliases](#46-glims_m_parameter_aliases)
   - 4.7  [glims_m_parameter_accreditations](#47-glims_m_parameter_accreditations)
   - 4.8  [glims_m_methods](#48-glims_m_methods)
   - 4.9  [glims_p_method_parameters](#49-glims_p_method_parameters)
   - 4.10 [glims_m_regulations](#410-glims_m_regulations)
   - 4.11 [glims_m_regulation_appendices](#411-glims_m_regulation_appendices)
   - 4.12 [glims_r_regulation_attachments](#412-glims_r_regulation_attachments)
   - 4.13 [glims_p_sample_type_parameters](#413-glims_p_sample_type_parameters)
   - 4.14 [glims_m_sample_type_groups](#414-glims_m_sample_type_groups)
   - 4.15 [glims_p_group_sample_types](#415-glims_p_group_sample_types)
   - 4.16 [glims_m_quality_standards](#416-glims_m_quality_standards)
   - 4.17 [glims_m_quality_standard_params](#417-glims_m_quality_standard_params)
5. [Enum / Status](#5-enum--status)
6. [Seed Data Contoh](#6-seed-data-contoh)
7. [Modul & DDD Structure](#7-modul--ddd-structure)
8. [Relasi ke Modul Sales Order](#8-relasi-ke-modul-sales-order)
9. [Checklist Implementasi](#9-checklist-implementasi)
10. [Menu Implementasi Saat Ini](#10-menu-implementasi-saat-ini)

---

## 1. Ringkasan Tabel

| # | Nama Tabel | Tipe | Asal | Deskripsi |
|---|---|---|---|---|
| 1 | `glims_m_sample_type_categories` | Master | Lama | Kategori jenis sampel (AIR, UDARA, TANAH, BIOTA, LIMBAH, PANGAN) |
| 2 | `glims_m_sample_types` | Master | Gabungan | Jenis sampel (Air Limbah, Air Minum, Tanah, dll.) |
| 3 | `glims_m_sample_type_fields` | Master | Lama | Custom/dynamic fields per jenis sampel |
| 4 | `glims_m_parameter_categories` | Master | Lama | Kategori parameter (FISIKA, KIMIA, MIKROBIOLOGI, dll.) |
| 5 | `glims_m_parameters` | Master | Gabungan | Parameter uji (pH, BOD, COD, TSS, dll.) |
| 6 | `glims_m_parameter_aliases` | Master | Lama | Nama alias parameter dari berbagai standar |
| 7 | `glims_m_parameter_accreditations` | Master | Lama | Status akreditasi per parameter per jenis sampel (KAN/ISO 17025) |
| 8 | `glims_m_methods` | Master | Gabungan | Metode pengujian (SNI, APHA, EPA, ISO) |
| 9 | `glims_p_method_parameters` | Pivot | Gabungan | Relasi metode ↔ parameter (many-to-many) |
| 10 | `glims_m_regulations` | Master | Gabungan | Regulasi/peraturan induk (PP, PerMen, SNI) |
| 11 | `glims_m_regulation_appendices` | Master | Baru | Lampiran/sub regulasi turunan dari regulasi |
| 12 | `glims_r_regulation_attachments` | Reference | Lama | File attachment regulasi (PDF, scan dokumen) |
| 13 | `glims_p_sample_type_parameters` | Pivot | Lama | Mapping operasional jenis sampel ↔ parameter (tabel terpenting!) |
| 14 | `glims_m_sample_type_groups` | Master | Baru | Grouping/paket pengujian |
| 15 | `glims_p_group_sample_types` | Pivot | Baru | Relasi group ↔ sample type + parameter + metode + status akreditasi + biaya |
| 16 | `glims_m_quality_standards` | Master | Baru | Header baku mutu (jenis sampel + regulasi + lampiran) |
| 17 | `glims_m_quality_standard_params` | Master | Baru | Detail baku mutu per parameter (nilai batas) |

---

## 2. ERD (Entity Relationship Diagram)

```
                    ┌────────────────────────┐
                    │  glims_m_sample_type_   │
                    │  categories            │
                    │  (Kategori Sampel)     │
                    │────────────────────────│
                    │  AIR, UDARA, TANAH,    │
                    │  BIOTA, LIMBAH, PANGAN │
                    └────────────┬───────────┘
                                 │ 1
                                 │
                                 │ N
┌──────────────────────────┐     │     ┌──────────────────────────┐
│  glims_m_regulations      │     │     │  glims_m_parameter_       │
│  (Regulasi Induk)        │     │     │  categories              │
│──────────────────────────│     │     │──────────────────────────│
│  id, uuid, code, name    │     │     │  FISIKA, KIMIA, MIKRO,   │
│  regulation_type, status │     │     │  BIOLOGI, ORGANOLEPTIK   │
│  issued_by, issued_date  │     │     └────────────┬─────────────┘
│  replaces_regulation_id  │     │                  │ 1
└──────┬───────────────────┘     │                  │
       │ 1                       │                  │ N
       │              ┌──────────▼──────────┐    ┌──▼──────────────────┐
       │              │  glims_m_sample_     │    │  glims_m_parameters  │
       ├──────────┐   │  types              │    │  (Parameter Uji)    │
       │          │   │  (Jenis Sampel)     │    │─────────────────────│
       │ N        │   │─────────────────────│    │  code, name, symbol │
┌──────▼────────┐ │   │  + category_id FK   │    │  + category_id FK   │
│ glims_m_       │ │   │  + storage_req      │    │  + default_unit     │
│ regulation_   │ │   │  + handling_time    │    │  + handling_time    │
│ appendices    │ │   │  + has_dynamic_flds │    └──┬──────────┬───────┘
│ (Lampiran)    │ │   └──┬──────────┬───────┘       │          │
└──────┬────────┘ │      │          │               │ N        │ N
       │          │      │ 1        │ N:M           │          │
       │          │      │   ┌──────▼──────────┐    │   ┌──────▼──────────┐
       │          │      │   │ glims_m_sample_  │    │   │ glims_m_         │
       │          │      │   │ type_fields     │    │   │ parameter_      │
       │   ┌──────▼──────▼───│ (Dynamic Flds)  │    │   │ aliases         │
       │   │glims_r_regulation│──────────────────│    │   └─────────────────┘
       │   │_attachments     │                  │    │
       │   │(File PDF/Scan)  │                  │    │ N
       │   └─────────────────┘                  │    │
       │                                        │    ├──────────────────────┐
       │    ┌───────────────────────────────┐    │    │  glims_m_parameter_  │
       │    │  glims_p_sample_type_          │    │    │  accreditations     │
       │    │  parameters                   │◄───┘    │  (KAN/ISO 17025)   │
       │    │  (Mapping Operasional)        │◄────────┘──────────────────────┘
       │    │───────────────────────────────│
       │    │  + unit, method_id, test_type │
       │    │  + turnaround_time, analyst   │
       │    │  + is_accredited, sampling    │
       │    └───────────────────────────────┘
       │
       │    ┌───────────────────────────────┐    ┌──────────────────────┐
       │    │  glims_m_methods               │    │  glims_m_sample_type_ │
       │    │  (Metode Pengujian)           │    │  groups (Paket)      │
       │    │───────────────────────────────│    └──────────┬───────────┘
       │    │  + standard_ref, version      │               │ 1
       │    │  + method_type, detection_lim │               │
       │    │  + equipment_req, reagent_req │               │ N
       │    └──────────┬───────────────────┘    ┌──────────▼───────────┐
       │               │ N:M                    │  glims_p_group_       │
       │               │                        │  sample_types        │
       │        ┌──────▼───────────┐            │  (Pivot Paket)       │
       │        │ glims_p_method_   │            └──────────────────────┘
       │        │ parameters       │
       │        │ (Pivot M↔P)      │
       │        └──────────────────┘
       │
       ▼
┌──────────────────────────────────────┐
│  glims_m_quality_standards            │
│  (Header Baku Mutu)                  │
│──────────────────────────────────────│
│  sample_type_id + regulation_id      │
│  + regulation_appendix_id            │
└──────────┬───────────────────────────┘
           │ 1
           │ N
┌──────────▼───────────────────────────┐
│  glims_m_quality_standard_params      │
│  (Detail Baku Mutu per Parameter)    │
│──────────────────────────────────────│
│  quality_standard_id                 │
│  parameter_id, method_id             │
│  method_id ───────────► method       │
│  min_value, max_value, unit          │
└──────────────────────────────────────┘

           ┌────────────────────────┐
           │  glims_m_parameters     │
           │  (Parameter Uji)       │
           │────────────────────────│
           │  id, uuid, code, name  │
           │  category, unit        │
           └────────────┬───────────┘
                        │
                        │ N:M
                        │
           ┌────────────▼───────────┐
           │  glims_p_method_        │
           │  parameter             │
           │  (Pivot)               │
           └────────────┬───────────┘
                        │
                        │ N:M
           ┌────────────▼───────────┐
           │  glims_m_methods        │
           │  (Metode Pengujian)    │
           │────────────────────────│
           │  id, uuid, code, name  │
           │  standard_ref          │
           └────────────────────────┘


┌───────────────────────────┐       ┌──────────────────────────┐
│  glims_m_sample_type_      │  1:N  │  glims_p_group_           │
│  groups                   │◄─────►│  sample_type             │
│  (Grouping)               │       │  (Pivot)                 │
│───────────────────────────│       │──────────────────────────│
│  id, uuid, code, name     │       │  group_id                │
│  description              │       │  sample_type_id          │
└───────────────────────────┘       │  parameter_id            │
                                    │  method_id               │
                                    └──────────────────────────┘
```

---

## 3. Flow Data Master

### 3.1 Flow Input Master Data (Urutan Setup Awal)

```
Step 1          Step 2              Step 3          Step 4
────────        ──────────          ────────        ────────
Regulasi   ──►  Lampiran/Sub   ──►  Parameter  ──►  Baku Mutu
(PP, PerMen)    Regulasi            & Metode        (Gabungan)


Step 1: Input master regulasi (PP No. 22/2021, PerMen LHK No. 5/2014, dll.)
Step 2: Input lampiran/sub regulasi per regulasi
Step 3: Input parameter uji (pH, BOD, COD) & metode (SNI, APHA)
Step 4: Buat mapping baku mutu = Jenis Sampel + Regulasi + Lampiran + Parameter + Nilai Batas
```

### 3.2 Flow Penggunaan di Proses Bisnis

```
┌─────────┐     ┌───────────┐     ┌──────────────┐     ┌───────────────┐
│ Customer │────►│ Buat SO   │────►│ Pilih Jenis  │────►│ Auto-Load     │
│ Datang   │     │           │     │ Sampel       │     │ Parameter +   │
└─────────┘     └───────────┘     └──────────────┘     │ Metode +      │
                                                        │ Baku Mutu     │
                                                        └───────┬───────┘
                                                                │
                                                                ▼
                                                        ┌───────────────┐
                                                        │ Pengujian di  │
                                                        │ Laboratorium  │
                                                        └───────┬───────┘
                                                                │
                                                                ▼
                                                        ┌───────────────┐
                                                        │ Bandingkan    │
                                                        │ Hasil vs      │
                                                        │ Baku Mutu     │
                                                        └───────┬───────┘
                                                                │
                                                                ▼
                                                        ┌───────────────┐
                                                        │ Cetak LHU     │
                                                        │ (Laporan Hasil│
                                                        │  Uji)         │
                                                        └───────────────┘
```

### 3.3 Flow Grouping (Paket Pengujian)

```
Group: "Paket Air Limbah Industri Tekstil"
│
├── Sample Type: Air Limbah Industri
│
├── Parameter + Metode:
│   ├── pH          → SNI 06-6989.11-2004
│   ├── BOD₅        → SNI 6989.72:2009
│   ├── COD         → SNI 6989.2:2019
│   ├── TSS         → SNI 06-6989.3-2004
│   ├── Warna       → SNI 6989.80:2011
│   └── Suhu        → SNI 06-6989.23-2005
│
├── Status Akreditasi + Biaya:
│   ├── pH          → Terakreditasi (KAN) + Rp 45.000
│   ├── BOD₅        → Terakreditasi (KAN) + Rp 120.000
│   ├── COD         → Terakreditasi (KAN) + Rp 110.000
│   ├── TSS         → Non-Akreditasi + Rp 65.000
│   └── Suhu        → Terakreditasi (KAN) + Rp 30.000
│
└── Saat SO dibuat → pilih group → otomatis isi parameter, metode, status akreditasi, dan biaya
```

### 3.4 Layout Konfigurasi Baku Mutu (4 Kolom Berurutan)

Gunakan layout berurutan kiri ke kanan (cascading):

1. Kolom 1: **Jenis Sampel**
2. Kolom 2: **Peraturan/Regulasi** (filter berdasarkan Jenis Sampel jika diperlukan)
3. Kolom 3: **Lampiran** (filter berdasarkan Peraturan)
4. Kolom 4: **Baku Mutu** (record `glims_m_quality_standards` hasil kombinasi 3 kolom sebelumnya)

Kombinasi kunci tetap: `sample_type_id + regulation_id + regulation_appendix_id`.

---

## 4. Detail Struktur Tabel

> Definisi lengkap ada di migration:
> `database/migrations/2026_04_13_000001_create_glims_master_data_tables.php`
>
> Kolom standard (`uuid`, `is_active`, `deactivated_at/by`, `created_by`, `updated_by`, `deleted_by`, `timestamps`, `softDeletes`)
> sudah mengikuti [ARCHITECTURE_GUIDE.md §19.5](../../ARCHITECTURE_GUIDE.md) dan **tidak diulang** di setiap tabel di bawah.

---

### 4.1 `glims_m_sample_type_categories`

> Kategori jenis sampel. Dipakai sebagai FK di `glims_m_sample_types.category_id`.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | AIR, UDARA, TANAH, BIOTA, LIMBAH, PANGAN |
| `name` | `varchar(100)` | Nama kategori |
| `description` | `text` nullable | |
| `icon` | `varchar(50)` nullable | Emoji/icon class (💧, 🌬️, 🏔️) |
| `display_order` | `integer` default 0 | Urutan tampil |

**Seed data:** AIR, UDARA, TANAH, BIOTA, LIMBAH, PANGAN (6 records dari DB lama)

---

### 4.2 `glims_m_sample_types`

> Jenis sampel yang diujikan di laboratorium.
> **Gabungan:** kolom operasional dari lama + `uuid`/`deactivated` dari konvensi baru.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | ST-AIR-001, ST-TNH-001 |
| `name` | `varchar(255)` | Nama jenis sampel |
| `description` | `text` nullable | |
| `category_id` | FK → `glims_m_sample_type_categories` nullable | Kategori (AIR, UDARA, dll.) |
| `storage_requirement` | `text` nullable | Syarat penyimpanan (suhu 4°C, dll.) |
| `handling_instruction` | `text` nullable | Instruksi penanganan |
| `handling_time` | `integer` nullable | Waktu handling dalam menit |
| `lhu_format_id` | `unsignedBigInteger` nullable | FK ke format LHU (dibuat nanti) |
| `has_dynamic_fields` | `boolean` default false | Punya custom fields tambahan |

**Seed data:** Air Minum, Air Limbah, Air Laut, Tanah, Sedimen, Udara Ambien, Udara Emisi, Makanan, Minuman, Biota Air (10 records)

---

### 4.3 `glims_m_sample_type_fields`

> Custom/dynamic fields per jenis sampel. Hanya aktif jika `has_dynamic_fields = true` pada sample type.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `sample_type_id` | FK → `glims_m_sample_types` | cascade delete |
| `field_name` | `varchar(100)` | Label tampil (Nama Pelanggan) |
| `field_key` | `varchar(50)` | Key untuk JSON (nama_pelanggan) |
| `field_type` | `varchar(20)` default TEXT | TEXT, NUMBER, DATE, SELECT, TEXTAREA |
| `field_options` | `json` nullable | Opsi untuk tipe SELECT |
| `placeholder` | `varchar(255)` nullable | |
| `default_value` | `varchar(255)` nullable | |
| `is_required` | `boolean` default false | |
| `display_order` | `integer` default 0 | |

---

### 4.4 `glims_m_parameter_categories`

> Kategori parameter uji. Dipakai sebagai FK di `glims_m_parameters.category_id`.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | FISIKA, KIMIA, MIKROBIOLOGI, BIOLOGI, ORGANOLEPTIK, RADIOAKTIF |
| `name` | `varchar(100)` | Nama kategori |
| `description` | `text` nullable | |
| `icon` | `varchar(50)` nullable | |
| `display_order` | `integer` default 0 | |

**Seed data:** FISIKA, KIMIA, MIKROBIOLOGI, BIOLOGI, ORGANOLEPTIK, RADIOAKTIF (6 records)

---

### 4.5 `glims_m_parameters`

> Parameter uji — besaran yang diukur dalam pengujian laboratorium.
> **Gabungan:** `category_id` FK dari lama + `symbol`, `default_unit` dari baru.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | P-001, PH, BOD, COD |
| `name` | `varchar(255)` | Nama parameter |
| `symbol` | `varchar(50)` nullable | Simbol teknis: pH, BOD₅, COD, Fe²⁺ |
| `category_id` | FK → `glims_m_parameter_categories` nullable | FISIKA, KIMIA, dll. |
| `default_unit` | `varchar(50)` nullable | Satuan default: mg/L, ppm, °C |
| `handling_time` | `integer` nullable | Waktu penanganan dalam menit |
| `description` | `text` nullable | |

**Contoh data:**

| code | name | symbol | category | default_unit |
|---|---|---|---|---|
| PH | Derajat Keasaman | pH | Kimia | - |
| BOD | Biochemical Oxygen Demand | BOD₅ | Kimia | mg/L |
| COD | Chemical Oxygen Demand | COD | Kimia | mg/L |
| TSS | Total Suspended Solid | TSS | Fisika | mg/L |
| SUHU | Suhu | T | Fisika | °C |
| ECOLI | Escherichia coli | E. coli | Mikrobiologi | MPN/100mL |

---

### 4.6 `glims_m_parameter_aliases`

> Nama alias parameter dari berbagai standar acuan (SNI, APHA, Internal SOP).

| Kolom | Tipe | Keterangan |
|---|---|---|
| `parameter_id` | FK → `glims_m_parameters` | cascade delete |
| `alias_name` | `varchar(255)` | Nama alternatif |
| `source` | `varchar(100)` nullable | Asal standar: SNI, APHA, Internal SOP |

**Contoh:** Parameter "Alkalinitas" punya alias "Alkalinitas Total" (SNI), "Total Alkalinity" (APHA)

---

### 4.7 `glims_m_parameter_accreditations`

> Status akreditasi **per parameter per jenis sampel**. Kritis untuk laboratorium terakreditasi KAN/ISO 17025.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `parameter_id` | FK → `glims_m_parameters` | cascade delete |
| `sample_type_id` | FK → `glims_m_sample_types` | cascade delete |
| `accreditation_status` | `varchar(20)` default NOT_ACCREDITED | ACCREDITED, NOT_ACCREDITED, IN_PROCESS |
| `accreditation_scope` | `varchar(255)` nullable | Lingkup akreditasi |
| `certificate_no` | `varchar(100)` nullable | Nomor sertifikat KAN |
| `valid_from` | `date` nullable | Mulai berlaku |
| `valid_until` | `date` nullable | Masa berlaku habis |
| `notes` | `text` nullable | |

**Unique:** `(parameter_id, sample_type_id)`

---

### 4.8 `glims_m_methods`

> Metode pengujian — standar/prosedur yang dipakai untuk mengukur parameter.
> **Gabungan:** kolom detail dari lama + `method_type` dari baru.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | SNI-6989-71 |
| `name` | `varchar(255)` | Nama metode |
| `standard_ref` | `varchar(255)` nullable | Nomor standar acuan: SNI 6989.72:2009 |
| `version` | `varchar(50)` nullable | Versi metode: 2019, 2021 |
| `category` | `varchar(50)` nullable | KIMIA, FISIKA, MIKROBIOLOGI, BIOLOGI |
| `method_type` | `varchar(50)` nullable | SNI, APHA, EPA, ISO, In-House |
| `description` | `text` nullable | |
| `procedure_summary` | `text` nullable | Ringkasan prosedur pengujian |
| `detection_limit` | `decimal(20,6)` nullable | Batas deteksi alat |
| `measurement_unit` | `varchar(50)` nullable | Satuan ukur hasil |
| `is_accredited` | `boolean` default false | Terakreditasi KAN |
| `accreditation_scope` | `varchar(255)` nullable | Lingkup akreditasi |
| `equipment_required` | `json` nullable | Daftar alat yang diperlukan |
| `reagent_required` | `json` nullable | Daftar reagen yang diperlukan |
| `estimated_duration_hours` | `decimal(5,2)` nullable | Estimasi durasi pengujian (jam) |

**Contoh data:**

| code | name | standard_ref | method_type |
|---|---|---|---|
| SNI-PH | pH meter — Elektrometri | SNI 06-6989.11-2004 | SNI |
| SNI-BOD | BOD₅ — Winkler | SNI 6989.72:2009 | SNI |
| SNI-COD | COD — Refluks Tertutup | SNI 6989.2:2019 | SNI |
| APHA-COL | Total Coliform — MPN | APHA 9221B | APHA |
| EPA-METAL | Logam Berat — AAS | EPA 3111 | EPA |

---

### 4.9 `glims_p_method_parameters`

> Pivot relasi many-to-many antara metode ↔ parameter.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `method_id` | FK → `glims_m_methods` | cascade delete |
| `parameter_id` | FK → `glims_m_parameters` | cascade delete |
| `is_primary` | `boolean` default false | Metode utama/default |
| `is_active` | `boolean` default true | Bisa nonaktifkan mapping |

**Unique:** `(method_id, parameter_id)`

---

### 4.10 `glims_m_regulations`

> Regulasi/peraturan induk yang menjadi dasar baku mutu.
> **Gabungan:** kolom detail dari baru + `status` dari lama.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | PP22-2021 |
| `name` | `varchar(255)` | Nama lengkap regulasi |
| `short_name` | `varchar(100)` nullable | Nama pendek untuk UI |
| `regulation_type` | `varchar(50)` nullable | PP, PerMen, PerDa, SNI, Keputusan |
| `regulation_number` | `varchar(100)` nullable | Nomor peraturan resmi |
| `issued_by` | `varchar(255)` nullable | Instansi penerbit |
| `issued_date` | `date` nullable | Tanggal diterbitkan |
| `effective_date` | `date` nullable | Tanggal berlaku efektif |
| `expired_date` | `date` nullable | Tanggal kadaluarsa |
| `replaces_regulation_id` | FK self nullable | Regulasi yang digantikan |
| `status` | `varchar(50)` nullable | BERLAKU, DICABUT, DRAFT |
| `description` | `text` nullable | |

---

### 4.11 `glims_m_regulation_appendices`

> Lampiran/sub regulasi turunan dari regulasi induk. **Tabel baru.**

| Kolom | Tipe | Keterangan |
|---|---|---|
| `regulation_id` | FK → `glims_m_regulations` | cascade delete |
| `code` | `varchar(50)` unique | PP22-2021-L1 |
| `name` | `varchar(255)` | Nama lampiran |
| `appendix_number` | `varchar(50)` nullable | Lampiran I, Lampiran II.A |
| `appendix_type` | `varchar(50)` nullable | lampiran, bagian, bab, pasal |
| `description` | `text` nullable | |
| `sort_order` | `integer` default 0 | Urutan tampil |

---

### 4.12 `glims_r_regulation_attachments`

> File attachment regulasi (PDF, scan dokumen). Tipe: **Reference** (tanpa soft delete).
> Berbeda dari `regulation_appendices` yang merupakan **struktur logis**.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `regulation_id` | FK → `glims_m_regulations` | cascade delete |
| `sample_type_id` | FK → `glims_m_sample_types` nullable | |
| `class_name` | `varchar(100)` nullable | Dokumen Utama, Lampiran I |
| `name` | `varchar(1024)` | Nama dokumen |
| `category` | `varchar(255)` nullable | |
| `file_name` | `varchar(255)` | Nama file |
| `file_path` | `varchar(255)` | Path file di storage |
| `file_type` | `varchar(100)` nullable | MIME type |
| `file_size` | `unsignedBigInteger` nullable | Ukuran file (bytes) |
| `description` | `text` nullable | |

---

### 4.13 `glims_p_sample_type_parameters`

> **Tabel TERPENTING** — mapping operasional jenis sampel ↔ parameter.
> Menentukan: parameter apa, unit apa, metode apa, siapa yang uji, berapa lama.

| Kolom | Tipe | Keterangan |
|---|---|---|
| `sample_type_id` | FK → `glims_m_sample_types` | cascade delete |
| `parameter_id` | FK → `glims_m_parameters` | cascade delete |
| `unit` | `varchar(50)` nullable | Satuan spesifik per kombinasi |
| `method_reference` | `varchar(255)` nullable | Referensi metode |
| `turnaround_time` | `integer` nullable | Waktu pengerjaan (hari) |
| `method_id` | FK → `glims_m_methods` nullable | Metode default |
| `subcontract_lab_id` | `unsignedBigInteger` nullable | FK ke lab subkontrak |
| `analyst_user_id` | `unsignedBigInteger` nullable | FK ke analis default |
| `fmmt_template_id` | `unsignedBigInteger` nullable | FK ke template form kerja |
| `test_type` | `varchar(20)` default INTERNAL | INTERNAL, SUBCONTRACT |
| `sampling_type` | `varchar(10)` default LAB | FIELD, LAB, BOTH |
| `handling_time` | `integer` nullable | Waktu handling (menit) |
| `is_accredited` | `boolean` default false | Terakreditasi |
| `accreditation_scope` | `varchar(255)` nullable | |
| `accreditation_valid_until` | `date` nullable | Masa berlaku akreditasi |
| `is_required` | `boolean` default false | Wajib diuji |
| `display_order` | `integer` default 0 | Urutan tampil |

**Unique:** `(sample_type_id, parameter_id)`

---

### 4.14 `glims_m_sample_type_groups`

> Grouping/paket pengujian. Pilih group → otomatis isi parameter, metode, status akreditasi, dan biaya. **Tabel baru.**

| Kolom | Tipe | Keterangan |
|---|---|---|
| `code` | `varchar(50)` unique | GRP-ALTX, GRP-AMINU |
| `name` | `varchar(255)` | Nama group/paket |
| `description` | `text` nullable | |
| `cost_note` | `varchar(255)` nullable | Keterangan biaya paket (mis. "Biaya belum termasuk sampling & transport") |

**Contoh data:**

| code | name |
|---|---|
| GRP-ALTX | Paket Air Limbah Industri Tekstil |
| GRP-ALDOM | Paket Air Limbah Domestik |
| GRP-AMINU | Paket Air Minum Lengkap |

---

### 4.15 `glims_p_group_sample_types`

> Pivot: group ↔ sample type + parameter + metode + status akreditasi + biaya. Setiap baris = 1 kombinasi. **Tabel baru.**

| Kolom | Tipe | Keterangan |
|---|---|---|
| `group_id` | FK → `glims_m_sample_type_groups` | cascade delete |
| `sample_type_id` | FK → `glims_m_sample_types` | cascade delete |
| `parameter_id` | FK → `glims_m_parameters` | cascade delete |
| `method_id` | FK → `glims_m_methods` nullable | |
| `accreditation_status` | `varchar(30)` default `non_accredited` | `accredited`, `non_accredited`, `by_method_scope` |
| `cost` | `decimal(15,2)` nullable | Biaya per parameter pada paket |
| `cost_currency` | `char(3)` default `IDR` | Mata uang biaya |
| `cost_note` | `varchar(255)` nullable | Catatan biaya item (opsional) |
| `sort_order` | `integer` default 0 | Urutan tampil |

**Unique:** `(group_id, sample_type_id, parameter_id, method_id)`

---

### 4.16 `glims_m_quality_standards`

> **Header baku mutu** — gabungan 3 kolom kunci: **Jenis Sampel + Regulasi + Lampiran**.
> Ini adalah "template" standar mutu yang dipakai untuk menilai apakah hasil uji sesuai regulasi.

| Kolom | Tipe | Constraint | Keterangan |
|---|---|---|---|
| `id` | `bigIncrements` | PK | |
| `uuid` | `uuid` | unique | |
| `code` | `varchar(50)` | unique | Kode baku mutu (BM-001) |
| `name` | `varchar(255)` | | Nama baku mutu |
| `sample_type_id` | `unsignedBigInteger` | FK → `glims_m_sample_types` | Jenis sampel |
| `regulation_id` | `unsignedBigInteger` | FK → `glims_m_regulations` | Regulasi induk |
| `regulation_appendix_id` | `unsignedBigInteger` | FK → `glims_m_regulation_appendices`, nullable | Lampiran/sub regulasi |
| `effective_date` | `date` | nullable | Tanggal berlaku |
| `description` | `text` | nullable | |
| `is_active` | `boolean` | default `true` | |
| `deactivated_at` | `timestamp` | nullable | |
| `deactivated_by` | `unsignedBigInteger` | nullable | |
| `created_by` | `unsignedBigInteger` | nullable | |
| `updated_by` | `unsignedBigInteger` | nullable | |
| `deleted_by` | `unsignedBigInteger` | nullable | |
| `created_at` | `timestamp` | | |
| `updated_at` | `timestamp` | | |
| `deleted_at` | `timestamp` | nullable | |

**Indexes:** `sample_type_id`, `regulation_id`, `regulation_appendix_id`, `is_active`
**Unique:** `(sample_type_id, regulation_id, regulation_appendix_id)` — satu kombinasi = satu baku mutu

**Contoh data:**

| code | name | sample_type | regulation | appendix |
|---|---|---|---|---|
| `BM-ALDOM` | Baku Mutu Air Limbah Domestik | Air Limbah | PP 22/2021 | Lampiran I |
| `BM-ALTX` | Baku Mutu Air Limbah Industri Tekstil | Air Limbah | PP 22/2021 | Lampiran II |
| `BM-ALMINU` | Baku Mutu Air Minum | Air Minum | PerMenKes 492/2010 | - |
| `BM-APK1` | Baku Mutu Air Permukaan Kelas I | Air Permukaan | PP 82/2001 | Lampiran I |
| `BM-APK2` | Baku Mutu Air Permukaan Kelas II | Air Permukaan | PP 82/2001 | Lampiran II |

---

### 4.17 `glims_m_quality_standard_params`

> **Detail baku mutu per parameter** — nilai batas (min/max) untuk setiap parameter di suatu baku mutu.
> Ini yang dipakai untuk membandingkan hasil uji vs standar di LHU (Laporan Hasil Uji).

| Kolom | Tipe | Constraint | Keterangan |
|---|---|---|---|
| `id` | `bigIncrements` | PK | |
| `uuid` | `uuid` | unique | |
| `quality_standard_id` | `unsignedBigInteger` | FK → `glims_m_quality_standards` | Header baku mutu |
| `parameter_id` | `unsignedBigInteger` | FK → `glims_m_parameters` | Parameter uji |
| `method_id` | `unsignedBigInteger` | FK → `glims_m_methods`, nullable | Metode acuan |
| `unit` | `varchar(50)` | nullable | Satuan (override dari parameter default) |
| `min_value` | `decimal(15,4)` | nullable | Nilai minimum (null = tidak ada batas bawah) |
| `max_value` | `decimal(15,4)` | nullable | Nilai maksimum (null = tidak ada batas atas) |
| `threshold_operator` | `varchar(10)` | nullable | Operator: `<`, `<=`, `>`, `>=`, `=`, `range` |
| `threshold_display` | `varchar(100)` | nullable | Teks tampilan: "6 - 9", "< 100", "Tidak berbau" |
| `sort_order` | `integer` | default `0` | Urutan tampil di LHU |
| `description` | `text` | nullable | Catatan khusus |
| `created_by` | `unsignedBigInteger` | nullable | |
| `updated_by` | `unsignedBigInteger` | nullable | |
| `deleted_by` | `unsignedBigInteger` | nullable | |
| `created_at` | `timestamp` | | |
| `updated_at` | `timestamp` | | |
| `deleted_at` | `timestamp` | nullable | |

**Indexes:** `quality_standard_id`, `parameter_id`
**Unique:** `(quality_standard_id, parameter_id)` — satu parameter per baku mutu

**Contoh data (Baku Mutu Air Limbah Domestik — PP 22/2021 Lampiran I):**

| parameter | unit | min | max | operator | display |
|---|---|---|---|---|---|
| pH | - | 6.0000 | 9.0000 | range | 6 - 9 |
| BOD₅ | mg/L | null | 30.0000 | <= | ≤ 30 |
| COD | mg/L | null | 100.0000 | <= | ≤ 100 |
| TSS | mg/L | null | 30.0000 | <= | ≤ 30 |
| Minyak & Lemak | mg/L | null | 5.0000 | <= | ≤ 5 |
| Amonia (NH₃-N) | mg/L | null | 10.0000 | <= | ≤ 10 |
| Total Coliform | MPN/100mL | null | 3000.0000 | <= | ≤ 3000 |
| Suhu | °C | null | 38.0000 | <= | ≤ 38 |

---

## 5. Enum / Status

> **Catatan v2:** `ParameterCategory` dan `SampleTypeCategory` sekarang pakai **tabel FK**
> (`glims_m_parameter_categories`, `glims_m_sample_type_categories`)
> bukan enum PHP. Ini lebih fleksibel — user bisa tambah kategori baru tanpa ubah code.

### 5.1 `RegulationType`

```php
enum RegulationType: string
{
    case PP = 'pp';              // Peraturan Pemerintah
    case PerMen = 'permen';      // Peraturan Menteri
    case PerDa = 'perda';        // Peraturan Daerah
    case SNI = 'sni';            // Standar Nasional Indonesia
    case Keputusan = 'keputusan'; // Surat Keputusan
}
```

### 5.2 `MethodType`

```php
enum MethodType: string
{
    case SNI = 'sni';
    case APHA = 'apha';
    case EPA = 'epa';
    case ISO = 'iso';
    case InHouse = 'in_house';
}
```

### 5.3 `ThresholdOperator`

```php
enum ThresholdOperator: string
{
    case LessThan = '<';
    case LessEqual = '<=';
    case GreaterThan = '>';
    case GreaterEqual = '>=';
    case Equal = '=';
    case Range = 'range';
}
```

### 5.4 `AccreditationStatus`

```php
enum AccreditationStatus: string
{
    case Accredited = 'ACCREDITED';
    case NotAccredited = 'NOT_ACCREDITED';
    case InProcess = 'IN_PROCESS';
}
```

### 5.5 `TestType`

```php
enum TestType: string
{
    case Internal = 'INTERNAL';
    case Subcontract = 'SUBCONTRACT';
}
```

### 5.6 `SamplingType`

```php
enum SamplingType: string
{
    case Field = 'FIELD';
    case Lab = 'LAB';
    case Both = 'BOTH';
}
```

### 5.7 `FieldType`

```php
enum FieldType: string
{
    case Text = 'TEXT';
    case Number = 'NUMBER';
    case Date = 'DATE';
    case Select = 'SELECT';
    case Textarea = 'TEXTAREA';
}
```

---

## 6. Seed Data Contoh

### 6.1 Skenario: Pengujian Air Limbah Industri Tekstil

```
Regulasi:
  PP No. 22 Tahun 2021 tentang Perlindungan dan Pengelolaan Lingkungan Hidup

Lampiran:
  Lampiran II — Baku Mutu Air Limbah bagi Usaha dan/atau Kegiatan Industri Tekstil

Jenis Sampel:
  Air Limbah

Baku Mutu (BM-ALTX) — Parameter & Nilai Batas:
  ┌─────────────────────┬────────┬────────┬────────┬──────────┐
  │ Parameter           │ Satuan │ Min    │ Max    │ Display  │
  ├─────────────────────┼────────┼────────┼────────┼──────────┤
  │ pH                  │ -      │ 6.0    │ 9.0    │ 6 - 9    │
  │ BOD₅                │ mg/L   │ -      │ 60     │ ≤ 60     │
  │ COD                 │ mg/L   │ -      │ 150    │ ≤ 150    │
  │ TSS                 │ mg/L   │ -      │ 50     │ ≤ 50     │
  │ Fenol               │ mg/L   │ -      │ 0.5    │ ≤ 0.5   │
  │ Kromium Total (Cr)  │ mg/L   │ -      │ 1.0    │ ≤ 1.0   │
  │ Minyak & Lemak      │ mg/L   │ -      │ 3.0    │ ≤ 3.0   │
  │ Warna               │ Pt.Co  │ -      │ 200    │ ≤ 200    │
  │ Sulfida (S²⁻)       │ mg/L   │ -      │ 0.3    │ ≤ 0.3   │
  │ Amonia (NH₃-N)      │ mg/L   │ -      │ 8.0    │ ≤ 8.0   │
  │ Suhu                │ °C     │ -      │ 38     │ ≤ 38     │
  └─────────────────────┴────────┴────────┴────────┴──────────┘
```

### 6.2 Skenario: Pengujian Air Minum

```
Regulasi:
  PerMenKes No. 492/MENKES/PER/IV/2010 tentang Persyaratan Kualitas Air Minum

Jenis Sampel:
  Air Minum

Baku Mutu (BM-AMINU) — Parameter & Nilai Batas:
  ┌─────────────────────┬─────────────┬────────┬────────┬──────────┐
  │ Parameter           │ Satuan      │ Min    │ Max    │ Display  │
  ├─────────────────────┼─────────────┼────────┼────────┼──────────┤
  │ E. coli             │ MPN/100mL   │ -      │ 0      │ 0        │
  │ Total Coliform      │ MPN/100mL   │ -      │ 0      │ 0        │
  │ Warna               │ TCU         │ -      │ 15     │ ≤ 15     │
  │ TDS                 │ mg/L        │ -      │ 500    │ ≤ 500    │
  │ Kekeruhan           │ NTU         │ -      │ 5      │ ≤ 5      │
  │ Rasa                │ -           │ -      │ -      │ Tdk Berasa│
  │ Bau                 │ -           │ -      │ -      │ Tdk Berbau│
  │ Suhu                │ °C          │ -      │ ±3     │ Suhu Udara│
  │ pH                  │ -           │ 6.5    │ 8.5    │ 6.5-8.5  │
  │ Besi (Fe)           │ mg/L        │ -      │ 0.3    │ ≤ 0.3    │
  │ Mangan (Mn)         │ mg/L        │ -      │ 0.4    │ ≤ 0.4   │
  │ Fluorida (F⁻)       │ mg/L        │ -      │ 1.5    │ ≤ 1.5   │
  │ Nitrit (NO₂⁻)       │ mg/L        │ -      │ 3      │ ≤ 3     │
  │ Nitrat (NO₃⁻)       │ mg/L        │ -      │ 50     │ ≤ 50    │
  └─────────────────────┴─────────────┴────────┴────────┴──────────┘
```

---

## 7. Modul & DDD Structure

```
app/Modules/MasterData/
│
├── Domain/
│   ├── Models/
│   │   ├── SampleTypeCategory.php      → glims_m_sample_type_categories
│   │   ├── SampleType.php              → glims_m_sample_types
│   │   ├── SampleTypeField.php         → glims_m_sample_type_fields
│   │   ├── ParameterCategory.php       → glims_m_parameter_categories
│   │   ├── Parameter.php               → glims_m_parameters
│   │   ├── ParameterAlias.php          → glims_m_parameter_aliases
│   │   ├── ParameterAccreditation.php  → glims_m_parameter_accreditations
│   │   ├── Method.php                  → glims_m_methods
│   │   ├── Regulation.php              → glims_m_regulations
│   │   ├── RegulationAppendix.php      → glims_m_regulation_appendices
│   │   ├── RegulationAttachment.php    → glims_r_regulation_attachments
│   │   ├── SampleTypeGroup.php         → glims_m_sample_type_groups
│   │   ├── QualityStandard.php         → glims_m_quality_standards
│   │   └── QualityStandardParam.php    → glims_m_quality_standard_params
│   │
│   ├── Enums/
│   │   ├── RegulationType.php
│   │   ├── MethodType.php
│   │   ├── ThresholdOperator.php
│   │   ├── AccreditationStatus.php
│   │   ├── TestType.php
│   │   ├── SamplingType.php
│   │   └── FieldType.php
│   │
│   └── Contracts/
│       ├── SampleTypeRepositoryInterface.php
│       ├── RegulationRepositoryInterface.php
│       ├── ParameterRepositoryInterface.php
│       ├── MethodRepositoryInterface.php
│       └── QualityStandardRepositoryInterface.php
│
├── Application/
│   ├── Actions/
│   │   ├── CreateSampleTypeAction.php
│   │   ├── CreateRegulationAction.php
│   │   ├── CreateParameterAction.php
│   │   ├── CreateMethodAction.php
│   │   ├── CreateQualityStandardAction.php
│   │   └── SyncGroupParametersAction.php
│   │
│   ├── Queries/
│   │   ├── GetSampleTypesQuery.php
│   │   ├── GetRegulationsWithAppendicesQuery.php
│   │   ├── GetParametersQuery.php
│   │   ├── GetMethodsQuery.php
│   │   ├── GetQualityStandardsQuery.php
│   │   └── GetGroupWithParametersQuery.php
│   │
│   └── DTOs/
│       ├── CreateSampleTypeDTO.php
│       ├── CreateRegulationDTO.php
│       ├── CreateQualityStandardDTO.php
│       └── SyncGroupDTO.php
│
└── Infrastructure/
    ├── Controllers/
    │   ├── SampleTypeController.php
    │   ├── RegulationController.php
    │   ├── ParameterController.php
    │   ├── MethodController.php
    │   ├── QualityStandardController.php
    │   └── SampleTypeGroupController.php
    │
    ├── Requests/
    │   ├── StoreSampleTypeRequest.php
    │   ├── StoreRegulationRequest.php
    │   ├── StoreParameterRequest.php
    │   ├── StoreMethodRequest.php
    │   └── StoreQualityStandardRequest.php
    │
    ├── Repositories/
    │   ├── EloquentSampleTypeRepository.php
    │   ├── EloquentRegulationRepository.php
    │   ├── EloquentParameterRepository.php
    │   ├── EloquentMethodRepository.php
    │   └── EloquentQualityStandardRepository.php
    │
    ├── Routes/
    │   └── web.php
    │
    └── Providers/
        └── MasterDataServiceProvider.php
```

---

## 8. Relasi ke Modul Sales Order

Tabel master data ini digunakan oleh modul SO yang sudah dibuat sebelumnya:

```
glims_t_sales_orders
  └── glims_t_sales_order_items
        │
        ├── test_type_id ──────► Bisa FK ke glims_m_sample_type_groups
        │                        (group = "paket pengujian" = jenis pengujian)
        │
        └── glims_t_sales_order_item_params
              ├── parameter_id ──► glims_m_parameters
              ├── test_method ────► bisa FK ke glims_m_methods
              ├── unit ───────────► dari glims_m_parameters.default_unit
              └── specification ──► dari glims_m_quality_standard_params
```

### Flow saat buat SO:

```
1. User pilih Customer
2. User pilih Jenis Sampel (glims_m_sample_types)
3. User pilih Group/Paket (glims_m_sample_type_groups) → OPSIONAL
   → Jika pilih group: auto-fill parameter, metode, status akreditasi, dan biaya dari glims_p_group_sample_types
   → Jika manual: user pilih parameter satu-satu
4. System load baku mutu (glims_m_quality_standards + params) berdasarkan:
   → sample_type_id + regulation_id + regulation_appendix_id
5. Data masuk ke glims_t_sales_order_items & glims_t_sales_order_item_params
6. Setelah pengujian selesai → hasil dibandingkan dengan baku mutu → cetak LHU
```

---

## 9. Checklist Implementasi

### Phase 1: Database & Migration
- [x] Buat migration file untuk **17 tabel** (`2026_04_13_000001_create_glims_master_data_tables.php`)
- [ ] Jalankan `php artisan migrate`
- [ ] Buat seeder untuk data lama (dari `persadal_lims.sql`)
- [ ] Buat seeder untuk data baru (regulasi appendices, quality standards)

### Phase 2: Domain Layer (Models + Enums)
- [ ] Buat semua 14 Model Eloquent dengan `$table` eksplisit
- [ ] Buat 7 Enum classes (RegulationType, MethodType, ThresholdOperator, AccreditationStatus, TestType, SamplingType, FieldType)
- [ ] Definisikan relasi Eloquent (`hasMany`, `belongsTo`, `belongsToMany`)
- [ ] Tambahkan `$casts` untuk enum fields

### Phase 3: Application Layer (Actions + Queries)
- [ ] CRUD Actions untuk setiap master
- [ ] Query classes dengan filter & pagination
- [ ] DTO classes

### Phase 4: Infrastructure Layer (Controllers + Routes)
- [x] Controllers dengan Inertia response untuk modul yang sudah dibuat: Sample Type, Regulation, Parameter, Method, Sample Type Group
- [x] Form Requests untuk modul yang sudah dibuat
- [x] Route registration untuk modul yang sudah dibuat (`/master-data/sample-types|regulations|parameters|methods|sample-type-groups`)
- [x] Service Provider (`MasterDataServiceProvider`)
- [x] Controller + route untuk modul lanjutan (baku mutu, appendices, attachments, alias, accreditation, test templates)

### Phase 5: Frontend (React + Inertia)
- [x] Halaman list untuk modul yang sudah dibuat: Sample Type, Regulation, Parameter, Method, Sample Type Group
- [x] Form create/edit untuk Sample Type
- [x] Form create/edit inline/modal untuk Regulation, Parameter, Method
- [x] Halaman list untuk modul lanjutan: Quality Standard, Regulation Appendix, Regulation Attachment, Parameter Alias, Parameter Accreditation, Test Template
- [ ] Cascading dropdown: Regulasi → Lampiran
- [ ] Multi-select: Parameter pada Quality Standard
- [ ] Group builder UI (mapping group -> sample type + parameter + method + accreditation status + cost)

### Phase 6: Integrasi dengan SO
- [ ] Update `test_type_id` di SO items untuk FK ke group
- [ ] Auto-fill parameter dari group saat buat SO
- [ ] Load baku mutu otomatis berdasarkan jenis sampel + regulasi

---

## 10. Menu Implementasi Saat Ini

Status menu telah disinkronkan dengan modul yang benar-benar sudah tersedia di backend + frontend.

### 10.1 Master Data (aktif)

- Regulasi → `/master-data/regulations`
- Lampiran Regulasi → `/master-data/regulation-appendices`
- Attachment Regulasi → `/master-data/regulation-attachments`
- Jenis Sampel → `/master-data/sample-types`
- Grouping / Paket → `/master-data/sample-type-groups`
- Parameter Uji → `/master-data/parameters`
- Parameter Alias → `/master-data/parameter-aliases`
- Parameter Accreditation → `/master-data/parameter-accreditations`
- Metode Pengujian → `/master-data/methods`
- Template Uji → `/master-data/test-templates`
- Konfigurasi Uji (Baku Mutu) → `/master-data/quality-standards`

### 10.2 Transaksi (aktif)

- Sales Order → `/sales-orders`

### 10.3 Ditahan sementara (belum jadi link menu)

- Tidak ada (per April 2026, item master data yang sudah punya route + halaman sudah ditampilkan di sidebar).

Catatan: jika ada modul baru yang belum memiliki route frontend stabil, tempatkan sementara pada bagian 10.3 sebelum diaktifkan ke sidebar.
