Pendahuluan

Dokumen ini menyediakan panduan mengenai arsitektur, deployment, dan konfigurasi sistem Web Assessment dan Smartlab System. Sistem ini dirancang untuk menangani berbagai layanan yang bekerja sama guna menghadirkan aplikasi yang skalabel, aman, dan berkinerja tinggi, mendukung interaksi real-time, penyimpanan data, dan komunikasi yang mulus antara beberapa klien.

Arsitektur mengikuti pendekatan microservices, di mana setiap layanan dijalankan dalam container menggunakan Docker. Sistem ini memanfaatkan teknologi-teknologi utama seperti NestJS untuk layanan backend, Redis untuk caching dan manajemen sesi, PostgreSQL untuk penyimpanan data yang persisten, serta PeerJS bersama dengan TURN server untuk menangani streaming media real-time dan komunikasi peer-to-peer.

Sistem ini menggunakan enkripsi SSL/TLS untuk melindungi komunikasi data antar klien dan backend. Karena sistem ini tidak bergantung pada Certificate Authority (CA) eksternal, self-signed certificates digunakan untuk enkripsi berbasis alamat IP di lingkungan non-produksi maupun produksi.


Tech Stack

Bagian ini memberikan gambaran umum tentang teknologi-teknologi utama yang digunakan dalam Sistem Web Assessment dan Smartlab. Arsitektur dibangun dengan framework dan teknologi modern untuk memastikan skalabilitas, pemeliharaan, dan kinerja yang optimal.

Frontend

  • Nuxt.js. Sebuah hybrid framework yang dibangun di atas Vue.js untuk rendering sisi server dan pembuatan situs statis. Nuxt.js memungkinkan aplikasi untuk berjalan baik sebagai Single Page Application (SPA) maupun Server-Side Rendered (SSR), memberikan fleksibilitas untuk berbagai kasus penggunaan. Dalam sistem ini, digunakan untuk antarmuka dashboard admin, memberikan pengalaman yang mulus bagi administrator sistem.
  • Vue 3. Sebuah framework JavaScript progresif yang digunakan untuk membangun frontend platform assessment, menawarkan antarmuka yang modern, reaktif, dan berbasis komponen untuk para peserta.

Backend

  • NestJs. Sebuah framework Node.js progresif yang digunakan untuk backend Admin dan Assessment. Framework ini menyediakan struktur yang kokoh dan skalabel untuk mengelola API, business logic, dan layanan real-time.

Services

  • PeerJs. Sebuah library JavaScript untuk memungkinkan komunikasi peer-to-peer (P2P) antara klien menggunakan WebRTC, digunakan dalam sistem proctoring.

  • Socket.IO Sebuah library yang digunakan untuk komunikasi real-time berbasis event-driven antara klien dan server. Digunakan dalam sistem untuk menangani sinkronisasi dan komunikasi real-time antar peserta dan admin selama assessment berlangsung.

  • Turn Server Sistem ini menggunakan coturn sebagai server TURN untuk menyalurkan lalu lintas media ketika koneksi peer-to-peer langsung tidak memungkinkan, memastikan komunikasi yang lancar di jaringan yang terbatas.

  • Database

    • PostgreSQL: sebuah database relasional open source untuk menyimpan data terstuktur.

    • Redis: Penyimpanan in-memory key-value yang digunakan untuk caching data dan session management, meningkatkan performa untuk data yang sering diakses.

  • Storage

    • gRPC: digunakan untuk komunikasi antara Main Backend dan layanan Penyimpanan untuk mengunggah aset.

    • NFS (Network File System): Digunakan oleh main backend untuk mengambil aset dari sistem penyimpanan.

  • Web Server and Proxy

    • Caddy: Sebuah web server dan reverse proxy digunakan untuk menangani lalu lintas HTTPS dan mengarahkan permintaan klien ke layanan yang sesuai. Dalam sistem ini, Caddy juga dgunakan untuk mengelola sertifikat SSL (self-signed untuk deployment berbasis IP).




Microservices Architecture

Sistem Web Assessment dan Smartlab mengikuti arsitektur berbasis microservices, di mana setiap layanan berjalan dalam container-nya masing-masing, memberikan modularitas, skalabilitas, dan kemudahan pemeliharaan. Diagram di bawah ini mengilustrasikan komponen utama sistem dan bagaimana mereka saling berinteraksi:

Diagram

Komponen Utama

1. Admin Client (Nuxt.js)

Admin Client dibangun dengan Nuxt.js, sebuah framework untuk membuat aplikasi Vue.js yang dirender di server. Admin Client digunakan oleh administrator sistem untuk mengelola konten, memantau aktivitas, dan melakukan tugas administratif. Client ini berinteraksi dengan Admin Backend melalui panggilan API RESTful.

2. Assessment Client (Vue 3)

Assessment Client dibangun dengan Vue 3 dan menyediakan antarmuka front-end bagi pengguna yang berpartisipasi dalam assessment. Client ini berinteraksi dengan Assessment Backend, memungkinkan pengguna untuk login, mengikuti assessment, dan melihat hasilnya. Assessment Client mendukung interaksi real-time menggunakan PeerJS untuk komunikasi media selama assessment berlangsung.

3. Main Backend (Admin) [NestJS]

Admin Backend, dibangun menggunakan NestJS, menangani business logic dan API endpoints yang dibutuhkan oleh Admin Client. Backend ini bertanggung jawab atas manajemen siswa, pembuatan soal, manajemen acara ujian, sistem proctoring, serta tugas administratif lainnya.

4. Main Backend (Assessment) [NestJS]

Assessment Backend, juga dibangun menggunakan NestJS, mengelola fungsi inti dari platform assessment. Backend ini menangani otentikasi user, pengiriman assessment, pemrosesan hasil.

5. Storage

Layanan storage menangani pengunggahan dan modifikasi aset melalui gRPC, memungkinkan komunikasi yang efisien antara layanan storage dan Main Backend. Untuk pengambilan aset, Main Backend menggunakan NFS (Network File System) untuk melayani aset kepada klien, memastikan file besar seperti media atau dokumen mudah diakses selama assessment atau lainnya.

6. Database (PostgreSQL)

Sebuah database sentral PostgreSQL menyimpan semua data terstruktur. Baik Admin maupun Assessment Backend berinteraksi dengan database ini, menggunakan query dan pengindeksan untuk akses data.

7. Redis

Redis digunakan sebagai penyimpanan in-memory key-value untuk manajemen session user di kedua backend.

8. PeerJS

PeerJS digunakan untuk menangani sinyal WebRTC untuk komunikasi peer-to-peer antar klien, memungkinkan streaming media real-time selama assessment. Ini memastikan interaksi berkualitas tinggi dengan latensi rendah.

9. TURN Server

TURN Server men-relay trafik ketika komunikasi peer-to-peer langsung tidak memungkinkan karena pembatasan jaringan. Server ini memastikan bahwa user yang berada di belakang NAT atau firewall masih dapat berkomunikasi dengan efektif selama assessment.






Data Flow

  • Admin Client (Nuxt.js) berkomunikasi dengan Main Backend (Admin) melalui RESTful APIs, memungkinkan administrator untuk melakukan tugas-tugas seperti manajemen user, pemantauan sistem, dan pembuatan konten. Backend menyimpan data di dalam PostgreSQL database.

  • Assessment Client (Vue 3) berinteraksi dengan Main Backend (Assessment) untuk mengautentikasi user, mengirimkan assessment, dan menampilkan hasil. Client ini juga menggunakan PeerJS untuk komunikasi real-time selama assessment. Backend mengelola data session di Redis dan menyimpan hasil assessment di dalam PostgreSQL database.

  • Storage Service menggunakan gRPC untuk menangani pengunggahan dan modifikasi aset dari Main Backend. Untuk pengambilan aset, Main Backend menggunakan NFS untuk melayani file media kepada klien, memastikan pengiriman file yang efisien baik untuk tugas admin maupun assessment.

  • PeerJS memfasilitasi streaming media peer-to-peer antar klien, sementara TURN Server men-relay trafik media jika koneksi langsung tidak tersedia.

  • Redis digunakan bersama antara kedua backend untuk menangani caching dan manajemen session, mengoptimalkan kinerja sistem.




Database Design

Bagian ini menjelaskan struktur database Web Assessment dan Smartlab System, termasuk tabel-tabel, hubungan antar entitas, dan alur data dalam sistem. Skema database dirancang untuk memastikan penyimpanan, query, dan manajemen data yang efisien, seperti informasi user, dan assessment.

Database Schema Diagram

Di bawah ini adalah diagram yang mengilustrasikan hubungan antara entitas utama dalam sistem, termasuk tabel untuk users, assessment, log, dan komponen utama lainnya.

DB DIAGRAM




API Documentation

A. Web Assessment System API Documentation

Bagian ini menjelaskan dokumentasi API pada sistem web assessment (platform ujian online). API ini mendukung operasi CRUD dan service lainnya.

Base URL

Semua permintaan API menggunakan URL berikut sebagai basis:

https://xx.xx.xx.xxx/api/v1

