penambahan dan perbaikan untuk log

This commit is contained in:
2026-06-11 11:07:49 +07:00
parent 423a2d1095
commit 7c1f1db72a
4 changed files with 228 additions and 144 deletions

No files matched your search

+125 -125
View File
@@ -1,5 +1,5 @@
{ {
"last_updated": "2026-05-18T03:15:28Z", "last_updated": "2026-05-18T04:35:15Z",
"rooms": { "rooms": {
"BARI1": { "BARI1": {
"kode_ruang": "BARI1", "kode_ruang": "BARI1",
@@ -28,20 +28,20 @@
"nama_ruang": "RUANG BARITO KELAS 2", "nama_ruang": "RUANG BARITO KELAS 2",
"old_value": { "old_value": {
"kapasitas": 4, "kapasitas": 4,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"new_value": { "new_value": {
"kapasitas": 4, "kapasitas": 4,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:52Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"BARI3": { "BARI3": {
"kode_ruang": "BARI3", "kode_ruang": "BARI3",
@@ -49,20 +49,20 @@
"nama_ruang": "RUANG BARITO KELAS 3", "nama_ruang": "RUANG BARITO KELAS 3",
"old_value": { "old_value": {
"kapasitas": 11, "kapasitas": 11,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"new_value": { "new_value": {
"kapasitas": 11, "kapasitas": 11,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:52Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"BARIV": { "BARIV": {
"kode_ruang": "BARIV", "kode_ruang": "BARIV",
@@ -133,10 +133,10 @@
"nama_ruang": "RUANG BROMO KELAS 3", "nama_ruang": "RUANG BROMO KELAS 3",
"old_value": { "old_value": {
"kapasitas": 42, "kapasitas": 42,
"tersedia": 12, "tersedia": 11,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 12 "tersedia_pria_wanita": 11
}, },
"new_value": { "new_value": {
"kapasitas": 42, "kapasitas": 42,
@@ -145,8 +145,8 @@
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 12 "tersedia_pria_wanita": 12
}, },
"changed": false, "changed": true,
"last_synced": "2026-05-18T02:35:44Z" "last_synced": "2026-05-18T04:35:15Z"
}, },
"BUGV3": { "BUGV3": {
"kode_ruang": "BUGV3", "kode_ruang": "BUGV3",
@@ -154,20 +154,20 @@
"nama_ruang": "RUANG BUGENVILE KELAS 3", "nama_ruang": "RUANG BUGENVILE KELAS 3",
"old_value": { "old_value": {
"kapasitas": 20, "kapasitas": 20,
"tersedia": 10, "tersedia": 8,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 10 "tersedia_pria_wanita": 8
}, },
"new_value": { "new_value": {
"kapasitas": 20, "kapasitas": 20,
"tersedia": 10, "tersedia": 8,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 10 "tersedia_pria_wanita": 8
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:56Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"BUNA2": { "BUNA2": {
"kode_ruang": "BUNA2", "kode_ruang": "BUNA2",
@@ -196,10 +196,10 @@
"nama_ruang": "RUANG BUNAKEN KELAS 3", "nama_ruang": "RUANG BUNAKEN KELAS 3",
"old_value": { "old_value": {
"kapasitas": 16, "kapasitas": 16,
"tersedia": 5, "tersedia": 4,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 5 "tersedia_pria_wanita": 4
}, },
"new_value": { "new_value": {
"kapasitas": 16, "kapasitas": 16,
@@ -208,7 +208,7 @@
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 4
}, },
"changed": true, "changed": false,
"last_synced": "2026-05-18T03:15:28Z" "last_synced": "2026-05-18T03:15:28Z"
}, },
"CILI2": { "CILI2": {
@@ -343,20 +343,20 @@
"nama_ruang": "RUANG GILI TRAWANGAN KELAS 3", "nama_ruang": "RUANG GILI TRAWANGAN KELAS 3",
"old_value": { "old_value": {
"kapasitas": 9, "kapasitas": 9,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"new_value": { "new_value": {
"kapasitas": 9, "kapasitas": 9,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:39Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"HMEL1": { "HMEL1": {
"kode_ruang": "HMEL1", "kode_ruang": "HMEL1",
@@ -364,10 +364,10 @@
"nama_ruang": "RUANG HCU INFEKSI MELATI", "nama_ruang": "RUANG HCU INFEKSI MELATI",
"old_value": { "old_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 7, "tersedia": 8,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 7 "tersedia_pria_wanita": 8
}, },
"new_value": { "new_value": {
"kapasitas": 8, "kapasitas": 8,
@@ -376,8 +376,8 @@
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 7 "tersedia_pria_wanita": 7
}, },
"changed": false, "changed": true,
"last_synced": "2026-05-18T02:35:56Z" "last_synced": "2026-05-18T04:35:15Z"
}, },
"IMEL1": { "IMEL1": {
"kode_ruang": "IMEL1", "kode_ruang": "IMEL1",
@@ -406,20 +406,20 @@
"nama_ruang": "RUANG JIMBARAN KELAS 2", "nama_ruang": "RUANG JIMBARAN KELAS 2",
"old_value": { "old_value": {
"kapasitas": 28, "kapasitas": 28,
"tersedia": 13, "tersedia": 12,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 13 "tersedia_pria_wanita": 12
}, },
"new_value": { "new_value": {
"kapasitas": 28, "kapasitas": 28,
"tersedia": 13, "tersedia": 12,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 13 "tersedia_pria_wanita": 12
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:52:15Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"KAPA1": { "KAPA1": {
"kode_ruang": "KAPA1", "kode_ruang": "KAPA1",
@@ -469,20 +469,20 @@
"nama_ruang": "RUANG ICU KAPUAS C KELAS 1", "nama_ruang": "RUANG ICU KAPUAS C KELAS 1",
"old_value": { "old_value": {
"kapasitas": 14, "kapasitas": 14,
"tersedia": 3, "tersedia": 4,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 4
}, },
"new_value": { "new_value": {
"kapasitas": 14, "kapasitas": 14,
"tersedia": 3, "tersedia": 4,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 4
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:56Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"KELI1": { "KELI1": {
"kode_ruang": "KELI1", "kode_ruang": "KELI1",
@@ -490,20 +490,20 @@
"nama_ruang": "RUANG KELIMUTU KELAS 1", "nama_ruang": "RUANG KELIMUTU KELAS 1",
"old_value": { "old_value": {
"kapasitas": 16, "kapasitas": 16,
"tersedia": 7, "tersedia": 6,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 7 "tersedia_pria_wanita": 6
}, },
"new_value": { "new_value": {
"kapasitas": 16, "kapasitas": 16,
"tersedia": 7, "tersedia": 6,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 7 "tersedia_pria_wanita": 6
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:47Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"KELI2": { "KELI2": {
"kode_ruang": "KELI2", "kode_ruang": "KELI2",
@@ -511,20 +511,20 @@
"nama_ruang": "RUANG KELIMUTU KELAS 2", "nama_ruang": "RUANG KELIMUTU KELAS 2",
"old_value": { "old_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"new_value": { "new_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:48Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"KERC2": { "KERC2": {
"kode_ruang": "KERC2", "kode_ruang": "KERC2",
@@ -658,20 +658,20 @@
"nama_ruang": "RUANG MAWAR KELAS 1", "nama_ruang": "RUANG MAWAR KELAS 1",
"old_value": { "old_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 13, "tersedia": 12,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 13 "tersedia_pria_wanita": 12
}, },
"new_value": { "new_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 13, "tersedia": 12,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 13 "tersedia_pria_wanita": 12
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T03:02:15Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"PANG3": { "PANG3": {
"kode_ruang": "PANG3", "kode_ruang": "PANG3",
@@ -679,20 +679,20 @@
"nama_ruang": "RUANG PANGANDARAN", "nama_ruang": "RUANG PANGANDARAN",
"old_value": { "old_value": {
"kapasitas": 35, "kapasitas": 35,
"tersedia": 3, "tersedia": 1,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 1
}, },
"new_value": { "new_value": {
"kapasitas": 35, "kapasitas": 35,
"tersedia": 3, "tersedia": 1,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 1
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:41Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"PARA3": { "PARA3": {
"kode_ruang": "PARA3", "kode_ruang": "PARA3",
@@ -700,20 +700,20 @@
"nama_ruang": "RUANG PARANGTRITIS", "nama_ruang": "RUANG PARANGTRITIS",
"old_value": { "old_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 6, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 6 "tersedia_pria_wanita": 3
}, },
"new_value": { "new_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 5, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 5 "tersedia_pria_wanita": 3
}, },
"changed": true, "changed": false,
"last_synced": "2026-05-18T03:15:28Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RANKB3": { "RANKB3": {
"kode_ruang": "RANKB3", "kode_ruang": "RANKB3",
@@ -742,20 +742,20 @@
"nama_ruang": "RUANG HCU RANU GRATI", "nama_ruang": "RUANG HCU RANU GRATI",
"old_value": { "old_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"new_value": { "new_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 4, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 4 "tersedia_pria_wanita": 3
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:54Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RANU3": { "RANU3": {
"kode_ruang": "RANU3", "kode_ruang": "RANU3",
@@ -763,20 +763,20 @@
"nama_ruang": "RUANG RANU KUMBOLO KELAS 3", "nama_ruang": "RUANG RANU KUMBOLO KELAS 3",
"old_value": { "old_value": {
"kapasitas": 18, "kapasitas": 18,
"tersedia": 12, "tersedia": 11,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 12 "tersedia_pria_wanita": 11
}, },
"new_value": { "new_value": {
"kapasitas": 18, "kapasitas": 18,
"tersedia": 12, "tersedia": 11,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 12 "tersedia_pria_wanita": 11
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:59Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RGPLT21": { "RGPLT21": {
"kode_ruang": "RGPLT21", "kode_ruang": "RGPLT21",
@@ -889,20 +889,20 @@
"nama_ruang": "RUANG HCU RANU PANE KELAS 2", "nama_ruang": "RUANG HCU RANU PANE KELAS 2",
"old_value": { "old_value": {
"kapasitas": 38, "kapasitas": 38,
"tersedia": 26, "tersedia": 25,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 26 "tersedia_pria_wanita": 25
}, },
"new_value": { "new_value": {
"kapasitas": 38, "kapasitas": 38,
"tersedia": 26, "tersedia": 25,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 26 "tersedia_pria_wanita": 25
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:36:05Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RINJ1": { "RINJ1": {
"kode_ruang": "RINJ1", "kode_ruang": "RINJ1",
@@ -931,20 +931,20 @@
"nama_ruang": "RUANG RINJANI KELAS 2", "nama_ruang": "RUANG RINJANI KELAS 2",
"old_value": { "old_value": {
"kapasitas": 2, "kapasitas": 2,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"new_value": { "new_value": {
"kapasitas": 2, "kapasitas": 2,
"tersedia": 1, "tersedia": 0,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 1 "tersedia_pria_wanita": 0
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-11T10:23:47+07:00" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RINJ3": { "RINJ3": {
"kode_ruang": "RINJ3", "kode_ruang": "RINJ3",
@@ -952,20 +952,20 @@
"nama_ruang": "RUANG RINJANI KELAS 3", "nama_ruang": "RUANG RINJANI KELAS 3",
"old_value": { "old_value": {
"kapasitas": 18, "kapasitas": 18,
"tersedia": 8, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 8 "tersedia_pria_wanita": 3
}, },
"new_value": { "new_value": {
"kapasitas": 18, "kapasitas": 18,
"tersedia": 8, "tersedia": 3,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 8 "tersedia_pria_wanita": 3
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:52:15Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RNICU1": { "RNICU1": {
"kode_ruang": "RNICU1", "kode_ruang": "RNICU1",
@@ -973,20 +973,20 @@
"nama_ruang": "RUANG NICU MANINJAU KELAS 1", "nama_ruang": "RUANG NICU MANINJAU KELAS 1",
"old_value": { "old_value": {
"kapasitas": 12, "kapasitas": 12,
"tersedia": 0, "tersedia": 1,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 0 "tersedia_pria_wanita": 1
}, },
"new_value": { "new_value": {
"kapasitas": 12, "kapasitas": 12,
"tersedia": 0, "tersedia": 1,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 0 "tersedia_pria_wanita": 1
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:36:06Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RNS1": { "RNS1": {
"kode_ruang": "RNS1", "kode_ruang": "RNS1",
@@ -994,20 +994,20 @@
"nama_ruang": "RUANG NUSA DUA KELAS 1", "nama_ruang": "RUANG NUSA DUA KELAS 1",
"old_value": { "old_value": {
"kapasitas": 20, "kapasitas": 20,
"tersedia": 9, "tersedia": 7,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 9 "tersedia_pria_wanita": 7
}, },
"new_value": { "new_value": {
"kapasitas": 20, "kapasitas": 20,
"tersedia": 8, "tersedia": 7,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 8 "tersedia_pria_wanita": 7
}, },
"changed": true, "changed": false,
"last_synced": "2026-05-18T03:15:28Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"ROE2": { "ROE2": {
"kode_ruang": "ROE2", "kode_ruang": "ROE2",
@@ -1036,20 +1036,20 @@
"nama_ruang": "RUANG SINGKARAK KELAS 3", "nama_ruang": "RUANG SINGKARAK KELAS 3",
"old_value": { "old_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 26, "tersedia": 22,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 26 "tersedia_pria_wanita": 22
}, },
"new_value": { "new_value": {
"kapasitas": 30, "kapasitas": 30,
"tersedia": 26, "tersedia": 22,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 26 "tersedia_pria_wanita": 22
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:36:04Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"RTOBY2": { "RTOBY2": {
"kode_ruang": "RTOBY2", "kode_ruang": "RTOBY2",
@@ -1099,20 +1099,20 @@
"nama_ruang": "RUANG SEMERU", "nama_ruang": "RUANG SEMERU",
"old_value": { "old_value": {
"kapasitas": 43, "kapasitas": 43,
"tersedia": 34, "tersedia": 30,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 34 "tersedia_pria_wanita": 30
}, },
"new_value": { "new_value": {
"kapasitas": 43, "kapasitas": 43,
"tersedia": 34, "tersedia": 30,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 34 "tersedia_pria_wanita": 30
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:35:53Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"TOBA1": { "TOBA1": {
"kode_ruang": "TOBA1", "kode_ruang": "TOBA1",
@@ -1162,20 +1162,20 @@
"nama_ruang": "RUANG TOBA (IBU) KELAS 2", "nama_ruang": "RUANG TOBA (IBU) KELAS 2",
"old_value": { "old_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 3, "tersedia": 4,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 4
}, },
"new_value": { "new_value": {
"kapasitas": 8, "kapasitas": 8,
"tersedia": 3, "tersedia": 4,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 3 "tersedia_pria_wanita": 4
}, },
"changed": false, "changed": false,
"last_synced": "2026-05-18T02:52:15Z" "last_synced": "2026-05-18T04:30:15Z"
}, },
"TOND3": { "TOND3": {
"kode_ruang": "TOND3", "kode_ruang": "TOND3",
@@ -1183,20 +1183,20 @@
"nama_ruang": "RUANG TONDANO", "nama_ruang": "RUANG TONDANO",
"old_value": { "old_value": {
"kapasitas": 50, "kapasitas": 50,
"tersedia": 29, "tersedia": 27,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 29 "tersedia_pria_wanita": 27
}, },
"new_value": { "new_value": {
"kapasitas": 50, "kapasitas": 50,
"tersedia": 28, "tersedia": 27,
"tersedia_pria": 0, "tersedia_pria": 0,
"tersedia_wanita": 0, "tersedia_wanita": 0,
"tersedia_pria_wanita": 28 "tersedia_pria_wanita": 27
}, },
"changed": true, "changed": false,
"last_synced": "2026-05-18T03:15:28Z" "last_synced": "2026-05-18T04:30:15Z"
} }
} }
} }
+86
View File
@@ -159,7 +159,12 @@ func (h *AdminHandler) GetPage(c *gin.Context) {
.toast.show { opacity: 1; } .toast.show { opacity: 1; }
.toast-ok { background: #2ecc71; } .toast-ok { background: #2ecc71; }
.toast-err { background: #e74c3c; } .toast-err { background: #e74c3c; }
.charts-row { display: flex; gap: 16px; margin-bottom: 16px; }
.chart-card { background: white; border-radius: 8px; padding: 16px 20px; flex: 1; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.chart-card h3 { font-size: 14px; font-weight: 600; color: #555; margin-bottom: 12px; }
@media (max-width: 768px) { .charts-row { flex-direction: column; } }
</style> </style>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
</head> </head>
<body> <body>
@@ -184,6 +189,17 @@ func (h *AdminHandler) GetPage(c *gin.Context) {
</div> </div>
<div class="container"> <div class="container">
<div class="charts-row">
<div class="chart-card">
<h3>Status Mapping</h3>
<canvas id="chartPie" height="200"></canvas>
</div>
<div class="chart-card">
<h3>Kapasitas per Kelas</h3>
<canvas id="chartBar" height="200"></canvas>
</div>
</div>
<div class="search-bar"> <div class="search-bar">
<input type="text" id="search" placeholder="🔍 Cari nama ruangan..." oninput="filterTable()"> <input type="text" id="search" placeholder="🔍 Cari nama ruangan..." oninput="filterTable()">
</div> </div>
@@ -409,6 +425,76 @@ document.querySelectorAll('.modal-overlay').forEach(el => {
}); });
init(); init();
initCharts();
function initCharts() {
const sudah = DATA.filter(r => r.sudah_mapping).length;
const belum = DATA.filter(r => !r.sudah_mapping).length;
// Pie chart — sudah vs belum mapping
new Chart(document.getElementById('chartPie'), {
type: 'doughnut',
data: {
labels: ['Sudah Mapping', 'Belum Mapping'],
datasets: [{
data: [sudah, belum],
backgroundColor: ['#2ecc71', '#f4a261'],
borderWidth: 0
}]
},
options: {
responsive: true,
plugins: {
legend: { position: 'bottom', labels: { font: { size: 12 } } }
}
}
});
// Bar chart — kapasitas per kelas
const kelasSummary = {};
DATA.forEach(r => {
const kelas = r.kode_kelas || 'Belum';
if (!kelasSummary[kelas]) kelasSummary[kelas] = { kapasitas: 0, ruangan: 0 };
kelasSummary[kelas].kapasitas += r.jumlah_tt;
kelasSummary[kelas].ruangan += 1;
});
const labels = Object.keys(kelasSummary).sort();
const kapasitas = labels.map(k => kelasSummary[k].kapasitas);
const colors = labels.map((_, i) => 'hsl(' + ((i * 47) % 360) + ', 65%, 55%)');
new Chart(document.getElementById('chartBar'), {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Total Kapasitas',
data: kapasitas,
backgroundColor: colors,
borderRadius: 6,
borderWidth: 0
}]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
afterLabel: ctx => {
const kelas = labels[ctx.dataIndex];
return 'Ruangan: ' + kelasSummary[kelas].ruangan;
}
}
}
},
scales: {
y: { beginAtZero: true, grid: { color: '#f0f0f0' } },
x: { grid: { display: false } }
}
}
});
}
</script> </script>
</body> </body>
</html>` </html>`
+15 -19
View File
@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath"
"time" "time"
) )
@@ -20,19 +21,25 @@ type SyncLog struct {
ResponseMs int64 `json:"response_ms,omitempty"` ResponseMs int64 `json:"response_ms,omitempty"`
} }
var logPath = "./logs/sync.log" // logPath sekarang fungsi yang mengembalikan path berdasarkan tanggal
func getLogPath() string {
// Format tanggal: 2026-06-11
dateStr := time.Now().Format("2006-01-02")
return filepath.Join("./logs", fmt.Sprintf("sync-%s.log", dateStr))
}
func init() { func init() {
_ = os.MkdirAll("./logs", 0755) _ = os.MkdirAll("./logs", 0755)
} }
// WriteLog menulis 1 entry log ke sync.log // WriteLog menulis 1 entry log ke file berdasarkan tanggal hari ini
func WriteLog(entry SyncLog) { func WriteLog(entry SyncLog) {
entry.Timestamp = time.Now().Format(time.RFC3339) entry.Timestamp = time.Now().Format(time.RFC3339)
writeToFile(entry) logPath := getLogPath()
writeToFile(entry, logPath)
} }
// WriteBatchLog menulis ringkasan 1 run sync // WriteBatchLog menulis ringkasan 1 run sync ke file berdasarkan tanggal hari ini
func WriteBatchLog(result *SyncResult) { func WriteBatchLog(result *SyncResult) {
if result == nil { if result == nil {
return return
@@ -57,6 +64,7 @@ func WriteBatchLog(result *SyncResult) {
"errors": result.Errors, "errors": result.Errors,
} }
logPath := getLogPath()
f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
return return
@@ -66,11 +74,10 @@ func WriteBatchLog(result *SyncResult) {
line, _ := json.Marshal(summary) line, _ := json.Marshal(summary)
_, _ = f.Write(append(line, '\n')) _, _ = f.Write(append(line, '\n'))
// Rotasi log — jaga ukuran file max 5MB // Rotasi log tidak diperlukan karena sudah otomatis terpisah per hari
rotateLogs()
} }
func writeToFile(entry SyncLog) { func writeToFile(entry SyncLog, logPath string) {
f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
fmt.Printf("gagal buka log file: %v\n", err) fmt.Printf("gagal buka log file: %v\n", err)
@@ -82,15 +89,4 @@ func writeToFile(entry SyncLog) {
_, _ = f.Write(append(line, '\n')) _, _ = f.Write(append(line, '\n'))
} }
// rotateLogs — kalau file > 5MB, rename jadi sync.log.old // rotateLogs dihapus karena sudah otomatis terpisah per hari
func rotateLogs() {
info, err := os.Stat(logPath)
if err != nil {
return
}
// 5MB
if info.Size() > 5*1024*1024 {
_ = os.Rename(logPath, logPath+".old")
}
}
+2
View File
@@ -1512,3 +1512,5 @@
{"action":"batch_sync","changed":2,"dry_run":true,"errors":null,"posted":2,"status":"sukses","timestamp":"2026-05-18T02:57:15Z","total_rooms":57} {"action":"batch_sync","changed":2,"dry_run":true,"errors":null,"posted":2,"status":"sukses","timestamp":"2026-05-18T02:57:15Z","total_rooms":57}
{"action":"batch_sync","changed":4,"dry_run":true,"errors":null,"posted":4,"status":"sukses","timestamp":"2026-05-18T03:02:15Z","total_rooms":57} {"action":"batch_sync","changed":4,"dry_run":true,"errors":null,"posted":4,"status":"sukses","timestamp":"2026-05-18T03:02:15Z","total_rooms":57}
{"action":"batch_sync","changed":4,"dry_run":true,"errors":null,"posted":4,"status":"sukses","timestamp":"2026-05-18T03:15:28Z","total_rooms":57} {"action":"batch_sync","changed":4,"dry_run":true,"errors":null,"posted":4,"status":"sukses","timestamp":"2026-05-18T03:15:28Z","total_rooms":57}
{"action":"batch_sync","changed":24,"dry_run":true,"errors":null,"posted":24,"status":"sukses","timestamp":"2026-05-18T04:30:15Z","total_rooms":57}
{"action":"batch_sync","changed":2,"dry_run":true,"errors":null,"posted":2,"status":"sukses","timestamp":"2026-05-18T04:35:15Z","total_rooms":57}