Files
web-antrean/docs/PRD.md
T

19 KiB
Raw Blame History

📋 PRD — Product Requirements Document

Project: Web Antrean — Sistem Manajemen Antrean Rawat Jalan RSSA Version: 1.0.0 Status: In Review Author: Akbar Stack: JavaScript · Vue 3 · TypeScript · Nuxt 3 · Vuetify 3 · Pinia Last Updated: 2026-05-25


🧠 AI Prompt — Cara Menggunakan Dokumen Ini

Salin prompt berikut ke Claude / ChatGPT untuk membantu melanjutkan PRD:

Kamu adalah product manager senior. Bantu aku mengembangkan PRD untuk project berikut:
- Nama project: Web Antrean — Sistem Manajemen Antrean Rawat Jalan RSSA
- Tujuan utama: Digitalisasi alur antrean pasien rawat jalan di rumah sakit
- Target pengguna: Pasien, Admin Loket, Admin Klinik, Admin Penunjang, Superadmin
- Tech stack: Nuxt 3, Vue 3, TypeScript, Vuetify 3, Pinia, WebSocket, Keycloak SSO

Buatkan:
1. Problem statement yang tajam
2. User stories tambahan dengan acceptance criteria
3. Risiko teknis dan mitigasinya

Format output dalam Markdown.

1. Overview

1.1 Executive Summary

Web Antrean adalah aplikasi manajemen antrean rawat jalan berbasis web yang dibangun untuk Rumah Sakit RSSA. Sistem ini mendigitalisasi seluruh alur antrean pasien mulai dari pendaftaran via anjungan mandiri, pemanggilan pasien di loket dan klinik, hingga monitoring real-time oleh administrator. Aplikasi ini kritis karena menggantikan sistem antrean manual yang tidak efisien dan rawan error.

1.2 Problem Statement

Rumah Sakit RSSA menghadapi masalah antrean rawat jalan yang tidak terstruktur: pasien tidak mengetahui posisi antrean mereka, petugas loket kesulitan mengelola urutan panggil, dan tidak ada visibilitas real-time lintas unit (loket, klinik, penunjang). Kondisi ini menyebabkan penumpukan pasien, waktu tunggu tidak terprediksi, dan pengalaman buruk bagi pasien.

1.3 Goals & Success Metrics

# Goal Metrik Target
1 Mengurangi waktu tunggu pasien Rata-rata waktu tunggu per sesi < 30 menit
2 Digitalisasi antrean loket & klinik % proses antrean via sistem 100%
3 Real-time sync antar perangkat Latensi update antrean via WebSocket < 2 detik
4 Kemandirian pasien dalam ambil antrean % pasien gunakan anjungan mandiri > 80%
5 Stabilitas sistem Uptime saat jam operasional > 99.5%

1.4 Non-Goals (Out of Scope)

  • Integrasi dengan sistem pembayaran / billing
  • Manajemen rekam medis (EMR)
  • Aplikasi mobile native (iOS/Android)
  • Antrean rawat inap (ranap) — fitur ranap admin tersedia tapi belum final
  • Sistem appointment/penjadwalan janji temu online

2. Stakeholders

Role Nama Tanggung Jawab
Product Owner Tim RSSA Prioritas fitur & validasi kebutuhan
Fullstack Engineer Akbar Arsitektur, implementasi, & deployment
UI/UX Designer Desain antarmuka (dikerjakan oleh engineer)
QA Engineer Pengujian via Cypress & Vitest
System Admin Tim IT RSSA Infrastruktur, server, & jaringan internal

3. User Personas

🧑 Persona 1: Pasien Rawat Jalan

  • Goals: Mendapatkan nomor antrean dengan mudah, mengetahui posisi antrean, dan dipanggil tepat waktu
  • Pain Points: Tidak tahu urutan antrean, harus menunggu tanpa informasi, bingung harus ke mana
  • Tech Level: Rendah — menggunakan anjungan layar sentuh di rumah sakit