1. Autentikasi

1.1 Mendapatkan Token CSRF

Endpoint: GET /auth/csrf-token

Deskripsi: Mendapatkan token CSRF yang akan digunakan untuk permintaan selanjutnya. Token ini disimpan dalam cookie x-xsrf-token dengan pengaturan secure untuk memastikan cookie hanya dikirim melalui koneksi HTTPS.

Contoh Response (200 OK):
{
  "csrfToken": "value"
}

Cookies:

  • x-xsrf-token: Disimpan dengan secure: true, httpOnly: true.
Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/auth/csrf-token


1.2 Login Peserta Ujian

Endpoint: POST /auth/login

Deskripsi: Gunakan endpoint ini untuk autentikasi peserta ujian menggunakan Nama Lengkap dan NRP. Setelah login berhasil, token JWT disimpan dalam cookie HTTP-only dengan pengaturan secure, memastikan hanya dikirim melalui HTTPS.

Request:

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "name": "johndoe",
  "registeredNumber": "12345678"
}
Contoh Response (200 OK):
{
  "name": "John Doe",
  "eventId": 1,
  "eventTitle": "Ujian Nasional",
  "eventSlug": "ujian-nasional",
  "id": 123,
  "examRegisteredNumber": "12304567892024"
}
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/auth/login \
-H 'Content-Type: application/json' \
-H 'Cookie: x-xsrf-token=<token-csrf>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"name": "johndoe", "registeredNumber": "password123"}'

Response Cookies:

  • sl_token: Token autentikasi JWT disimpan dengan secure: true, httpOnly: true.
1.3 Registrasi Pengguna Baru

Endpoint: POST /auth/register

Deskripsi: Gunakan endpoint ini untuk registrasi pengguna baru. CAPTCHA diperlukan untuk validasi. Setelah registrasi, pengguna akan otomatis login dan token JWT disimpan dalam cookie HTTP-only dengan pengaturan secure.

Request:

Headers:

X-XSRF-TOKEN: <token-csrf>

Query Parameters:

  • token (optional): Token opsional untuk registrasi otomatis di suatu even ujian.

Body:

{
  "name": "Jane Doe",
  "registeredNumber": "12345678",
  "rankId": 1,
  "positionId": 1,
  "unitId": 1,
  "captcha": "1234"
}
Contoh Response (201 Created):
{
  "id": 1,
  "name": "Jane Doe",
  "registeredNumber": "12345678",
  "rankId": 1,
  "positionId": 1,
  "unitId": 1,
  "accessCode": "unique_access_code"
}

Response Cookies:

  • sl_token: Response Token autentikasi disimpan dengan secure: true dan httpOnly: true (jika terdapat token untuk registrasi otomatis ke event ujian).
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/auth/register?token=event_token \
-H 'Content-Type: application/json' \
-H 'Cookie: x-xsrf-token=<token-csrf>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{""name": "Jane Doe","registeredNumber": "12345678","rankId": 1,"positionId": 1,"unitId": 1,"captcha": "1234"}'
1.4 Logout Pengguna

Endpoint: GET /auth/logout

Deskripsi: Gunakan endpoint ini untuk mengeluarkan pengguna dari sistem dengan menghapus cookie autentikasi.

Contoh Response (200 OK):
{
  "message": "Logout successful"
}

Cookies:

  • sl_token: Cookie dihapus dengan secure: true.
Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/auth/logout \


2.Peserta Ujian

2.1. Data Current Participant

Endpoint: GET /participant

Description: Retrieve the current participant's data based on the provided session token.

Request:

Cookies: sl_token (required): The session token used to identify the participant.

Contoh Response (200):
{
    "title": "Online English Skill Assessment",
    "date": "2024-08-05T17:00:00.000Z",
    "rule": "ibt",
    "startTime": "02:36:00",
    "endTime": "02:39:00",
    "sections": [Object Data]
}
Contoh Response (400):
{
  "statusCode": 400,
  "message": "Invalid token or participant ID",
  "error": "Bad Request"
}
Status Code (404 Not Found):
{
  "statusCode": 404,
  "message": "Participant not found",
  "error": "Not Found"
}


3. Event

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie sl_token.

3.1. Mendapatkan Data Simulation

Endpoint: GET /event/simulation

Deskripsi: Mendapatkan data simulasi dari event. Jika data simulasi tidak tersedia dalam cache, data akan diambil dari layanan event dan disimpan ke dalam cache untuk permintaan selanjutnya.

Contoh Response (200 OK):
{
  "id": 1,
  "name": "Simulation Test Package",
  "sections": [Object Data]
}
Contoh Request (Curl):
    curl -X GET https://xx.xx.xx.xxx/v1/event/simulation
3.2 Get Event for Signed-In Participant

Endpoint: GET /event

Deskripsi: Mendapatkan data event untuk peserta ujian yang sudah login berdasarkan token yang ada di cookie. Jika parameter sectionId disertakan, hanya data dari section tersebut yang akan dikembalikan.

Request:

Query Parameters:

  • sectionId (optional): ID section yang ingin diambil datanya.
Contoh Response (200 OK):
{
  "id": 1,
  "eventTitle": "Ujian Nasional",
  "sections": [Object Data]
}

Cookies:

  • sl_token: Token autentikasi JWT dari peserta ujian.
Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/event?sectionId=1 \
-b "sl_token=your-jwt-token"


3.3 Get Sections Data on Event Test

Endpoint: GET /event/sections

Deskripsi: Mendapatkan data sections pada sebuah event ujian berdasarkan ID peserta yang sudah login. Informasi ini diambil menggunakan token yang tersimpan dalam cookie.

Request:

Contoh Response (200 OK):
{
  "id": 1,
  "eventTitle": "Ujian Nasional",
  "sections": [
    {
      "id": 1,
      "title": "Section 1",
      "questions": [Object Data]
    }
  ]
}

Cookies:

  • sl_token: Token autentikasi JWT dari peserta ujian.
Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/event/sections \
-b "sl_token=your-jwt-token"


4. Test Responses

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie sl_token.

4.1 Submit Test Response

Endpoint: POST /test-responses

Deskripsi: Mengirimkan satu test response dari peserta ujian. Token peserta ujian diambil dari cookie sl_token dan digunakan untuk memvalidasi identitas.

Request Body:

{
  "questionId": 101,
  "answer": "Paris",
}

Cookies:

  • sl_token: Token autentikasi JWT dari peserta ujian.

Headers:

X-XSRF-TOKEN: <token-csrf>
Contoh Response (201 Created):
{
  "id": 1,
  "questionId": 101,
  "answer": "Paris",
  "participantId": 5,
  "packageId": 1,
  "eventId": 10,
  "score": 10,
  "createdAt": "2024-09-13T10:00:00Z",
  "updatedAt": "2024-09-13T10:00:00Z"
}
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/test-responses \
-H 'X-CSRF-TOKEN: <your-csrf-token>' \
-H 'Content-Type: application/json' \
--cookie "sl_token=<your-jwt-token>" \
-d '{
  "questionId": 101,
  "answer": "Paris",
}'
4.2 Submit Bulk Test Responses

Endpoint: POST /test-responses/bulk

Deskripsi: Mengirimkan beberapa test responses sekaligus dari peserta ujian. Token peserta ujian diambil dari cookie sl_token dan digunakan untuk memvalidasi identitas. Data responses dikirimkan dalam bentuk array.

Request Body:

[
  {
    "questionId": 101,
    "answer": "Paris",
  },
  {
    "questionId": 102,
    "answer": "Berlin",
  }
]
Query Parameters:
  • status (optional): Status tambahan yang ingin disertakan dalam submit bulk responses, misalnya completed.

Cookies:

  • sl_token: Token autentikasi JWT dari peserta ujian.

Headers:

X-XSRF-TOKEN: <token-csrf>
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/test-responses/bulk?status=completed \
-H 'X-CSRF-TOKEN: <your-csrf-token>' \
-H 'Content-Type: application/json' \
--cookie "sl_token=<your-jwt-token>" \
-d '[
  {
    "questionId": 101,
    "answer": "Paris",
  },
  {
    "questionId": 102,
    "answer": "Berlin",
  }
]'
4.3 Error Handling

Kode status yang umum digunakan dalam API ini meliputi:

Status Code Deskripsi
200 OK Permintaan berhasil dijalankan.
400 Bad Request Data permintaan tidak valid.
401 Unauthorized Token autentikasi tidak valid.
404 Not Found Resource yang diminta tidak ditemukan.
500 Internal Server Error Kesalahan server yang tidak terduga.


5. Media

5.1 Upload Video

Endpoint: POST /video

Deskripsi: Gunakan endpoint ini untuk mengunggah file video. Hanya video dengan format webm dan ukuran maksimum 10 MB yang diizinkan. Video ini diunggah dan diproses berdasarkan opsi yang diberikan.

Request: Headers:

X-XSRF-TOKEN: <token-csrf>
Content-Type: multipart/form-data
Query Parameters:
  • option (optional): Parameter opsional untuk menentukan opsi penanganan video khusus.

