Library npm Approval ERP Saya Tembus 1.200 Weekly Downloads

Foto oleh Screenshot: the hierarchical-approval page on npm, 7 September 2026
Ini engine berlisensi MIT dan TypeScript-first untuk workflow approval bertingkat di sistem enterprise, ditujukan bagi developer yang membangun alur bergaya ERP seperti purchase order, klaim biaya, dan persetujuan kontrak. Anda mendefinisikan sebuah template bernama satu kali lalu memakainya ulang untuk setiap dokumen sejenis. Library ini multi-tenant, siap audit, dan hanya punya dua runtime dependency.
Bisa, sejak versi 1.0.0. Level yang berbagi nama group terbuka bersama lalu menyatu sebelum rantai maju, sehingga Finance dan Legal dapat mereview kontrak yang sama secara bersamaan dan level CEO tetap menunggu sampai semua branch menyetujui. Menolak salah satu branch menolak seluruh instance, dan sebuah group juga boleh berada di awal rantai sehingga terbuka saat submit.
Sebuah instance kini menyediakan openLevels, daftar menaik berisi setiap level yang sedang mengumpulkan keputusan, karena satu angka currentLevel tidak sanggup menggambarkan frontier begitu sebuah parallel group punya beberapa branch terbuka. currentLevel tetap ada sebagai level terbuka terendah untuk tampilan dan audit. Pada template sekuensial keduanya selalu sepakat, jadi sebagian besar pemanggil tidak perlu berubah; pindah ke openLevels di tempat Anda memutuskan siapa yang boleh bertindak atau apa yang lewat tenggat.
Ada dua mekanisme. Optimistic locking pada field version dengan retry policy yang bisa diatur menangani dua approver yang bertindak pada saat bersamaan, dan idempotency bawaan yang dikunci pada tenant, dokumen, dan template membuat double-click atau retry jaringan mengembalikan instance yang sudah ada alih-alih membuat yang kedua. Setiap mutasi juga ditulis ke audit log immutable beserta diff state lama dan baru.
Tidak, dan npm menyatakannya secara terbuka. Counter itu mencatat respons HTTP 200 yang dilayani untuk file tarball, yang mencakup mirror, CI runner, dan robot analisis, dan mem-publish sebuah versi dijamin memicu ledakan karena setiap mirror menarik tarball baru. Angkanya indikator arah aktivitas, bukan hitungan pengguna, dan karena itu sinyal yang bertahan untuk package ini adalah 404 test yang lolos serta open issue-nya.

