Files
flashcards-api/requests/openapi-spec.json

1548 lines
38 KiB
JSON

{
"openapi": "3.0.0",
"paths": {
"/v1/users": {
"get": {
"operationId": "UsersController_findAll",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
}
},
"tags": ["Admin"]
},
"post": {
"operationId": "UsersController_create",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateUserDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
}
},
"tags": ["Admin"]
},
"delete": {
"operationId": "UsersController_removeAll",
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"tags": ["Admin"]
}
},
"/v1/users/{id}": {
"delete": {
"operationId": "UsersController_remove",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "boolean"
}
}
}
}
},
"tags": ["Admin"]
}
},
"/v1/auth/me": {
"get": {
"operationId": "AuthController_getUserData",
"summary": "Current user data",
"description": "Retrieve current user data.",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserEntity"
}
}
}
},
"400": {
"description": "User not found"
},
"401": {
"description": "Not logged in"
}
},
"tags": ["Auth"]
},
"patch": {
"operationId": "AuthController_updateUserData",
"summary": "Update user data",
"description": "Update current user data.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/UpdateUserDataDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserEntity"
}
}
}
},
"400": {
"description": "User not found"
},
"401": {
"description": "Not logged in"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/login": {
"post": {
"operationId": "AuthController_login",
"summary": "Sign in using email and password. Must have an account to do so.",
"description": "Sign in using email and password. Must have an account to do so.",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginResponse"
}
}
}
},
"401": {
"description": "Invalid credentials"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/sign-up": {
"post": {
"operationId": "AuthController_registration",
"summary": "Create a new user account",
"description": "Create a new user account",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RegistrationDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserEntity"
}
}
}
},
"400": {
"description": "Email already exists"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/verify-email": {
"post": {
"operationId": "AuthController_confirmRegistration",
"summary": "Verify user email",
"description": "Verify user email",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmailVerificationDto"
}
}
}
},
"responses": {
"204": {
"description": "Email verified successfully"
},
"400": {
"description": "Email has already been verified"
},
"404": {
"description": "User not found"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/resend-verification-email": {
"post": {
"operationId": "AuthController_resendVerificationEmail",
"summary": "Send verification email again",
"description": "Send verification email again",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResendVerificationEmailDto"
}
}
}
},
"responses": {
"204": {
"description": "Verification email sent successfully"
},
"400": {
"description": "Email has already been verified"
},
"404": {
"description": "User not found"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/logout": {
"post": {
"operationId": "AuthController_logout",
"summary": "Sign current user out",
"description": "Sign current user out",
"parameters": [],
"responses": {
"204": {
"description": "Logged out successfully"
},
"401": {
"description": "Not logged in"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/refresh-token": {
"post": {
"operationId": "AuthController_refreshToken",
"summary": "Get new access token using refresh token",
"description": "Get new access token using refresh token",
"parameters": [],
"responses": {
"204": {
"description": "New tokens generated successfully"
},
"401": {
"description": "Invalid or missing refreshToken"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/recover-password": {
"post": {
"operationId": "AuthController_recoverPassword",
"summary": "Send password recovery email",
"description": "Send password recovery email",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RecoverPasswordDto"
}
}
}
},
"responses": {
"204": {
"description": "Password recovery email sent successfully"
},
"400": {
"description": "Email has already been verified"
},
"404": {
"description": "User not found"
}
},
"tags": ["Auth"]
}
},
"/v1/auth/reset-password/{token}": {
"post": {
"operationId": "AuthController_resetPassword",
"summary": "Reset password",
"description": "Reset password",
"parameters": [
{
"name": "token",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResetPasswordDto"
}
}
}
},
"responses": {
"204": {
"description": "Password reset successfully"
},
"400": {
"description": "Password is required"
},
"404": {
"description": "Incorrect or expired password reset token"
}
},
"tags": ["Auth"]
}
},
"/v1/decks": {
"get": {
"operationId": "DecksController_findAll",
"summary": "Paginated decks list",
"description": "Retrieve paginated decks list.",
"parameters": [
{
"name": "minCardsCount",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
},
{
"name": "maxCardsCount",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
},
{
"name": "name",
"required": false,
"in": "query",
"description": "Search by deck name",
"schema": {
"type": "string"
}
},
{
"name": "authorId",
"required": false,
"in": "query",
"description": "Filter by deck authorId",
"schema": {
"type": "string"
}
},
{
"name": "orderBy",
"required": false,
"in": "query",
"description": "A string that represents the name of the field to order by and the order direction.\nThe format is: \"field_name-order_direction\".\nAvailable directions: \"asc\" and \"desc\".",
"example": "name-desc",
"schema": {
"nullable": true,
"type": "string"
}
},
{
"name": "currentPage",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
},
{
"name": "itemsPerPage",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
}
],
"responses": {
"206": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaginatedDecks"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"tags": ["Decks"]
},
"post": {
"operationId": "DecksController_create",
"summary": "Create a deck",
"description": "Create a deck",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/CreateDeckDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeckWithAuthor"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"tags": ["Decks"]
}
},
"/v1/decks/{id}": {
"get": {
"operationId": "DecksController_findOne",
"summary": "Retrieve a deck by id",
"description": "Retrieve a deck by id",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeckWithAuthor"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"tags": ["Decks"]
},
"patch": {
"operationId": "DecksController_update",
"summary": "Update a deck",
"description": "Update a deck",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/UpdateDeckDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeckWithAuthor"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Deck not found"
}
},
"tags": ["Decks"]
},
"delete": {
"operationId": "DecksController_remove",
"summary": "Delete a deck",
"description": "Delete a deck",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deck deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Deck"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Deck not found"
}
},
"tags": ["Decks"]
}
},
"/v1/decks/{id}/cards": {
"get": {
"operationId": "DecksController_findCardsInDeck",
"summary": "Retrieve cards in a deck",
"description": "Retrieve paginated cards in a deck",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "question",
"required": false,
"in": "query",
"schema": {
"minLength": 1,
"maxLength": 30,
"type": "string"
}
},
{
"name": "answer",
"required": false,
"in": "query",
"schema": {
"minLength": 1,
"maxLength": 30,
"type": "string"
}
},
{
"name": "orderBy",
"required": false,
"in": "query",
"schema": {
"nullable": true,
"type": "string"
}
},
{
"name": "currentPage",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
},
{
"name": "itemsPerPage",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaginatedCards"
}
}
}
}
},
"tags": ["Decks"]
},
"post": {
"operationId": "DecksController_createCardInDeck",
"summary": "Create a card",
"description": "Create card in a deck",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/CreateCardDto"
}
}
}
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Deck not found"
}
},
"tags": ["Decks"]
}
},
"/v1/decks/{id}/learn": {
"get": {
"operationId": "DecksController_findRandomCardInDeck",
"summary": "Retrieve a random card",
"description": "Retrieve a random card in a deck. The cards priority is based on the grade",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "previousCardId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"tags": ["Decks"]
},
"post": {
"operationId": "DecksController_saveGrade",
"summary": "Save the grade of a card",
"description": "Save the grade of a card",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SaveGradeDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
},
"204": {
"description": "Grade saved"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Card not found"
}
},
"tags": ["Decks"]
}
},
"/v1/cards/{id}": {
"get": {
"operationId": "CardsController_findOne",
"summary": "Get card by id",
"description": "Get card by id",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Card not found"
}
},
"tags": ["Cards"]
},
"patch": {
"operationId": "CardsController_update",
"summary": "Update card",
"description": "Update partial card data",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/UpdateCardDto"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Card not found"
}
},
"tags": ["Cards"]
},
"delete": {
"operationId": "CardsController_remove",
"summary": "Delete card by id",
"description": "Delete card by id",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "New tokens generated successfully"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Card not found"
}
},
"tags": ["Cards"]
}
}
},
"info": {
"title": "Flashcards",
"description": "Flashcards API",
"version": "1.0",
"contact": {}
},
"tags": [
{
"name": "Auth",
"description": ""
},
{
"name": "Decks",
"description": ""
},
{
"name": "Cards",
"description": ""
},
{
"name": "Admin",
"description": ""
}
],
"servers": [
{
"url": "https://api.flashcards.andrii.es"
}
],
"components": {
"schemas": {
"CreateUserDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 3,
"maxLength": 10
},
"password": {
"type": "string",
"minLength": 6,
"maxLength": 20
},
"email": {
"type": "string",
"description": "User's email address",
"pattern": "/^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$/"
}
},
"required": ["name", "password", "email"]
},
"UserEntity": {
"type": "object",
"properties": {
"avatar": {
"type": "string",
"format": "binary"
},
"id": {
"type": "string"
},
"email": {
"type": "string"
},
"isEmailVerified": {
"type": "boolean"
},
"name": {
"type": "string"
},
"created": {
"format": "date-time",
"type": "string"
},
"updated": {
"format": "date-time",
"type": "string"
}
},
"required": ["avatar", "id", "email", "isEmailVerified", "name", "created", "updated"]
},
"UpdateUserDataDto": {
"type": "object",
"properties": {
"avatar": {
"type": "string",
"format": "binary"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
},
"required": ["avatar", "name", "email"]
},
"LoginDto": {
"type": "object",
"properties": {
"password": {
"type": "string",
"minLength": 3,
"maxLength": 30
},
"email": {
"type": "string"
},
"rememberMe": {
"type": "boolean"
}
},
"required": ["password", "email", "rememberMe"]
},
"LoginResponse": {
"type": "object",
"properties": {
"accessToken": {
"type": "string"
}
},
"required": ["accessToken"]
},
"RegistrationDto": {
"type": "object",
"properties": {
"html": {
"type": "string",
"description": "HTML template to be sent in the email;\n ##name## will be replaced with the user's name; \n ##token## will be replaced with the password recovery token",
"example": "<b>Hello, ##name##!</b><br/>Please confirm your email by clicking on the link below:<br/><a href=\"http://localhost:3000/confirm-email/##token##\">Confirm email</a>. If it doesn't work, copy and paste the following link in your browser:<br/>http://localhost:3000/confirm-email/##token##"
},
"name": {
"type": "string",
"minLength": 3,
"maxLength": 30
},
"password": {
"type": "string",
"minLength": 3,
"maxLength": 30
},
"email": {
"type": "string"
},
"subject": {
"type": "string",
"description": "Email subject"
},
"sendConfirmationEmail": {
"type": "boolean",
"description": "Whether to send a confirmation email or not.\nDefaults to false",
"example": false
}
},
"required": ["password", "email"]
},
"EmailVerificationDto": {
"type": "object",
"properties": {
"code": {
"type": "string"
}
},
"required": ["code"]
},
"ResendVerificationEmailDto": {
"type": "object",
"properties": {
"html": {
"type": "string",
"description": "HTML template to be sent in the email;\n ##name## will be replaced with the user's name; \n ##token## will be replaced with the password recovery token",
"example": "<b>Hello, ##name##!</b><br/>Please confirm your email by clicking on the link below:<br/><a href=\"http://localhost:3000/confirm-email/##token##\">Confirm email</a>. If it doesn't work, copy and paste the following link in your browser:<br/>http://localhost:3000/confirm-email/##token##"
},
"userId": {
"type": "string"
},
"subject": {
"type": "string",
"description": "Email subject"
}
},
"required": ["userId"]
},
"RecoverPasswordDto": {
"type": "object",
"properties": {
"html": {
"type": "string",
"description": "HTML template to be sent in the email;\n ##name## will be replaced with the user's name; \n ##token## will be replaced with the password recovery token",
"example": "<h1>Hi, ##name##</h1><p>Click <a href=\"##token##\">here</a> to recover your password</p>"
},
"email": {
"type": "string",
"description": "User's email address"
},
"subject": {
"type": "string",
"description": "Email subject"
}
},
"required": ["email"]
},
"ResetPasswordDto": {
"type": "object",
"properties": {
"password": {
"type": "string",
"minLength": 3,
"maxLength": 30
}
},
"required": ["password"]
},
"DeckAuthor": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": ["id", "name"]
},
"DeckWithAuthor": {
"type": "object",
"properties": {
"author": {
"$ref": "#/components/schemas/DeckAuthor"
},
"id": {
"type": "string"
},
"userId": {
"type": "string"
},
"name": {
"type": "string"
},
"isPrivate": {
"type": "boolean"
},
"shots": {
"type": "number"
},
"cover": {
"type": "string",
"nullable": true
},
"rating": {
"type": "number"
},
"created": {
"format": "date-time",
"type": "string"
},
"updated": {
"format": "date-time",
"type": "string"
},
"cardsCount": {
"type": "number"
}
},
"required": [
"author",
"id",
"userId",
"name",
"isPrivate",
"shots",
"cover",
"rating",
"created",
"updated",
"cardsCount"
]
},
"Pagination": {
"type": "object",
"properties": {
"currentPage": {
"type": "number"
},
"itemsPerPage": {
"type": "number"
},
"totalPages": {
"type": "number"
},
"totalItems": {
"type": "number"
}
},
"required": ["currentPage", "itemsPerPage", "totalPages", "totalItems"]
},
"PaginatedDecks": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeckWithAuthor"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
},
"maxCardsCount": {
"type": "number"
}
},
"required": ["items", "pagination", "maxCardsCount"]
},
"CreateDeckDto": {
"type": "object",
"properties": {
"cover": {
"type": "string",
"description": "Cover image (binary)",
"format": "binary"
},
"name": {
"type": "string",
"minLength": 3,
"maxLength": 30
},
"isPrivate": {
"type": "boolean",
"description": "Private decks are not visible to other users"
}
},
"required": ["name"]
},
"UpdateDeckDto": {
"type": "object",
"properties": {
"cover": {
"type": "string",
"format": "binary"
},
"name": {
"type": "string"
},
"isPrivate": {
"type": "boolean"
}
}
},
"Deck": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"userId": {
"type": "string"
},
"name": {
"type": "string"
},
"isPrivate": {
"type": "boolean"
},
"shots": {
"type": "number"
},
"cover": {
"type": "string",
"nullable": true
},
"rating": {
"type": "number"
},
"created": {
"format": "date-time",
"type": "string"
},
"updated": {
"format": "date-time",
"type": "string"
},
"cardsCount": {
"type": "number"
}
},
"required": [
"id",
"userId",
"name",
"isPrivate",
"shots",
"cover",
"rating",
"created",
"updated",
"cardsCount"
]
},
"CardWithoutRating": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"deckId": {
"type": "string"
},
"userId": {
"type": "string"
},
"question": {
"type": "string"
},
"answer": {
"type": "string"
},
"shots": {
"type": "number"
},
"answerImg": {
"type": "string"
},
"questionImg": {
"type": "string"
},
"questionVideo": {
"type": "string"
},
"answerVideo": {
"type": "string"
},
"created": {
"format": "date-time",
"type": "string"
},
"updated": {
"format": "date-time",
"type": "string"
}
},
"required": [
"id",
"deckId",
"userId",
"question",
"answer",
"shots",
"answerImg",
"questionImg",
"questionVideo",
"answerVideo",
"created",
"updated"
]
},
"PaginatedCards": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CardWithoutRating"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
},
"required": ["items", "pagination"]
},
"CreateCardDto": {
"type": "object",
"properties": {
"question": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"answer": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"questionImg": {
"type": "string",
"minLength": 0,
"maxLength": 0
},
"answerImg": {
"type": "string",
"minLength": 0,
"maxLength": 0
},
"questionVideo": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"answerVideo": {
"type": "string",
"minLength": 3,
"maxLength": 500
}
},
"required": ["question", "answer"]
},
"Card": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"deckId": {
"type": "string"
},
"userId": {
"type": "string"
},
"question": {
"type": "string"
},
"answer": {
"type": "string"
},
"shots": {
"type": "number"
},
"answerImg": {
"type": "string"
},
"questionImg": {
"type": "string"
},
"questionVideo": {
"type": "string"
},
"answerVideo": {
"type": "string"
},
"rating": {
"type": "number"
},
"created": {
"format": "date-time",
"type": "string"
},
"updated": {
"format": "date-time",
"type": "string"
}
},
"required": [
"id",
"deckId",
"userId",
"question",
"answer",
"shots",
"answerImg",
"questionImg",
"questionVideo",
"answerVideo",
"rating",
"created",
"updated"
]
},
"SaveGradeDto": {
"type": "object",
"properties": {
"cardId": {
"type": "string"
},
"grade": {
"type": "number",
"minimum": 1,
"maximum": 5
}
},
"required": ["cardId", "grade"]
},
"UpdateCardDto": {
"type": "object",
"properties": {
"questionImg": {
"type": "string",
"minLength": 0,
"maxLength": 0,
"format": "binary"
},
"answerImg": {
"type": "string",
"minLength": 0,
"maxLength": 0,
"format": "binary"
},
"question": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"answer": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"questionVideo": {
"type": "string",
"minLength": 3,
"maxLength": 500
},
"answerVideo": {
"type": "string",
"minLength": 3,
"maxLength": 500
}
}
}
}
}
}