Body (multipart/form-data):

  • file: File video yang akan diunggah.

Cookies:

  • sl_token: Token autentikasi yang digunakan untuk mengidentifikasi peserta yang mengunggah video.
Contoh Response (201 Created):
{
  "message": "Video uploaded successfully"
}
Contoh Kesalahan (400 Bad Request):
{
  "statusCode": 400,
  "message": "Invalid file type or file size exceeds limit",
  "error": "Bad Request"
}

Cookies:

  • sl_token: Digunakan untuk autentikasi peserta.
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/video \
-H 'Content-Type: multipart/form-data' \
-H 'Cookie: sl_token=<your_token>' \
-H 'Cookie: x-xsrf-token=<csrf>' \
-F 'file=@video.webm' \
--form 'option=compress'


6. Audio

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie sl_token.

6.1 Stream Audio

Endpoint: GET /audio

Deskripsi: Mengalirkan (streaming) file audio berdasarkan parameter query audio. Nama atau path file audio harus diberikan melalui query string.

Query Parameters:

Nama Tipe Deskripsi Wajib
id String File Path Audio Ya


Headers:

X-XSRF-TOKEN: <token-csrf>

Cookies:

  • sl_token: Token autentikasi JWT dari pengguna.

Responses:

Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/audio?audio=example.mp3' \
--cookie "sl_token=<your-jwt-token>"


7. Units/Satuan

7.1 Mendapatkan Semua Unit/Satuan

Endpoint: GET /units

Deskripsi: Mengambil daftar semua unit yang tersedia dalam sistem.

Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/units'
Response Contoh (200):
[
  {
    "id": 10,
    "title": "Komando Operasi Angkatan Udara (Koopsau)",
    "abbr": "Koopsau"
  },
  {
    "id": 11,
    "title": "Komando Pendidikan dan Latihan Angkatan Udara (Kodiklatau)",
    "abbr": "Kodiklatau"
  }
]
7.2 Mendapatkan Unit Berdasarkan ID

Endpoint: GET /units/{id}

Deskripsi: Mengambil informasi unit berdasarkan id yang diberikan.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari unit yang ingin diambil.


Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/units/1' \
Response Contoh (200):
{
  "id": 11,
  "title": "Komando Pendidikan dan Latihan Angkatan Udara (Kodiklatau)",
  "abbr": "Kodiklatau"
}
Response Contoh (404):
{
  "statusCode": 404,
  "message": "Unit with ID 1 not found",
  "error": "Not Found"
}
7.3 Error Handling

Kode status yang umum digunakan dalam API ini meliputi:

Status Code Deskripsi
200 OK Permintaan berhasil dijalankan.
400 Bad Request Data permintaan tidak valid.
401 Unauthorized Token autentikasi tidak valid.
404 Not Found Resource yang diminta tidak ditemukan.
500 Internal Server Error Kesalahan server yang tidak terduga.


8. Position/Jabatan

8.1 Mendapatkan Semua Unit/Satuan

Endpoint: GET /positions

Deskripsi: Mengambil daftar semua jabatan yang tersedia dalam sistem.

Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/positions'
Response Contoh (200):
[
  {
    "id": 1,
    "title": "Komandan Satuan Pemeliharaan (KSP)",
    "abbr": "KSP"
  },
  {
    "id": 2,
    "title": "Komandan Satuan Radar (KSR)",
    "abbr": "KSR"
  },
  {
    "id": 3,
    "title": "Komandan Satuan Pendidikan (KSPd)",
    "abbr": "KSPd"
  }
]


8.2 Mendapatkan Position/Jabatan Berdasarkan ID

Endpoint: GET /posistions/{id}

Deskripsi: Mengambil informasi jabatan berdasarkan id yang diberikan.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari position yang ingin diambil.


Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/positions/1' \
Response Contoh (200):
  {
    "id": 2,
    "title": "Komandan Satuan Radar (KSR)",
    "abbr": "KSR"
  }


Response Contoh (404):
{
  "statusCode": 404,
  "message": "Position with ID 1 not found",
  "error": "Not Found"
}


9. Pangkat

9.1 Mendapatkan Semua Pangkat

Endpoint: GET /ranks

Deskripsi: Mengambil daftar semua pangkat yang tersedia dalam sistem.

Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/ranks'
Response Contoh (200):
[
  {
    "id": 1,
    "title": "Prajurit Dua"
  },
  {
    "id": 2,
    "title": "Prajurit Satu"
  }
]


8.2 Mendapatkan Pangkat Berdasarkan ID

Endpoint: GET /ranks/{id}

Deskripsi: Mengambil informasi pangkat berdasarkan id yang diberikan.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pangkat yang ingin diambil.


Contoh Request (Curl):
curl -X GET 'https://xx.xx.xx.xxx/v1/ranks/1' \
Response Contoh (200):
{
    "id": 2,
    "title": "Prajurit Satu"
  }


Response Contoh (404):
{
  "statusCode": 404,
  "message": "Rank with ID 1 not found",
  "error": "Not Found"
}


9. Kode Status

Kode status yang umum digunakan dalam API ini meliputi:

Status Code Deskripsi
200 OK Permintaan berhasil dijalankan.
400 Bad Request Data permintaan tidak valid.
401 Unauthorized Token autentikasi tidak valid.
404 Not Found Resource yang diminta tidak ditemukan.
500 Internal Server Error Kesalahan server yang tidak terduga.






B. ADMINISTRATOR - Web Assessment System API Documentation

Bagian ini menjelaskan dokumentasi API pada sistem web assessment (platform ujian online). API ini mendukung operasi CRUD dan service lainnya.

Base URL

Semua permintaan API menggunakan URL berikut sebagai basis:

https://xx.xx.xx.xxx/api/v1


1. Autentikasi

1.1 Mendapatkan Token CSRF

Endpoint: GET /auth/csrf-token

Deskripsi: Mendapatkan token CSRF yang akan digunakan untuk permintaan selanjutnya. Token ini disimpan dalam cookie x-xsrf-token dengan pengaturan secure untuk memastikan cookie hanya dikirim melalui koneksi HTTPS.

Contoh Response (200 OK):
{
  "csrfToken": "value"
}


**Cookies:**

- `x-xsrf-token`: Disimpan dengan secure: true, httpOnly: true.

##### Contoh Request (Curl):
```bash
curl -X GET https://xx.xx.xx.xxx/v1/auth/csrf-token
1.2 Cek Status Autentikasi

Endpoint: GET /auth/check

Deskripsi: Memeriksa apakah pengguna sudah terautentikasi. Mengembalikan status autentikasi sebagai respons.

Contoh Response (200 OK):
{
  "isAuthenticated": true
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/auth/check
1.3 Login Administrator

Endpoint: POST /auth/login

Deskripsi: Gunakan endpoint ini untuk melakukan login sebagai administrator dengan menggunakan kredensial yang valid. Setelah login berhasil, token akses disimpan sebagai cookie HTTP-only dengan pengaturan secure.

Request:

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "username": "adminuser",
  "password": "adminpassword"
}
Contoh Response (200 OK):
{
  "id": 1,
  "username": "adminuser",
  "role": "administrator"
}

Response Cookies:

  • adm-token: Token autentikasi JWT disimpan dengan secure: true, httpOnly: true.
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/auth/login \
-H 'Content-Type: application/json' \
-H 'Cookie: x-xsrf-token=<token-csrf>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"username": "adminuser", "password": "adminpassword"}'


1.4 Mendapatkan Token Autentikasi

Endpoint: GET /auth/token

Deskripsi: Mengambil token autentikasi yang disimpan dalam cookie adm-token.


Contoh Response (200 OK):
{
  "token": "your_auth_token"
}
Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/auth/token \
-H 'Cookie: adm-token=<your_auth_token>'
1.5 Logout Pengguna

Endpoint: GET /auth/logout

Deskripsi: Gunakan endpoint ini untuk melakukan logout pengguna dengan menghapus cookie autentikasi.


Contoh Response (200 OK):
{
  "message": "Logout successful"
}

Cookies:

  • adm-token: Cookie dihapus dengan secure: true.


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/auth/logout


2. Administrator

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.

2.1 Membuat Administrator Baru

Endpoint: POST /admins

Deskripsi: Endpoint ini memungkinkan pembuatan akun admin baru. Hanya pengguna dengan roleId 1 yang diizinkan untuk melakukan tindakan ini.

Request:

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "username": "JohnDoe",
  "roleId": 1,
  "password": "admin123"
}

<br>

###### Contoh Response (201 Created):
```json
{
  "id": 1,
  "username": "JohnDoe",
  "roleId": 1
}


Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/admins \
-H 'Content-Type: application/json' \
-H 'Cookie: adm-token=<your_auth_token>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"username": "JohnDoe", "roleId": 1, "password": "admin123"}'


2.2 Mendapatkan Daftar Administrator

Endpoint: GET /admins

Deskripsi: Mengambil daftar semua administrator yang ada.

