/**
 * Kontrak hasil pemrosesan satu baris: nilai data, bukan exception.
 * Varian terkunci lewat sealed sehingga compiler memaksa setiap switch
 * menangani semua kemungkinan — termasuk varian GagalTetap yang ditambahkan
 * ketika kebijakan percobaan ulang menyerah.
 */
public sealed interface HasilBaris permits HasilBaris.Sah, HasilBaris.TidakSah,
        HasilBaris.GagalTetap {

    /** Nomor baris sumber — dipakai pelaporan galat dan pengurutan hasil. */
    int nomorBaris();

    /** Baris selesai diproses dan membawa kejadian siap agregasi. */
    record Sah(KejadianTerproses kejadian) implements HasilBaris {
        @Override
        public int nomorBaris() {
            return kejadian.nomorBaris();
        }
    }

    /** Baris ditolak validator; alasan ditulis untuk laporan galat. */
    record TidakSah(int nomorBaris, String alasan) implements HasilBaris {
        @Override
        public int nomorBaris() {
            return nomorBaris;
        }
    }

    /** Baris gagal diproses setelah kebijakan retry menyerah; akar masalah dirunut. */
    record GagalTetap(int nomorBaris, int percobaan, String pesan, String penyebabAkar)
            implements HasilBaris {
        @Override
        public int nomorBaris() {
            return nomorBaris;
        }
    }
}
