# Runbook Cutover Stok Telur Historis Kandang ke Gudang Farm

## Tujuan

Runbook ini dipakai untuk memindahkan **stok telur historis yang masih on-hand di gudang kandang** ke **gudang farm** secara aman, audit-able, dan reversible.

Cutover dilakukan dengan **transfer stok eksplisit**, bukan dengan mengubah `recording_eggs.product_warehouse_id` historis.

## Scope

Runbook ini hanya untuk:
- stok telur historis kandang-level yang masih punya saldo on-hand
- lokasi yang masuk kategori **clean cutover**
- lokasi yang sudah punya gudang farm

Runbook ini **tidak** dipakai untuk:
- lokasi overlap seperti `Cijangkar`
- koreksi histori `recording_eggs`
- migrasi stok non-telur

## Kebijakan yang Dikunci

- Sumber qty yang dipindah adalah **`product_warehouses.qty` saat cutover**
- Perintah dijalankan **per lokasi**
- Wajib mulai dari `dry-run`
- `--apply` hanya boleh dijalankan setelah review dry-run dan SQL checklist
- Lokasi overlap tidak ikut otomatis kecuali ada approval khusus dan `--include-overlap`
- Rollback hanya boleh dilakukan jika transfer hasil cutover belum dipakai transaksi turunan

## Lokasi Fase 1

Lokasi yang boleh dieksekusi pada fase pertama:
- `Jamali`
- `Cantilan`
- `Darawati`
- `Tamansari`

Lokasi yang harus ditahan:
- `Cijangkar`

## Prasyarat

Sebelum eksekusi, pastikan:
- backend sudah ter-deploy dengan command [main.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/cmd/migrate-legacy-egg-stock-to-farm/main.go)
- reusable transfer core sudah ikut ter-deploy:
  - [transfer.service.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/internal/modules/inventory/transfers/services/transfer.service.go)
  - [system_transfer.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/internal/modules/inventory/transfers/services/system_transfer.go)
- migrasi farm stock attribution sebelumnya sudah terpasang
- akses database target sudah tersedia
- environment target memakai SSL bila RDS mewajibkan, contoh:
  - `DB_SSLMODE=require`

## Catatan Output Command

Mode `--output table` adalah mode operasional yang direkomendasikan.

Mode `--output json` bisa dipakai, tetapi pada environment saat ini output JSON masih dapat didahului log bootstrap aplikasi atau SQL logger. Untuk review manual gunakan `table`. Untuk parsing otomatis, filter payload mulai dari `{`.

## Format Command

### Dry-run

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --location-name Jamali \
  --output table
```

### Apply

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --location-name Jamali \
  --cutover-date 2026-04-07 \
  --apply \
  --output table
```

### Rollback Preview

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --rollback-run-id <run_id> \
  --output table
```

### Rollback Apply

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --rollback-run-id <run_id> \
  --apply \
  --output table
```

## Arti `run_id`

Setiap dry-run/apply menghasilkan `run_id`, misalnya:

```text
egg-cutover-20260407T130344.220407000Z
```

`run_id` ini wajib disimpan karena dipakai untuk:
- audit hasil cutover
- query verifikasi
- rollback

## Prosedur Eksekusi Per Lokasi

### 1. Persiapan

Tentukan:
- `location_name`
- `cutover_date`
- operator yang bertanggung jawab

Contoh:
- lokasi: `Jamali`
- cutover date: `2026-04-07`

### 2. Jalankan Dry-run

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --location-name Jamali \
  --output table
```

Yang harus dicek pada hasil dry-run:
- status lokasi `CLEAN_CUTOVER`
- semua baris yang akan dipindah punya `status=eligible`
- gudang tujuan adalah gudang farm lokasi tersebut
- qty yang dipindah masuk akal dan sesuai saldo on-hand aktual
- tidak ada `missing_farm_warehouse`
- tidak ada `overlap_location`

### 3. Jalankan Checklist SQL Before

Gunakan file:
- [legacy_egg_cutover_verification_checklist.sql](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/docs/sql/legacy_egg_cutover_verification_checklist.sql)

Minimal pastikan:
- lokasi memang clean cutover
- stok telur kandang positif masih ada
- gudang farm ada
- belum ada transfer `EGG_FARM_CUTOVER` aktif untuk lokasi yang sama pada run yang akan dipakai

### 4. Simpan Evidence Sebelum Apply

Simpan:
- output dry-run
- hasil query before
- nama operator
- waktu eksekusi

Disarankan simpan dalam ticket / change record.

### 5. Jalankan Apply

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --location-name Jamali \
  --cutover-date 2026-04-07 \
  --apply \
  --output table
```