Contoh Response (200 OK):
[
  {
    "id": 1,
    "username": "JohnDoe",
    "roleId": 1
  },
  {
    "id": 2,
    "username": "JaneSmith",
    "roleId": 2
  }
]


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/admins \
-H 'Cookie: adm-token=<your_auth_token>'


2.3 Mendapatkan Administrator Berdasarkan ID

Endpoint: GET /admins/:id

Deskripsi: Mengambil detail administrator berdasarkan ID unik mereka.


Contoh Response (200 OK):
{
  "id": 1,
  "username": "JohnDoe",
  "roleId": 1
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/admins/1 \
-H 'Cookie: adm-token=<your_auth_token>'


2.4 Mengecek Password

Endpoint: POST /admins/check-password

Deskripsi: Endpoint ini memverifikasi apakah password yang diberikan cocok dengan password lama administrator.

Request: Headers:

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "password": "oldpassword123"
}


Contoh Response (200 OK):
{
  "status": "verified"
}


Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/admins/check-password \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Cookie: adm-token=<your_auth_token>'\
-d '{"password": "oldpassword123"}'


2.5 Mengubah Password Administrator

Endpoint: PATCH /admins/password/:id

Deskripsi: Mengubah password administrator yang ada. Diperlukan header X-XSRF-TOKEN yang valid.

Request: Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "password": "newpassword123"
}


Contoh Response (200 OK):
{
  "id": 1,
  "username": "JohnDoe",
  "roleId": 1,
  "password": "newpassword123"
}


Contoh Request (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/admins/password/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Cookie: adm-token=<your_auth_token>' \
-d '{"password": "newpassword123"}'


2.6 Mengubah Data Administrator

Endpoint: PATCH /admins/:id

Deskripsi: Mengubah data administrator yang ada. Diperlukan header X-XSRF-TOKEN yang valid.

Request: Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "username": "JohnUpdatedDoe",
  "roleId": 1
}


Contoh Response (200 OK):
{
  "id": 1,
  "username": "JohnUpdatedDoe",
  "roleId": 1
}


Contoh Request (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/admins/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Cookie: adm-token=<your_auth_token>' \
-d '{"username": "JohnUpdatedDoe", "roleId": 1}'


2.7 Menghapus Administrator Berdasarkan ID

Endpoint: DELETE /admins/:id

Deskripsi: Menghapus administrator berdasarkan ID unik mereka.

Contoh Response (200 OK):
{
  "message": "Admin successfully deleted"
}


Contoh Request (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/admins/1 \
-H 'Cookie: adm-token=<your_auth_token>' \
-H 'X-XSRF-TOKEN: <token-csrf>'


3. Pertanyaan

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


3.1 Mendapatkan Semua Data Pertanyaan

Endpoint: GET /questions

Deskripsi: Mengambil daftar semua pertanyaan dengan opsi pagination dan sorting.

Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan pertanyaan (ASC atau DESC).
limit Integer Jumlah maksimum pertanyaan yang ingin diambil.
offset Integer Jumlah pertanyaan yang dilewatkan sebelum mengambil data.
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: audio,answer).
search String Mencari berdasarkan kata kunci pertanyaan.
filterBySection String Filter pertanyaan berdasarkan section.
Contoh Response (200 OK):
[
  {
    "id": 1,
    "question": "What is the capital of France?",
    "sectionDetailId": 2,
    "audioId": 3,
    "packageId": 1,
    "point": 10,
    "passageId": 4,
    "preparationTime": 30,
    "responseTime": 60,
    "questionType": "multiple_choice",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/questions?order=ASC&limit=10&offset=0 \
-H 'Cookie: adm-token=<your_auth_token>'


3.2 Mendapatkan Semua Pertanyaan Berdasarkan Package ID

Endpoint: GET /questions/package/:packageId

Deskripsi: Mengambil semua pertanyaan yang terkait dengan package ID dengan opsi pagination, sorting, dan filter berdasarkan section.

Path Parameters:

Nama Tipe Deskripsi
packageId Integer ID dari package yang ingin diambil.

Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan pertanyaan (ASC atau DESC).
orderBy String Kolom yang digunakan untuk sorting (contoh: question).
limit Integer Jumlah maksimum pertanyaan yang ingin diambil.
offset Integer Jumlah pertanyaan yang dilewatkan sebelum mengambil data.
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: audio,answer).
search String Mencari berdasarkan kata kunci pertanyaan.
filterBySection String Filter pertanyaan berdasarkan section.
Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 100,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "id": 1,
      "question": "What is the capital of France?",
      "sectionDetailId": 2,
      "audioId": 3,
      "packageId": 1,
      "point": 10,
      "passageId": 4,
      "preparationTime": 30,
      "responseTime": 60,
      "questionType": "multiple_choice",
      "createdAt": "2023-09-14T12:00:00Z",
      "updatedAt": "2023-09-14T12:00:00Z"
    }
  ]
}


Contoh Request (Curl):

bash curl -X GET https://xx.xx.xx.xxx/v1/questions/package/1?order=ASC&limit=10&offset=0&entities=question,audio \ -H 'Cookie: adm-token='


3.3 Mendapatkan Pertanyaan Berdasarkan ID

Endpoint: GET /questions/:id

Deskripsi: Mengambil detail pertanyaan berdasarkan ID beserta entitas terkait.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pertanyaan yang ingin diambil

Query Parameters:

Nama Tipe Deskripsi
entities String Daftar entitas terkait yang ingin disertakan dalam respons, dipisahkan dengan koma (contoh: audio,answer).


Contoh Response (200 OK):
{
  "id": 1,
  "question": "What is the capital of France?",
  "sectionDetailId": 2,
  "audioId": 3,
  "packageId": 1,
  "point": 10,
  "passageId": 4,
  "preparationTime": 30,
  "responseTime": 60,
  "questionType": "multiple_choice",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z",
  "entities": {
    "audio": "...",
    "answer": "..."
  }
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/questions/1?entities=audio,answer \
-H 'Cookie: adm-token=<your_auth_token>'


3.4 Membuat Pertanyaan Baru

Endpoint: POST /questions

Deskripsi: Membuat pertanyaan baru beserta detail seperti passage, sectiondetail, optionquestion, dan jawaban yang benar.

Headers:

X-XSRF-TOKEN: <token-csrf>
Cookie: adm-token=<your_auth_token>

Body:

{
  "packageId": 1,
  "sectionId": 2,
  "sectionDuration": 120,
  "sectionInstruction": "Answer the following questions",
  "question": "What is the capital of France?",
  "questionType": "multiple_choice",
  "audioId": 3,
  "pasageId": 4,
  "responseTime": 60,
  "optionQuestions": [
    {
      "label": "A",
      "value": "Paris"
    },
    {
      "label": "B",
      "value": "London"
    }
  ],
  "answerKey": ["A"]
}


Contoh Response (201 Created):
{
  "id": 1,
  "packageId": 1,
  "sectionId": 2,
  "question": "What is the capital of France?",
  "questionType": "multiple_choice",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/questions \
-H 'Content-Type: application/json' \
-H 'Cookie: adm-token=<your_auth_token>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{
  "packageId": 1,
  "sectionId": 2,
  "sectionDuration": 120,
  "sectionInstruction": "Answer the following questions",
  "question": "What is the capital of France?",
  "questionType": "multiple_choice",
  "audioId": 3,
  "pasageId": 4,
  "responseTime": 60,
  "optionQuestions": [
    {
      "label": "A",
      "value": "Paris"
    },
    {
      "label": "B",
      "value": "London"
    }
  ],
  "answerKey": ["A"]
}'


3.5 Memperbarui Pertanyaan

Endpoint: PATCH /questions/:id

Deskripsi: Memperbarui detail pertanyaan yang ada beserta detail seperti passage, sectiondetail, optionquestion, dan jawaban yang benar.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pertanyaan yang ingin diupdate.

Headers:

X-XSRF-TOKEN: <token-csrf>
Cookie: adm-token=<your_auth_token>

Body:

{
  "packageId": 1,
  "sectionId": 2,
  "sectionDuration": 120,
  "sectionInstruction": "Answer the following questions",
  "question": "What is the capital of France?",
  "questionType": "multiple_choice",
  "audioId": 3,
  "pasageId": 4,
  "responseTime": 60,
  "optionQuestions": [
    {
      "label": "A",
      "value": "Paris"
    },
    {
      "label": "B",
      "value": "London"
    }
  ],
  "answerKey": ["A"]
}


Contoh Response (200 OK):
{
  "id": 1,
  "question": "What is the capital of France?",
  "updatedAt": "2023-09-14T12:30:00Z"
}


Contoh Request (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/questions/1 \
-H 'Content-Type: application/json' \
-H 'Cookie: adm-token=<your_auth_token>' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{
  "packageId": 1,
  "sectionId": 2,
  "sectionDuration": 120,
  "sectionInstruction": "Answer the following questions",
  "question": "What is the capital of France?",
  "questionType": "multiple_choice",
  "audioId": 3,
  "pasageId": 4,
  "responseTime": 60,
  "optionQuestions": [
    {
      "label": "A",
      "value": "Paris"
    },
    {
      "label": "B",
      "value": "London"
    }
  ],
  "answerKey": ["A"]
}'


4. Test Packages

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


4.1 Mendapatkan Semua Test Packages

Endpoint: GET /test-packages

Deskripsi: Mengambil semua test packages dengan opsi sorting, pagination, dan pencarian.

Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan test packages (ASC atau DESC).
limit Integer Jumlah maksimum test packages yang ingin diambil.
offset Integer Jumlah test packages yang dilewatkan sebelum mengambil data.
entities String Mengambil data dengan entitas terkait.
search String Mencari test package berdasarkan judul.
Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 50,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "id": 1,
      "title": "Ujian Nasional",
      "createdAt": "2023-09-14T12:00:00Z",
      "updatedAt": "2023-09-14T12:00:00Z"
    }
  ]
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/test-packages?order=ASC&limit=10&offset=0&search=Ujian \
-H 'Cookie: adm-token=<your_auth_token>'


