Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
CHL Sales Admin System — BIO District Next.js 15 (App Router) + PostgreSQL 16 + TypeScript. Implementasi PRD v1.7 untuk PT. Serpong Bangun Lestari: pengajuan klaim Closing Fee, Komisi, Cash Reward, dan Overriding; gate verifikasi pajak; tanda tangan digital lewat tautan WhatsApp; crosscheck paralel; sirkulasi dokumen cetak; penginputan tanggal pembayaran; dan export Laporan Master ke Excel. Aplikasi tersedia di http://localhost:3000; migrasi dijalankan otomatis saat kontainer aplikasi menyala. Butuh Node 22 dan PostgreSQL 16 yang sudah berjalan.檢視完整 README ↗
Next.js 15 (App Router) + PostgreSQL 16 + TypeScript.
Implementasi PRD v1.7 untuk PT. Serpong Bangun Lestari: pengajuan klaim Closing Fee, Komisi, Cash Reward, dan Overriding; gate verifikasi pajak; tanda tangan digital lewat tautan WhatsApp; crosscheck paralel; sirkulasi dokumen cetak; penginputan tanggal pembayaran; dan export Laporan Master ke Excel.
cp .env.example .env
docker compose up --build
Aplikasi tersedia di http://localhost:3000; migrasi dijalankan otomatis saat kontainer aplikasi menyala.
Butuh Node 22 dan PostgreSQL 16 yang sudah berjalan.
npm install
cp .env.example .env # sesuaikan DATABASE_URL
npm run db:migrate # buat 24 tabel, enum, indeks, dan rule
npm run db:seed # konfigurasi dan data contoh
npm run dev # http://localhost:3000
Menjalankan uji alur ujung-ke-ujung terhadap basis data sungguhan:
npm run test # 39 pengujian
Tombol Uji gate memanggil endpoint penerbitan tautan pada klaim yang belum
diverifikasi pajak. Jawaban 409 adalah perilaku yang benar.
Pengguna demo (ganti lewat dropdown): admin · ratna (Finance Pajak) ·
ratih (Finance Pembayaran) · fmanager · mgmt · sysadmin.
db/schema.sql Skema PostgreSQL: enum, tabel, indeks parsial, rule
src/lib/
db.ts Pool, transaksi, audit, konfigurasi, idempotensi
money.ts Aritmetika rupiah eksak dan terbilang
calc.ts Perhitungan insentif dan matriks tarif pajak
signature.ts Pencocokan tanda tangan: lapis statis + dinamis
workflow.ts State machine, empat gate, aturan bisnis
settlement.ts Tanggal transfer, penguncian periode, rekap
report.ts Penyusun Laporan Master (view atas data klaim)
api.ts Helper route: auth, peran, problem+json
src/app/
page.tsx Konsol internal
sign/[token]/page.tsx Layar tanda tangan agent
api/**/route.ts 33 route handler
scripts/
migrate.ts seed.ts test-flow.ts synthetic-signature.ts
Berada di src/lib/workflow.ts, bukan di komponen React. Menyembunyikan tombol tidak
menghentikan siapa pun yang memanggil API langsung.
| Gate | Perilaku | Rujukan |
|---|---|---|
| Verifikasi pajak | POST /api/claims/{id}/signature-requests menolak 409 selama status bukan tax_verified. Tidak ada parameter, peran, atau flag yang melewatinya. | BR-13 |
| Dokumen bersegel | Setelah tanda tangan terverifikasi, hitung ulang dan perubahan dokumen ditolak 409. Perubahan nilai hanya lewat financial-findings, yang membatalkan tanda tangan. | BR-11, BR-20 |
| Pemisahan tugas | Verifikator pajak tidak dapat menyetujui pembayaran klaim yang sama. | FR-4.23 |
| Tanpa penolakan permanen | Verifikasi tanda tangan tidak pernah mengembalikan status ditolak. Setelah percobaan ketiga, klaim naik ke tinjauan manusia. | FR-5.13 |
Penginputan tanggal pembayaran menambah empat batas lagi: tanggal masa depan ditolak, bukti transfer wajib, mundur melebihi toleransi perlu Finance Manager, dan periode tertutup mengalihkan entri terlambat ke periode terbuka berikutnya dengan rujukan.
Beberapa aturan sekarang dijaga PostgreSQL, bukan hanya kode aplikasi. Ini yang paling berubah dibanding versi sebelumnya:
Anti-duplikat klaim memakai UNIQUE INDEX parsial pada kombinasi
(unit_id, claim_type, recipient_role) untuk status aktif saja. Satu unit boleh punya
tiga klaim Closing Fee dengan peran berbeda (Sales Inhouse, Sales Manager, Markom) dan
dua Cash Reward — sesuai koreksi kardinalitas PRD 7.B.2. Race condition antar-request
ditolak basis data, bukan diserahkan ke pemeriksaan aplikasi yang bisa saling menyalip.
Konsistensi nilai bersih dijaga CHECK (net_amount = gross_amount + vat - withholding_tax). Kombinasi yang tidak mungkin ditolak sebelum tersimpan.
Tanggal transfer masa depan ditolak CHECK (transfer_date <= CURRENT_DATE) pada
tabel settlements, selain pemeriksaan di lapisan aplikasi.
audit_log append-only memakai RULE ... DO INSTEAD NOTHING untuk UPDATE dan
DELETE. Rule berlaku bahkan bagi pemilik tabel, tidak seperti trigger yang dapat
dilewati dengan ALTER TABLE ... DISABLE TRIGGER.
Uang selalu BIGINT rupiah penuh di basis data dan number di TypeScript.
Persentase memakai NUMERIC(12,8) dan dibiarkan sebagai string oleh driver pg —
parser int8 diubah menjadi angka, numeric sengaja tidak.
Perkalian persentase memakai BigInt berskala, bukan floating point. Alasannya
konkret: 185_000_000 * 0.0025 pada IEEE-754 menghasilkan 462499.99999999994.
Dibulatkan memang tetap benar untuk kasus ini, tetapi pada tarif dan nilai lain
selisihnya muncul sebagai rupiah yang hilang — kecil per transaksi, tidak pernah nol
saat direkonsiliasi setahun. Seluruh perkalian melewati applyRate() di
src/lib/money.ts, dan pembulatan hanya terjadi di sana.
Setiap perhitungan menyimpan snapshot berisi versi skema, basis, tarif, status PKP, jenis NPWP, dan aturan pembulatan. Ini yang memungkinkan auditor tiga tahun ke depan menjawab "mengapa angkanya segini" tanpa menebak konfigurasi saat itu.
Dua lapis di src/lib/signature.ts, tanpa dependensi biner:
zlib.inflateSync, pembalikan
filter per baris), dinormalisasi dengan menjaga rasio aspek, lalu dibandingkan lewat
tumpang tindih (IoU), jarak momen Hu, profil proyeksi, dan rasio aspek.Bila data goresan tidak tersedia, verifikasi jatuh ke lapis statis saja dan skornya
cenderung lebih rendah. Ini dilaporkan lewat layers_used, bukan disembunyikan.
Pembanding per klaim adalah baseline spesimen digital, bukan tanda tangan KTP. KTP hanya dipakai sekali saat onboarding sebagai jangkar identitas, dengan ambang lebih longgar karena sifatnya lintas-medium.
Ambang tanda tangan: ada alatnya, datanya belum ada. Angka 75 berasal dari PRD sebagai nilai sementara, bukan hasil pengukuran — skor kemiripan tidak punya makna universal, 75 pada mesin ini tidak setara 75 pada mesin lain.
Menu Administrasi → Kalibrasi ambang tanda tangan (hanya Admin IT) mengukur
sebaran skor pada spesimen yang tersimpan: pasangan spesimen milik orang yang sama
menghasilkan False Reject Rate, pasangan milik dua orang berbeda menghasilkan False
Accept Rate, dan tabelnya menunjukkan keduanya pada tiap ambang. Ambang yang dipasang
tersimpan bersama bukti pengukurannya dan tercatat di jejak audit; percobaan lama tetap
menyimpan threshold_at_time sehingga riwayatnya tidak berubah arti.
Dua hal yang membuat hasilnya belum dapat disebut kalibrasi produksi:
Spesimennya masih harus dikumpulkan. Jalurnya sudah ada — menu Data
marketing menerbitkan tautan pendaftaran per orang, dan agent menempuh empat
langkah lewat /daftar-ttd/<token>: OTP, persetujuan pemakaian data, foto KTP,
lalu lima tanda tangan (onboarding_specimen_count) yang tiap goresannya
dicocokkan dengan goresan sebelumnya pada ambang onboarding sebelum disimpan.
KTP adalah jangkar identitas, bukan pembanding klaim. Agent menandai sendiri
bagian tanda tangan pada fotonya; potongan itu disimpan sebagai
marketings.reference_signature_png (reference_signature_source='ktp') dan
diperlihatkan kepada Admin bersebelahan dengan goresan-goresannya saat pemeriksaan.
Tanpa jangkar itu, yang dapat dinilai Admin hanya konsistensi antar goresan — dan
tanda tangan palsu yang konsisten juga lolos ujian itu.
Foto KTP utuh dihapus begitu pendaftarannya diputus, disetujui maupun ditolak. Yang tersimpan seterusnya hanya potongan tanda tangannya: bukan NIK, bukan alamat, bukan foto wajah (UU PDP 27/2022 — secukupnya, selama diperlukan saja).
Pendaftaran sekali per orang. Spesimen yang disetujui dipakai terus sebagai pembanding; tautannya tidak muncul lagi di layar Admin, dan perekaman ulang menuntut alasan tertulis yang ikut tercatat di jejak audit. Tanpa itu, siapa pun yang dapat meminta tautan dapat mengganti pembanding pembayaran dirinya sendiri.
Yang belum: protokol PRD §12.2 meminta 30–50 agent dan sepuluh tanda tangan per orang, sedangkan yang dikumpulkan lima — keputusan bisnis yang menukar ketajaman ukuran dengan waktu agent. Layar kalibrasi menyebutkan kekurangan itu apa adanya, dan sampai agent-nya terkumpul angkanya belum mewakili apa pun. Marketing tanpa spesimen tidak ditolak — klaimnya diteruskan ke pemeriksaan Admin Sales pada percobaan pertama, dengan sebabnya disebutkan kepada agent.
Kelompok pembanding bukan pemalsu sungguhan. Yang dibandingkan adalah tanda tangan orang lain, bukan orang yang sengaja meniru setelah melihat aslinya. FAR yang dihitung karenanya batas bawah — kenyataannya lebih buruk.
Aplikasi ini butuh Node runtime dan PostgreSQL yang dapat dijangkau. Cocok untuk Vercel (dengan Neon/Supabase), Railway, Fly.io, atau kontainer di VPS sendiri.
Untuk Vercel, ikuti DEPLOY-VERCEL.md. Build akan berhasil
tanpa konfigurasi apa pun, tetapi aplikasinya tidak berfungsi sampai DATABASE_URL
diisi dan migrasi dijalankan sekali — dua hal yang tidak tertangkap saat build.
TLS diaktifkan otomatis untuk host non-lokal; PGSSL hanya diperlukan bila Anda
ingin memaksanya (require) atau mematikannya (disable).
Periksa hasilnya lewat /api/health. Endpoint itu benar-benar menyentuh basis data
dan menyebutkan langkah perbaikan bila gagal, bukan sekadar membalas "ok".
Autentikasi sudah berupa username dan kata sandi dengan sesi cookie; header X-User
sudah dihapus. Sebelum menyentuh pembayaran sungguhan, aktifkan MFA untuk peran
Finance, Management, dan Admin IT, dan ganti seluruh sandi awal.
| Bagian | Status | Alasan |
|---|---|---|
| Pengiriman WhatsApp sungguhan | Tautan dan OTP ditampilkan di layar | Perlu akun WhatsApp Business API lewat BSP resmi dan template yang disetujui Meta (PRD Q11) |
| Autentikasi | Selesai — username/sandi, scrypt bergaram, sesi cookie HttpOnly | MFA untuk Finance, Management, dan Admin IT belum ada |
| Unggah berkas | Selesai — isi berkas tersimpan (bytea, maks. 3 MB), diunggah agent dari tautan tanda tangan | Enkripsi at-rest dan kebijakan retensi masih menunggu Legal (PRD Q14, Q27) |
| PDF paket cetak & QR | Selesai — GET /api/claims/{id}/print-package/pdf | Tata letak mengikuti form eksisting; QR dan potongan hash dibubuhkan di setiap halaman |
| Batch Overriding | Tabel dan tingkat sudah ada; penyusun batch periodik belum | Menunggu persentase dan penerima tiap tingkat (PRD Q35) |
| Insentif non-tunai | Tersimpan dan tampil di laporan; belum ada alur pengajuan | Menunggu kepastian apakah dicatat manual atau punya form sendiri (PRD Q36, Q37) |
| Pendaftaran spesimen tanda tangan | Selesai — menu Data marketing, tautan sekali per orang, jangkar KTP, persetujuan tercatat, disetujui Admin | Datanya sendiri masih harus dikumpulkan dari agent sungguhan sebelum kalibrasi berarti |
| Enkripsi at-rest, PSrE, Dukcapil, host-to-host bank | Belum | Fase 4 pada roadmap PRD |
Angka tarif pada scripts/seed.ts adalah dugaan terbaik dari catatan laporan master
dan Form Klaim Komisi. Keduanya belum sejalan: laporan menulis PPN 10%, form klaim
menyiratkan 11%. Seed memakai 10% untuk kontrak sebelum April 2022 dan 11% sesudahnya.
Konfirmasi Finance tetap diperlukan sebelum dipakai menghitung pembayaran nyata
(PRD Q38).