HoshiAI-be/storage/api-docs/api-docs.json
2025-11-11 21:45:51 +01:00

2492 lines
100 KiB
JSON

{
"openapi": "3.0.0",
"info": {
"title": "HoshiAI API",
"description": "Documentaion for project",
"version": "1.0.0"
},
"paths": {
"/api/auth/register": {
"post": {
"tags": [
"Auth"
],
"summary": "Register a new user",
"operationId": "d764dd091cc4494ae0baf360b03319f3",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"username",
"email",
"password",
"password_confirmation"
],
"properties": {
"username": {
"type": "string",
"maxLength": 100,
"example": "root"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 100,
"example": "root@example.com"
},
"password": {
"type": "string",
"format": "password",
"example": "123456"
},
"password_confirmation": {
"type": "string",
"format": "password",
"example": "123456"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "User registered successfully. Confirmation email sent.",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "You successfully registered! Please, confirm your account using email"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"email": [
"The email has already been taken."
],
"password": [
"The password must be at least 6 characters."
]
}
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/auth/login": {
"post": {
"tags": [
"Auth"
],
"summary": "User login",
"operationId": "8dcb70df1020986038d098cc08d05dae",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "root@example.com"
},
"password": {
"type": "string",
"format": "password",
"example": "123456"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Login successful",
"content": {
"application/json": {
"schema": {
"properties": {
"access_token": {
"type": "string",
"example": "1|JfjOc5DkOHHTtWnM4SdpLM0BR0YvpycoeNAWanlH1305fab7"
},
"token_type": {
"type": "string",
"example": "Bearer"
},
"user": {
"$ref": "#/components/schemas/UserResource"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Invalid credentials",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Invalid credentials"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Email not verified",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Please verify your email first"
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/auth/logout": {
"post": {
"tags": [
"Auth"
],
"summary": "Logout current user",
"operationId": "69281b12abb272c76871f19cb17ca563",
"responses": {
"200": {
"description": "Successfully logged out",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Successfully logged out"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthenticated",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Unauthenticated"
}
},
"type": "object"
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/auth/forgot-password": {
"post": {
"tags": [
"Auth"
],
"summary": "Send password reset link to user email",
"operationId": "cff9b52a898f73f39d684747bd69c4e1",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "user@example.com"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Password reset link sent successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Password reset link has been sent to your email. Please check your inbox."
}
},
"type": "object"
}
}
}
},
"404": {
"description": "User not found",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "User is not found"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"email": [
"The email must be a valid email address."
]
}
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/auth/reset-password": {
"post": {
"tags": [
"Auth"
],
"summary": "Reset user password using token",
"operationId": "6af92e090f994419a2295111b391a205",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"token",
"password",
"password_confirmation"
],
"properties": {
"token": {
"type": "string",
"example": "abcdef123456"
},
"password": {
"type": "string",
"format": "password",
"example": "newpassword123"
},
"password_confirmation": {
"type": "string",
"format": "password",
"example": "newpassword123"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Password reset successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Your password was successfully changed!"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Invalid token",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Your token is not valid"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"password": [
"The password must be at least 6 characters."
],
"password_confirmation": [
"The password confirmation does not match."
]
}
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/auth/confirmation-account": {
"post": {
"tags": [
"Auth"
],
"summary": "Confirm user account via email verification token",
"operationId": "c8ecdf6fd50dc4c70fcc5bf19233e462",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"token"
],
"properties": {
"token": {
"type": "string",
"example": "abcdef123456"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Account successfully activated",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Your account was successfully activated"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Invalid token",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Your token is not valid"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"token": [
"The token field is required."
]
}
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/auth/me": {
"get": {
"tags": [
"Auth"
],
"summary": "Get current user info",
"operationId": "b9abb1a7a74670a19c215c2c133f14d8",
"responses": {
"200": {
"description": "User info",
"content": {
"application/json": {
"schema": {
"properties": {
"user": {
"$ref": "#/components/schemas/UserResource"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/categories": {
"get": {
"tags": [
"Categories"
],
"summary": "Get all categories",
"operationId": "3f5817a34833d0a1f4af4548dd3aeaba",
"responses": {
"200": {
"description": "List of categories",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CategoryResource"
}
}
}
}
}
},
"security": [
{
"bearerAuth": []
}
]
},
"post": {
"tags": [
"Categories"
],
"summary": "Create a new category (only admin)",
"operationId": "71fcad552bb0eaba9fb191fd8d8dcab0",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Physics"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Category created successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CategoryResource"
}
}
}
},
"403": {
"description": "Forbidden"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/categories/{id}": {
"get": {
"tags": [
"Categories"
],
"summary": "Get a specific category",
"operationId": "c68e76d323c008827a9e47398b1583de",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the category",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Category retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CategoryResource"
}
}
}
},
"404": {
"description": "Category not found"
}
}
},
"put": {
"tags": [
"Categories"
],
"summary": "Update a category (only admin)",
"operationId": "0e686b2748211cc688333ed705dc111f",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the category",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Physics Updated"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Category updated successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CategoryResource"
}
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Category not found"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Categories"
],
"summary": "Delete a category (only admin)",
"operationId": "4c12e22a7f8c617bd83bfa1fdc05428d",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the category",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Category deleted successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The category was deleted"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Category not found"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/hitcounts": {
"get": {
"tags": [
"Hitcounts"
],
"summary": "Get list of hitcounts (paginated, only admin)",
"description": "Returns a paginated list of all recorded hitcounts. Requires admin privileges.",
"operationId": "getHitcounts",
"responses": {
"200": {
"description": "List of hitcounts",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/HitcountResource"
}
},
"links": {
"type": "object"
},
"meta": {
"type": "object"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthenticated"
},
"403": {
"description": "Forbidden (not admin)"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/hitcounts/{id}": {
"get": {
"tags": [
"Hitcounts"
],
"summary": "Get a specific hitcount (only admin)",
"description": "Returns detailed information about a specific hitcount. Requires admin privileges.",
"operationId": "getHitcount",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Hitcount ID",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Hitcount details",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HitcountResource"
}
}
}
},
"401": {
"description": "Unauthenticated"
},
"403": {
"description": "Forbidden (not admin)"
},
"404": {
"description": "Not Found"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Hitcounts"
],
"summary": "Delete a hitcount (only admin)",
"description": "Deletes a specific hitcount entry. Requires admin privileges.",
"operationId": "deleteHitcount",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Hitcount ID to delete",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Hitcount deleted successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The hitcount was deleted"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthenticated"
},
"403": {
"description": "Forbidden (not admin)"
},
"404": {
"description": "Not Found"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/hit": {
"post": {
"tags": [
"Hitcounts"
],
"summary": "Register a hit for a URL",
"description": "Stores information about a visit, including IP, device, user agent, and country",
"operationId": "8297226e4c0d09764edb0821edbf282f",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 255,
"example": "https://my-application.com"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Hitcount successfully set",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The hitcount is set"
}
},
"type": "object"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"url": [
"The url field is required."
]
}
}
},
"type": "object"
}
}
}
}
}
}
},
"/api/logs": {
"get": {
"tags": [
"Logs"
],
"summary": "Get all logs (paginated, only admin)",
"operationId": "07258c00ce1b2cbc7c7151a7cc8ca986",
"responses": {
"200": {
"description": "List of logs",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LogResource"
}
}
}
}
},
"403": {
"description": "Forbidden"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/logs/{id}": {
"get": {
"tags": [
"Logs"
],
"summary": "Get a specific log (only admin)",
"operationId": "caa09131dde473dca25ea025d181146a",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the log",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Log retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LogResource"
}
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Log not found"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Logs"
],
"summary": "Delete a specific log (only admin)",
"operationId": "2a0e57b9168eaca7e207f5b35f469666",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the log",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "Log deleted successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "This log is successfully deleted"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Log not found"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/questions": {
"get": {
"tags": [
"Questions"
],
"summary": "Get a paginated list of questions (paginated)",
"description": "Retrieve questions. Optional filter by category_id.",
"operationId": "e64d3c7a745fc05662a4a1e1eb3d96ab",
"parameters": [
{
"name": "category_id",
"in": "query",
"description": "Filter questions by category ID",
"required": false,
"schema": {
"type": "integer"
}
},
{
"name": "page",
"in": "query",
"description": "Page number for pagination",
"required": false,
"schema": {
"type": "integer",
"default": 1
}
}
],
"responses": {
"200": {
"description": "Paginated list of questions",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/QuestionResource"
}
},
"links": {
"type": "object",
"example": {
"first": "http://localhost/api/questions?page=1",
"last": "http://localhost/api/questions?page=10",
"prev": null,
"next": "http://localhost/api/questions?page=2"
}
},
"meta": {
"type": "object",
"example": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "http://localhost/api/questions",
"per_page": 15,
"to": 15,
"total": 150
}
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthorized"
}
}
},
"post": {
"tags": [
"Questions"
],
"summary": "Create a new question (only admin or creator)",
"description": "Store a new question in the system.",
"operationId": "788d85763184ddf1b557afb040547f32",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"title",
"type",
"difficulty",
"variants",
"correct_answers"
],
"properties": {
"title": {
"type": "string",
"maxLength": 255,
"example": "Sample question"
},
"description": {
"type": "string",
"example": "Optional description",
"nullable": true
},
"type": {
"type": "string",
"enum": [
"single",
"multiply",
"text"
],
"example": "single"
},
"difficulty": {
"type": "integer",
"example": 2
},
"variants": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"text": {
"type": "string",
"example": "Option 1"
}
},
"type": "object"
}
},
"correct_answers": {
"type": "array",
"items": {
"type": "integer",
"example": 1
}
},
"category_id": {
"type": "integer",
"example": 3,
"nullable": true
},
"is_pending_question": {
"type": "integer",
"example": 0
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Question created successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuestionResource"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Validation error"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/questions/{id}": {
"get": {
"tags": [
"Questions"
],
"summary": "Get a single question",
"description": "Retrieve a single question by its ID, including author and category",
"operationId": "bea45702e58c27163e9dc928d8984dfa",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the question to retrieve",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Question retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuestionResource"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Question not found"
}
}
},
"put": {
"tags": [
"Questions"
],
"summary": "Update a question (only admin or creator)",
"description": "Update an existing question by ID.",
"operationId": "795b02e5ecdc23fd74f20e0671a40f8c",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the question to update",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"title",
"type",
"difficulty",
"variants",
"correct_answers"
],
"properties": {
"title": {
"type": "string",
"maxLength": 255,
"example": "Updated question"
},
"description": {
"type": "string",
"example": "Updated description",
"nullable": true
},
"type": {
"type": "string",
"enum": [
"single",
"multiply",
"text"
],
"example": "multiply"
},
"difficulty": {
"type": "integer",
"example": 3
},
"variants": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"text": {
"type": "string",
"example": "Option 1"
}
},
"type": "object"
}
},
"correct_answers": {
"type": "array",
"items": {
"type": "integer",
"example": 1
}
},
"category_id": {
"type": "integer",
"example": 2,
"nullable": true
},
"is_pending_question": {
"type": "integer",
"example": 0
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Question updated successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuestionResource"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Validation error"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Questions"
],
"summary": "Delete a question (only admin or creator)",
"description": "Delete a question by ID .",
"operationId": "b2cbd34337a604c75c8a94f1a6e2f252",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of the question to delete",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Question deleted successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The hitcount was deleted"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Question not found"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/tests": {
"get": {
"tags": [
"Tests"
],
"summary": "Get a list of tests (paginated)",
"description": "Retrieve a paginated list of tests. Optionally filter by category_id.",
"operationId": "5f539f69bb1d910182eb35136c5baa3a",
"parameters": [
{
"name": "category_id",
"in": "query",
"description": "Filter tests by category ID",
"required": false,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Paginated list of tests",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TestResource"
}
},
"links": {
"properties": {
"first": {
"type": "string",
"example": "http://api.example.com/tests?page=1"
},
"last": {
"type": "string",
"example": "http://api.example.com/tests?page=10"
},
"prev": {
"type": "string",
"example": null,
"nullable": true
},
"next": {
"type": "string",
"example": "http://api.example.com/tests?page=2",
"nullable": true
}
},
"type": "object"
},
"meta": {
"properties": {
"current_page": {
"type": "integer",
"example": 1
},
"from": {
"type": "integer",
"example": 1
},
"last_page": {
"type": "integer",
"example": 10
},
"path": {
"type": "string",
"example": "http://api.example.com/tests"
},
"per_page": {
"type": "integer",
"example": 15
},
"to": {
"type": "integer",
"example": 15
},
"total": {
"type": "integer",
"example": 150
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthorized"
}
}
},
"post": {
"tags": [
"Tests"
],
"summary": "Create a new test (only admin or creator)",
"description": "Store a new test in the system (only admin or creator).",
"operationId": "7728a2f3dd87105d6d617df9a3f231d4",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"title",
"closed_at",
"questions"
],
"properties": {
"title": {
"type": "string",
"maxLength": 255,
"example": "Sample Test"
},
"description": {
"type": "string",
"example": "Optional description",
"nullable": true
},
"closed_at": {
"type": "string",
"format": "date-time",
"example": "2025-12-01T23:59:59Z",
"nullable": true
},
"category_id": {
"type": "integer",
"example": 3,
"nullable": true
},
"questions": {
"description": "Array of question IDs to attach to this test",
"type": "array",
"items": {
"type": "integer",
"example": 1
}
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Test created successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TestResource"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Validation error"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/tests/{id}": {
"get": {
"tags": [
"Tests"
],
"summary": "Get a single test",
"description": "Retrieve a single test with its questions, category, and author",
"operationId": "7e3d8428f4df82c6d4ee7bd1d4d2128c",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Test ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Test retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TestResource"
}
}
}
},
"404": {
"description": "Test not found"
}
}
},
"put": {
"tags": [
"Tests"
],
"summary": "Update a test (only admin or creator)",
"description": "Update a test's data and associated questions (only admin/creator).",
"operationId": "ca1490751234c723e0a4a708afe16dd6",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Test ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"title",
"questions"
],
"properties": {
"title": {
"type": "string",
"maxLength": 255,
"example": "Updated Test Title"
},
"description": {
"type": "string",
"example": "Optional description",
"nullable": true
},
"category_id": {
"type": "integer",
"example": 3,
"nullable": true
},
"closed_at": {
"type": "string",
"format": "date-time",
"example": "2025-12-01T23:59:59Z",
"nullable": true
},
"questions": {
"description": "Array of question IDs to attach to this test",
"type": "array",
"items": {
"type": "integer",
"example": 1
}
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Test updated successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TestResource"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Validation error"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Tests"
],
"summary": "Delete a test (only admin or creator)",
"description": "Delete a test by ID (only admin or creator).",
"operationId": "92f76a68796679554c71a4659f62b296",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Test ID",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Test deleted successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The test was deleted"
}
},
"type": "object"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Test not found"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/users": {
"get": {
"tags": [
"Users"
],
"summary": "Get list of users (paginated, only admin)",
"operationId": "c457726701591d1183b53aa71fc13441",
"responses": {
"200": {
"description": "List of users retrieved successfully",
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserResource"
}
},
"links": {
"type": "object"
},
"meta": {
"type": "object"
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden — user is not authorized to view users"
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"post": {
"tags": [
"Users"
],
"summary": "Create a new user (only admin)",
"operationId": "592819a0265360b2014512d6dbfaf0e7",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"username",
"email",
"password",
"type"
],
"properties": {
"username": {
"type": "string",
"maxLength": 100,
"example": "newuser"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 100,
"example": "newuser@example.com"
},
"password": {
"type": "string",
"format": "password",
"example": "secret123"
},
"type": {
"type": "string",
"enum": [
"admin",
"user"
],
"example": "user"
}
},
"type": "object"
}
}
}
},
"responses": {
"201": {
"description": "User created successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserResource"
}
}
}
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"email": [
"The email has already been taken."
],
"password": [
"The password must be at least 6 characters."
]
}
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden — only admins can create users"
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"/api/users/{id}": {
"get": {
"tags": [
"Users"
],
"summary": "Get a specific user (only admin)",
"operationId": "36a33ff774d5cba33c039dec2c3e0287",
"parameters": [
{
"name": "id",
"in": "path",
"description": "User ID",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"200": {
"description": "User retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserResource"
}
}
}
},
"404": {
"description": "User not found"
},
"403": {
"description": "Forbidden — user not authorized to view this resource"
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"put": {
"tags": [
"Users"
],
"summary": "Update an existing user (only admin)",
"operationId": "b9091397c8b25f12c6adb74be6ce3a5a",
"parameters": [
{
"name": "id",
"in": "path",
"description": "User ID",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"required": [
"username",
"email",
"password",
"type"
],
"properties": {
"username": {
"type": "string",
"maxLength": 100,
"example": "updated_user"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 100,
"example": "updated_user@example.com"
},
"password": {
"type": "string",
"format": "password",
"example": "newpassword123"
},
"type": {
"type": "string",
"enum": [
"admin",
"user"
],
"example": "user"
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "User updated successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserResource"
}
}
}
},
"404": {
"description": "User not found"
},
"422": {
"description": "Validation error",
"content": {
"application/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "The given data was invalid."
},
"errors": {
"type": "object",
"example": {
"email": [
"The email has already been taken."
],
"password": [
"The password must be at least 6 characters."
]
}
}
},
"type": "object"
}
}
}
},
"403": {
"description": "Forbidden — only admins can update users"
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
},
"delete": {
"tags": [
"Users"
],
"summary": "Delete a user (only admin)",
"operationId": "fa56cffde745d3f152f95cbacd936c0b",
"parameters": [
{
"name": "id",
"in": "path",
"description": "User ID",
"required": true,
"schema": {
"type": "integer",
"example": 1
}
}
],
"responses": {
"204": {
"description": "User deleted successfully (no content)"
},
"404": {
"description": "User not found"
},
"403": {
"description": "Forbidden — only admins can delete users"
},
"401": {
"description": "Unauthenticated"
}
},
"security": [
{
"bearerAuth": []
}
]
}
}
},
"components": {
"schemas": {
"CategoryResource": {
"title": "Category",
"description": "Category resource with dynamic count",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "Books"
},
"created_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-10T18:00:00Z"
},
"count": {
"description": "Dynamic count of related items",
"type": "integer",
"example": 5
}
},
"type": "object"
},
"HitcountResource": {
"title": "Hitcount",
"description": "Hitcount resource",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"ip": {
"type": "string",
"example": "127.0.0.1"
},
"device_type": {
"type": "string",
"example": "desktop"
},
"user_agent": {
"type": "string",
"example": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0"
},
"country": {
"type": "string",
"example": "Japan"
},
"url": {
"type": "string",
"example": "https://my-application.com"
},
"created_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-10T17:45:00.000000Z"
}
},
"type": "object"
},
"LogResource": {
"title": "Log",
"description": "Log resource",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"description": {
"type": "string",
"example": "User logged in"
},
"created_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-10T17:45:00.000000Z"
}
},
"type": "object"
},
"QuestionResource": {
"title": "Question",
"description": "Question resource",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"title": {
"type": "string",
"example": "What is the capital of Japan?"
},
"description": {
"type": "string",
"example": "Choose the correct option",
"nullable": true
},
"type": {
"type": "string",
"enum": [
"single",
"multiply",
"text"
],
"example": "single"
},
"difficulty": {
"type": "integer",
"example": 3
},
"variants": {
"type": "array",
"items": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"text": {
"type": "string",
"example": "Tokyo"
}
},
"type": "object"
},
"nullable": true
},
"correct_answers": {
"type": "array",
"items": {
"type": "integer",
"example": 1
}
},
"is_pending_question": {
"type": "integer",
"example": 0
},
"category_id": {
"type": "integer",
"example": 3,
"nullable": true
},
"category": {
"$ref": "#/components/schemas/CategoryResource"
},
"author_id": {
"type": "integer",
"example": 2,
"nullable": true
},
"author": {
"$ref": "#/components/schemas/UserResource"
},
"created_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-11T10:00:00.000000Z"
},
"updated_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-11T10:05:00.000000Z"
}
},
"type": "object"
},
"TestResource": {
"title": "Test",
"description": "Test resource",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"title": {
"type": "string",
"example": "Sample Test"
},
"description": {
"type": "string",
"example": "Optional description",
"nullable": true
},
"category_id": {
"type": "integer",
"example": 3,
"nullable": true
},
"category": {
"$ref": "#/components/schemas/CategoryResource"
},
"questions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/QuestionResource"
}
},
"author_id": {
"type": "integer",
"example": 2,
"nullable": true
},
"author": {
"$ref": "#/components/schemas/UserResource"
},
"closed_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-11T10:30:00Z",
"nullable": true
},
"created_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-11T10:00:00Z"
},
"updated_at": {
"type": "string",
"format": "date-time",
"example": "2025-11-11T10:15:00Z"
}
},
"type": "object"
},
"UserResource": {
"properties": {
"id": {
"type": "integer",
"example": 1
},
"username": {
"type": "string",
"example": "root"
},
"email": {
"type": "string",
"example": "root@example.com"
},
"email_verified_at": {
"type": "string",
"format": "date-time"
},
"type": {
"type": "string",
"example": "user"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"type": "object"
}
},
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
}
},
"tags": [
{
"name": "Auth",
"description": "Auth"
},
{
"name": "Categories",
"description": "Categories"
},
{
"name": "Hitcounts",
"description": "Hitcounts"
},
{
"name": "Logs",
"description": "Logs"
},
{
"name": "Questions",
"description": "Questions"
},
{
"name": "Tests",
"description": "Tests"
},
{
"name": "Users",
"description": "Users"
}
]
}