mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
287 lines
8.2 KiB
Markdown
287 lines
8.2 KiB
Markdown
# 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)
|