{ "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" } ] }