🧑 Persona 2: Petugas Loket

  • Goals: Memanggil pasien secara urut, memproses lebih dari satu loket secara paralel, melihat daftar antrean real-time
  • Pain Points: Antrean manual rawan konflik antar loket, sulit pantau siapa yang sudah dipanggil
  • Tech Level: Menengah — menggunakan PC/tablet di meja loket

🧑 Persona 3: Admin Klinik / Dokter

  • Goals: Melihat daftar pasien yang akan dilayani di kliniknya, memanggil pasien sesuai urutan, mencatat status kunjungan
  • Pain Points: Tidak tahu berapa pasien tersisa, data pasien tidak sinkron antar perangkat
  • Tech Level: Menengah

🧑 Persona 4: Superadmin / Admin IT

  • Goals: Mengelola master data (klinik, loket, penunjang, screen), mengatur hak akses user, memonitor seluruh antrean
  • Pain Points: Tidak ada dashboard terpusat, perubahan konfigurasi butuh restart sistem
  • Tech Level: Tinggi

4. User Stories

ID Epic Story Priority Acceptance Criteria Status
US-001 Anjungan Sebagai pasien, saya ingin mengambil nomor antrean via anjungan mandiri agar tidak perlu antri ke loket 🔴 High - [ ] Pasien dapat memilih klinik tujuan
- [ ] Sistem generate nomor antrean unik
- [ ] Tiket dicetak atau ditampilkan di layar
Done
US-002 Anjungan Sebagai pasien eksekutif, saya ingin memilih sub-spesialis di anjungan agar antrean sesuai dokter yang dituju 🔴 High - [ ] Daftar subspesialis tampil berdasarkan klinik
- [ ] Pilihan tersimpan ke nomor antrean
Done
US-003 Check-in Sebagai pasien, saya ingin check-in via scan QR agar kedatangan saya tercatat di sistem 🔴 High - [ ] QR scanner aktif via kamera
- [ ] Status pasien berubah menjadi "hadir"
- [ ] Notifikasi berhasil muncul
Done
US-004 Loket Sebagai petugas loket, saya ingin memanggil pasien berikutnya agar antrean berjalan terurut 🔴 High - [ ] Tombol "Panggil Berikutnya" tersedia
- [ ] Nomor antrean tampil di display screen
- [ ] Sync real-time via WebSocket
Done
US-005 Klinik Sebagai admin klinik, saya ingin melihat daftar pasien yang akan dilayani agar saya bisa mempersiapkan pelayanan 🔴 High - [ ] Daftar pasien tampil dengan status terkini
- [ ] Update otomatis tanpa refresh manual
Done
US-006 Monitoring Sebagai superadmin, saya ingin melihat dashboard antrean seluruh unit agar dapat memantau kondisi operasional 🟡 Medium - [ ] Statistik antrean per unit tersedia
- [ ] Data diperbarui real-time
Done
US-007 Setting Sebagai superadmin, saya ingin mengatur hak akses per user/group agar keamanan data terjaga 🟡 Medium - [ ] CRUD hak akses per role & group Keycloak
- [ ] Perubahan langsung efektif tanpa restart
Done
US-008 Penunjang Sebagai admin penunjang, saya ingin mengelola antrean unit penunjang (lab, radiologi) agar terpisah dari antrean klinik 🟡 Medium - [ ] Antrean penunjang terpisah per unit
- [ ] Admin hanya melihat unit penunjangnya
In Progress

5. Functional Requirements

5.1 Modul: Anjungan Mandiri

  • FR-01: Pasien dapat memilih klinik tujuan dari daftar klinik aktif
  • FR-02: Sistem mengenerate nomor antrean berformat [KodeKlinik]-[Nomor] (contoh: PDL-001)
  • FR-03: Anjungan mendukung pilihan subspesialis untuk klinik eksekutif
  • FR-04: Tiket antrean dapat dicetak via thermal printer
  • FR-05: Anjungan dapat dikonfigurasi per tipe (klinik, penunjang, klinik ruang)