4.2 Mendapatkan Template Test Package

Endpoint: GET /test-packages/download-package-template

Deskripsi: Mengunduh template dokumen test package dalam format DOCX.


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/test-packages/download-package-template \
-H 'Cookie: adm-token=<your_auth_token>' \
-O


4.3 Mendapatkan Test Package Berdasarkan ID

Endpoint: GET /test-packages/:id

Deskripsi: Mengambil detail test package berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari test package yang ingin diambil.
Contoh Response (200 OK):
{
  "id": 1,
  "title": "Ujian Nasional",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/test-packages/1 \
-H 'Cookie: adm-token=<your_auth_token>'


4.4 Membuat Test Package Baru

Endpoint: POST /test-packages

Deskripsi: Membuat test package baru.

Headers: X-XSRF-TOKEN: <token-csrf>

Body:

{
  "title": "Ujian Akhir Semester"
}
Contoh Response (201 Created):
{
  "id": 1,
  "title": "Ujian Akhir Semester",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/test-packages \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Ujian Akhir Semester"}'


4.5 Mengunggah Dokumen Test Package

Endpoint: POST /test-packages/upload

Deskripsi: Mengunggah file PDF atau DOCX yang berisi dokumen test package.

Headers: X-XSRF-TOKEN: <token-csrf>

Body (multipart/form-data):

Nama Tipe Deskripsi
file File File yang berisi dokumen test package.


Contoh Response (201 Created):
{
  "message": "File berhasil diproses."
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/test-packages/upload \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-F file=@/path/to/your/file.docx


4.6 Menghapus Test Package Berdasarkan ID

Endpoint: DELETE /test-packages/:id

Deskripsi: Menghapus test package berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari test package yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Test package berhasil dihapus"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/test-packages/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


5. Section (Bagian Ujian)

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


5.1 Membuat Section Baru

Endpoint: POST /sections

Deskripsi: Membuat section (bagian) baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "title": "Section 1",
  "duration": 120
}


Contoh Response (201 Created):
{
  "id": 1,
  "title": "Section 1",
  "duration": 120,
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/sections \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Section 1", "duration": 120}'


5.2 Mendapatkan Semua Section

Endpoint: GET /sections

Deskripsi: Mengambil daftar semua section (bagian) yang ada.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "title": "Section 1",
    "duration": 120,
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  },
  {
    "id": 2,
    "title": "Section 2",
    "duration": 90,
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/sections \
-H 'Cookie: adm-token=<your_auth_token>'


5.3 Mendapatkan Section Berdasarkan Package ID

Endpoint: GET /sections/package/:packageId

Deskripsi: Mengambil daftar section yang berhubungan dengan packageId.

Path Parameters:

Nama Tipe Deskripsi
packageId String ID dari package (paket ujian) yang ingin diambil.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "title": "Section 1",
    "duration": 120,
    "packageId": 3,
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/sections/package/3 \
-H 'Cookie: adm-token=<your_auth_token>'


5.4 Mendapatkan Section Berdasarkan ID

Endpoint: GET /sections/:id

Deskripsi: Mengambil detail section berdasarkan ID.


Path Parameters:

Nama Tipe Deskripsi
id String ID dari section yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Section 1",
  "duration": 120,
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/sections/1 \
-H 'Cookie: adm-token=<your_auth_token>'


5.5 Memperbarui Section Berdasarkan ID

Endpoint: PATCH /sections/:id

Deskripsi: Memperbarui detail section berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters: | Nama | Tipe | Deskripsi | |------|------|-----------| | id | String | ID dari section yang ingin diperbarui. |

Body:

{
  "title": "Updated Section Title"
}


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Updated Section Title",
  "duration": 120,
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-15T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/sections/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Updated Section Title"}'


5.6 Menghapus Section Berdasarkan ID

Endpoint: DELETE /sections/:id

Deskripsi: Menghapus section berdasarkan ID.


Path Parameters:

Nama Tipe Deskripsi
id String ID dari section yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Section has been successfully deleted"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/sections/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


5.7. Section Details

Endpoint: GET /section-details/by-package

Deskripsi: Mengambil detail section dalam paket ujian tertentu berdasarkan ID paket dan ID section.

Query Parameters:

Nama Tipe Deskripsi
packageId String ID dari paket ujian yang ingin diambil.
sectionId String ID dari section yang ingin diambil.
Contoh Response (200 OK):
{
  "id": 88,
  "sectionId": 3,
  "instruction": "The following Speaking section of the test will last approximately 17 minutes.  To complete it, you will need a recording device that you can play back to listen to your  responses.  During the test, you will answer four speaking questions. One question asks about a famil- iar topic.",
  "duration": 1200
}


Contoh Response (404 Not Found):
{
  "message": "Section details not found for the provided package and section IDs."
}


6. Media Audio

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


6.1 Stream Audio

Endpoint: GET /audio/:event/:filename

Deskripsi: Stream file audio dari server berdasarkan event dan nama file.

Path Parameters:

Nama Tipe Deskripsi
event String Nama event dari audio yang diambil.
filename String Nama file audio yang diambil.
Contoh Response (200 OK):
File audio dikirim ke client.
Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/audio/Cambridge%20IELTS%2013/ielts13-tests1-4cd1track_01.mp3


6.2 Mendapatkan Semua Audio Media

Endpoint: GET /audio

Deskripsi: Mengambil daftar semua file audio media yang tersedia di sistem.

Query Parameters:

Nama Tipe Deskripsi
search String Pencarian berdasarkan nama file audio.
limit Integer Jumlah maksimum audio yang ingin diambil.
offset Integer Jumlah audio yang dilewatkan sebelum mengambil data.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "filename": "audio-file-1.mp3",
    "event": "Event 1",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  },
  {
    "id": 2,
    "filename": "audio-file-2.mp3",
    "event": "Event 2",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/audio?search=audio-file&limit=10&offset=0


6.3 Mendapatkan Audio Berdasarkan ID

Endpoint: GET /audio/:id

Deskripsi: Mengambil detail file audio berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari file audio yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "filename": "audio-file-1.mp3",
  "event": "Event 1",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/audio/1


6.4 Mengunggah Audio ZIP Terkait Paket Ujian

Endpoint: POST /audio/bulk

Deskripsi: Mengunggah file audio dalam format ZIP yang terkait dengan paket ujian. Nama file harus sama dengan nama paket.

Headers: X-XSRF-TOKEN: <token-csrf>


Body (multipart/form-data):

Nama Tipe Deskripsi
file File File audio dalam format ZIP.


Contoh Response (200 OK):
{
  "message": "Audio file successfully uploaded"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/audio/bulk \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-F file=@/path/to/your/file.zip


6.5 Mengunggah Audio File

Endpoint: POST /audio

Deskripsi: Mengunggah file audio yang terkait dengan pertanyaan. Audio harus dalam format MP3 atau WAV dengan maksimal ukuran 20MB.

Headers: X-XSRF-TOKEN: <token-csrf>


Body (multipart/form-data):

Nama Tipe Deskripsi
file File File audio yang akan diunggah (MP3/WAV).
eventTitle String Nama event terkait (opsional).


Contoh Response (200 OK):
{
  "message": "Audio file successfully uploaded",
  "fileUrl": "audio/Event1/20230914-audio-file.mp3"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/audio \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-F file=@/path/to/your/audio-file.mp3 \
-F eventTitle="Event 1"


6.6 Menghapus Audio Berdasarkan ID

Endpoint: DELETE /audio/:id

Deskripsi: Menghapus file audio berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari file audio yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Audio file has been successfully deleted"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/audio/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


7. Event Ujian

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


7.1 Membuat Event Baru

Endpoint: POST /events

Deskripsi: Membuat event baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "packageId": 1,
  "title": "Ujian Nasional",
  "description": "Ujian tahunan nasional",
  "date": "2023-07-12",
  "startTime": "10:00:00",
  "endTime": "12:00:00",
  "prodikId": "P123"
}


Contoh Response (201 Created):
{
  "id": 1,
  "packageId": 1,
  "title": "Ujian Nasional",
  "description": "Ujian tahunan nasional",
  "date": "2023-07-12",
  "startTime": "10:00:00",
  "endTime": "12:00:00"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/events \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"packageId": 1, "title": "Ujian Nasional", "description": "Ujian tahunan nasional", "date": "2023-07-12", "startTime": "10:00:00", "endTime": "12:00:00", "prodikId": "P123"}'


7.2 Mendapatkan Semua Event

Endpoint: GET /events

Deskripsi: Mengambil daftar semua event dengan opsi pagination dan sorting.

Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan event (ASC atau DESC).
limit Integer Jumlah maksimum event yang ingin diambil.
offset Integer Jumlah event yang dilewatkan sebelum mengambil data.
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: package,title,description,date,startTime,endTime).
search String Mencari event berdasarkan kata kunci.
mode String Mode pilihan, nilai yang tersedia: proctor, event.


Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 50,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "id": 1,
      "title": "Ujian Nasional",
      "description": "Ujian tahunan nasional",
      "date": "2023-07-12",
      "startTime": "10:00:00",
      "endTime": "12:00:00"
    }
  ]
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/events?order=ASC&limit=10&offset=0&entities=package,title,date \
-H 'Cookie: adm-token=<your_auth_token>'


7.3 Mendapatkan Event Berdasarkan ID

Endpoint: GET /events/:id

Deskripsi: Mengambil detail event berdasarkan ID beserta entitas terkait.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari event yang ingin diambil.


Query Parameters:

Nama Tipe Deskripsi
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: title,participants).
search String Mencari peserta event berdasarkan kata kunci.
option String Opsi flat untuk mendapatkan data dalam format yang disederhanakan.


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Ujian Nasional",
  "description": "Ujian tahunan nasional",
  "date": "2023-07-12",
  "startTime": "10:00:00",
  "endTime": "12:00:00"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/events/1?entities=title,participants \
