Tambah konfirmasi password & auto-arsip sebelum hapus nilai

Tombol "Mulai Ulang (hapus semua nilai)" di halaman Input Nilai
sebelumnya cuma dijaga confirm() browser biasa — gampang ke-klik tanpa
sadar, apalagi datanya sekarang ratusan mahasiswa per MK.

- Dialog konfirmasi kini menyebut jumlah mahasiswa yang akan hilang
- Password akun yang login harus dimasukkan ulang & diverifikasi
  server-side (auth.verifikasi_password) sebelum aksi hapus dieksekusi
- Isi nilai lama diarsipkan otomatis ke tabel nilai_arsip_hapus sebelum
  dihapus (mk_kode, tahun, data JSON, kapan, oleh siapa) — jaring
  pengaman, ikut ke-backup lewat /cadangan.db yang sudah ada; belum ada
  UI pemulihan (di luar cakupan saat ini, cukup query manual bila perlu)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Power BI Dev
2026-08-09 18:51:09 +07:00
parent efc14dc7a7
commit 6375bc88f4
3 changed files with 63 additions and 12 deletions
+25 -2
View File
@@ -185,6 +185,16 @@ def init_db() -> None:
updated_by TEXT NOT NULL
)"""
)
conn.execute(
"""CREATE TABLE IF NOT EXISTS nilai_arsip_hapus (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mk_kode TEXT NOT NULL,
tahun TEXT NOT NULL,
data TEXT NOT NULL,
dihapus_at TEXT NOT NULL,
dihapus_oleh TEXT NOT NULL
)"""
)
conn.execute(
"""CREATE TABLE IF NOT EXISTS pengaturan (
kunci TEXT PRIMARY KEY,
@@ -292,6 +302,19 @@ def simpan_dok(tabel: str, mk_kode: str, data: dict, status: str, updated_by: st
)
def arsipkan_nilai_hapus(mk_kode: str, tahun: str, data: dict, dihapus_oleh: str) -> None:
"""Simpan salinan nilai sebelum dihapus (jaring pengaman) — tak ada UI
pemulihan otomatis, tapi baris ini tetap ikut ke-backup lewat /cadangan.db
dan bisa diambil manual bila suatu saat perlu dipulihkan."""
now = datetime.now(WIB).strftime("%Y-%m-%d %H:%M")
with get_conn() as conn:
conn.execute(
"""INSERT INTO nilai_arsip_hapus (mk_kode, tahun, data, dihapus_at, dihapus_oleh)
VALUES (?,?,?,?,?)""",
(mk_kode, tahun, json.dumps(data, ensure_ascii=False), now, dihapus_oleh),
)
def hapus_dok(tabel: str, mk_kode: str, tahun: str | None = None) -> None:
assert tabel in _TABEL_DOK
tahun = tahun or tahun_aktif()
@@ -362,11 +385,11 @@ def dump_semua() -> dict:
"""Seluruh isi database sebagai dict (untuk cadangan JSON)."""
out = {}
with get_conn() as conn:
for tabel in (*_TABEL_DOK, "rps_arsip", "pengaturan",
for tabel in (*_TABEL_DOK, "rps_arsip", "nilai_arsip_hapus", "pengaturan",
"pengguna", "penugasan", "mahasiswa"):
rows = conn.execute(f"SELECT * FROM {tabel}").fetchall()
out[tabel] = [dict(r) for r in rows]
for tabel in _TABEL_DOK + ("rps_arsip",):
for tabel in _TABEL_DOK + ("rps_arsip", "nilai_arsip_hapus"):
for r in out.get(tabel, []):
r["data"] = json.loads(r["data"])
return out