5.2 Modul: Check-in Pasien

  • FR-06: Pasien dapat check-in mandiri via scan QR code
  • FR-07: Sistem memvalidasi QR dan mengupdate status kunjungan ke "hadir"
  • FR-08: Riwayat check-in pasien dapat dilihat oleh petugas

5.3 Modul: Loket

  • FR-09: Petugas loket dapat memanggil pasien berikutnya sesuai urutan antrean
  • FR-10: Setiap loket memiliki state antrean yang terisolasi (tidak interferensi antar loket)
  • FR-11: Petugas dapat skip, recall, atau selesaikan pasien
  • FR-12: Display nomor panggil sinkron via WebSocket ke layar display
  • FR-12b: Pemanggilan antrean dilengkapi dengan notifikasi suara (voice over) otomatis

5.4 Modul: Klinik / Dokter

  • FR-13: Admin klinik melihat daftar pasien berdasarkan klinik yang diampu
  • FR-14: Status pasien (menunggu, dipanggil, selesai) dapat diupdate
  • FR-15: Pemanggilan pasien di klinik sync ke display screen ruangan

5.5 Modul: Dashboard & Monitoring

  • FR-16: Dashboard menampilkan statistik antrean real-time (total, menunggu, selesai)
  • FR-17: Superadmin dapat melihat data seluruh unit sekaligus
  • FR-18: Data diperbarui via WebSocket + polling fallback 30 detik

5.6 Modul: Setting & Master Data

  • FR-19: CRUD Master Klinik, Loket, Penunjang, Klinik Ruang, Screen
  • FR-20: Manajemen hak akses berbasis Keycloak role & group
  • FR-21: Konfigurasi screen display untuk setiap loket/klinik
  • FR-22: Manajemen user login dan sesi

5.7 Modul: Penunjang

  • FR-23: Antrean unit penunjang (lab, radiologi, dll) dikelola terpisah
  • FR-24: Admin penunjang hanya mengakses unit yang menjadi tanggung jawabnya

6. Non-Functional Requirements

Kategori Requirement Target
Performance WebSocket latency update antrean < 2 detik
Performance Waktu load halaman utama < 3 detik
Performance Polling fallback interval 30 detik
Security Auth method Keycloak SSO (OAuth 2.0 / OIDC)
Security Session duration 1 jam (configurable)
Security Hak akses berbasis role & group Role-Based + Group-Based
Availability Uptime jam operasional (06.0021.00) > 99.5%
Accessibility Anjungan — touch target size > 44px (mudah dioperasikan pasien)
Scalability Jumlah koneksi WebSocket simultan > 50 device sekaligus
Compatibility Browser support Chrome, Edge (terbaru)
Network Operasi di jaringan LAN internal RS Fully LAN-based

7. Technical Specifications

7.1 Tech Stack

Layer Teknologi
Frontend Framework Nuxt 3 (SSR — server-side rendering)
UI Framework Vue 3 · Vuetify 3
Language TypeScript · JavaScript
State Management Pinia + pinia-plugin-persistedstate
Styling SCSS (Vuetify override) + Material Design Icons
Real-time WebSocket (native browser API via useWebSocket.ts)
Auth Keycloak SSO (OAuth 2.0 / OIDC)
Charts Chart.js · vue-chartjs · nuxt-charts
QR html5-qrcode (scanner) · qrcode.vue (generator)
Print Thermal printer via useThermalPrint.ts
Date Day.js
Icons FontAwesome · Material Design Icons
Testing Vitest · Cypress
Fonts Inter (Google Fonts)

7.2 Backend APIs (Eksternal)

Service Base URL Keterangan
Visit API http://10.10.123.135:8084/api/v1 Data kunjungan & antrean utama
Antrian API (Klinik) http://10.10.123.140:8089/api/v1 Verifikasi & data klinik/dokter
WebSocket ws://10.10.123.135:8084/api/v1/ws Real-time queue update