-H 'Cookie: adm-token=<your_auth_token>'


7.4 Memperbarui Event

Endpoint: PATCH /events/:id

Deskripsi: Memperbarui detail event.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari event yang ingin diperbarui.


Body:

{
  "title": "Ujian Nasional 2023",
  "description": "Ujian tahunan nasional 2023",
  "date": "2023-07-14",
  "startTime": "09:00:00",
  "endTime": "11:00:00"
}


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Ujian Nasional 2023",
  "description": "Ujian tahunan nasional 2023",
  "date": "2023-07-14",
  "startTime": "09:00:00",
  "endTime": "11:00:00"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/events/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Ujian Nasional 2023", "description": "Ujian tahunan nasional 2023", "date": "2023-07-14", "startTime": "09:00:00", "endTime": "11:00:00"}'


7.5 Menghapus Event

Endpoint: DELETE /events/:id

Deskripsi: Menghapus event berdasarkan ID.

Headers:

X-XSRF-TOKEN: <token-csrf>


Path Parameters:

| Nama | Tipe | Deskripsi| | id | String | ID dari event yang ingin dihapus.|


Contoh Response (200 OK):
{
  "message": "Event deleted successfully"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/events/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


8. User

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


8.1 Membuat Pengguna Baru

Endpoint: POST /users

Deskripsi: Membuat pengguna baru dengan detail yang diberikan.

Headers: X-XSRF-TOKEN: <token-csrf>

Body:

Nama Tipe Deskripsi
registeredNumber String Nomor registrasi pengguna.
name String Nama lengkap pengguna.
rankId Integer ID pangkat pengguna.
unitId Integer ID unit pengguna.
positionId Integer ID jabatan pengguna.
Contoh Response (201 Created):
{
  "id": 1,
  "registeredNumber": "1234567890",
  "name": "John Doe",
  "rankId": 2,
  "unitId": 1,
  "positionId": 3,
  "createdAt": "2024-09-14T12:00:00Z",
  "updatedAt": "2024-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/users \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Content-Type: application/json' \
-d '{"registeredNumber": "1234567890", "name": "John Doe", "rankId": 2, "unitId": 1, "positionId": 3}'


8.2 Mendapatkan Pengguna Berdasarkan ID

Endpoint: GET /users/:id

Deskripsi: Mengambil detail pengguna berdasarkan ID dan entitas terkait yang dipilih.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pengguna yang ingin diambil.


Query Parameters:

Nama Tipe Deskripsi
entities String Daftar entitas terkait (misal: name,unit,rank).
option String Opsi untuk menampilkan data lengkap dengan riwayat.


Contoh Response (200 OK):
{
  "id": 1,
  "registeredNumber": "1234567890",
  "name": "John Doe",
  "rankId": 2,
  "unitId": 1,
  "positionId": 3,
  "rank": {
    "id": 2,
    "title": "Lieutenant"
  },
  "unit": {
    "id": 1,
    "name": "Unit A"
  },
  "position": {
    "id": 3,
    "title": "Commander"
  },
  "participants": []
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/users/1?entities=name,unit,rank


8.3 Mendapatkan Daftar Semua Pengguna

Endpoint: GET /users

Deskripsi: Mengambil daftar semua pengguna dengan opsi entitas terkait, pagination, dan sorting.

Query Parameters:

Nama Tipe Deskripsi
entities String Daftar entitas terkait (misal: name,unit,rank).
order String Urutan hasil (ASC atau DESC).
limit Integer Jumlah maksimum pengguna yang ingin diambil.
offset Integer Jumlah pengguna yang dilewatkan sebelum mengambil.
search String Pencarian berdasarkan nama pengguna.
unit Integer Filter berdasarkan ID unit.
rank Integer Filter berdasarkan ID pangkat.


Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 100,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "id": 1,
      "registeredNumber": "1234567890",
      "name": "John Doe",
      "rankId": 2,
      "unitId": 1,
      "positionId": 3
    },
    {
      "id": 2,
      "registeredNumber": "1234567891",
      "name": "Jane Doe",
      "rankId": 3,
      "unitId": 2,
      "positionId": 4
    }
  ]
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/users?entities=name,rank,unit&limit=10&offset=0&order=ASC&search=doe


8.4 Memperbarui Data Pengguna

Endpoint: PATCH /users/:id

Deskripsi: Memperbarui data pengguna berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari pengguna yang ingin diperbarui.

Body:

Nama Tipe Deskripsi
registeredNumber String Nomor registrasi pengguna. (opsional)
name String Nama lengkap pengguna. (opsional)
rankId Integer ID pangkat pengguna. (opsional)
unitId Integer ID unit pengguna. (opsional)
positionId Integer ID jabatan pengguna. (opsional)


Contoh Response (200 OK):
{
  "id": 1,
  "registeredNumber": "1234567890",
  "name": "John Doe Updated",
  "rankId": 2,
  "unitId": 1,
  "positionId": 3,
  "updatedAt": "2024-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/users/1 \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Content-Type: application/json' \
-d '{"name": "John Doe Updated"}'


9. Hasil Test Peserta

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


9.1 Mendapatkan Semua Test Response Berdasarkan ID Peserta

Endpoint: GET /test-response/participant/:participantId

Deskripsi: Mengambil semua test response yang terkait dengan ID peserta tertentu, beserta metadata.

Path Parameters:

Nama Tipe Deskripsi
participantId String ID dari peserta ujian yang ingin diambil.
Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 50,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "sectionId": 1,
      "sectionTitle": "Reading",
      "responses": [
        {
          "id": 1,
          "answer": "Paris",
          "participantId": 1,
          "questionId": 1,
          "packageId": 1,
          "eventId": 1,
          "audioResponseId": null,
          "score": 10,
          "createdAt": "2023-09-14T12:00:00Z",
          "updatedAt": "2023-09-14T12:00:00Z",
          "audio": null
        }
      ]
    }
  ]
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/test-response/participant/1 \
-H 'Cookie: adm-token=<your_auth_token>'


9.2 Mendapatkan Test Response Berdasarkan ID Pertanyaan

Endpoint: GET /test-response/question/:questionId/:participantId

Deskripsi: Mengambil test response yang terkait dengan ID pertanyaan tertentu dan ID peserta tertentu.

Path Parameters:

Nama Tipe Deskripsi
questionId String ID dari pertanyaan yang ingin diambil.
participantId String ID dari peserta ujian yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "answer": "Paris",
  "participantId": 1,
  "questionId": 1,
  "packageId": 1,
  "eventId": 1,
  "audioResponseId": null,
  "score": 10,
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z",
  "audio": null
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/test-response/question/1/1 \
-H 'Cookie: adm-token=<your_auth_token>'


9.3 Memperbarui Test Response Berdasarkan ID

Endpoint: PATCH /test-response/:id

Deskripsi: Memperbarui test response berdasarkan ID dengan data yang baru.

Headers:

X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari test response yang ingin diperbarui.

Body:

{
  "answer": "London",
  "score": 15
}


Contoh Response (200 OK):
{
  "id": 1,
  "answer": "London",
  "participantId": 1,
  "questionId": 1,
  "packageId": 1,
  "eventId": 1,
  "audioResponseId": null,
  "score": 15,
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:30:00Z",
  "audio": null
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/test-response/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"answer": "London", "score": 15}'


10. Peserta Ujian

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


