Files
neomovies-api/pkg/handlers/docs.go
2025-08-13 18:02:03 +00:00

1432 lines
47 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"encoding/json"
"fmt"
"net/http"
"os"
"github.com/MarceloPetrucio/go-scalar-api-reference"
)
type DocsHandler struct{}
func NewDocsHandler() *DocsHandler {
return &DocsHandler{}
}
func (h *DocsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.ServeDocs(w, r)
}
func (h *DocsHandler) RedirectToDocs(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/docs/", http.StatusMovedPermanently)
}
func (h *DocsHandler) GetOpenAPISpec(w http.ResponseWriter, r *http.Request) {
baseURL := os.Getenv("BASE_URL")
if baseURL == "" {
if r.TLS != nil {
baseURL = fmt.Sprintf("https://%s", r.Host)
} else {
baseURL = fmt.Sprintf("http://%s", r.Host)
}
}
spec := getOpenAPISpecWithURL(baseURL)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(spec)
}
func (h *DocsHandler) ServeDocs(w http.ResponseWriter, r *http.Request) {
baseURL := os.Getenv("BASE_URL")
if baseURL == "" {
if r.TLS != nil {
baseURL = fmt.Sprintf("https://%s", r.Host)
} else {
baseURL = fmt.Sprintf("http://%s", r.Host)
}
}
htmlContent, err := scalar.ApiReferenceHTML(&scalar.Options{
SpecURL: fmt.Sprintf("%s/openapi.json", baseURL),
CustomOptions: scalar.CustomOptions{
PageTitle: "Neo Movies API Documentation",
},
DarkMode: true,
})
if err != nil {
fmt.Printf("Error generating documentation: %v", err)
http.Error(w, fmt.Sprintf("Error generating documentation: %v", err), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, htmlContent)
}
type OpenAPISpec struct {
OpenAPI string `json:"openapi"`
Info Info `json:"info"`
Servers []Server `json:"servers"`
Paths map[string]interface{} `json:"paths"`
Components Components `json:"components"`
}
type Info struct {
Title string `json:"title"`
Description string `json:"description"`
Version string `json:"version"`
Contact Contact `json:"contact"`
}
type Contact struct {
Name string `json:"name"`
URL string `json:"url"`
}
type Server struct {
URL string `json:"url"`
Description string `json:"description"`
}
type Components struct {
SecuritySchemes map[string]SecurityScheme `json:"securitySchemes"`
Schemas map[string]interface{} `json:"schemas"`
}
type SecurityScheme struct {
Type string `json:"type"`
Scheme string `json:"scheme,omitempty"`
BearerFormat string `json:"bearerFormat,omitempty"`
}
func getOpenAPISpecWithURL(baseURL string) *OpenAPISpec {
return &OpenAPISpec{
OpenAPI: "3.0.0",
Info: Info{
Title: "Neo Movies API",
Description: "Современный API для поиска фильмов и сериалов с интеграцией TMDB и поддержкой авторизации",
Version: "2.0.0",
Contact: Contact{
Name: "API Support",
URL: "https://github.com/your-username/neomovies-api-go",
},
},
Servers: []Server{
{
URL: baseURL,
Description: "Production server",
},
},
Paths: map[string]interface{}{
"/api/v1/health": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Health Check",
"description": "Проверка работоспособности API",
"tags": []string{"Health"},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "API работает корректно",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/APIResponse",
},
},
},
},
},
},
},
"/search/multi": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Мультипоиск",
"description": "Поиск фильмов, сериалов и актеров",
"tags": []string{"Search"},
"parameters": []map[string]interface{}{
{
"name": "query",
"in": "query",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Поисковый запрос",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
"description": "Номер страницы",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Результаты поиска",
},
},
},
},
"/api/v1/categories": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Получить категории",
"description": "Получение списка категорий фильмов",
"tags": []string{"Categories"},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список категорий",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "array",
"items": map[string]interface{}{"$ref": "#/components/schemas/Category"},
},
},
},
},
},
},
},
"/api/v1/categories/{id}/movies": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Фильмы по категории",
"description": "Получение фильмов по категории",
"tags": []string{"Categories"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID категории",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Фильмы категории",
},
},
},
},
"/api/v1/players/alloha/{imdb_id}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Плеер Alloha",
"description": "Получение плеера Alloha по IMDb ID",
"tags": []string{"Players"},
"parameters": []map[string]interface{}{
{
"name": "imdb_id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "IMDb ID фильма",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Данные плеера",
},
},
},
},
"/api/v1/players/lumex/{imdb_id}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Плеер Lumex",
"description": "Получение плеера Lumex по IMDb ID",
"tags": []string{"Players"},
"parameters": []map[string]interface{}{
{
"name": "imdb_id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "IMDb ID фильма",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Данные плеера",
},
},
},
},
"/api/v1/players/vibix/{imdb_id}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Vibix плеер по IMDb ID",
"description": "Возвращает HTML-страницу с iframe Vibix для указанного IMDb ID",
"tags": []string{"Players"},
"parameters": []map[string]interface{}{
{
"name": "imdb_id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "IMDb ID, например tt0133093",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "HTML со встроенным Vibix плеером",
"content": map[string]interface{}{
"text/html": map[string]interface{}{},
},
},
"404": map[string]interface{}{"description": "Фильм не найден"},
"503": map[string]interface{}{"description": "VIBIX_TOKEN не настроен"},
},
},
},
"/api/v1/torrents/search/{imdbId}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Поиск торрентов",
"description": "Поиск торрентов по IMDB ID",
"tags": []string{"Torrents"},
"parameters": []map[string]interface{}{
{
"name": "imdbId",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "IMDB ID фильма или сериала",
},
{
"name": "type",
"in": "query",
"required": true,
"schema": map[string]interface{}{"type": "string", "enum": []string{"movie", "tv", "serial"}},
"description": "Тип контента: movie (фильм) или tv/serial (сериал)",
},
{
"name": "season",
"in": "query",
"required": false,
"schema": map[string]interface{}{"type": "integer"},
"description": "Номер сезона (для сериалов)",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Результаты поиска торрентов",
},
},
},
},
"/api/v1/reactions/{mediaType}/{mediaId}/counts": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Количество реакций",
"description": "Получение количества реакций для медиа",
"tags": []string{"Reactions"},
"parameters": []map[string]interface{}{
{
"name": "mediaType",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Тип медиа (movie/tv)",
},
{
"name": "mediaId",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "ID медиа",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Количество реакций",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/ReactionCounts",
},
},
},
},
},
},
},
"/api/v1/images/{size}/{path}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Изображения",
"description": "Прокси для изображений TMDB",
"tags": []string{"Images"},
"parameters": []map[string]interface{}{
{
"name": "size",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Размер изображения",
},
{
"name": "path",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Путь к изображению",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Изображение",
"content": map[string]interface{}{
"image/*": map[string]interface{}{},
},
},
},
},
},
"/api/v1/auth/register": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Регистрация пользователя",
"description": "Создание нового аккаунта пользователя",
"tags": []string{"Authentication"},
"requestBody": map[string]interface{}{
"required": true,
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/RegisterRequest",
},
},
},
},
"responses": map[string]interface{}{
"201": map[string]interface{}{
"description": "Пользователь успешно зарегистрирован",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/AuthResponse",
},
},
},
},
"409": map[string]interface{}{
"description": "Пользователь с таким email уже существует",
},
},
},
},
"/api/v1/auth/verify": map[string]interface{}{
"post": map[string]interface{}{
"tags": []string{"Authentication"},
"summary": "Подтверждение email",
"description": "Подтверждение email пользователя с помощью кода",
"requestBody": map[string]interface{}{
"required": true,
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "object",
"required": []string{"email", "code"},
"properties": map[string]interface{}{
"email": map[string]interface{}{
"type": "string",
"format": "email",
"description": "Email пользователя",
"example": "user@example.com",
},
"code": map[string]interface{}{
"type": "string",
"description": "6-значный код верификации",
"example": "123456",
},
},
},
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Email успешно подтвержден",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"success": map[string]interface{}{
"type": "boolean",
},
"message": map[string]interface{}{
"type": "string",
},
},
},
},
},
},
"400": map[string]interface{}{
"description": "Неверный или истекший код",
},
},
},
},
"/api/v1/auth/resend-code": map[string]interface{}{
"post": map[string]interface{}{
"tags": []string{"Authentication"},
"summary": "Повторная отправка кода",
"description": "Повторная отправка кода верификации на email",
"requestBody": map[string]interface{}{
"required": true,
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "object",
"required": []string{"email"},
"properties": map[string]interface{}{
"email": map[string]interface{}{
"type": "string",
"format": "email",
"description": "Email пользователя",
"example": "user@example.com",
},
},
},
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Код отправлен на email",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"success": map[string]interface{}{
"type": "boolean",
},
"message": map[string]interface{}{
"type": "string",
},
},
},
},
},
},
"400": map[string]interface{}{
"description": "Email уже подтвержден или пользователь не найден",
},
},
},
},
"/api/v1/auth/login": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Авторизация пользователя",
"description": "Получение JWT токена для доступа к приватным эндпоинтам",
"tags": []string{"Authentication"},
"requestBody": map[string]interface{}{
"required": true,
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/LoginRequest",
},
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Успешная авторизация",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/AuthResponse",
},
},
},
},
"401": map[string]interface{}{
"description": "Неверный email или пароль",
},
},
},
},
"/api/v1/auth/profile": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Получить профиль пользователя",
"description": "Получение информации о текущем пользователе",
"tags": []string{"Authentication"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Информация о пользователе",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/User",
},
},
},
},
},
},
"put": map[string]interface{}{
"summary": "Обновить профиль пользователя",
"description": "Обновление информации о пользователе",
"tags": []string{"Authentication"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Профиль успешно обновлен",
},
},
},
"delete": map[string]interface{}{
"summary": "Удалить аккаунт пользователя",
"description": "Полное и безвозвратное удаление аккаунта пользователя и всех связанных с ним данных (избранное, реакции)",
"tags": []string{"Authentication"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Аккаунт успешно удален",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"success": map[string]interface{}{"type": "boolean"},
"message": map[string]interface{}{"type": "string"},
},
},
},
},
},
"401": map[string]interface{}{
"description": "Неавторизованный запрос",
},
"500": map[string]interface{}{
"description": "Внутренняя ошибка сервера",
},
},
},
},
"/api/v1/movies/search": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Поиск фильмов",
"description": "Поиск фильмов по названию с поддержкой фильтров",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "query",
"in": "query",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Поисковый запрос",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
"description": "Номер страницы",
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
"description": "Язык ответа",
},
{
"name": "year",
"in": "query",
"schema": map[string]string{"type": "integer"},
"description": "Год выпуска",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Результаты поиска фильмов",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/MovieSearchResponse",
},
},
},
},
},
},
},
"/api/v1/movies/popular": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Популярные фильмы",
"description": "Получение списка популярных фильмов",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список популярных фильмов",
},
},
},
},
"/api/v1/movies/{id}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Получить фильм по ID",
"description": "Подробная информация о фильме",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID фильма в TMDB",
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Информация о фильме",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/Movie",
},
},
},
},
},
},
},
"/api/v1/favorites": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Получить избранные фильмы",
"description": "Список избранных фильмов пользователя",
"tags": []string{"Favorites"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список избранных фильмов",
},
},
},
},
"/api/v1/favorites/{id}": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Добавить в избранное",
"description": "Добавление фильма в избранное",
"tags": []string{"Favorites"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "ID фильма",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Фильм добавлен в избранное",
},
},
},
"delete": map[string]interface{}{
"summary": "Удалить из избранного",
"description": "Удаление фильма из избранного",
"tags": []string{"Favorites"},
"security": []map[string][]string{
{"bearerAuth": []string{}},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "ID фильма",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Фильм удален из избранного",
},
},
},
},
"/api/v1/movies/top-rated": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Топ рейтинг фильмов",
"description": "Получение списка фильмов с высоким рейтингом",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список фильмов с высоким рейтингом",
},
},
},
},
"/api/v1/movies/upcoming": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Скоро в прокате",
"description": "Получение списка фильмов, которые скоро выйдут в прокат",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список фильмов, которые скоро выйдут",
},
},
},
},
"/api/v1/movies/now-playing": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Сейчас в прокате",
"description": "Получение списка фильмов, которые сейчас в прокате",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список фильмов в прокате",
},
},
},
},
"/api/v1/movies/{id}/recommendations": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Рекомендации фильмов",
"description": "Получение рекомендаций фильмов на основе выбранного",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID фильма в TMDB",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Рекомендуемые фильмы",
},
},
},
},
"/api/v1/movies/{id}/similar": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Похожие фильмы",
"description": "Получение похожих фильмов",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID фильма в TMDB",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Похожие фильмы",
},
},
},
},
"/api/v1/tv/search": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Поиск сериалов",
"description": "Поиск сериалов по названию",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "query",
"in": "query",
"required": true,
"schema": map[string]string{"type": "string"},
"description": "Поисковый запрос",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
"description": "Номер страницы",
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
"description": "Язык ответа",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Результаты поиска сериалов",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/TVSearchResponse",
},
},
},
},
},
},
},
"/api/v1/tv/popular": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Популярные сериалы",
"description": "Получение списка популярных сериалов",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список популярных сериалов",
},
},
},
},
"/api/v1/tv/top-rated": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Топ рейтинг сериалов",
"description": "Получение списка сериалов с высоким рейтингом",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список сериалов с высоким рейтингом",
},
},
},
},
"/api/v1/tv/on-the-air": map[string]interface{}{
"get": map[string]interface{}{
"summary": "В эфире",
"description": "Получение списка сериалов, которые сейчас в эфире",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список сериалов в эфире",
},
},
},
},
"/api/v1/tv/airing-today": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Сегодня в эфире",
"description": "Получение списка сериалов, которые выходят сегодня",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Список сериалов, выходящих сегодня",
},
},
},
},
"/api/v1/tv/{id}": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Получить сериал по ID",
"description": "Подробная информация о сериале",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID сериала в TMDB",
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Информация о сериале",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/TVSeries",
},
},
},
},
},
},
},
"/api/v1/tv/{id}/recommendations": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Рекомендации сериалов",
"description": "Получение рекомендаций сериалов на основе выбранного",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID сериала в TMDB",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Рекомендуемые сериалы",
},
},
},
},
"/api/v1/tv/{id}/similar": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Похожие сериалы",
"description": "Получение похожих сериалов",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID сериала в TMDB",
},
{
"name": "page",
"in": "query",
"schema": map[string]string{"type": "integer", "default": "1"},
},
{
"name": "language",
"in": "query",
"schema": map[string]string{"type": "string", "default": "ru-RU"},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Похожие сериалы",
},
},
},
},
"/api/v1/movies/{id}/external-ids": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Внешние идентификаторы фильма",
"description": "Получить внешние ID (IMDb, TVDB, Facebook и др.) для фильма по TMDB ID",
"tags": []string{"Movies"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID фильма в TMDB",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Внешние идентификаторы фильма",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/ExternalIDs",
},
},
},
},
},
},
},
"/api/v1/tv/{id}/external-ids": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Внешние идентификаторы сериала",
"description": "Получить внешние ID (IMDb, TVDB, Facebook и др.) для сериала по TMDB ID",
"tags": []string{"TV Series"},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"required": true,
"schema": map[string]string{"type": "integer"},
"description": "ID сериала в TMDB",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Внешние идентификаторы сериала",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{
"$ref": "#/components/schemas/ExternalIDs",
},
},
},
},
},
},
},
"/api/v1/auth/google/login": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Google OAuth: начало",
"description": "Редирект на страницу авторизации Google",
"tags": []string{"Authentication"},
"responses": map[string]interface{}{
"302": map[string]interface{}{"description": "Redirect to Google"},
"400": map[string]interface{}{"description": "OAuth не сконфигурирован"},
},
},
},
"/api/v1/auth/google/callback": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Google OAuth: коллбек",
"description": "Обработка кода авторизации и выдача JWT",
"tags": []string{"Authentication"},
"parameters": []map[string]interface{}{
{"name": "state", "in": "query", "required": true, "schema": map[string]string{"type": "string"}},
{"name": "code", "in": "query", "required": true, "schema": map[string]string{"type": "string"}},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Успешная авторизация через Google",
"content": map[string]interface{}{
"application/json": map[string]interface{}{
"schema": map[string]interface{}{"$ref": "#/components/schemas/AuthResponse"},
},
},
},
"400": map[string]interface{}{"description": "Неверный state или ошибка обмена кода"},
},
},
},
},
Components: Components{
SecuritySchemes: map[string]SecurityScheme{
"bearerAuth": {
Type: "http",
Scheme: "bearer",
BearerFormat: "JWT",
},
},
Schemas: map[string]interface{}{
"APIResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"success": map[string]string{"type": "boolean"},
"data": map[string]string{"type": "object"},
"message": map[string]string{"type": "string"},
"error": map[string]string{"type": "string"},
},
},
"RegisterRequest": map[string]interface{}{
"type": "object",
"required": []string{"email", "password", "name"},
"properties": map[string]interface{}{
"email": map[string]interface{}{
"type": "string",
"format": "email",
"example": "user@example.com",
},
"password": map[string]interface{}{
"type": "string",
"minLength": 6,
"example": "password123",
},
"name": map[string]interface{}{
"type": "string",
"example": "Иван Иванов",
},
},
},
"LoginRequest": map[string]interface{}{
"type": "object",
"required": []string{"email", "password"},
"properties": map[string]interface{}{
"email": map[string]interface{}{
"type": "string",
"format": "email",
"example": "user@example.com",
},
"password": map[string]interface{}{
"type": "string",
"example": "password123",
},
},
},
"AuthResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"token": map[string]string{"type": "string"},
"user": map[string]interface{}{"$ref": "#/components/schemas/User"},
},
},
"User": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]string{"type": "string"},
"email": map[string]string{"type": "string"},
"name": map[string]string{"type": "string"},
"avatar": map[string]string{"type": "string"},
"favorites": map[string]interface{}{
"type": "array",
"items": map[string]string{"type": "string"},
},
"created_at": map[string]interface{}{
"type": "string",
"format": "date-time",
},
"updated_at": map[string]interface{}{
"type": "string",
"format": "date-time",
},
},
},
"Movie": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]string{"type": "integer"},
"title": map[string]string{"type": "string"},
"original_title": map[string]string{"type": "string"},
"overview": map[string]string{"type": "string"},
"poster_path": map[string]string{"type": "string"},
"backdrop_path": map[string]string{"type": "string"},
"release_date": map[string]string{"type": "string"},
"vote_average": map[string]string{"type": "number"},
"vote_count": map[string]string{"type": "integer"},
"popularity": map[string]string{"type": "number"},
"adult": map[string]string{"type": "boolean"},
"original_language": map[string]string{"type": "string"},
},
},
"MovieSearchResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"page": map[string]string{"type": "integer"},
"results": map[string]interface{}{
"type": "array",
"items": map[string]interface{}{"$ref": "#/components/schemas/Movie"},
},
"total_pages": map[string]string{"type": "integer"},
"total_results": map[string]string{"type": "integer"},
},
},
"TVSeries": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]string{"type": "integer"},
"name": map[string]string{"type": "string"},
"original_name": map[string]string{"type": "string"},
"overview": map[string]string{"type": "string"},
"poster_path": map[string]string{"type": "string"},
"backdrop_path": map[string]string{"type": "string"},
"first_air_date": map[string]string{"type": "string"},
"vote_average": map[string]string{"type": "number"},
"vote_count": map[string]string{"type": "integer"},
"popularity": map[string]string{"type": "number"},
"original_language": map[string]string{"type": "string"},
"number_of_seasons": map[string]string{"type": "integer"},
"number_of_episodes": map[string]string{"type": "integer"},
"status": map[string]string{"type": "string"},
},
},
"TVSearchResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"page": map[string]string{"type": "integer"},
"results": map[string]interface{}{
"type": "array",
"items": map[string]interface{}{"$ref": "#/components/schemas/TVSeries"},
},
"total_pages": map[string]string{"type": "integer"},
"total_results": map[string]string{"type": "integer"},
},
},
"Category": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]string{"type": "integer"},
"name": map[string]string{"type": "string"},
"description": map[string]string{"type": "string"},
},
},
"Player": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"url": map[string]string{"type": "string"},
"title": map[string]string{"type": "string"},
"quality": map[string]string{"type": "string"},
"type": map[string]string{"type": "string"},
},
},
"Torrent": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"title": map[string]string{"type": "string"},
"size": map[string]string{"type": "string"},
"seeds": map[string]string{"type": "integer"},
"peers": map[string]string{"type": "integer"},
"magnet": map[string]string{"type": "string"},
"hash": map[string]string{"type": "string"},
},
},
"Reaction": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"type": map[string]string{"type": "string"},
"count": map[string]string{"type": "integer"},
},
},
"ReactionCounts": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"like": map[string]string{"type": "integer"},
"dislike": map[string]string{"type": "integer"},
"love": map[string]string{"type": "integer"},
},
},
"ExternalIDs": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]string{"type": "integer"},
"imdb_id": map[string]string{"type": "string"},
"tvdb_id": map[string]string{"type": "integer"},
"wikidata_id": map[string]string{"type": "string"},
"facebook_id": map[string]string{"type": "string"},
"instagram_id": map[string]string{"type": "string"},
"twitter_id": map[string]string{"type": "string"},
},
},
},
},
}
}