{ "swagger": "2.0", "info": { "description": "REST API for Ristek Task Backend", "title": "Ristek Task API", "contact": {}, "version": "1.0" }, "host": "localhost:8080", "basePath": "/", "paths": { "/api/auth/login": { "post": { "description": "Authenticate with email and password to receive access and refresh tokens", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Login", "parameters": [ { "description": "Login credentials", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.Auth" } } ], "responses": { "200": { "description": "access_token, refresh_token, expires_in", "schema": { "type": "object", "additionalProperties": true } }, "400": { "description": "Bad request", "schema": { "type": "string" } }, "401": { "description": "Unauthorized (invalid credentials)", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/logout": { "post": { "description": "Invalidate the given refresh token to log out the current session", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Logout", "parameters": [ { "description": "Refresh token to invalidate", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.LogoutRequest" } } ], "responses": { "204": { "description": "No Content" }, "400": { "description": "Bad request", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/logout/all": { "delete": { "security": [ { "BearerAuth": [] } ], "description": "Invalidate all refresh tokens for the authenticated user", "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Logout all sessions", "responses": { "204": { "description": "No Content" }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/me": { "get": { "security": [ { "BearerAuth": [] } ], "description": "Return profile information for the authenticated user", "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Get current user", "responses": { "200": { "description": "id, email, created_at, updated_at", "schema": { "type": "object", "additionalProperties": true } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/me/password": { "patch": { "security": [ { "BearerAuth": [] } ], "description": "Update the password of the currently authenticated user", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Change password", "parameters": [ { "description": "Old and new password", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.ChangePasswordRequest" } } ], "responses": { "204": { "description": "No Content" }, "400": { "description": "Bad request (e.g. incorrect old password)", "schema": { "type": "string" } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/refresh": { "post": { "description": "Exchange a valid refresh token for a new access token and refresh token pair", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Refresh access token", "parameters": [ { "description": "Refresh token payload", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.RefreshRequest" } } ], "responses": { "200": { "description": "access_token, refresh_token, expires_in", "schema": { "type": "object", "additionalProperties": true } }, "400": { "description": "Bad request", "schema": { "type": "string" } }, "401": { "description": "Unauthorized (invalid or expired refresh token)", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/auth/register": { "post": { "description": "Create a new user account with email and password", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "auth" ], "summary": "Register a new user", "parameters": [ { "description": "Register credentials", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.Auth" } } ], "responses": { "201": { "description": "Created" }, "400": { "description": "Bad request (e.g. email already exists, password too short)", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/form": { "post": { "security": [ { "BearerAuth": [] } ], "description": "Create a new form with title, description, and questions for the authenticated user", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Create a form", "parameters": [ { "description": "Form creation payload", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.CreateFormRequest" } } ], "responses": { "201": { "description": "Created form", "schema": { "$ref": "#/definitions/handler.FormResponse" } }, "400": { "description": "Bad request (e.g. title is required)", "schema": { "type": "string" } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/form/{id}": { "get": { "description": "Retrieve a form and its questions by form ID (publicly accessible)", "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Get a form", "parameters": [ { "type": "string", "description": "Form ID (UUID)", "name": "id", "in": "path", "required": true } ], "responses": { "200": { "description": "Form details", "schema": { "$ref": "#/definitions/handler.FormResponse" } }, "400": { "description": "Invalid form ID", "schema": { "type": "string" } }, "404": { "description": "Form not found", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } }, "put": { "security": [ { "BearerAuth": [] } ], "description": "Replace a form's title, description, and questions. Only the form owner can update it", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Update a form", "parameters": [ { "type": "string", "description": "Form ID (UUID)", "name": "id", "in": "path", "required": true }, { "description": "Form update payload", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.UpdateFormRequest" } } ], "responses": { "200": { "description": "Updated form", "schema": { "$ref": "#/definitions/handler.FormResponse" } }, "400": { "description": "Bad request (e.g. title is required)", "schema": { "type": "string" } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "403": { "description": "Forbidden (not the form owner)", "schema": { "type": "string" } }, "404": { "description": "Form not found", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } }, "delete": { "security": [ { "BearerAuth": [] } ], "description": "Delete a form by ID. Only the form owner can delete it. Deletion is blocked if the form already has responses", "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Delete a form", "parameters": [ { "type": "string", "description": "Form ID (UUID)", "name": "id", "in": "path", "required": true } ], "responses": { "204": { "description": "No Content" }, "400": { "description": "Invalid form ID", "schema": { "type": "string" } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "403": { "description": "Forbidden (not the form owner)", "schema": { "type": "string" } }, "404": { "description": "Form not found", "schema": { "type": "string" } }, "409": { "description": "Conflict (form already has responses)", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/form/{id}/response": { "post": { "security": [ { "BearerAuth": [] } ], "description": "Submit answers to a form's questions. Authentication is optional (anonymous submissions allowed). Required questions must be answered. Choice answers must match valid options", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Submit a form response", "parameters": [ { "type": "string", "description": "Form ID (UUID)", "name": "id", "in": "path", "required": true }, { "description": "Response answers payload", "name": "body", "in": "body", "required": true, "schema": { "$ref": "#/definitions/handler.SubmitResponseRequest" } } ], "responses": { "201": { "description": "Submitted response", "schema": { "$ref": "#/definitions/handler.SubmitResponseResponse" } }, "400": { "description": "Bad request (e.g. invalid answer, missing required question)", "schema": { "type": "string" } }, "404": { "description": "Form not found", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/form/{id}/responses": { "get": { "security": [ { "BearerAuth": [] } ], "description": "Retrieve all submitted responses for a form. Only the form owner can access this", "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "Get form responses", "parameters": [ { "type": "string", "description": "Form ID (UUID)", "name": "id", "in": "path", "required": true } ], "responses": { "200": { "description": "List of form responses with answers", "schema": { "type": "array", "items": { "$ref": "#/definitions/handler.SubmitResponseResponse" } } }, "400": { "description": "Invalid form ID", "schema": { "type": "string" } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "403": { "description": "Forbidden (not the form owner)", "schema": { "type": "string" } }, "404": { "description": "Form not found", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/api/forms": { "get": { "security": [ { "BearerAuth": [] } ], "description": "Retrieve all forms belonging to the authenticated user, with optional search, status filter, and sort options", "produces": [ "application/json" ], "tags": [ "forms" ], "summary": "List forms", "parameters": [ { "type": "string", "description": "Filter by title (case-insensitive)", "name": "search", "in": "query" }, { "type": "string", "description": "Filter by response status: has_responses | no_responses", "name": "status", "in": "query" }, { "type": "string", "description": "Sort field: created_at (default) | updated_at", "name": "sort_by", "in": "query" }, { "type": "string", "description": "Sort direction: newest (default) | oldest", "name": "sort_dir", "in": "query" } ], "responses": { "200": { "description": "List of forms", "schema": { "type": "array", "items": { "$ref": "#/definitions/handler.FormResponse" } } }, "401": { "description": "Unauthorized", "schema": { "type": "string" } }, "500": { "description": "Internal server error", "schema": { "type": "string" } } } } }, "/health": { "get": { "description": "Returns 200 OK if the server is running", "produces": [ "text/plain" ], "tags": [ "health" ], "summary": "Health check", "responses": { "200": { "description": "OK", "schema": { "type": "string" } } } } } }, "definitions": { "handler.AnswerInput": { "type": "object", "properties": { "answer": { "type": "string" }, "question_id": { "type": "string" } } }, "handler.AnswerResponse": { "type": "object", "properties": { "answer": { "type": "string" }, "question_id": { "type": "string" } } }, "handler.Auth": { "type": "object", "properties": { "email": { "type": "string" }, "password": { "type": "string" } } }, "handler.ChangePasswordRequest": { "type": "object", "properties": { "new_password": { "type": "string" }, "old_password": { "type": "string" } } }, "handler.CreateFormRequest": { "type": "object", "properties": { "description": { "type": "string" }, "questions": { "type": "array", "items": { "$ref": "#/definitions/handler.QuestionInput" } }, "title": { "type": "string" } } }, "handler.FormResponse": { "type": "object", "properties": { "created_at": { "type": "string" }, "description": { "type": "string" }, "id": { "type": "string" }, "questions": { "type": "array", "items": { "$ref": "#/definitions/handler.QuestionResponse" } }, "response_count": { "type": "integer" }, "title": { "type": "string" }, "updated_at": { "type": "string" }, "user_id": { "type": "string" } } }, "handler.LogoutRequest": { "type": "object", "properties": { "refresh_token": { "type": "string" } } }, "handler.QuestionInput": { "type": "object", "properties": { "options": { "type": "array", "items": { "$ref": "#/definitions/handler.QuestionOptionInput" } }, "position": { "type": "integer" }, "required": { "type": "boolean" }, "title": { "type": "string" }, "type": { "type": "string" } } }, "handler.QuestionOptionInput": { "type": "object", "properties": { "label": { "type": "string" }, "position": { "type": "integer" } } }, "handler.QuestionOptionResponse": { "type": "object", "properties": { "id": { "type": "integer" }, "label": { "type": "string" }, "position": { "type": "integer" } } }, "handler.QuestionResponse": { "type": "object", "properties": { "id": { "type": "string" }, "options": { "type": "array", "items": { "$ref": "#/definitions/handler.QuestionOptionResponse" } }, "position": { "type": "integer" }, "required": { "type": "boolean" }, "title": { "type": "string" }, "type": { "type": "string" } } }, "handler.RefreshRequest": { "type": "object", "properties": { "refresh_token": { "type": "string" } } }, "handler.SubmitResponseRequest": { "type": "object", "properties": { "answers": { "type": "array", "items": { "$ref": "#/definitions/handler.AnswerInput" } } } }, "handler.SubmitResponseResponse": { "type": "object", "properties": { "answers": { "type": "array", "items": { "$ref": "#/definitions/handler.AnswerResponse" } }, "form_id": { "type": "string" }, "id": { "type": "string" }, "submitted_at": { "type": "string" } } }, "handler.UpdateFormRequest": { "type": "object", "properties": { "description": { "type": "string" }, "questions": { "type": "array", "items": { "$ref": "#/definitions/handler.QuestionInput" } }, "title": { "type": "string" } } } }, "securityDefinitions": { "BearerAuth": { "description": "Enter your bearer token in the format: Bearer {token}", "type": "apiKey", "name": "Authorization", "in": "header" } } }