10.1 Membuat Peserta Ujian Baru

Endpoint: POST /participants

Deskripsi: Membuat peserta ujian baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "name": "John Doe",
  "eventId": 1,
  "registeredNumber": "12345678"
}
Contoh Response (201 Created):
{
  "id": 1,
  "name": "John Doe",
  "eventId": 1,
  "registeredNumber": "12345678"
}
Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/participants \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-H 'Cookie: adm-token=<your_auth_token>'
-d '{"name": "John Doe", "eventId": 1, "registeredNumber": "12345678"}'
10.2 Mendapatkan Semua Peserta Ujian

Endpoint: GET /participants

Deskripsi: Mengambil daftar semua peserta ujian dengan opsi pagination dan sorting.

Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan peserta (ASC atau DESC).
limit Integer Jumlah maksimum peserta yang ingin diambil.
offset Integer Jumlah peserta yang dilewatkan sebelum mengambil data.
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: userId,eventId,totalScore,user).
search String Mencari peserta berdasarkan nama.


Contoh Response (200 OK):

json { "metadata": { "totalItems": 100, "currentPage": 1, "itemsPerPage": 10 }, "data": [ { "id": 1, "name": "John Doe", "eventId": 1, "registeredNumber": "12345678" } ] }

Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/participants?order=ASC&limit=10&offset=0 \
-H 'Cookie: adm-token=<your_auth_token>'


10.3 Mengunduh Template Excel Peserta Ujian

Endpoint: GET /participants/download-package-template

Deskripsi: Mengunduh file template Excel untuk mengunggah data peserta.


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/participants/download-package-template \
-H 'Cookie: adm-token=<your_auth_token>'


10.4 Menghasilkan URL dengan Token Pendaftaran

Endpoint: GET /participants/url-registration-token

Deskripsi: Menghasilkan URL dengan token pendaftaran untuk sebuah event.

Query Parameters:

Nama Tipe Deskripsi
eventId String ID dari event yang ingin dibuatkan token.


Contoh Response (201 Created):
{
  "url": "https://xx.xx.xx.xxx/registration?token=abcd1234"
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/participants/url-registration-token?eventId=1 \
-H 'Cookie: adm-token=<your_auth_token>'


10.5 Mengunggah Data Peserta via File Excel

Endpoint: POST /participants/upload-file

Deskripsi: Mengunggah data peserta menggunakan file Excel.

Headers:

X-XSRF-TOKEN: <token-csrf>
Cookie: adm-token=<your_auth_token>

Body (Multipart Form Data):

file: File Excel dengan format .xlsx.


Contoh Request (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/participants/upload-file \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-F 'file=@/path/to/excel-file.xlsx'
10.6 Mendapatkan Peserta Ujian Berdasarkan Event ID

Endpoint: GET /participants/event/:eventId

Deskripsi: Mengambil daftar peserta berdasarkan ID event dengan opsi pagination dan sorting.

Path Parameters:

Nama Tipe Deskripsi
eventId String ID dari event yang ingin diambil.


Query Parameters:

Nama Tipe Deskripsi
order String Mengurutkan peserta (ASC atau DESC).
limit Integer Jumlah maksimum peserta yang ingin diambil.
offset Integer Jumlah peserta yang dilewatkan sebelum mengambil data.
entities String Entitas terkait yang ingin disertakan dalam respons (contoh: userId,eventId,totalScore,user).
search String Mencari peserta berdasarkan nama.


Contoh Response (200 OK):
{
  "metadata": {
    "totalItems": 50,
    "currentPage": 1,
    "itemsPerPage": 10
  },
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "eventId": 1,
      "registeredNumber": "12345678"
    }
  ]
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/participants/event/1?order=ASC&limit=10&offset=0 \
-H 'Cookie: adm-token=<your_auth_token>'
10.7 Mendapatkan Peserta Ujian Berdasarkan ID

Endpoint: GET /participants/:id

Deskripsi: Mengambil detail peserta ujian berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari peserta ujian yang ingin diambil.


Query Parameters:

Nama Tipe Deskripsi
option String Tambahkan ?option=raw untuk respons dalam format raw, defaultnya compact prettified.


Contoh Response (200 OK):
{
  "id": 1,
  "name": "John Doe",
  "eventId": 1,
  "registeredNumber": "12345678"
}


Contoh Request (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/participants/1?option=raw \
-H 'Cookie: adm-token=<your_auth_token>'


11. Proctoring

Semua permintaan API terkait video proctoring.


11.1 Mendapatkan Video Berdasarkan ID Peserta

Endpoint: GET /video-proctor/participant/:participantId

Deskripsi: Mengambil semua video yang terkait dengan ID peserta tertentu.

Path Parameters:

Nama Tipe Deskripsi
participantId String ID dari peserta yang videonya diambil.
Contoh Response (200 OK):
[
  {
    "id": 1,
    "filename": "video1.webm",
    "participantId": 123
  },
  {
    "id": 2,
    "filename": "video2.webm",
    "participantId": 123
  }
]


Contoh Response (404 Not Found):
{
  "message": "No videos found for the participant."
}


11.2 Mendapatkan Semua Video Berdasarkan ID Event

Endpoint: GET /video-proctor/event/:eventId

Deskripsi: Mengambil semua video yang terkait dengan ID event tertentu.

Path Parameters:

Nama Tipe Deskripsi
eventId String ID dari event yang videonya diambil.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "filename": "video1.webm",
    "eventId": 456
  },
  {
    "id": 2,
    "filename": "video2.webm",
    "eventId": 456
  }
]


Contoh Response (404 Not Found):
{
  "message": "No videos found for the event."
}


11.3 Mendapatkan Video Berdasarkan Lokasi Spesifik

Endpoint: GET /video-proctor/:videoOption/:directory/:filename

Deskripsi: Mengambil video berdasarkan opsi, direktori, dan nama file yang ditentukan.

Path Parameters:

Nama Tipe Deskripsi
videoOption String Jenis opsi video (misal: "raw", "final").
directory String Direktori tempat file video disimpan.
filename String Nama file video yang diambil.


Contoh Response (200 OK):
Video akan langsung di-stream melalui respons.


Contoh Response (404 Not Found):
{
  "message": "Video file not found."
}


Contoh Response (500 Internal Server Error):
{
  "message": "Internal server error."
}


12. Jabatan

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


12.1 Membuat Jabatan Baru

Endpoint: POST /positions

Deskripsi: Membuat jabatan baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "title": "Manager"
}


Contoh Response (201 Created):
{
  "id": 1,
  "title": "Manager",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/positions \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Manager"}'


12.2 Mendapatkan Semua Jabatan

Endpoint: GET /positions

Deskripsi: Mengambil daftar semua jabatan yang ada.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "title": "Manager",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  },
  {
    "id": 2,
    "title": "Staff",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/positions \
-H 'Cookie: adm-token=<your_auth_token>'


12.3 Mendapatkan Jabatan Berdasarkan ID

Endpoint: GET /positions/:id

Deskripsi: Mengambil detail jabatan berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari jabatan yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Manager",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/positions/1 \
-H 'Cookie: adm-token=<your_auth_token>'


12.4 Memperbarui Jabatan Berdasarkan ID

Endpoint: PATCH /positions/:id

Deskripsi: Memperbarui detail jabatan yang ada berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari jabatan yang ingin diperbarui.


Body:

{
  "title": "Senior Manager"
}
Contoh Response (200 OK):
{
  "id": 1,
  "title": "Senior Manager",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T13:00:00Z"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/positions/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Senior Manager"}'


12.5 Menghapus Jabatan Berdasarkan ID

Endpoint: DELETE /positions/:id

Deskripsi: Menghapus jabatan berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari jabatan yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Position has been successfully deleted"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/positions/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


13. Pangkat (Ranks)

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


13.1 Membuat Pangkat Baru

Endpoint: POST /ranks

Deskripsi: Membuat pangkat baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "title": "Kolonel"
}


