diff --git a/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.down.sql b/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.down.sql new file mode 100644 index 00000000..25a6c864 --- /dev/null +++ b/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.down.sql @@ -0,0 +1,29 @@ +BEGIN; + +-- ============================================================ +-- Rollback stock_log drift fix: DELETE corrective rows yang di-insert UP. +-- IDs ditarik dari audit table `migration_audit.jamali_w10_stocklog_corrections`. +-- Setelah delete, `last_stock_log.stock` kembali ke nilai pre-fix (drift muncul lagi). +-- ============================================================ + +-- Guard: audit table harus ada +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = 'migration_audit' + AND table_name = 'jamali_w10_stocklog_corrections' + ) THEN + RAISE EXCEPTION + 'Audit table migration_audit.jamali_w10_stocklog_corrections tidak ditemukan. UP belum dijalankan atau audit sudah di-drop.'; + END IF; +END $$; + +-- DELETE corrective stock_logs yang di-insert oleh UP +DELETE FROM stock_logs +WHERE id IN (SELECT stock_log_id FROM migration_audit.jamali_w10_stocklog_corrections); + +-- Cleanup audit table +DROP TABLE migration_audit.jamali_w10_stocklog_corrections; + +COMMIT; diff --git a/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.up.sql b/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.up.sql new file mode 100644 index 00000000..0fa92e02 --- /dev/null +++ b/internal/database/migrations/20260528123243_fix_stock_log_drift_jamali_merge.up.sql @@ -0,0 +1,111 @@ +BEGIN; + +-- ============================================================ +-- Fix stock_log drift pasca-merge warehouse Jamali (NON_AKTIF) -> Gudang Farm Jamali. +-- Follow-up migration setelah 20260528121631_normalize_warehouse_jamali_10_to_25. +-- +-- Setelah merge, `stock_logs.stock` (running ledger) drift dari +-- `product_warehouses.qty` karena: pre-existing drift di W10 + W25 sources, +-- plus FIFO reflow yang trigger pasca-merge (Recording-Edit) recompute +-- pw.qty tapi stock_logs tidak ikut update. +-- +-- Migration ini insert 1 ADJUSTMENT stock_log corrective per PW yang drift +-- supaya `last_stock_log.stock = pw.qty`. Logic ekivalen dengan +-- `cmd/fix-stock-log-drift`. +-- +-- Karakteristik dynamic: +-- - Tidak hardcode PW IDs atau drift values +-- - Iterate via merge target + W10-only kept PWs (data-driven dari snapshot) +-- - Per PW: hitung drift runtime, skip kalau negligible (< 0.001) atau no logs +-- - Track stock_log IDs yang di-insert untuk DOWN reverse +-- ============================================================ + +-- Guard: previous migration (normalisasi) audit harus ada +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = 'migration_audit' + AND table_name = 'jamali_w10_qty_merge' + ) THEN + RAISE EXCEPTION + 'Migration 20260528121631 (normalize_warehouse_jamali) belum dijalankan atau audit-nya sudah di-drop. Apply UP-nya dulu sebelum migration ini.'; + END IF; +END $$; + +-- Audit table untuk track stock_log IDs yang di-insert (untuk DOWN reverse) +DROP TABLE IF EXISTS migration_audit.jamali_w10_stocklog_corrections; +CREATE TABLE migration_audit.jamali_w10_stocklog_corrections ( + stock_log_id BIGINT NOT NULL PRIMARY KEY, + product_warehouse_id BIGINT NOT NULL, + drift NUMERIC(15,3) NOT NULL, + inserted_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Insert corrective ADJUSTMENT stock_log untuk tiap PW yang drift +DO $$ +DECLARE + rec RECORD; + v_last_log_stock NUMERIC(15,3); + v_drift NUMERIC(15,3); + v_new_log_id BIGINT; + v_inserts INT := 0; +BEGIN + FOR rec IN ( + SELECT pw.id AS pw_id, pw.qty AS qty + FROM product_warehouses pw + WHERE pw.id IN ( + -- Merge target W25 PWs (9 rows) + SELECT target_pw_id FROM migration_audit.jamali_w10_qty_merge + UNION + -- W10-only PWs yang di-update warehouse_id 10->25 (4 rows) + SELECT id FROM migration_audit.jamali_w10_pw_w10only_snapshot + ) + ) LOOP + -- Ambil stock akhir di stock_logs ledger + SELECT stock INTO v_last_log_stock + FROM stock_logs + WHERE product_warehouse_id = rec.pw_id + ORDER BY id DESC + LIMIT 1; + + -- PW tanpa stock_logs entry (mis. 1188/1189/1190 ayam) -> skip + IF v_last_log_stock IS NULL THEN + CONTINUE; + END IF; + + v_drift := rec.qty - v_last_log_stock; + + -- Drift negligible -> skip + IF ABS(v_drift) < 0.001 THEN + CONTINUE; + END IF; + + -- Insert corrective ADJUSTMENT stock_log + INSERT INTO stock_logs ( + product_warehouse_id, loggable_type, loggable_id, + notes, increase, decrease, stock, created_by, created_at + ) VALUES ( + rec.pw_id, + 'ADJUSTMENT', + 0, + 'Koreksi stock_log drift pasca-merge warehouse Jamali (migration 20260528123243)', + CASE WHEN v_drift > 0 THEN v_drift ELSE 0 END, + CASE WHEN v_drift < 0 THEN -v_drift ELSE 0 END, + rec.qty, + 1, + NOW() + ) RETURNING id INTO v_new_log_id; + + -- Track ke audit table untuk DOWN + INSERT INTO migration_audit.jamali_w10_stocklog_corrections ( + stock_log_id, product_warehouse_id, drift + ) VALUES (v_new_log_id, rec.pw_id, v_drift); + + v_inserts := v_inserts + 1; + END LOOP; + + RAISE NOTICE 'Inserted % corrective stock_logs to align ledger with pw.qty', v_inserts; +END $$; + +COMMIT;