{"info":{"description":"REST API for the monorepo-fullstack project","title":"monorepo-fullstack API","version":"0.0.1"},"openapi":"3.1.0","servers":[{"url":"/"}],"paths":{"/api/auth/login":{"post":{"operationId":"login","summary":"Log in with login/email and password","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"loginOrEmail":{"type":"string","minLength":1,"maxLength":100},"password":{"type":"string","minLength":1,"maxLength":72}},"required":["loginOrEmail","password"]}}}},"responses":{"200":{"description":"Login successful. Returns accessToken in body and sets a refreshToken HttpOnly cookie.","headers":{"Set-Cookie":{"description":"refreshToken=<token>; Path=/; HttpOnly; SameSite=Strict","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"accessToken":{"type":"string"}},"required":["accessToken"],"additionalProperties":false}}}},"400":{"description":"Invalid request body"},"401":{"description":"Invalid credentials"}}}},"/api/auth/logout":{"post":{"operationId":"logout","security":[{"cookieAuth":[]}],"summary":"Revoke the current refreshToken and clear the cookie","tags":["Auth"],"responses":{"204":{"description":"Logged out. refreshToken cookie cleared."},"401":{"description":"No valid refreshToken cookie"},"403":{"description":"Missing or invalid Origin/Referer header"}}}},"/api/auth/me":{"get":{"operationId":"me","security":[{"bearerAuth":[]}],"summary":"Get current authenticated user","tags":["Auth"],"responses":{"200":{"description":"Current user info","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"login":{"type":"string"},"role":{"type":"string","enum":["superAdmin","admin","user"]},"userId":{"type":"string"}},"required":["email","login","role","userId"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"}}}},"/api/auth/new-password":{"post":{"description":"Confirms a password recovery using the recoveryCode received by email and sets a new password. Recovery codes are single-use and expire in 1 hour.","operationId":"newPassword","summary":"Set a new password using a recovery code","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"newPassword":{"type":"string","minLength":6,"maxLength":20},"recoveryCode":{"type":"string","minLength":1}},"required":["newPassword","recoveryCode"]}}}},"responses":{"204":{"description":"Password updated successfully"},"400":{"description":"Invalid or expired recoveryCode, or invalid newPassword","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"429":{"description":"Too many requests"}}}},"/api/auth/password-recovery":{"post":{"description":"Always responds with 204 to prevent email enumeration: the response is identical whether or not the email belongs to a registered user. If the email is registered, a recovery code is generated and a reset link is emailed.","operationId":"passwordRecovery","summary":"Request a password recovery email","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","pattern":"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$"}},"required":["email"]}}}},"responses":{"204":{"description":"Password recovery email sent (or silently ignored)"},"400":{"description":"Invalid email format","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"429":{"description":"Too many requests"}}}},"/api/auth/refresh-token":{"post":{"operationId":"refreshToken","security":[{"cookieAuth":[]}],"summary":"Generate a new pair of access + refresh tokens","tags":["Auth"],"responses":{"200":{"description":"New access + refresh token pair issued. Previous refreshToken is revoked. New refreshToken set as HttpOnly cookie.","headers":{"Set-Cookie":{"description":"refreshToken=<token>; Path=/; HttpOnly; SameSite=Strict","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"accessToken":{"type":"string"}},"required":["accessToken"],"additionalProperties":false}}}},"401":{"description":"No valid refreshToken cookie or token is revoked/expired"},"403":{"description":"Missing or invalid Origin/Referer header"}}}},"/api/auth/registration":{"post":{"operationId":"registration","summary":"Register a new user (sends confirmation email)","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","pattern":"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$"},"login":{"type":"string","minLength":3,"maxLength":10,"pattern":"^[a-zA-Z0-9_-]+$"},"password":{"type":"string","minLength":6,"maxLength":20}},"required":["email","login","password"]}}}},"responses":{"204":{"description":"Registration successful, confirmation email sent"},"400":{"description":"Validation error or login/email already taken","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/auth/registration-confirmation":{"post":{"operationId":"registrationConfirmation","summary":"Confirm email with a confirmation code","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":1}},"required":["code"]}}}},"responses":{"204":{"description":"Email confirmed successfully"},"400":{"description":"Invalid, expired, or already-used confirmation code","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/auth/registration-email-resending":{"post":{"operationId":"registrationEmailResending","summary":"Resend email confirmation code","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","pattern":"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$"}},"required":["email"]}}}},"responses":{"204":{"description":"Confirmation email resent"},"400":{"description":"Email not found, already confirmed, or invalid format","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/blogs":{"get":{"operationId":"listBlogs","summary":"Get all blogs","tags":["Blogs"],"parameters":[{"in":"query","name":"pageNumber","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"minimum":1,"type":"integer"}},{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt","name"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}},{"in":"query","name":"searchNameTerm","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated list of blogs","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"description":{"type":"string"},"id":{"type":"string"},"isMembership":{"type":"boolean"},"name":{"type":"string"},"websiteUrl":{"type":"string"}},"required":["createdAt","description","id","isMembership","name","websiteUrl"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"400":{"description":"Invalid query params","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}},"post":{"operationId":"createBlog","summary":"Create a blog","tags":["Blogs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":500},"name":{"type":"string","minLength":1,"maxLength":15},"websiteUrl":{"type":"string","maxLength":100,"pattern":"^https:\\/\\/([a-zA-Z0-9_-]+\\.)+[a-zA-Z0-9_-]+(\\/[a-zA-Z0-9_-]+)*\\/?$"}},"required":["description","name","websiteUrl"]}}}},"responses":{"201":{"description":"Blog created","content":{"application/json":{"schema":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"description":{"type":"string"},"id":{"type":"string"},"isMembership":{"type":"boolean"},"name":{"type":"string"},"websiteUrl":{"type":"string"}},"required":["createdAt","description","id","isMembership","name","websiteUrl"],"additionalProperties":false}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/blogs/lookup":{"get":{"operationId":"listBlogLookup","summary":"Lookup blogs — id + name only","tags":["Blogs"],"parameters":[{"in":"query","name":"pageNumber","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"minimum":1,"type":"integer"}},{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt","name"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}},{"in":"query","name":"searchNameTerm","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated lightweight list of blogs (id + name) for dropdowns","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"400":{"description":"Invalid query params","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/blogs/{id}":{"delete":{"operationId":"deleteBlog","summary":"Delete a blog","tags":["Blogs"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Blog deleted"},"404":{"description":"Blog not found"}}},"get":{"operationId":"getBlog","summary":"Get a blog by id","tags":["Blogs"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blog found","content":{"application/json":{"schema":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"description":{"type":"string"},"id":{"type":"string"},"isMembership":{"type":"boolean"},"name":{"type":"string"},"websiteUrl":{"type":"string"}},"required":["createdAt","description","id","isMembership","name","websiteUrl"],"additionalProperties":false}}}},"404":{"description":"Blog not found"}}},"put":{"operationId":"updateBlog","summary":"Update a blog","tags":["Blogs"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":500},"name":{"type":"string","minLength":1,"maxLength":15},"websiteUrl":{"type":"string","maxLength":100,"pattern":"^https:\\/\\/([a-zA-Z0-9_-]+\\.)+[a-zA-Z0-9_-]+(\\/[a-zA-Z0-9_-]+)*\\/?$"}},"required":["description","name","websiteUrl"]}}}},"responses":{"204":{"description":"Blog updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"404":{"description":"Blog not found"}}}},"/api/blogs/{id}/posts":{"get":{"operationId":"listPostsForBlog","summary":"Get posts by blog id","tags":["Blogs"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"pageNumber","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"minimum":1,"type":"integer"}},{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt","title","blogName"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}}],"responses":{"200":{"description":"Paginated list of posts for the blog","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"blogId":{"type":"string"},"blogName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"string"},"shortDescription":{"type":"string"},"title":{"type":"string"}},"required":["blogId","blogName","content","createdAt","id","shortDescription","title"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"400":{"description":"Invalid query params","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"404":{"description":"Blog not found"}}},"post":{"operationId":"createPostForBlog","summary":"Create a post for a blog","tags":["Blogs"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":1000},"shortDescription":{"type":"string","minLength":1,"maxLength":100},"title":{"type":"string","minLength":1,"maxLength":30}},"required":["content","shortDescription","title"]}}}},"responses":{"201":{"description":"Post created","content":{"application/json":{"schema":{"type":"object","properties":{"blogId":{"type":"string"},"blogName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"string"},"shortDescription":{"type":"string"},"title":{"type":"string"}},"required":["blogId","blogName","content","createdAt","id","shortDescription","title"],"additionalProperties":false}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"404":{"description":"Blog not found"}}}},"/api/comments/{commentId}":{"delete":{"operationId":"deleteComment","security":[{"bearerAuth":[]}],"summary":"Delete a comment","tags":["Comments"],"parameters":[{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Comment deleted"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Comment not found"}}},"get":{"operationId":"getCommentById","summary":"Get comment by id","tags":["Comments"],"parameters":[{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Comment found","content":{"application/json":{"schema":{"type":"object","properties":{"commentatorInfo":{"type":"object","properties":{"userId":{"type":"string"},"userLogin":{"type":"string"}},"required":["userId","userLogin"],"additionalProperties":false},"content":{"type":"string"},"createdAt":{"type":"string"},"id":{"type":"string"},"likesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]}},"required":["dislikesCount","likesCount","myStatus"],"additionalProperties":false}},"required":["commentatorInfo","content","createdAt","id","likesInfo"],"additionalProperties":false}}}},"404":{"description":"Comment not found"}}},"put":{"operationId":"updateComment","security":[{"bearerAuth":[]}],"summary":"Update comment content","tags":["Comments"],"parameters":[{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":20,"maxLength":300}},"required":["content"]}}}},"responses":{"204":{"description":"Comment updated"},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Comment not found"}}}},"/api/comments/{commentId}/like-status":{"put":{"operationId":"setCommentLikeStatus","security":[{"bearerAuth":[]}],"summary":"Set like/dislike status for a comment","tags":["Comments"],"parameters":[{"in":"path","name":"commentId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"likeStatus":{"type":"string","enum":["None","Like","Dislike"]}},"required":["likeStatus"]}}}},"responses":{"204":{"description":"Like status updated"},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"404":{"description":"Comment not found"}}}},"/api/health":{"get":{"operationId":"getHealth","summary":"Health check","tags":["System"],"responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded","down"]},"timestamp":{"type":"string","description":"ISO 8601 timestamp"},"uptimeSeconds":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["status","timestamp","uptimeSeconds"],"additionalProperties":false}}}}}}},"/api/posts/{postId}/comments":{"get":{"operationId":"listPostComments","summary":"Get comments for a post","tags":["Comments"],"parameters":[{"in":"path","name":"postId","required":true,"schema":{"type":"string"}},{"in":"query","name":"pageNumber","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"minimum":1,"type":"integer"}},{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}}],"responses":{"200":{"description":"Paginated list of comments for a post","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"commentatorInfo":{"type":"object","properties":{"userId":{"type":"string"},"userLogin":{"type":"string"}},"required":["userId","userLogin"],"additionalProperties":false},"content":{"type":"string"},"createdAt":{"type":"string"},"id":{"type":"string"},"likesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]}},"required":["dislikesCount","likesCount","myStatus"],"additionalProperties":false}},"required":["commentatorInfo","content","createdAt","id","likesInfo"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"404":{"description":"Post not found"}}},"post":{"operationId":"createPostComment","security":[{"bearerAuth":[]}],"summary":"Create a comment for a post","tags":["Comments"],"parameters":[{"in":"path","name":"postId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":20,"maxLength":300}},"required":["content"]}}}},"responses":{"201":{"description":"Comment created","content":{"application/json":{"schema":{"type":"object","properties":{"commentatorInfo":{"type":"object","properties":{"userId":{"type":"string"},"userLogin":{"type":"string"}},"required":["userId","userLogin"],"additionalProperties":false},"content":{"type":"string"},"createdAt":{"type":"string"},"id":{"type":"string"},"likesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]}},"required":["dislikesCount","likesCount","myStatus"],"additionalProperties":false}},"required":["commentatorInfo","content","createdAt","id","likesInfo"],"additionalProperties":false}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"404":{"description":"Post not found"}}}},"/api/posts/{postId}/like-status":{"put":{"operationId":"setPostLikeStatus","security":[{"bearerAuth":[]}],"summary":"Set like/dislike status for a post","tags":["Posts"],"parameters":[{"in":"path","name":"postId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"likeStatus":{"type":"string","enum":["None","Like","Dislike"]}},"required":["likeStatus"]}}}},"responses":{"204":{"description":"Like status updated"},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"404":{"description":"Post not found"}}}},"/api/posts":{"get":{"operationId":"listPosts","summary":"Get all posts","tags":["Posts"],"parameters":[{"in":"query","name":"pageNumber","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"minimum":1,"type":"integer"}},{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt","title","blogName"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}}],"responses":{"200":{"description":"Paginated list of posts","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"blogId":{"type":"string"},"blogName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"extendedLikesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]},"newestLikes":{"type":"array","items":{"type":"object","properties":{"addedAt":{"type":"string"},"login":{"type":"string"},"userId":{"type":"string"}},"required":["addedAt","login","userId"],"additionalProperties":false}}},"required":["dislikesCount","likesCount","myStatus","newestLikes"],"additionalProperties":false},"id":{"type":"string"},"shortDescription":{"type":"string"},"title":{"type":"string"}},"required":["blogId","blogName","content","createdAt","extendedLikesInfo","id","shortDescription","title"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"400":{"description":"Invalid query params","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}},"post":{"operationId":"createPost","summary":"Create a post","tags":["Posts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"blogId":{"type":"string","minLength":1},"content":{"type":"string","minLength":1,"maxLength":1000},"shortDescription":{"type":"string","minLength":1,"maxLength":100},"title":{"type":"string","minLength":1,"maxLength":30}},"required":["blogId","content","shortDescription","title"]}}}},"responses":{"201":{"description":"Post created","content":{"application/json":{"schema":{"type":"object","properties":{"blogId":{"type":"string"},"blogName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"extendedLikesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]},"newestLikes":{"type":"array","items":{"type":"object","properties":{"addedAt":{"type":"string"},"login":{"type":"string"},"userId":{"type":"string"}},"required":["addedAt","login","userId"],"additionalProperties":false}}},"required":["dislikesCount","likesCount","myStatus","newestLikes"],"additionalProperties":false},"id":{"type":"string"},"shortDescription":{"type":"string"},"title":{"type":"string"}},"required":["blogId","blogName","content","createdAt","extendedLikesInfo","id","shortDescription","title"],"additionalProperties":false}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/posts/{id}":{"delete":{"operationId":"deletePost","summary":"Delete a post","tags":["Posts"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Post deleted"},"404":{"description":"Post not found"}}},"get":{"operationId":"getPost","summary":"Get a post by id","tags":["Posts"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Post found","content":{"application/json":{"schema":{"type":"object","properties":{"blogId":{"type":"string"},"blogName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"extendedLikesInfo":{"type":"object","properties":{"dislikesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"myStatus":{"type":"string","enum":["None","Like","Dislike"]},"newestLikes":{"type":"array","items":{"type":"object","properties":{"addedAt":{"type":"string"},"login":{"type":"string"},"userId":{"type":"string"}},"required":["addedAt","login","userId"],"additionalProperties":false}}},"required":["dislikesCount","likesCount","myStatus","newestLikes"],"additionalProperties":false},"id":{"type":"string"},"shortDescription":{"type":"string"},"title":{"type":"string"}},"required":["blogId","blogName","content","createdAt","extendedLikesInfo","id","shortDescription","title"],"additionalProperties":false}}}},"404":{"description":"Post not found"}}},"put":{"operationId":"updatePost","summary":"Update a post","tags":["Posts"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"blogId":{"type":"string","minLength":1},"content":{"type":"string","minLength":1,"maxLength":1000},"shortDescription":{"type":"string","minLength":1,"maxLength":100},"title":{"type":"string","minLength":1,"maxLength":30}},"required":["blogId","content","shortDescription","title"]}}}},"responses":{"204":{"description":"Post updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"404":{"description":"Post not found"}}}},"/api/security/devices":{"delete":{"operationId":"terminateOtherDevices","security":[{"cookieAuth":[]}],"summary":"Terminate all other active sessions for current user","tags":["Security"],"responses":{"204":{"description":"All sessions except the current one were terminated"},"401":{"description":"No valid refreshToken cookie"},"403":{"description":"Missing or invalid Origin/Referer header"}}},"get":{"operationId":"listActiveDevices","security":[{"cookieAuth":[]}],"summary":"List all active devices for current user","tags":["Security"],"responses":{"200":{"description":"List of all active devices for the authenticated user","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"deviceId":{"type":"string"},"ip":{"type":"string"},"isCurrent":{"type":"boolean"},"lastActiveDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"title":{"type":"string"}},"required":["deviceId","ip","isCurrent","lastActiveDate","title"],"additionalProperties":false}}}}},"401":{"description":"No valid refreshToken cookie"}}}},"/api/security/devices/{deviceId}":{"delete":{"operationId":"terminateDevice","security":[{"cookieAuth":[]}],"summary":"Terminate a specific device session by deviceId","tags":["Security"],"parameters":[{"in":"path","name":"deviceId","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Device session terminated"},"401":{"description":"No valid refreshToken cookie"},"403":{"description":"Missing or invalid Origin/Referer header, or attempting to terminate current session"},"404":{"description":"Device not found"}}}},"/api/testing/all-data":{"delete":{"operationId":"clearAllData","summary":"Clear all in-memory data (testing only)","tags":["Testing"],"responses":{"204":{"description":"All data cleared"}}}},"/api/users":{"get":{"operationId":"listUsers","security":[{"bearerAuth":[]}],"summary":"Get all users","tags":["Users"],"parameters":[{"in":"query","name":"sortBy","schema":{"default":"createdAt","enum":["createdAt","login","email"],"type":"string"}},{"in":"query","name":"sortDirection","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}},{"in":"query","name":"pageNumber","schema":{"default":1,"format":"int32","minimum":1,"type":"integer"}},{"in":"query","name":"pageSize","schema":{"default":10,"format":"int32","minimum":1,"type":"integer"}},{"in":"query","name":"searchLoginTerm","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"searchEmailTerm","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"description":"Paginated list of users","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"email":{"type":"string"},"id":{"type":"string"},"login":{"type":"string"},"role":{"type":"string","enum":["superAdmin","admin","user"]}},"required":["createdAt","email","id","login","role"],"additionalProperties":false}},"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pagesCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["items","page","pagesCount","pageSize","totalCount"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}},"post":{"operationId":"createUser","security":[{"bearerAuth":[]}],"summary":"Create a user","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","pattern":"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$"},"login":{"type":"string","minLength":3,"maxLength":10,"pattern":"^[a-zA-Z0-9_-]+$"},"password":{"type":"string","minLength":6,"maxLength":20}},"required":["email","login","password"]}}}},"responses":{"201":{"description":"User created","content":{"application/json":{"schema":{"type":"object","properties":{"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"email":{"type":"string"},"id":{"type":"string"},"login":{"type":"string"},"role":{"type":"string","enum":["superAdmin","admin","user"]}},"required":["createdAt","email","id","login","role"],"additionalProperties":false}}}},"400":{"description":"Validation failed or duplicate login/email","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/api/users/{id}":{"delete":{"operationId":"deleteUser","security":[{"bearerAuth":[]}],"summary":"Delete a user","tags":["Users"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"User deleted"},"400":{"description":"Cannot delete super-admin"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"User not found"}}}},"/api/users/{id}/role":{"put":{"operationId":"updateUserRole","security":[{"bearerAuth":[]}],"summary":"Update user role (super-admin only)","tags":["Users"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin","user"]}},"required":["role"]}}}},"responses":{"204":{"description":"Role updated"},"400":{"description":"Self-role change / target is super-admin / invalid body","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"User not found"}}}},"/api/videos":{"get":{"operationId":"listVideos","summary":"Get all videos","tags":["Videos"],"responses":{"200":{"description":"List of all videos","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"author":{"type":"string"},"availableResolutions":{"type":"array","items":{"type":"string","enum":["P144","P240","P360","P480","P720","P1080","P1440","P2160"]}},"canBeDownloaded":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"minAgeRestriction":{"anyOf":[{"type":"integer","minimum":1,"maximum":18},{"type":"null"}]},"publicationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"title":{"type":"string"}},"required":["author","availableResolutions","canBeDownloaded","createdAt","id","minAgeRestriction","publicationDate","title"],"additionalProperties":false}}}}}}},"post":{"operationId":"createVideo","summary":"Create a video","tags":["Videos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"author":{"type":"string","minLength":1,"maxLength":20},"availableResolutions":{"minItems":1,"type":"array","items":{"type":"string","enum":["P144","P240","P360","P480","P720","P1080","P1440","P2160"]}},"title":{"type":"string","minLength":1,"maxLength":40}},"required":["author","availableResolutions","title"]}}}},"responses":{"201":{"description":"Video created","content":{"application/json":{"schema":{"type":"object","properties":{"author":{"type":"string"},"availableResolutions":{"type":"array","items":{"type":"string","enum":["P144","P240","P360","P480","P720","P1080","P1440","P2160"]}},"canBeDownloaded":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"minAgeRestriction":{"anyOf":[{"type":"integer","minimum":1,"maximum":18},{"type":"null"}]},"publicationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"title":{"type":"string"}},"required":["author","availableResolutions","canBeDownloaded","createdAt","id","minAgeRestriction","publicationDate","title"],"additionalProperties":false}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}}}}},"/api/videos/{id}":{"delete":{"operationId":"deleteVideo","summary":"Delete a video","tags":["Videos"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int32","type":"integer"}}],"responses":{"204":{"description":"Video deleted"},"404":{"description":"Video not found"}}},"get":{"operationId":"getVideo","summary":"Get a video by id","tags":["Videos"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int32","type":"integer"}}],"responses":{"200":{"description":"Video found","content":{"application/json":{"schema":{"type":"object","properties":{"author":{"type":"string"},"availableResolutions":{"type":"array","items":{"type":"string","enum":["P144","P240","P360","P480","P720","P1080","P1440","P2160"]}},"canBeDownloaded":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"minAgeRestriction":{"anyOf":[{"type":"integer","minimum":1,"maximum":18},{"type":"null"}]},"publicationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"title":{"type":"string"}},"required":["author","availableResolutions","canBeDownloaded","createdAt","id","minAgeRestriction","publicationDate","title"],"additionalProperties":false}}}},"404":{"description":"Video not found"}}},"put":{"operationId":"updateVideo","summary":"Update a video","tags":["Videos"],"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int32","type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"author":{"type":"string","minLength":1,"maxLength":20},"availableResolutions":{"minItems":1,"type":"array","items":{"type":"string","enum":["P144","P240","P360","P480","P720","P1080","P1440","P2160"]}},"canBeDownloaded":{"type":"boolean"},"minAgeRestriction":{"anyOf":[{"type":"integer","minimum":1,"maximum":18},{"type":"null"}]},"publicationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"title":{"type":"string","minLength":1,"maxLength":40}},"required":["author","availableResolutions","canBeDownloaded","minAgeRestriction","publicationDate","title"]}}}},"responses":{"204":{"description":"Video updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"errorsMessages":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["errorsMessages"],"additionalProperties":false}}}},"404":{"description":"Video not found"}}}}},"components":{"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","scheme":"bearer","type":"http"},"cookieAuth":{"in":"cookie","name":"refreshToken","type":"apiKey"}}}}