Contoh Response (201 Created):
{
  "id": 1,
  "title": "Kolonel",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/ranks \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Kolonel"}'


13.2 Mendapatkan Semua Pangkat

Endpoint: GET /ranks

Deskripsi: Mengambil daftar semua pangkat yang ada.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "title": "Kolonel",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  },
  {
    "id": 2,
    "title": "Mayor",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/ranks \
-H 'Cookie: adm-token=<your_auth_token>'


13.3 Mendapatkan Pangkat Berdasarkan ID

Endpoint: GET /ranks/:id

Deskripsi: Mengambil detail pangkat berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pangkat yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Kolonel",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/ranks/1 \
-H 'Cookie: adm-token=<your_auth_token>'


13.4 Memperbarui Pangkat Berdasarkan ID

Endpoint: PATCH /ranks/:id

Deskripsi: Memperbarui detail pangkat yang ada berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari pangkat yang ingin diperbarui.

Body:

{
  "title": "Brigadir Jenderal"
}


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Brigadir Jenderal",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T13:00:00Z"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/ranks/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Brigadir Jenderal"}'


13.5 Menghapus Pangkat Berdasarkan ID

Endpoint: DELETE /ranks/:id

Deskripsi: Menghapus pangkat berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari pangkat yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Rank has been successfully deleted"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/ranks/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


14. Satuan (Unit)

Semua permintaan API memerlukan autentikasi menggunakan JWT yang disimpan dalam cookie adm-token.


14.1 Membuat Satuan Baru

Endpoint: POST /units

Deskripsi: Membuat unit baru.

Headers:

X-XSRF-TOKEN: <token-csrf>

Body:

{
  "title": "Peleton"
}


Contoh Response (201 Created):
{
  "id": 1,
  "title": "Peleton",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X POST https://xx.xx.xx.xxx/v1/units \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Peleton"}'


14.2 Mendapatkan Semua Satuan

Endpoint: GET /units

Deskripsi: Mengambil daftar semua satuan yang ada.


Contoh Response (200 OK):
[
  {
    "id": 1,
    "title": "Peleteon",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  },
  {
    "id": 2,
    "title": "Batalyon",
    "createdAt": "2023-09-14T12:00:00Z",
    "updatedAt": "2023-09-14T12:00:00Z"
  }
]


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/units \
-H 'Cookie: adm-token=<your_auth_token>'


14.3 Mendapatkan Satuan Berdasarkan ID

Endpoint: GET /units/:id

Deskripsi: Mengambil detail Satuan berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari Satuan yang ingin diambil.


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Peleton",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T12:00:00Z"
}


Contoh Permintaan (Curl):
curl -X GET https://xx.xx.xx.xxx/v1/units/1 \
-H 'Cookie: adm-token=<your_auth_token>'


14.4 Memperbarui Satuan Berdasarkan ID

Endpoint: PATCH /units/:id

Deskripsi: Memperbarui detail Satuan yang ada berdasarkan ID.

Headers: X-XSRF-TOKEN: <token-csrf>


Path Parameters:

Nama Tipe Deskripsi
id String ID dari Satuan yang ingin diperbarui.

Body:

{
  "title": "Batalyon"
}


Contoh Response (200 OK):
{
  "id": 1,
  "title": "Batalyon",
  "createdAt": "2023-09-14T12:00:00Z",
  "updatedAt": "2023-09-14T13:00:00Z"
}


Contoh Permintaan (Curl):
curl -X PATCH https://xx.xx.xx.xxx/v1/units/1 \
-H 'Content-Type: application/json' \
-H 'X-XSRF-TOKEN: <token-csrf>' \
-d '{"title": "Batalyon"}'


14.5 Menghapus Satuan Berdasarkan ID

Endpoint: DELETE /units/:id

Deskripsi: Menghapus satuan berdasarkan ID.

Path Parameters:

Nama Tipe Deskripsi
id String ID dari satuan yang ingin dihapus.


Contoh Response (200 OK):
{
  "message": "Unit has been successfully deleted"
}


Contoh Permintaan (Curl):
curl -X DELETE https://xx.xx.xx.xxx/v1/units/1 \
-H 'X-XSRF-TOKEN: <token-csrf>'


15. Kode Status

Kode status yang umum digunakan dalam API ini meliputi:

Status Code Deskripsi
200 OK Permintaan berhasil dijalankan.
400 Bad Request Data permintaan tidak valid.
401 Unauthorized Token autentikasi tidak valid.
404 Not Found Resource yang diminta tidak ditemukan.
500 Internal Server Error Kesalahan server yang tidak terduga.













Deployment

Bagian ini menjelaskan pertimbangan dan kegiatan utama untuk deploy sistem Web Assessment dan Smartlab ke lingkungan produksi. Meskipun pilihan metode orkestrasi dan deployment (misalnya, Docker Swarm, Kubernetes, atau manajemen container manual) bergantung pada kebutuhan spesifik pengguna, langkah-langkah berikut memberikan contoh sistem diatur dengan aman dan efisien.

Containerization

Semua komponen utama dari sistem, termasuk Admin Backend, Assessment Backend, Storage Service, TURN Server (coturn), Redis, dan PostgreSQL, dikontainerisasi menggunakan Docker. Pendekatan ini memastikan bahwa sistem mudah di-deploy, skalabel, dan terisolasi dari potensi konflik di lingkungan host.

Setiap servis dijelaskan dalam file docker-compose.yml masing-masing atau dalam konfigurasi orkestrasi container lainnya.

Networking and Security
SSL/TLS Setup

Untuk memastikan komunikasi yang aman antara frontend dan backend, penting untuk mengonfigurasi sertifikat SSL/TLS. Karena sistem mungkin beroperasi menggunakan alamat IP alih-alih nama domain, digunakan sertifikat self-signed untuk enkripsi untuk lingkungan produksi.

Berikut adalah contoh cara mengatur sertifikat self-signed menggunakan openssl:

  1. Buat file san.cnf

    Create a san.cnf file with the following content to define the Subject Alternative Names (SAN) for your SSL certificate:

    [ req ]
    distinguished_name = req_distinguished_name
    req_extensions     = req_ext
    x509_extensions    = v3_req
    prompt             = no
    
    [ req_distinguished_name ]
    CN = xx.xx.xx.xxx
    
    [ req_ext ]
    subjectAltName = @alt_names
    
    [ v3_req ]
    subjectAltName = @alt_names
    
    [ alt_names ]
    IP.1 = xx.xx.xx.xxx
    
  2. Generate Penerbit (Issuer)

    Jalankan perintah berikut untuk menghasilkan private key dan sertifikat self-signed untuk Certificate Authority (CA):

    # Generate CA private key
    openssl genrsa -out smartlabCA.key 2048
    
    # Generate self-signed CA certificate
    openssl req -x509 -new -nodes -key smartlabCA.key -sha256 -days 3650 -out smartlabCA.crt -subj "/CN=Smartlab CA"
    
  3. Generate SSL Certificate

    Generate private key, CSR (Certificate Signing Request), dan SSL certificate menggunakan CA and konfigurasi SAN yang sudah dibuat.

    openssl genrsa -out self-signed-smartlab.key 2048
    
    openssl req -new -key self-signed-smartlab.key -out self-signed-smartlab.csr -config san.cnf
    
    openssl x509 -req -in self-signed-smartlab.csr -CA smartlabCA.crt -CAkey smartlabCA.key -CAcreateserial -out self-signed-smartlab.crt -days 365 -sha256 -extfile san.cnf -extensions req_ext
    

File yang dihasilkan:

 - smartlabCA.key: Root CA private key
 - smartlabCA.crt: Root CA certificate
 - self-signed-smartlab.csr: Server Certificate Signing Request
 - self-signed-smartlab.key: Server private key
 - self-signed-smartlab.crt: SSL certificate

File self-signed-smartlab.key dan self-signed-smartlab.crt digunakan dalam konfigurasi web server untuk mengaktifkan SSL.

File smartlabCA.crt, yang merupakan sertifikat Root Certificate Authority (CA), adalah file yang harus diinstal di perangkat mana pun yang perlu mempercayai sertifikat SSL self-signed. Langkah ini sangat penting karena memungkinkan sistem atau browser untuk mengenali sertifikat SSL yang Anda buat sebagai sertifikat yang dipercaya.

Pada banyak sistem (seperti Windows dan macOS), penginstallan bisa cukup dengan mengklik dua kali file smartlabCA.crt untuk membuka dialog instalasi sertifikat, yang akan menyederhanakan proses.

Web Server & Proxy

Web server bertanggung jawab untuk menangani trafik masuk, mengelola sertifikat SSL/TLS, dan mengarahkan permintaan ke servis yang sesuai. Bagian ini menjelaskan cara mengonfigurasi web server untuk sistem Web Assessment dan Smartlab menggunakan Caddy sebagai reverse proxy. Konfigurasi ini memastikan bahwa trafik dienkripsi menggunakan SSL/TLS, dan permintaan diarahkan ke servis yang tepat berdasarkan arsitektur sistem.

Caddy untuk Reverse Proxy dan Setup SSL/TLS
  • Contoh Konfigurasi Web Assessment Caddy:

    https://xx.xx.xx.xxx {
        handle /api/v1* {
            uri strip_prefix /api/v1
            reverse_proxy localhost:3010
        }
    
        #socketio
        handle /socket.io/* {
            reverse_proxy localhost:3010 {
                lb_policy cookie #cookie-based load balancing untuk sticky sessions
            }
        }
    
        handle /socket/* {
            reverse_proxy localhost:3010 {
                lb_policy cookie  #cookie-based load balancing untuk sticky sessions
            }
        }
    
        handle {
            reverse_proxy localhost:3000
        }
    
        tls /etc/caddy/certs/self-signed-smartlab.crt /etc/caddy/certs/self-signed-smartlab.key
    
    }
    

    Perhatikan pengaturan lb_policy cookie dalam konfigurasi Caddy. Pengaturan ini mengaktifkan sticky sessions. Sticky sessions atau session persistence sangat penting ketika memiliki beberapa instance backend atau menggunakan load balancing untuk servis yang mempertahankan koneksi long polling pada Socket.IO.