Foto oleh Screenshot: the hierarchical-approval page on npm, 7 September 2026
Saya mem-publish versi 0.1.0 hierarchical-approval pada 21 Juni, terutama supaya berhenti membangun rantai approval yang sama secara manual. Kode itu sudah saya tulis tiga kali dalam delapan belas bulan untuk tiga proyek ERP berbeda, dan pada kali ketiga saya memilih mengekstraknya. Pada 7 September halaman npm-nya menunjukkan 1.204 weekly downloads dan versi 4.0.0. Itu minggu yang bagus, dan layak dicatat apa saja yang membawanya ke sana.
Tulisan ini adalah cerita sebelas minggu itu: apa yang library ini kerjakan, rilis yang membuat API-nya stabil, rilis yang memperbaiki model datanya alih-alih gejala keenam dari model itu, dan catatan jujur soal apa yang sebenarnya diukur oleh counter npm. Setiap angka berasal dari registry API atau changelog, keduanya tertaut di bagian akhir.
Badge menampilkan tujuh hari terakhir. Range endpoint menampilkan seluruh lengkungnya, dan lengkung itu berisi satu peluncuran, satu bagian tengah yang sepi ketika saya sibuk membangun alih-alih merilis, lalu September ketika library-nya beranjak dewasa. 2.620 download sepanjang sebelas minggu pertama, ditutup dengan minggu terbaik sejauh ini.
hierarchical-approval, downloads per week since launch
21 Jun 820 ███████████████████████████ 0.1.0 - 0.3.1
28 Jun 50 ██
05 Jul 26 █
12 Jul 5 ▏
19 Jul 286 ██████████ 0.4.0, 0.5.0
26 Jul 17 ▌
02 Aug 15 ▌
09 Aug 22 ▊
16 Aug 145 █████ 0.6.0
23 Aug 26 █
30 Aug 1,020 ██████████████████████████████████ 0.7.0 - 4.0.0
----------------------------------------------------------------
2,620 downloads across the first eleven weeks.
Latest seven-day window: 1,204. Latest version: 4.0.0.Bagian sepi pada Juli dan Agustus justru yang akan saya bela. Tidak ada yang meng-install karena memang tidak ada yang baru untuk ditawarkan: engine-nya sudah bekerja, tetapi baru bisa menangani rantai sekuensial, dan saya sedang menulis model parallel branch yang akhirnya dikirim di 1.0.0. Library yang mengerjakan satu hal dengan baik dan jujur soal sisanya adalah titik awal yang lebih baik daripada library luas yang keliru di enam tempat.
Premisnya tidak berubah sejak rilis pertama. Rantai approval bukan business logic yang layak ditulis ulang di tiap proyek, ia infrastruktur: sebuah template bernama, dokumen yang bergerak melewatinya, dan sekumpulan jaminan soal concurrency serta audit yang semua orang butuhkan dan tidak ada yang senang membangunnya. Masing-masing hal berikut mendarat karena saya lebih dulu menabraknya di production.
| Masalah di setiap ERP yang pernah saya tangani | Yang diberikan library ini | Sejak |
|---|---|---|
| Rantai approval di-hardcode per jenis dokumen | Template bernama, didefinisikan sekali dan dipakai ulang di mana saja | 0.1.0 |
| Dua approver menekan tombol pada detik yang sama | Optimistic locking pada field version, dengan retry policy yang bisa diatur | 0.1.0 |
| Double-click atau retry jaringan membuat dua pengajuan | Idempotency yang dikunci pada tenant, dokumen, dan template | 0.1.0 |
| Test yang menuntut database sungguhan dan jam sungguhan | ApprovalTestKit dan ManualClock yang bisa di-inject, tanpa I/O | 0.4.0 |
| Finance dan Legal mereview bergantian tanpa alasan | Parallel branch group yang terbuka bersama lalu menyatu sebelum rantai maju | 1.0.0 |
Di sekelilingnya ada enam adapter interface yang bisa dicolok, untuk notifikasi, metrics, audit, scheduling, otorisasi, dan middleware, sehingga engine-nya bisa menulis ke Kafka, Datadog, BullMQ, atau apa pun yang sudah berjalan di platform Anda tanpa perlu tahu semua itu ada. Audit log-nya immutable dan mencatat diff state lama dan baru pada setiap mutasi, dan bagian itulah yang benar-benar diminta oleh compliance.
Sampai 1.0.0 setiap rantai bersifat sekuensial ketat, jadi langkah yang sebenarnya berjalan bersamaan harus dipalsukan. Finance dan Legal mereview kontrak yang sama secara independen, dan memodelkannya sebagai Finance lalu Legal menambah cycle time berhari-hari demi memuaskan model data, bukan bisnisnya. Level yang berbagi nama group kini aktif bersama lalu menyatu sebelum rantai maju.
// Before 1.0.0 this needed an arbitrary order: Finance waits on Legal,
// or Legal waits on Finance, and the cycle time pays for the guess.
levels: [
{ level: 1, name: 'Manager', approvers: [...], mode: 'any' },
{ level: 2, name: 'Finance', group: 'review', approvers: [...], mode: 'any' },
{ level: 3, name: 'Legal', group: 'review', approvers: [...], mode: 'any' },
{ level: 4, name: 'CEO', approvers: [...], mode: 'any' },
]
// Levels sharing a group name open together and join before the chain
// advances. Decisions arrive in any order; level 4 stays 'waiting' until
// every branch is approved. Rejecting any branch rejects the instance.
// Five ways a level can pass, not one:
// 'any' one approver is enough
// 'all' every listed approver must act
// 'majority' more than half
// 'quorum' a fixed N-of-M threshold (minApprovals)
// 'weighted' cumulative approver weight (threshold, weights)Ini item terakhir di roadmap, sekaligus rilis yang membuat saya berani menyebut API publiknya sudah mapan: sejak titik itu perubahan breaking mendapat versi major. Detail yang paling saya syukuri adalah seluruh 673 test yang ditulis untuk engine sekuensial lolos tanpa diubah, karena level tanpa group cukup diperlakukan sebagai group berisi dirinya sendiri. Backward compatibility lebih mudah dijanjikan daripada dibuktikan, dan test suite adalah tempat Anda tahu yang mana yang terjadi.
Enam defect di sepanjang jalur 3.x berbagi satu akar yang sama. Sebuah instance melacak posisinya dengan satu angka, currentLevel, dan angka tunggal itu memang tidak bisa menggambarkan frontier approval begitu sebuah parallel group punya beberapa level terbuka sekaligus. Tiap rilis memperbaiki satu pembaca angka itu: sebuah return yang malah melangkah balik ke group yang sedang ditinggalkan, escalation yang mengawasi branch keliru, query workload yang melewatkan separuh pekerjaan terbuka. Enam gejala, satu field yang salah.
// Wrong: one number cannot describe a frontier with two branches open.
if (instance.currentLevel === myLevel) { /* may I act? */ }
// Right: ask what the instance is actually waiting on.
const open = await engine.getOpenLevels(id); // number[], ascending
// [2] a sequential chain sitting on level 2
// [2, 3] a parallel group with both branches collecting decisions
// [] terminal - approved, rejected, cancelled or expired
// currentLevel survives as the lowest open level, recomputed by the engine
// on every write. It stays for display and for the audit trail, and a
// terminal instance keeps its last value so the record still shows where
// the request stopped. On a sequential template the two always agree,
// which is why most callers needed no change at all.Maka 4.0.0 berhenti menambal para pembacanya dan mengubah modelnya. Setiap penulisan instance kini melewati satu jalur yang lebih dulu menghitung ulang frontier, artinya operasi baru tidak mungkin menyimpan level tanpa memperbarui daftar level terbuka. Itu disiplin yang sama yang diterapkan pada konstruksi level di 3.0.0 dan pada daftar kolom Postgres di 1.6.0, yang keduanya melenceng karena alasan persis sama: dua tempat membangun hal yang sama, dan hanya satu yang dijaga tetap mutakhir.
Kalau Anda masih di 3.x dan membaca currentLevel untuk menentukan siapa yang boleh bertindak, apa yang perlu dinotifikasi, atau apa yang sudah lewat tenggat, pindahkan pembacaan itu ke openLevels sebelum upgrade. Pada template sekuensial keduanya selalu sepakat, jadi sebagian besar upgrade tidak perlu perubahan sama sekali. Storage adapter buatan sendiri wajib mengembalikan field baru itu utuh, sebagaimana sudah wajib untuk levels; PostgresAdapter bawaan menambahkan kolomnya lewat langkah migrate miliknya.
Saya memeriksa angka itu sebelum menikmatinya, karena npm sejak dulu terbuka soal apa yang dihitungnya: respons HTTP 200 yang dilayani untuk file tarball, yang mencakup mirror, CI runner, dan robot analisis di samping manusia. Mem-publish sebuah versi dijamin memicu ledakan, sebab setiap mirror menarik tarball baru itu, dan satu malam penuh rilis terlihat di grafik tepat karena alasan tersebut. Pedoman kasar dari registry sendiri menaruh sinyal yang meyakinkan di atas kisaran 50 download per hari.
Itu tidak membuat pencapaiannya jadi kurang nyata, hanya membuatnya lebih spesifik. Angka yang bertahan adalah yang tidak bergerak ketika saya mem-publish: 404 test lolos, dua belas entry point, sebelas open issue dari orang yang membaca dokumentasi cukup teliti sampai menemukan kasus pinggiran, dan sebuah package yang ter-install bersih hanya dengan dua runtime dependency. 1.204 itu judulnya; angka-angka tadi alasan kenapa arahnya benar, dan itu yang akan saya pantau bulan depan.
Antara pukul 17:16 UTC pada 3 September dan 02:14 keesokan paginya saya mem-publish 28 versi. Isinya nyata, setiap entri changelog adalah defect dengan cara reproduksi dan mode kegagalan yang disebut jelas, dan mengirim perbaikan di malam yang sama saat Anda menemukannya adalah naluri yang benar untuk library tempat orang membangun approval. Pengemasannya yang tidak benar, dan tiga hal berubah karenanya:
Tidak satu pun dari itu jadi alasan menyesali malamnya. Library yang mengirim 4.0.0 sebelas minggu setelah 0.1.0 adalah library yang dipakai cukup serius sampai menemukan sudut-sudutnya sendiri, dan saya lebih rela menemukan enam defect frontier itu sendiri daripada ada orang lain menemukannya di dalam sebuah purchase order.
Seluruh package berlisensi MIT dan ter-install dalam satu baris, dengan pg hanya dibutuhkan kalau Anda memakai adapter Postgres. Entry point-nya dipecah supaya mengimpor engine tidak ikut menyeret NestJS, test kit, atau tujuh plugin yang tidak Anda pakai.
npm install hierarchical-approval
npm install pg @types/pg # peer dep, Postgres adapter only
# Twelve entry points, so you pay only for what you import:
# hierarchical-approval the engine
# hierarchical-approval/nestjs the NestJS module
# hierarchical-approval/testing ApprovalTestKit + ManualClock
# hierarchical-approval/adapters/memory zero-I/O storage
# hierarchical-approval/adapters/postgres production storage
# hierarchical-approval/plugins/audit + notify, metrics, tracing,
# webhook, scheduler, resilience
# Runtime dependencies: zod and eventemitter3. That is the whole list.Anda bisa menjalankan library ini di browser sebelum memutuskan apa pun. RunKit memberi notebook instan dengan require hierarchical-approval yang sudah teresolusi, dan playground StackBlitz menyalakan satu rantai approval purchase order lengkap beserta condition-nya tanpa install lokal. Kedua tautan ada di halaman npm, dan itu cara tercepat mengetahui apakah model template-nya cocok untuk dokumen Anda.
Sebelas minggu, 37 versi, 404 test, dan minggu terbaik dengan 1.204 download. Angka yang membuat saya membuka halaman itu bukan angka yang akan menjaga library ini tetap hidup, tetapi ia sinyal nyata bahwa sesuatu yang saya bangun untuk pekerjaan ERP sendiri kini berguna di luar itu, dan itulah seluruh alasan menerbitkan apa pun. Versi 4.0.0 adalah yang akan saya sarankan untuk Anda install.
hierarchical-approval di npm
Berlisensi MIT, TypeScript-first, multi-tenant dan siap audit. Tanpa runtime dependency yang tidak Anda pilih sendiri.
npmjs.com/package/hierarchical-approval