DoseRx
Kalkulator dosis untuk 127 obat yang membulatkan dosis ke tablet dan sirup yang dijual apotek Indonesia

- obat, lengkap dengan rentang dan batas dosis
- 127
- kelompok klinis yang menyusun katalog obat
- 9
- pecahan tablet terkecil yang disarankan
- ¼
Di halaman ini
- Masalahnya
- Yang saya bangun
- Hitungannya ada di satu tempat, terpisah dari tampilan
- Dosis dibulatkan ke sediaan yang dijual apotek Indonesia
- Satu obat bisa punya lebih dari satu dosis
- Obat yang belum diverifikasi menunggu di gerbang tinjauan
- Navigasi mengikuti tugas klinis yang sedang dihadapi
- Hasilnya
- Di balik layar
Masalahnya
Dokter menghitung dosis berdasarkan berat badan untuk setiap pasien. Kalikan dosis per kilogram dengan berat badan, bagi dengan jumlah pemberian, ubah ke mililiter, lalu cek terhadap batas maksimum. Pada anak, dosisnya bergantung pada berat badan, dan kesalahan bisa membahayakan. Alat yang biasa dipakai adalah buku referensi, kalkulator ponsel, atau spreadsheet. Tidak satu pun yang cepat dipakai dengan satu tangan di samping tempat tidur pasien.
DoseRx dibuat untuk satu dokter praktik yang bekerja lewat ponsel di samping pasien dan lewat desktop. Aplikasinya tidak butuh akun dan tidak butuh server.
Yang saya bangun
Hitungannya ada di satu tempat, terpisah dari tampilan
Saya memisahkan perhitungan dosis dari antarmuka. Mesin hitungnya menerima input bertipe, mengeceknya, menerapkan batas dosis, lalu mengembalikan hasil atau pesan galat. Layar harus mengecek mana yang diterima sebelum menampilkan angka. Jadi perhitungan yang gagal tidak mungkin tampil sebagai dosis, dan nilai yang rusak tidak pernah sampai ke dokter. Mesin yang sama melayani semua kalkulator dan dites tersendiri.
Dosis dibulatkan ke sediaan yang dijual apotek Indonesia
Setelah menghitung dosis, aplikasi menyarankan pecahan tablet atau volume sirup yang perlu diberikan, berdasarkan sediaan yang dijual di apotek Indonesia. Tablet dibulatkan ke pecahan yang bisa dipotong: ¼, ½, ¾, 1, 1½, dan 2. Aplikasi menampilkan dosis yang akhirnya diberikan di samping dosis target, jadi dokter bisa melihat selisih pembulatannya. Tab Puyer melakukan hal yang sama untuk obat racikan. Tab ini menghitung setiap obat dalam satu racikan, lalu mencetak kartu resep gabungan lengkap dengan jumlah tablet dan signa.
Satu obat bisa punya lebih dari satu dosis
Katalognya semula memodelkan satu dosis per obat. Itu berantakan begitu diazepam butuh satu dosis lewat IV untuk kejang dan dosis berbeda lewat mulut untuk kecemasan, dan begitu dosis dewasa ditaruh berdampingan dengan angka pediatrik obat yang sama. Saya memisahkan "obat" dari "dosis": setiap obat kini punya satu atau lebih regimen, satu per rute, indikasi, dan populasi, sementara setiap dosis yang sudah ada tetap persis seperti semula, sehingga perhitungan lama tetap memakai angka yang sama. Katalognya ikut tumbuh seiring perubahan ini, dari 8 obat contoh awal menjadi 127, kini disusun dalam 9 kelompok klinis, bukan 17 kategori datar seperti sebelumnya.
Obat yang belum diverifikasi menunggu di gerbang tinjauan
Obat, rute, dan dosis baru muncul lebih cepat daripada yang bisa saya verifikasi ulang sendiri ke sumbernya. Saya membuat status tinjauan terpisah. Entri baru dimulai sebagai draf dengan sumbernya dicantumkan dan tidak terlihat di luar mode tinjauan, ditandai belum diverifikasi di mana pun ia seharusnya tampil. Hanya saya yang bisa memindahkannya ke katalog yang sudah ditinjau. Per commit terakhir, daftar drafnya kosong, artinya daftar obat saat ini sudah melewati pemeriksaan itu.
Navigasi mengikuti tugas klinis yang sedang dihadapi
Aplikasi ini semula terdiri dari empat tab: Preset, Custom, Puyer, Infus. Itu cocok dengan empat mesin hitungnya, bukan dengan cara dokter berpikir sebenarnya di samping pasien, yang lebih dekat ke "apa yang saya butuhkan untuk keadaan darurat ini" daripada "kalkulator mana yang harus saya buka". Saya mengganti tab-tab itu dengan tujuan berbasis tugas: Obat, Darurat, Puyer, Cairan, dan Riwayat, dengan satu bilah berat pasien yang dipakai bersama di semuanya.
Hasilnya
DoseRx sudah live di GitHub Pages dan bisa dipasang di layar utama ponsel, dan jalan tanpa internet setelah dimuat. Obat yang baru dibuka dan yang diberi bintang muncul paling atas, membuat katalog 127 obat tetap cepat dicari dengan satu tangan, dan setiap perhitungan tersimpan di browser lengkap dengan catatan opsional. Spesifikasi awalnya berisi 8 obat dan tiga panel, dibangun dalam sekitar tiga setengah minggu di bulan Juni dan Juli 2026. Saya terus mengerjakannya sampai September untuk tahap kedua yang mengganti struktur tab dengan navigasi berbasis tugas, menambahkan alur tinjauan untuk obat yang belum diverifikasi, dan membesarkan katalognya ke ukuran sekarang. Aplikasi menyatakan dengan jelas bahwa ini alat bantu hitung, bukan sistem pendukung keputusan klinis.
Di balik layarDetail teknis untuk engineer
- React 18 dan TypeScript di Vite, dengan
vite-plugin-pwa. CSS biasa. Tanpa library UI, state, atau router; routing memakai router kecil buatan sendiri, bukan react-router. src/lib/calculate.tstidak berisi kode DOM atau React dan mengembalikanCalcResult | CalcError. UI harus mengecekresult.validsebelum membaca angka apa pun, jadi bug tampilan NaN dan Infinity hilang secara struktural. Pola yang sama dipakaicalculateInfusion.ts,calculateElectrolyte.ts,calculateFluidRate.ts, dancalculateDextrose.ts.calculate.test.tsdi Vitest mencakup dosis normal, batas harian dan sekali pemberian, konsentrasi yang kosong, dan input tidak valid.calculateInfusion.tsmendukung mcg/kg/menit, mcg/kg/jam, mg/kg/jam, dan unit/kg/jam, dan menghasilkan laju pompa dalam mL/jam serta laju tetes makro dan mikro.estimateWeight.tsmemakai rumus pediatrik APLS dan Luscombe-Owens, diberi label sebagai perkiraan di mana pun ditampilkan.suggest.tsmembulatkan dosis ke arraySOLID_FRACTIONS.catalog.tsmenumpukCatalogDrug/Regimendi atas data preset dan infus yang sudah ada tanpa menulis ulang, jadi setiap regimen tetap memegang objek asli yang dipakai tes-tesnya. Katalognya mencakup 164 regimen dosis di 127 obatnya.- Obat baru masuk ke
drafts.tsdenganstatus: 'draft'dan sumber yang dikutip; seorang klinisi menerbitkannya ke berkas domain denganstatus: 'verified'dan nama peninjau agar tampil — perubahan kode, bukan sekadar sakelar data. - Katalog ada di tujuh modul domain (analgesics, anti-infectives, antiparasitics, cardiorespiratory, emergency, gastro-allergy, steroids-nutrition) ditambah
requested.ts(daftar permintaan bangsal) dandrafts.ts, di balik barrelindex.ts. TipeDrugPresetmemisahkan field perhitungan dari metadata yang hanya untuk tampilan. - Metadata halaman (judul, deskripsi, tag OG/Twitter, manifest PWA, sitemap) semuanya dihasilkan dari satu sumber data
site.ts/routes.tssaat build, setelah manifest dan deskripsi halaman pernah tidak sinkron satu kali. - Proses build menjalankan typecheck, build Vite untuk klien, build Vite SSR untuk entry point, lalu skrip prerender Node yang mengembangkan setiap route, termasuk satu per obat, menjadi HTML statis untuk GitHub Pages.
- Pilihan input dosis per kali atau per hari disimpan dan dipakai di seluruh aplikasi. Saat dosis preset diubah dalam rentang yang sah, muncul penanda kuning dan tombol reset.
- Riwayat disimpan lewat
storage.ts, pembungkus bertipe dan satu-satunya kode yang menyentuhlocalStoragesecara langsung. Preset kustom, obat terakhir, dan favorit juga disimpan di perangkat, dengan kunci id obat yang stabil. - Perbaikan mode gelap dan aksesibilitas menambahkan palet teal medis, didokumentasikan sebagai token desain "Ward Day / Ward Night".
- 165 tes di 20 berkas mencakup mesin hitung, integritas katalog, pencarian, pencocokan route, saran dosis kemasan, penandaan posisi dosis, token gaya, dan tes asap yang merender setiap halaman obat.
- GitHub Actions melakukan deploy ke GitHub Pages. Sekitar 15.400 baris TypeScript, 134 commit antara 20 Juni dan 27 September 2026.
Tangkapan layar
Sedang merekrut, atau membangun hal serupa?
Saya terbuka untuk posisi full-time dan proyek freelance tertentu.