7.3 Arsitektur Sistem

┌─────────────────────────────────────────────┐
│         Nuxt 3 Frontend (SSR/CSR)            │
│  Pages · Components · Stores (Pinia)         │
│  Composables: useWebSocket · useQueue ·      │
│  useCheckIn · useThermalPrint · useQRScanner │
└──────────┬──────────────────┬────────────────┘
           │ $fetch / useFetch │ WebSocket
┌──────────▼──────────┐  ┌────▼───────────────┐
│  Nuxt Server (Nitro) │  │   WebSocket Server  │
│  server/api/         │  │   ws://10.10.123.   │
│  server/routes/      │  │   135:8084/api/v1/ws│
│  (Proxy + API layer) │  └────────────────────┘
└──────────┬──────────┘
           │ HTTP Proxy (CORS bypass)
┌──────────▼──────────────────────────────────┐
│           Backend Services (Eksternal)        │
│  Visit API (8084) · Antrian API (8089)        │
│  Keycloak SSO (auth.rssa.top)                 │
└─────────────────────────────────────────────┘

7.4 Proxy Routes (Nuxt Server)

Proxy Path Target Backend Keterangan
/visit-api/** http://10.10.123.135:8084/api/v1/** Data kunjungan pasien
/klinik-api/** http://10.10.123.140:8089/api/v1/** Data klinik & dokter
/stats-api/** http://10.10.123.135:8084/api/v1/** Statistik dashboard

7.5 Struktur Folder

web-antrean/
├── assets/scss/         ← Global styles & variables
├── components/          ← Reusable UI components
├── composables/         ← useWebSocket, useQueue, useCheckIn,
│                           useThermalPrint, useQRScanner, useAPI
├── layouts/             ← Layout default & admin
├── middleware/          ← Auth & permission guards
├── pages/               ← Semua halaman (lihat seksi 8.1)
├── server/
│   ├── api/             ← Internal API (auth, hak-akses, queue, users)
│   └── routes/          ← Proxy routes (visit-api, klinik-api, stats-api)
├── stores/              ← Pinia stores (queue, clinic, loket, dll)
├── types/               ← TypeScript interfaces & types
├── public/              ← Static assets (favicon, logo)
├── nuxt.config.ts       ← Konfigurasi utama Nuxt
└── .env                 ← Environment variables (tidak di-commit)

7.6 Internal API Endpoints (Nuxt Nitro)

Method Endpoint Deskripsi Auth
GET /api/permission Ambil permissions berdasarkan role & group
GET /api/hak-akses Daftar semua hak akses
POST /api/hak-akses Buat hak akses baru
PATCH /api/hak-akses/:id Update hak akses
DELETE /api/hak-akses/:id Hapus hak akses
GET /api/users/list Daftar user dari Keycloak
POST /api/auth/login Login via Keycloak SSO
POST /api/auth/logout Logout & invalidate session
POST /api/external/validate-token Validasi JWT token eksternal
GET /api/config/... Konfigurasi aplikasi

7.7 TypeScript Types Utama

// types/user.ts
export interface User {
  id: string
  namaLengkap: string
  namaUser: string
  email: string
  tipeUser: string
  roles: string[]
  groups: string[]
  lastLogin: number
  createdAt: number
}

// types/queue.ts
export interface QueuePatient {
  nomorAntrean: string
  namaPassien: string
  noRM: string
  klinik: string
  status: 'menunggu' | 'dipanggil' | 'selesai' | 'skip'
  loketId?: string
  subspesialis?: string
  createdAt: Date
}

// types/permission.ts
export interface Permission {
  id: number
  pagename: string
  read: boolean
  create: boolean
  update: boolean
  delete: boolean
  disable: boolean
  active: boolean
  level: number
  parent: number | null
}

// types/api.ts
export interface ApiResponse<T> {
  data: T
  message: string
  success: boolean
}

8. UI/UX

8.1 Halaman & Routes

Halaman Route Auth Role
Landing / Home / Public
Login /login-page Public
Dashboard /dashboard Superadmin
Admin Klinik /admin-klinik Admin Klinik
Admin Loket /admin-loket Admin Loket
Admin Penunjang /admin-penunjang Admin Penunjang
Buat Antrean /buat-antrean Loket
Klinik Ruang Admin /klinik-ruang-admin Admin Klinik Ruang
Ranap Admin /ranap-admin Admin Ranap
Anjungan Utama /anjungan Kiosk
Admin Anjungan /anjungan/admin-anjungan Superadmin
Antrian Klinik /anjungan/antrian-klinik Kiosk
Antrian Klinik Ruang /anjungan/antrian-klinik-ruang Kiosk
Antrian Penunjang /anjungan/antrian-penunjang Kiosk
Antrean Masuk Screen /anjungan/antrean-masuk Display
Check In Pasien /check-in-pasien/check-in Kiosk
Data Pasien /data-pasien Admin
Edit Data Pasien /data-pasien/edit/:id Admin
Monitoring Pasien /monitoring-pasien/monitoring-pasien Admin
Detail Pasien /monitoring-pasien/pasien/:id Admin
Profil /profile/profil Semua
User Login /setting/user-login Superadmin
Hak Akses /setting/hak-akses Superadmin
Master Klinik /setting/master-klinik Superadmin
Master Klinik Ruang /setting/master-klinik-ruang Superadmin
Master Loket /setting/master-loket Superadmin
Master Penunjang /setting/master-penunjang Superadmin
Screen Settings /setting/screen Superadmin
Verifikasi Akun /verifikasi-akun/verifikasi-akun Public
Detail Akun Verifikasi /verifikasi-akun/detail-akun Admin

8.2 Breakpoints

Nama Size Keterangan
Mobile < 640px Tidak diprioritaskan (akses via PC/tablet)
Tablet 6401024px Anjungan & loket (tablet)
Desktop > 1024px Admin & monitoring

8.3 Design System

  • Framework UI: Vuetify 3 (Material Design 3)
  • Font: Inter (400, 500, 600, 700)
  • Icons: Material Design Icons (@mdi/font) + FontAwesome
  • Color scheme: Mengikuti theme Vuetify (light/dark configurable)
  • SCSS Variables: Didefinisikan di assets/scss/_variables.scss & _colors.scss

9. Risks

Risk Likelihood Impact Mitigasi
WebSocket disconnect saat jaringan LAN tidak stabil Tinggi Tinggi Polling fallback 30 detik + auto-reconnect logic
Backend API eksternal down (Visit API / Antrian API) Sedang Tinggi Error handling graceful, retry logic, blacklist endpoint gagal
Konflik antrean antar loket (race condition) Sedang Tinggi State isolasi per loketId, strict filtering di processNextQueue
Sesi Keycloak expire saat jam operasional Sedang Sedang Session duration dikonfigurasi 1 jam, refresh token otomatis
Thermal printer tidak kompatibel di semua device Rendah Sedang Uji di device target sebelum go-live, fallback ke tampilan layar
Data antrean tidak sinkron antar display screen Sedang Tinggi WebSocket deterministic client ID + polling fallback
Kapasitas WebSocket server saat pasien peak Rendah Tinggi Monitor jumlah koneksi, koordinasi dengan tim backend

10. Deployment

Item Detail
Server VPS / Server internal RSSA
Domain dev http://10.10.150.175:3000
Domain staging https://antrean.dev.rssa.id
Domain prod https://antrean.rssa.id
Containerisasi Docker + docker-compose
Auth Server Keycloak (https://auth.rssa.top/realms/sandbox)
Build command nuxt build
Start command node .output/server/index.mjs

11. Changelog

Versi Tanggal Author Perubahan
1.0.0 2026-05-25 Akbar Initial PRD — dibuat berdasarkan kondisi project aktual