Setelah apply, simpan:
- `run_id`
- seluruh row dengan `transfer_id`
- movement number yang terbentuk

### 6. Jalankan Checklist SQL After

Masih menggunakan file:
- [legacy_egg_cutover_verification_checklist.sql](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/docs/sql/legacy_egg_cutover_verification_checklist.sql)

Minimal pastikan:
- transfer header/detail tercatat untuk `run_id`
- qty source berkurang sesuai transfer
- qty farm bertambah sesuai transfer
- total gabungan source+dest per produk per lokasi tetap sama
- stok eligible tidak lagi tersedia di gudang kandang
- stok telur sekarang tersedia di gudang farm

### 7. Smoke Test UI

Lakukan minimal:
- buka product stock farm untuk lokasi tersebut
- pastikan produk telur hasil migrasi muncul
- buat SO farm-level dan pastikan opsi produk telur tersedia
- pastikan recording telur baru setelah cutover tetap langsung masuk ke gudang farm

### 8. Tutup Eksekusi

Catat hasil akhir:
- sukses/gagal
- `run_id`
- lokasi
- tanggal cutover
- operator
- link ke evidence SQL/UI

## Kriteria Go / No-Go

### Boleh lanjut apply bila:

- dry-run menunjukkan hanya row yang memang expected
- lokasi `CLEAN_CUTOVER`
- gudang farm valid
- query before menunjukkan tidak ada anomaly blocking

### Wajib stop bila:

- lokasi terdeteksi `OVERLAP`
- ada qty aneh atau tidak sesuai data lapangan
- gudang farm tidak ada
- ada transfer lama serupa yang belum direkonsiliasi
- setelah apply terjadi selisih total source+dest

## Rollback Runbook

### Kapan rollback boleh dilakukan

Rollback boleh jika:
- transfer hasil cutover belum dipakai transaksi turunan
- verifikasi after menunjukkan issue yang membuat hasil cutover tidak dapat diterima

### Langkah rollback

1. Preview rollback:

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --rollback-run-id <run_id> \
  --output table
```

2. Jalankan query rollback readiness pada file audit/helper SQL.
3. Jika aman, apply rollback:

```bash
DB_SSLMODE=require go run ./cmd/migrate-legacy-egg-stock-to-farm \
  --rollback-run-id <run_id> \
  --apply \
  --output table
```

4. Jalankan ulang query verifikasi after rollback.

### Kapan rollback akan gagal by design

Rollback memang harus gagal jika:
- transfer hasil cutover sudah dipakai sales/recording/transaksi turunan
- sudah ada `stock_allocations` consume aktif terhadap `STOCK_TRANSFER_IN`

## Urutan Rollout yang Direkomendasikan

### Dev

1. Dry-run per lokasi
2. Review SQL before
3. Apply per lokasi
4. SQL after
5. Smoke UI
6. Simpan `run_id`

### Production

1. Freeze operasional lokasi target bila perlu
2. Dry-run
3. Review by dev + ops + finance/stock owner
4. Apply
5. SQL after
6. Smoke UI
7. Release lokasi berikutnya

## Referensi

- Command cutover: [main.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/cmd/migrate-legacy-egg-stock-to-farm/main.go)
- Test command: [main_test.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/cmd/migrate-legacy-egg-stock-to-farm/main_test.go)
- Core reusable transfer: [system_transfer.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/internal/modules/inventory/transfers/services/system_transfer.go)
- Transfer service refactor: [transfer.service.go](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/internal/modules/inventory/transfers/services/transfer.service.go)
- Checklist SQL: [legacy_egg_cutover_verification_checklist.sql](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/docs/sql/legacy_egg_cutover_verification_checklist.sql)
- Helper query audit: [legacy_egg_cutover_audit_queries.sql](/Users/macbookair/Documents/coding/projects/LTI-ERP/lti-api/docs/sql/legacy_egg_cutover_audit_queries.sql)
