- TypeScript 50.8%
- Go 36.4%
- CSS 12%
- JavaScript 0.4%
- Makefile 0.2%
|
All checks were successful
check / check (push) Successful in 2m47s
SETTINGS_ENCRYPTION_KEY has no development default, so the recipe as written started a server that could not decrypt the SMTP password admins store on the Pengaturan page. Both forms of the server now set it, with a note on why the key must not change once secrets are on file. Also points at .env.example and the README table as the list to check after a pull or merge, since a new feature can add a required variable long before this page catches up, and records that pkill on the server pattern also kills the shell issuing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .claude/skills/run-app | ||
| .forgejo/workflows | ||
| cmd | ||
| docs | ||
| internal | ||
| migrations | ||
| scripts | ||
| uploads | ||
| web | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .golangci.yml | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
| VERSION | ||
Ruang Sinau
Sistem Informasi dan Pengembangan Kompetensi ASN untuk Belajar dan Berkarya
Ruang Sinau adalah Learning Management System untuk penyelenggaraan pelatihan ASN Pemerintah Daerah. Aplikasi menyatukan pengelolaan peserta, pelatihan, video, webinar, quiz, progres belajar, penilaian, dan sertifikat dalam satu platform berbasis role.
Tentang Ruang Sinau
Ruang Sinau menyediakan pengalaman yang berbeda untuk setiap pengguna:
- Participant — ASN maupun peserta umum — mendaftar sendiri, lalu mendapatkan learning portal responsif untuk menemukan pelatihan, melanjutkan kelas, menonton video, mengerjakan quiz, mengikuti webinar, dan mengunduh sertifikat.
- Instructor mendapatkan workspace untuk mengelola pelatihan yang ditugaskan, materi, webinar, dan enrollment.
- Admin mendapatkan akses lintas resource untuk mengelola peserta, pelatihan, enrollment, sertifikat, dashboard, dan audit log.
Fitur
- Pendaftaran mandiri peserta, dibedakan ASN (NIP wajib) atau umum; akun langsung aktif.
- Aktivasi akun buatan admin melalui single-use activation link.
- Login JWT, password bcrypt, RBAC, dan resource-level authorization.
- Profil kepegawaian ASN dengan validasi NIP 18 digit; peserta umum cukup profil ringkas.
- Lifecycle pelatihan
draft → published → archived. - Enrollment dengan pemeriksaan kapasitas dan status machine terkontrol.
- Video lokal atau YouTube, dengan waktu tonton diakumulasi di server (lompat ke depan dan idle tidak dihitung) dan completion threshold.
- Bahan bacaan: PDF yang diunggah, atau artikel yang ditulis langsung di aplikasi.
- Quiz pilihan ganda dan benar/salah, dalam dua peran. Quiz materi mengikuti sepotong materi dan cukup dikerjakan — ia tidak punya KKM. Post-test adalah penilaian pelatihan dan satu-satunya quiz yang harus lulus.
- Quiz materi yang menyela videonya sendiri pada detik yang ditentukan, bukan hanya menunggu di akhir.
- Auto-completion untuk pelatihan setelah seluruh video ditonton, seluruh bahan bacaan dibuka, seluruh quiz materi dikerjakan, dan post-test lulus.
- Kurikulum berurutan: materi disusun dalam modul dan dikerjakan berurutan, dengan gerbang urutan divalidasi di server.
- Sertifikat PDF bernomor unik untuk enrollment yang selesai.
- Dua mode katalog: pelatihan (materi berurutan) atau webinar (sesi live), yang diselesaikan dengan mengisi kuesioner evaluasinya — itu satu-satunya syaratnya.
- Webinar terintegrasi dengan jadwal, meeting link, dan status.
- Q&A sesi webinar: peserta bertanya dan mendukung pertanyaan, penyelenggara menjawab.
- Glosarium istilah: halaman publik A–Z beserta dasar regulasi tiap istilah, dan pengelolaan draf/terbit oleh admin.
- Profil instansi penyelenggara berikut logo, dengan halaman publiknya sendiri.
- Dashboard per role dan audit log untuk aktivitas sensitif.
- Antarmuka Ruang Sinau responsif dengan light/dark mode.
Teknologi
| Bagian | Teknologi |
|---|---|
| Backend | Go, chi, pgx |
| Database | PostgreSQL 16, Goose migrations |
| Authentication | JWT, bcrypt |
| Frontend | React 19, TypeScript, Vite |
| UI | Shadcn/ui, Tailwind CSS 4, Lucide icons, Framer Motion |
| Server state | TanStack Query |
| Client state | Zustand |
| Development | Nix flake, Docker Compose |
Arsitektur
Repository menggunakan modular monolith. Setiap business domain memiliki model, repository, service, handler, dan test sendiri di bawah internal/<domain>.
cmd/
├── account/ # CLI untuk membuat akun admin/instructor
├── sweep/ # CLI penyapu gambar yatim di UPLOAD_DIR
└── server/ # HTTP application entry point
internal/
├── auth/ # Login, activation, JWT, RBAC
├── participant/ # Profil dan lifecycle participant
├── training/ # Pelatihan dan status workflow
├── enrollment/ # Enrollment dan completion rules
├── quiz/ # Soal, attempt, scoring, grading
├── certificate/ # Penerbitan sertifikat PDF
├── video/ # Storage dan progress video
├── document/ # Bahan bacaan — PDF unggahan atau artikel — dan progress baca
├── module/ # Kurikulum berurutan: modul, item, gerbang urutan
├── evaluation/ # Kuesioner yang menyelesaikan sebuah webinar
├── qna/ # Tanya jawab seputar sesi webinar
├── webinar/ # Jadwal dan meeting webinar
├── glossary/ # Glosarium istilah beserta dasar regulasinya
├── organization/ # Instansi penyelenggara dan logonya
├── account/ # Manajemen akun staff (CLI + API)
├── audit/ # Audit trail
├── dashboard/ # Statistik per role
├── publiccertificate/ # Verifikasi sertifikat publik
├── publictraining/ # Prospektus pelatihan publik (tanpa login)
├── publicwebinar/ # Halaman webinar publik (tanpa login)
└── platform/ # Database, middleware, HTTP server
web/src/
├── app/ # Router, provider, application shell
├── components/ui/ # Shadcn/ui primitives
├── features/ # UI, API, hook, dan type per domain
├── lib/ # Helper teknis yang dipakai primitives
└── shared/ # API client dan komponen lintas feature
Keputusan arsitektur dijelaskan di docs/adr.
Menjalankan Lokal
1. Siapkan toolchain
Dengan Nix, satu perintah menyediakan semuanya:
nix develop path:.
Tanpa Nix, pasang sendiri toolchain berikut lewat package manager distro masing-masing. Versinya mengikuti pin yang sudah ada di repository, supaya hasil lokal sama dengan CI:
| Tool | Versi | Pin |
|---|---|---|
| Go | ≥ 1.23 | go.mod |
| Node.js + npm | 24 | flake.nix, image CI |
| goose | v3.24.1 | Dockerfile — go install github.com/pressly/goose/v3/cmd/goose@v3.24.1 |
| golangci-lint | v2.13.1 | .forgejo/workflows/check.yml — hanya untuk make check |
| PostgreSQL | 16 | docker-compose.yml — lewat Docker atau dipasang langsung |
Langkah-langkah selanjutnya sama untuk keduanya; bedanya hanya pengguna
Nix menjalankannya dari dalam nix develop, yang lain dari shell biasa.
2. Siapkan konfigurasi dan PostgreSQL
cp .env.example .env
PostgreSQL bisa disiapkan lewat Docker atau langsung, dan DATABASE_URL
bawaan di .env.example cocok untuk keduanya.
Dengan Docker:
docker compose up -d postgres
Tanpa Docker, jalankan satu instance yang datanya milik repository ini sendiri, sehingga tidak bentrok dengan PostgreSQL lain di mesin yang sama:
PGDATA="$HOME/.local/share/sinau/pgdata"
# sekali saja:
initdb -D "$PGDATA" -U lms -A trust -E UTF8
# setiap mulai kerja:
pg_ctl -D "$PGDATA" -l "$PGDATA/pg.log" \
-o "-p 5432 -h 127.0.0.1 -k $PGDATA" start
# sekali saja, setelah instance-nya hidup:
createdb -h 127.0.0.1 -p 5432 -U lms lms
-A trust berarti tanpa password di lokal; DATABASE_URL yang menyertakan
password lms tetap diterima. Menghentikannya:
pg_ctl -D "$PGDATA" stop.
Setelah database siap, muat konfigurasi dan jalankan migrasi:
set -a
source .env
set +a
make migrate-up
Ganti JWT_SECRET dan seluruh credential contoh di .env sebelum digunakan di luar development lokal.
3. Buat akun staff pertama
Atur variabel berikut di .env:
ACCOUNT_EMAIL=admin@pemda.go.id
ACCOUNT_DISPLAY_NAME=Administrator SINAU
ACCOUNT_ROLE=admin
ACCOUNT_PASSWORD=replace-with-a-strong-password
Kemudian jalankan:
make create-account
ACCOUNT_ROLE menerima nilai admin atau instructor. Perintah ini hanya diperlukan untuk admin pertama pada database kosong — akun staff berikutnya dibuat admin melalui halaman Akun di aplikasi dan aktif lewat activation link. Participant mendaftar sendiri di halaman /signup; admin juga bisa mendaftarkan satu peserta dari halaman Peserta ketika pendaftarannya bersifat penugasan resmi (docs/account-management.md).
Untuk development lokal, akun admin yang biasa dipakai:
Email : admin@example.go.id
Password : RahasiaAdmin123!
Akun ini hanya ada di database lokal masing-masing — buat dengan make create-account menggunakan nilai di atas. Jangan gunakan credential ini di luar development.
4. Jalankan backend
go run ./cmd/server
Backend tersedia di http://localhost:8080 dan health check di http://localhost:8080/health.
5. Jalankan frontend
Pada terminal lain (pengguna Nix: masuk nix develop path:. dulu):
cd web
npm install
npm run dev
Frontend tersedia di http://localhost:5173.
Konfigurasi
| Variable | Kegunaan |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
JWT_SECRET |
Secret minimal 32 karakter untuk signing JWT |
HTTP_ADDR |
Alamat backend, default :8080 |
WEB_ORIGIN |
Origin frontend untuk CORS |
PUBLIC_BASE_URL |
Tujuan QR verifikasi pada sertifikat. Kosong berarti mengikuti WEB_ORIGIN |
UPLOAD_DIR |
Direktori penyimpanan video dan sertifikat |
WEB_DIST_DIR |
Direktori hasil build frontend. Kosong di development |
ACTIVATION_BASE_URL |
URL halaman aktivasi frontend |
SETTINGS_ENCRYPTION_KEY |
Passphrase minimal 32 karakter untuk mengenkripsi rahasia yang disimpan dari halaman Pengaturan (kata sandi SMTP) |
ACCOUNT_* |
Input sementara untuk CLI pembuatan staff |
Lihat .env.example untuk contoh lengkap.
Verifikasi
Jalankan dari shell yang berisi toolchain di atas:
make check
Perintah tersebut menjalankan:
- pemeriksaan nama package terlarang (
make check-layout) - pemeriksaan versi toolchain (
make check-toolchain) - pemeriksaan konsistensi versi rilis (
make check-version) go vet ./...golangci-lint rungo test ./...- ESLint
- TypeScript typecheck
- Vitest
- Vite production build
Formatting dipisahkan dari verification karena mengubah source:
make fmt
Build untuk Deployment
make build
Menghasilkan dua artifact di satu direktori:
bin/
├── server # binary Go, tanpa runtime dependency di host
└── dist/ # hasil vite build
Di server, arahkan WEB_DIST_DIR ke dist tersebut. Server API menyajikan
frontend sekaligus, jadi tidak ada web server tambahan yang perlu dipasang —
alasannya di ADR 010.
Deployment membutuhkan tiga hal: isi bin/, direktori migrations/ untuk
goose, dan environment variable pada tabel di atas. UPLOAD_DIR harus
persisten karena video dan sertifikat tersimpan di filesystem.
Perhatikan: bin/server dan bin/dist adalah artifact terpisah dan bisa
tidak sinkron. Backend baru dengan frontend lama tetap berjalan tanpa keluhan,
dan gejalanya menyerupai bug aplikasi. Salin bin/ sebagai satu kesatuan.
bin/VERSION dan bin/COMMIT mencatat identitas paket tersebut; endpoint
/health melaporkan nilai yang sama dari binary server.
Versioning dan Rilis
Backend, frontend, migrasi, dan paket deployment memakai satu Semantic Version
dari file VERSION. Perubahan versi dilakukan ketika menyiapkan
rilis dari master, bukan untuk setiap commit atau merge. Tag Git beranotasi
v<version> menandai rilis resmi dan memicu workflow pembentukan artifact.
Prosedur pemilihan versi, release commit, validasi, tagging, dan publikasinya ada di docs/releasing.md.
Continuous Integration
make check dijalankan otomatis pada setiap push dan pull request
melalui Forgejo Actions (.forgejo/workflows/check.yml). CI tidak memakai
Nix flake dan menetapkan versi toolchain-nya sendiri — alasannya di
ADR 009.
Dokumentasi
- Account management — pengelolaan akun lintas role: pembuatan staff, aktif/nonaktif, tautan reset.
- Training lifecycle — jendela tanggal, publikasi, arsip, mode enrollment, dan aturan penyelesaian.
- Uploaded files — isi
UPLOAD_DIR, konsekuensinya untuk backup, dan penyapu gambar yatim. - Release procedure — aturan versi, changelog, tag, dan artifact rilis.
- Architecture Decision Records — alasan keputusan arsitektur.
- Open questions — keputusan produk yang masih dijawab oleh default, bukan oleh stakeholder.
- Frontend design system — identitas dan bahasa visual Ruang Sinau.
- Pages and roles — inventaris halaman dan matriks peran × halaman.
- Participant flow — alur learning portal.
- Admin/instructor flow — alur management workspace.
- Wireframes — hierarki dan responsive layout.
Status
Ruang Sinau saat ini merupakan MVP fungsional. Integrasi object storage, email delivery, dan SSO/LDAP disiapkan sebagai pengembangan berikutnya.