Ikhtisar & Stack Teknologi
Selamat datang di portal spesifikasi teknis platform tryout komputer basis web (CBT) Triton Denpasar. Dokumentasi ini disusun sebagai manual lengkap untuk maintainer, arsitek sistem, dan pengembang baru.
Platform Triton Denpasar adalah sistem Computer Based Test (CBT) modern yang dioptimalkan untuk meminimalkan kecurangan ujian. Platform ini membagi data operasional tryout berdasarkan tiga jenjang sekolah (**SD, SMP, SMA**) menggunakan arsitektur microservices terisolasi (database per-jenjang terpisah) dengan satu entry-point gateway yang aman.
Core Technology Stack
Next.js 14 App Router
Ditulis menggunakan TypeScript dan Tailwind CSS. Menggunakan KaTeX / React-KaTeX untuk render formula matematika kompleks secara instan pada browser client.
Express.js Microservices
Terdiri atas 6 layanan node terpisah yang berkomunikasi menggunakan API RESTful, terikat dengan validasi skema runtime masukan ketat menggunakan pustaka Zod.
PostgreSQL & Redis
Pemisahan data multi-database PostgreSQL untuk isolasi level sekolah. Redis digunakan oleh `auth-service` untuk manajemen penyimpanan session cookie (`express-session`).
Pemetaan Port Layanan Lokal
| Port | Nama Layanan | Database PostgreSQL | Tanggung Jawab Utama |
|---|---|---|---|
| 4000 | api-gateway | - | Single Entry Point, routing proxy (menggunakan http-proxy-middleware), verifikasi cookie session. |
| 4001 | auth-service | db_auth | Autentikasi kredensial (bcrypt hash), registrasi pengguna, manajemen session-state cookie dan integrasi Redis. |
| 4002 | user-service | db_user | Manajemen data profil pengguna lengkap (Guru/Siswa), master data registrasi kelas & mapel, serta pencatatan audit log platform. |
| 4005 | sd-service | db_sd | Bank Soal & Tryout, runner ujian CBT, serta kalkulasi nilai ujian otomatis khusus jenjang SD (Sekolah Dasar). |
| 4006 | smp-service | db_smp | Bank Soal & Tryout, runner ujian CBT, serta kalkulasi nilai ujian otomatis khusus jenjang SMP (Sekolah Menengah Pertama). |
| 4007 | sma-service | db_sma | Bank Soal & Tryout, runner ujian CBT, serta kalkulasi nilai ujian otomatis khusus jenjang SMA (Sekolah Menengah Atas). |
| 3000 | frontend | - | User interface client Next.js (Dashboard Admin, Guru, Siswa, dan Exam Room). |
Visualisasi Arsitektur Aliran Data
[ Next.js Frontend Client (Port 3000) ]
│
▼ (Request HTTP API)
[ API Gateway (Port 4000) ]
── Auth Verifikasi cookie triton.sid via Port 4001
── Injeksi HTTP headers: x-user-id, x-user-role, x-user-class
│
┌─────────┼─────────┬──────────────────────┐
▼ ▼ ▼ ▼
[auth-serv] [user-serv] [sd-serv] [sma-serv]
Port 4001 Port 4002 Port 4005 ... Port 4007
│ │ │ │
(Redis) │ │ │
Session cache ▼ ▼ ▼
db_user db_sd db_sma
(Postgres) (Postgres) (Postgres)
Setup & Instalasi Lokal
Ikuti instruksi di bawah ini untuk menginstal seluruh repositori dan menjalankan platform tryout Triton di komputer lokal Anda dari awal.
Syarat Instalasi (Prerequisites)
Pastikan komputer pengembang Anda telah terinstal perkakas berikut:
- Node.js v18.0 atau lebih tinggi
- Docker & Docker Compose (untuk PostgreSQL dan Redis lokal)
- GNU Make (untuk mempermudah command pipeline)
1. Salin File Environment Variables
Salin file template `.env` pada folder root proyek. File `.env` ini mendefinisikan koneksi database lokal dan pemetaan URL mikro.
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=triton_user
POSTGRES_PASSWORD=triton_secret_2024
REDIS_HOST=localhost
REDIS_PORT=6379
SESSION_SECRET=triton_session_super_secret_change_me_in_prod
SESSION_MAX_AGE_MS=28800000
AUTH_SERVICE_URL=http://localhost:4001
USER_SERVICE_URL=http://localhost:4002
SD_SERVICE_URL=http://localhost:4005
SMP_SERVICE_URL=http://localhost:4006
SMA_SERVICE_URL=http://localhost:4007
NEXT_PUBLIC_API_URL=http://localhost:4000
FRONTEND_URL=http://localhost:3000
2. Pipeline Perintah CLI (Makefile)
Gunakan file `Makefile` di root proyek untuk mengautomasi seluruh fase instalasi:
Menginstal dependencies untuk semua layanan backend & frontend Next.js.
Menjalankan container PostgreSQL & Redis di latar belakang menggunakan Docker Compose.
Melakukan inisialisasi skema tabel database dan mengisi data master awal (Seed data).
Menjalankan 6 Express microservices & Next.js frontend secara bersamaan dalam mode live reload.
Menghentikan seluruh microservices lokal dan mematikan container Docker.
Alur Kerja Logika Peran & Sistem
Spesifikasi detail mengenai hak akses, dashboard routing, workflow persetujuan soal, engine pengacakan CBT, serta sistem proteksi kecurangan.
1. Alur Kerja Peran Admin
Admin bertugas memantau seluruh ekosistem tryout, melakukan manajemen akun, serta melakukan verifikasi akhir kelayakan tryout:
- Login System: Mengakses `/login` ➔ dialihkan otomatis ke `/admin/dashboard`.
- Dashboard & Filtering: Menampilkan statistik jumlah guru, siswa, tryout aktif, dan session. Admin dibekali tab filter sekolah **(SD, SMP, SMA)** di mana ketika diklik, data tabel Siswa dan Tryout di dashboard terfilter secara real-time, namun data Guru tidak terfilter (Guru tetap tampil menyeluruh).
- Alur Persetujuan (Approval): Pada card Tryout di dashboard Admin, terdapat link
"Lihat semua" yang akan membawa Admin langsung ke halaman **Approval / Persetujuan**. Di
halaman ini, Admin dapat meninjau detail draf soal satu-persatu (bukan sekadar tolak/setuju buta) untuk
memberikan keputusan:
- Setujui (Approve): Mengubah status tryout menjadi `approved`.
- Tolak dengan Catatan (Reject): Memberikan feedback perbaikan tertulis di field `revision_notes` dan status tryout menjadi `rejected`.
- Manajemen Pengguna: Admin dapat membuat, mengedit, menghapus, atau menonaktifkan akun Guru (`/admin/users?role=guru`) dan Siswa (`/admin/users?role=siswa`) secara dinamis.
- Superuser Logs Monitor: Mengakses panel `/admin/logs` untuk memantau audit trail audit logging yang tersimpan di sistem.
2. Alur Kerja Peran Guru (Pembuatan & Pengelolaan Ujian)
Guru memiliki tanggung jawab mengelola pustaka materi dan membuat soal ujian tryout:
- Login System: Login di `/login` ➔ diarahkan ke `/guru/dashboard`.
- Workflow Tryout Builder: Klik **"Buat Tryout Baru"** dialog ➔ input Nama Tryout, Mapel,
Kelas, Durasi, serta opsi pengacakan ➔ dikirim lewat `POST /tryouts`.
TRN-05: Tombol Batal / Kembali pada form pembuatan tryout akan langsung mengembalikan Guru ke Dashboard Utama tanpa jeda. - Manajemen Pembuatan Soal:
- Metode Manual: Menulis teks pertanyaan, opsi jawaban A-E, kunci jawaban yang benar, serta bobot soal. Mendukung sintaks formula LaTeX yang diapit tanda `$$` (contoh: `$$f(x) = x^2$$`).
- Import MS Word (.docx): Mengunggah template berkas dokumen Word dengan aturan parser parser yang ketat (format ada di tab selanjutnya).
- Generator Soal AI: Memilih kuantitas soal untuk secara instan men-generate soal-soal tryout siap pakai berbasis AI.
- Pengajuan & Siklus Approval: Setelah soal dirasa lengkap, Guru menekan tombol **"Ajukan Persetujuan (Submit for Approval)"** yang mengubah status tryout menjadi `pending_approval` ➔ Menunggu ACC Admin. Jika status menjadi `rejected` (ditolak), Guru dapat membaca field `revision_notes`, memperbaikinya, dan mengajukan ulang. Setelah mendapat status `approved`, Guru (atau Admin) dapat menekan tombol **"Publish"** untuk merilis ujian.
3. Alur Kerja Peran Siswa (Computer Based Test)
Siswa bertindak sebagai peserta tes tryout dengan mekanisme proteksi ujian yang ketat:
- Akses Tryout Terkunci Jenjang: Siswa login di `/login` ➔ diarahkan ke `/siswa/dashboard`. Siswa hanya diizinkan melihat daftar tryout yang relevan berdasarkan level edukasi mereka (`profiles.education_level` = SD/SMP/SMA) dan tingkat kelasnya.
- Akses Cepat Tautan Sesi (Share Link): Admin/Guru dapat membagikan tautan sesi tryout. Ketika Siswa membuka tautan tersebut, sistem secara otomatis mengecek autentikasi; jika belum masuk, Siswa diminta login dan secara instan langsung diarahkan ke halaman mulai ujian tryout tersebut (auto redirect).
- Mulai Ujian & Engine Pengacakan: Saat ujian dimulai (`POST /sesi`), sistem akan
mengecek parameter tryout. Jika pengacakan aktif:
- Randomize Questions: Urutan soal diacak secara dinamis menggunakan algoritme Fisher-Yates shuffle dan disimpan di kolom array `sesi_tryout.question_order` agar konsisten jika browser di-refresh.
- Randomize Options: Urutan pilihan jawaban (A, B, C, D, E) diacak secara deterministik per siswa dan disimpan di field JSONB `sesi_tryout.option_order`.
- Sistem Proteksi Kecurangan (Anti-Cheating):
// Implementasi Proctoring Engine pada Client-Side:
1. Fullscreen Lock: Memaksa halaman ujian berjalan dalam Fullscreen API. Jika siswa keluar dari fullscreen, dialog peringatan pengunci muncul menutupi seluruh layar ujian.
2. Tab Switch Detection (Visibility Change): Mendeteksi perpindahan tab browser. Setiap kejadian tab tidak aktif akan memicu log peringatan kecurangan.
3. Window Blur Focus Check: Mendeteksi saat kursor keluar dari jendela browser (kehilangan fokus window).
4. Copy-Paste Restrictions: Menonaktifkan total fungsi keyboard: Copy (Ctrl+C), Cut (Ctrl+X), Paste (Ctrl+V), klik kanan mouse (contextmenu), serta blok seleksi teks bebas.
5. Auto-Submit Warning: Jika jumlah pelanggaran kecurangan terdeteksi melampaui ambang batas maksimum, sistem akan memicu auto-submit paksa sesi tryout siswa saat itu juga.
- Penyimpanan Otomatis (Auto-Save): Setiap opsi atau jawaban essay yang dipilih/ditik oleh siswa dikirim langsung melalui `POST /sesi/:id/jawab` ke database secara asinkron untuk mengantisipasi mati listrik atau kegagalan perangkat komputer.
- Hasil Ujian: Setelah tryout dikumpulkan atau waktu habis, skor dihitung otomatis. Hasil ditampilkan di `/siswa/hasil/:sesiId` dengan styling kontras tinggi (skor dan grade A/B/C/D jelas dibaca).
Skema Database Lengkap & Spesifik
Struktur fisik relasional lengkap dari database yang terbagi pada microservices Triton. Database menggunakan PostgreSQL.
db_auth
Database ini dikelola oleh `auth-service`. Digunakan untuk mencatat data user kredensial dasar dan hak akses platform.
Tabel: users
| Field | Tipe Data | Constraints | Keterangan |
|---|---|---|---|
| id | UUID | PRIMARY KEY, DEFAULT gen_random_uuid() | ID unik internal user. |
| VARCHAR(255) | UNIQUE, NOT NULL | Alamat email login platform. | |
| password_hash | VARCHAR(255) | NOT NULL | Hasil hash password bcrypt (cost factor: 12). |
| role | VARCHAR(20) | NOT NULL, CHECK (role IN ('admin','guru','siswa')) | Hak akses peran user di platform. |
| is_active | BOOLEAN | DEFAULT true | Status aktif akun (aktif/suspend). |
| created_at | TIMESTAMPTZ | DEFAULT NOW() | Tanggal akun pertama kali terdaftar. |
| updated_at | TIMESTAMPTZ | DEFAULT NOW() | Tanggal pembaharuan status akun. |
db_user
Database yang dikelola oleh `user-service`. Menyimpan data profil lengkap, data master referensi sekolah, serta log aktivitas audit trail.
Tabel: profiles
| Field | Tipe Data | Constraints | Keterangan |
|---|---|---|---|
| id | UUID | PRIMARY KEY, DEFAULT gen_random_uuid() | ID profile unik. |
| user_id | UUID | UNIQUE, NOT NULL | Referensi user key ke `db_auth.users.id`. |
| nama_lengkap | VARCHAR(255) | NOT NULL | Nama lengkap pengguna. |
| no_telepon | VARCHAR(20) | - | Nomor kontak telepon / WhatsApp. |
| kelas | VARCHAR(50) | - | Kelas (contoh: 'XII-IPA-1', 'VI-A'). Khusus Siswa. |
| mata_pelajaran | VARCHAR(255) | - | Mata pelajaran yang diajarkan (koma terpisah). Khusus Guru. |
| education_level | VARCHAR(10) | CHECK (education_level IN ('SD','SMP','SMA')) | Level filter utama validasi kecocokan tryout jenjang siswa. |
| avatar_url | TEXT | - | Tautan gambar avatar profil. |
| bio | TEXT | - | Deskripsi biografi singkat user. |
Tabel: master_kelas
| Field | Tipe | Constraints |
|---|---|---|
| id | UUID | PK |
| nama | VARCHAR(50) | UNIQUE, NOT NULL |
| level | VARCHAR(10) | CHECK (level IN ('SD','SMP','SMA')) |
Tabel: master_mata_pelajaran
| Field | Tipe | Constraints |
|---|---|---|
| id | UUID | PK |
| nama | VARCHAR(100) | UNIQUE, NOT NULL |
| level | VARCHAR(10) | CHECK (level IN ('SD','SMP','SMA')) |
Tabel: audit_logs
| Field | Tipe Data | Constraint / Index | Deskripsi Audit |
|---|---|---|---|
| id | UUID | PRIMARY KEY | ID log unik. |
| user_id | UUID | - | Pihak pembuat aksi (dapat NULL jika gagal login). |
| VARCHAR(255) | NOT NULL, INDEX (email) | Email aktor pelaku. | |
| role | VARCHAR(20) | NOT NULL | Role aktor ('admin' | 'guru' | 'siswa' | 'system'). |
| action | VARCHAR(100) | NOT NULL | Nama aksi (contoh: `AUTH_LOGIN_SUCCESS`, `TRYOUT_PUBLISH`). |
| target_id | UUID | - | Entity ID yang terkena dampak CRUD (siswa/tryout/session). |
| description | TEXT | NOT NULL | Rincian deskripsi teks log aktivitas audit. |
| ip_address | VARCHAR(50) | - | IP Address client yang memicu aksi. |
| user_agent | TEXT | - | User-agent browser client pengakses. |
| created_at | TIMESTAMPTZ | INDEX (created_at DESC) | Waktu kejadian log dicatat. |
db_sd / db_smp / db_sma
Database level-spesifik terisolasi yang menampung bank soal, draf persetujuan tryout, sesi ujian CBT peserta, auto-save jawaban, dan nilai akhir tryout.
Tabel: tryouts
Core tryout entity| Field | Tipe Data | Constraints | Keterangan |
|---|---|---|---|
| id | UUID | PRIMARY KEY, DEFAULT gen_random_uuid() | ID unik tryout. |
| nama_tryout | VARCHAR(255) | NOT NULL | Nama/judul paket tryout. |
| mata_pelajaran | VARCHAR(100) | NOT NULL | Nama kategori mapel. |
| sub_mata_pelajaran | VARCHAR(100) | - | Sub-kategori bab mapel. |
| kelas | VARCHAR(50) | - | Tingkatan kelas spesifik. |
| durasi_menit | INTEGER | DEFAULT 90 | Durasi pengerjaan dalam satuan menit. |
| dibuat_oleh | UUID | NOT NULL | ID Guru pembuat paket (referensi ke `db_user.profiles.id`). |
| status | VARCHAR(20) | DEFAULT 'draft', CHECK status IN ('draft', 'pending_approval', 'approved', 'rejected', 'published', 'closed') | Status alur kerja verifikasi tryout. |
| revision_notes | TEXT | - | Catatan perbaikan revisi dari Admin. |
| randomize_questions | BOOLEAN | DEFAULT true | Status acak soal untuk pengerjaan siswa. |
| randomize_options | BOOLEAN | DEFAULT true | Status acak opsi pilihan jawaban A-E per siswa. |
Tabel: soal
| Field | Tipe | Constraints |
|---|---|---|
| id | UUID | PRIMARY KEY |
| tryout_id | UUID | REFERENCES tryouts(id) ON DELETE CASCADE |
| nomor_soal | INTEGER | NOT NULL |
| tipe | VARCHAR(20) | CHECK tipe IN ('pilihan_ganda','essay') |
| pertanyaan | TEXT | NOT NULL |
| pertanyaan_html | TEXT | - |
| gambar_url | TEXT | - |
| gambar_base64 | TEXT | - |
| equation_latex | TEXT | Formula matematika LaTeX |
| panduan_essay | TEXT | Rubrik panduan penilaian essay |
| bobot | INTEGER | DEFAULT 1 |
Tabel: opsi_jawaban
| Field | Tipe | Constraints |
|---|---|---|
| id | UUID | PRIMARY KEY |
| soal_id | UUID | REFERENCES soal(id) ON DELETE CASCADE |
| huruf | CHAR(1) | NOT NULL (A, B, C, D, E) |
| teks | TEXT | NOT NULL |
| teks_html | TEXT | - |
| is_benar | BOOLEAN | DEFAULT false |
Tabel Ujian CBT & Penilaian: sesi_tryout, jawaban, hasil
Tabel: sesi_tryout
Mencatat session pengerjaan tryout siswa.
- id: UUID (PK)
- siswa_id: UUID (NOT NULL)
- tryout_id: UUID (NOT NULL)
- mulai_at: TIMESTAMPTZ (NOW())
- selesai_at: TIMESTAMPTZ (NULL)
- status: VARCHAR(20) ('berlangsung', 'selesai', 'timeout')
- question_order: UUID[] (Urutan soal yang diacak)
- option_order: JSONB (Pola acak opsi jawaban)
- Constraint: UNIQUE(siswa_id, tryout_id)
Tabel: jawaban
Auto-save jawaban per butir soal.
- id: UUID (PK)
- sesi_id: UUID (REFERENCES sesi_tryout)
- soal_id: UUID (NOT NULL)
- jawaban_teks: TEXT (Jawaban essay)
- opsi_id: UUID (Opsi terpilih PG)
- created_at: TIMESTAMPTZ
- updated_at: TIMESTAMPTZ
- Constraint: UNIQUE(sesi_id, soal_id)
Tabel: hasil
Skor rekapitulasi nilai akhir ujian.
- id: UUID (PK)
- sesi_id: UUID (UNIQUE, REFERENCES)
- siswa_id: UUID (NOT NULL)
- tryout_id: UUID (NOT NULL)
- total_benar: INTEGER
- total_soal: INTEGER
- nilai: NUMERIC(5,2)
- dihitung_at: TIMESTAMPTZ
API Gateway Endpoints
Semua permintaan luar client harus dikirim melalui port **API Gateway (4000)**. Gateway melakukan routing proxy internal dan verifikasi session cookie `triton.sid`.
Request Body (JSON)
{
"email": "siswa@triton.id",
"password": "password123"
}
Response 200 (Success - Cookie Ditetapkan)
{
"success": true,
"message": "Login berhasil",
"user": {
"id": "180bdfb5-12cf-4b77-83eb-69c5e3157e10",
"email": "siswa@triton.id",
"role": "siswa"
}
}
Response 200 (Success)
{
"success": true,
"user": {
"id": "180bdfb5-12cf-4b77-83eb-69c5e3157e10",
"email": "siswa@triton.id",
"role": "siswa",
"profile": {
"nama_lengkap": "Siswa Budi Utomo",
"kelas": "VI-A",
"education_level": "SD"
}
}
}
Request Body (JSON)
{
"email": "guru.baru@triton.id",
"password": "securedpassword1",
"role": "guru",
"nama_lengkap": "Guru Matematika Baru",
"no_telepon": "081234567890",
"mata_pelajaran": "Matematika",
"education_level": "SMA"
}
Response 201 (Created)
{
"success": true,
"data": {
"user_id": "22ffef9c-ea0e-436f-8a03-75b25ad362c9",
"email": "guru.baru@triton.id",
"role": "guru"
}
}
Request Body (JSON)
{
"tryout_id": "f514b8a2-2cf1-45a7-bc1a-6df26ba9b512"
}
Response 201 (Created / Resumed)
Response mengembalikan tata letak soal teracak (`question_order`) dan detail acak pilihan (`option_order`) yang aman tersimpan di session database:
{
"success": true,
"session": {
"id": "eef7c02b-a8cf-48f5-9be3-c28fa48bb514",
"siswa_id": "180bdfb5-12cf-4b77-83eb-69c5e3157e10",
"tryout_id": "f514b8a2-2cf1-45a7-bc1a-6df26ba9b512",
"status": "berlangsung",
"question_order": [
"soal-uuid-3",
"soal-uuid-1",
"soal-uuid-2"
],
"option_order": {
"soal-uuid-1": ["C", "B", "A", "D"],
"soal-uuid-2": ["D", "A", "C", "B"]
}
}
}
Request Body (JSON)
// Untuk Pilihan Ganda (PG)
{
"soal_id": "soal-uuid-1",
"opsi_id": "opsi-uuid-c"
}
// Untuk Essay
{
"soal_id": "soal-uuid-2",
"jawaban_teks": "Ini adalah uraian jawaban yang ditik siswa."
}
Response 200 (Saved)
{
"success": true,
"message": "Jawaban berhasil disimpan otomatis"
}
Pemeliharaan & Debugging
Panduan praktis bagi tim operasional dan DevOps untuk memonitor log kesehatan aplikasi, membersihkan resource, serta mengatasi kendala runtime.
1. Manajemen Logging & Monitoring
Platform mengarahkan log runtime output ke folder `/logs` lokal. Gunakan Makefile command untuk tailing log:
# Memantau log gabungan semua microservices secara real-time
make logs
# Hanya memantau log yang memicu error / crash
make logs-error
# Menghapus seluruh file logs lokal yang menumpuk
make logs-clean
2. Pembebasan Port yang Terkunci (Port Conflicts)
Jika Anda mengalami kendala kegagalan bind port (EADDRINUSE) saat menjalankan `make dev`, temukan proses PID yang mengunci port dan paksa hentikan:
# Cari PID yang menempati port API Gateway (4000) lsof -i :4000 # Contoh output: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 9876 user 22u IPv6 0x1a2 0t0 TCP *:4000 (LISTEN) # Hentikan proses secara paksa menggunakan PID tersebut kill -9 9876
3. Aturan Syntax Upload Soal Word (.docx)
Format template dokumen harus terstruktur rapi agar dapat diproses oleh parser. Berikut adalah spesifikasi teks dokumen Word:
[SOAL]
Tipe: pilihan_ganda
Bobot: 3
Pertanyaan: Jika nilai dari fungsi kuadrat adalah $$f(x) = x^2 - 4x + 4$$, berapakah nilai $$f(2)$$?
A. -1
*B. 0
C. 1
D. 2
E. 4
// === Contoh Soal Uraian (Essay) dengan Gambar ===
[SOAL]
Tipe: essay
Bobot: 5
Pertanyaan: Tuliskan kesimpulan mekanisme peredaran darah berdasarkan ilustrasi berikut!
[IMAGE_1]
Rubrik: Jawaban benar harus mencakup aliran darah besar (3 point) dan kecil (2 point).
Panduan Deployment Cloud
Panduan lengkap langkah demi langkah untuk melakukan deploy platform Triton ke lingkungan produksi awan (Supabase, Vercel, & Hosting Microservices).
Langkah A: Penyediaan Database PostgreSQL Central di Supabase
1. Buat satu project database utama di konsol admin Supabase.
2. Karena Triton menggunakan 5 database terpisah untuk arsitektur mikro, Anda perlu membuat 5 skema/database
berbeda di Supabase atau menyewa 5 instance project kecil terpisah. Jika menyewa 5 instance terpisah, ambil
masing-masing connection URI string PostgreSQL.
3. Jalankan skema migrasi tabel SQL. Masuk ke panel **SQL Editor** pada masing-masing instance Supabase,
lalu salin dan jalankan isi file `schema.sql` dari folder masing-masing service:
- Jalankan services/user-service/src/db/schema.sql pada DB User
- Jalankan sd/smp/sma-service schemas pada DB SD, SMP, SMA masing-masing.
Langkah B: Deployment Frontend Client di Vercel
1. Hubungkan akun GitHub repositori Triton Anda ke layanan Vercel.
2. Pada konfigurasi project Vercel:
- Atur **Root Directory** ke folder `frontend`.
- Atur **Build Command** ke `npm run build`.
- Atur **Output Directory** ke `.next`.
3. Masukkan Environment Variables produksi pada dashboard setting Vercel:
NEXT_PUBLIC_API_URL=https://gateway.tritondenpasar.com # URL endpoint API Gateway produksi
Langkah C: Hosting Backend Microservices (Railway / Render / VPS)
1. Deploy 6 web service backend (Gateway, Auth, User, SD, SMP, SMA) secara terpisah di platform cloud
pilihan Anda (misal Railway atau Render).
2. Konfigurasikan variabel lingkungan produksi pada masing-masing web service:
# Contoh Variabel Lingkungan Produksi untuk Service Level (contoh: sd-service) POSTGRES_HOST=aws-0-ap-southeast-3.pooler.supabase.com POSTGRES_PORT=5432 POSTGRES_USER=postgres.your_project_id POSTGRES_PASSWORD=your_secure_supabase_password POSTGRES_DB=db_sd USER_SERVICE_URL=https://user-service-production.up.railway.app PORT=4005
3. Pada `api-gateway` produksi, pastikan seluruh variabel URL rute service mengarah ke domain production url masing-masing backend service yang sudah menyala.