239 lines
6.2 KiB
Markdown
239 lines
6.2 KiB
Markdown
# Kaboot Backend API Documentation
|
|
|
|
The Kaboot backend provides a RESTful API for managing quizzes and user profiles.
|
|
|
|
## Base URL
|
|
The backend server runs at:
|
|
`http://localhost:3001`
|
|
|
|
## Authentication
|
|
All routes under `/api/*` require authentication using an OIDC Bearer token in the `Authorization` header.
|
|
|
|
```http
|
|
Authorization: Bearer <your_access_token>
|
|
```
|
|
|
|
Tokens are issued by the Authentik Identity Provider.
|
|
|
|
---
|
|
|
|
## Endpoints
|
|
|
|
### Health Check
|
|
|
|
#### GET /health
|
|
Check the operational status of the backend server.
|
|
|
|
- **Authentication**: None
|
|
- **Response**: `200 OK`
|
|
- **Example Response**:
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"timestamp": "2026-01-13T10:00:00.000Z"
|
|
}
|
|
```
|
|
- **Curl Example**:
|
|
```bash
|
|
curl http://localhost:3001/health
|
|
```
|
|
|
|
---
|
|
|
|
### User Profile
|
|
|
|
#### GET /api/users/me
|
|
Retrieve the profile of the currently authenticated user.
|
|
|
|
- **Authentication**: Required
|
|
- **Response**: `200 OK`
|
|
- **Example Response**:
|
|
```json
|
|
{
|
|
"id": "user_123",
|
|
"username": "jdoe",
|
|
"email": "jdoe@example.com",
|
|
"displayName": "John Doe",
|
|
"createdAt": "2026-01-13T10:00:00.000Z",
|
|
"lastLogin": "2026-01-13T10:00:00.000Z",
|
|
"isNew": false
|
|
}
|
|
```
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -H "Authorization: Bearer <token>" http://localhost:3001/api/users/me
|
|
```
|
|
|
|
---
|
|
|
|
### Quizzes
|
|
|
|
#### GET /api/quizzes
|
|
List all quizzes created by the authenticated user.
|
|
|
|
- **Authentication**: Required
|
|
- **Response**: `200 OK`
|
|
- **Example Response**:
|
|
```json
|
|
[
|
|
{
|
|
"id": "quiz_8b3f...",
|
|
"title": "World Capitals",
|
|
"source": "manual",
|
|
"aiTopic": null,
|
|
"createdAt": "2026-01-13T10:00:00.000Z",
|
|
"updatedAt": "2026-01-13T10:00:00.000Z",
|
|
"questionCount": 5
|
|
}
|
|
]
|
|
```
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -H "Authorization: Bearer <token>" http://localhost:3001/api/quizzes
|
|
```
|
|
|
|
#### GET /api/quizzes/:id
|
|
Retrieve full details for a specific quiz, including all questions and answer options.
|
|
|
|
- **Authentication**: Required
|
|
- **Response**: `200 OK` or `404 Not Found`
|
|
- **Example Response**:
|
|
```json
|
|
{
|
|
"id": "quiz_8b3f...",
|
|
"title": "World Capitals",
|
|
"source": "manual",
|
|
"aiTopic": null,
|
|
"createdAt": "2026-01-13T10:00:00.000Z",
|
|
"updatedAt": "2026-01-13T10:00:00.000Z",
|
|
"questions": [
|
|
{
|
|
"id": "question_456",
|
|
"text": "What is the capital of Japan?",
|
|
"timeLimit": 20,
|
|
"orderIndex": 0,
|
|
"options": [
|
|
{
|
|
"id": "option_789",
|
|
"text": "Tokyo",
|
|
"isCorrect": true,
|
|
"shape": "triangle",
|
|
"color": "red",
|
|
"reason": "Tokyo is the political and economic center of Japan.",
|
|
"orderIndex": 0
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -H "Authorization: Bearer <token>" http://localhost:3001/api/quizzes/quiz_8b3f...
|
|
```
|
|
|
|
#### POST /api/quizzes
|
|
Create a new quiz.
|
|
|
|
- **Authentication**: Required
|
|
- **Validation Rules**:
|
|
- `title`: Required, non-empty string.
|
|
- `source`: Required, must be `'manual'` or `'ai_generated'`.
|
|
- `questions`: Required, array with at least 1 question.
|
|
- **Question validation**:
|
|
- `text`: Required, non-empty string.
|
|
- `options`: Required, array with at least 2 options.
|
|
- Each option:
|
|
- `text`: Required, non-empty string.
|
|
- `isCorrect`: Required, boolean.
|
|
- `shape`: Required, one of `'triangle'`, `'diamond'`, `'circle'`, `'square'`.
|
|
- `color`: Required, one of `'red'`, `'blue'`, `'yellow'`, `'green'`.
|
|
- `reason`: Optional, string explaining the answer.
|
|
- At least one option must be marked as correct (`isCorrect: true`).
|
|
- **Request Body**:
|
|
```json
|
|
{
|
|
"title": "Space Exploration",
|
|
"source": "manual",
|
|
"questions": [
|
|
{
|
|
"text": "Which planet is known as the Red Planet?",
|
|
"timeLimit": 20,
|
|
"options": [
|
|
{ "text": "Mars", "isCorrect": true, "shape": "triangle", "color": "red" },
|
|
{ "text": "Venus", "isCorrect": false, "shape": "diamond", "color": "blue" }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
- **Response**: `201 Created`
|
|
- **Example Response**:
|
|
```json
|
|
{
|
|
"id": "new_quiz_uuid"
|
|
}
|
|
```
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
|
|
-d '{"title":"Space Quiz","source":"manual","questions":[{"text":"Which planet is known as the Red Planet?","options":[{"text":"Mars","isCorrect":true,"shape":"triangle","color":"red"},{"text":"Venus","isCorrect":false,"shape":"diamond","color":"blue"}]}]}' \
|
|
http://localhost:3001/api/quizzes
|
|
```
|
|
|
|
#### PUT /api/quizzes/:id
|
|
Update an existing quiz. This operation replaces the existing questions and options.
|
|
|
|
- **Authentication**: Required
|
|
- **Validation Rules**: Same as `POST /api/quizzes`.
|
|
- **Response**: `200 OK` or `404 Not Found`
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -X PUT -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
|
|
-d '{"title":"Updated Space Quiz","questions":[{"text":"Which planet is red?","options":[{"text":"Mars","isCorrect":true,"shape":"triangle","color":"red"},{"text":"Venus","isCorrect":false,"shape":"diamond","color":"blue"}]}]}' \
|
|
http://localhost:3001/api/quizzes/quiz_uuid
|
|
```
|
|
|
|
#### DELETE /api/quizzes/:id
|
|
Permanently delete a quiz.
|
|
|
|
- **Authentication**: Required
|
|
- **Response**: `204 No Content` or `404 Not Found`
|
|
- **Curl Example**:
|
|
```bash
|
|
curl -X DELETE -H "Authorization: Bearer <token>" http://localhost:3001/api/quizzes/quiz_uuid
|
|
```
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
The API returns standard HTTP status codes along with a JSON error object.
|
|
|
|
- **400 Bad Request**
|
|
Returned when the request body is invalid or validation fails.
|
|
```json
|
|
{ "error": "Title is required and cannot be empty" }
|
|
```
|
|
|
|
- **401 Unauthorized**
|
|
Returned when the Bearer token is missing, expired, or invalid.
|
|
```json
|
|
{ "error": "Missing or invalid authorization header" }
|
|
```
|
|
or
|
|
```json
|
|
{ "error": "Invalid token", "details": "..." }
|
|
```
|
|
|
|
- **404 Not Found**
|
|
Returned when the requested quiz does not exist or does not belong to the user.
|
|
```json
|
|
{ "error": "Quiz not found" }
|
|
```
|
|
|
|
- **500 Internal Server Error**
|
|
Returned when an unexpected error occurs on the server.
|
|
```json
|
|
{ "error": "Internal server error" }
|
|
```
|