{"components":{"schemas":{"ActivateRequest":{"properties":{"password":{"description":"Пароль для аккаунта (опционально).\n- Если пароль уже есть — будет обновлён\n- При указании сессия создаётся автоматически\n- Минимум 8 символов\n","example":"password123","format":"password","minLength":8,"type":"string"},"personal_data_consent_accepted":{"description":"Согласие на обработку данных (опционально).\n- Сохраняется только если ещё не заполнено\n- Если уже заполнено — значение игнорируется\n","example":true,"type":"boolean"},"privacy_policy_accepted":{"description":"Принятие политики конфиденциальности (опционально).\n- Сохраняется только если ещё не заполнено\n- Если уже заполнено — значение игнорируется\n","example":true,"type":"boolean"},"token":{"description":"Токен активации из письма","example":"abc123def456...","type":"string"}},"required":["token"],"type":"object"},"ActivationInfoResponse":{"properties":{"is_activated":{"description":"Уже активирован ли аккаунт","type":"boolean"},"personal_data_consent_accepted_at":{"description":"Время согласия на обработку данных. NULL если не дано.","format":"date-time","nullable":true,"type":"string"},"privacy_policy_accepted_at":{"description":"Время принятия политики конфиденциальности. NULL если не принято.","format":"date-time","nullable":true,"type":"string"},"user":{"properties":{"email":{"format":"email","type":"string"},"first_name":{"nullable":true,"type":"string"},"user_id":{"format":"uuid","type":"string"}},"type":"object"}},"type":"object"},"AddUserRequest":{"properties":{"email":{"example":"user@example.com","format":"email","type":"string"}},"required":["email"],"type":"object"},"AuthResponse":{"properties":{"expires_at":{"example":"2025-01-01 00:00:00+00:00","format":"date-time","type":"string"},"token":{"description":"Токен сессии (Bearer)","example":"abc123def456...","type":"string"},"user":{"$ref":"#/components/schemas/User"}},"type":"object"},"ChangePasswordRequest":{"properties":{"new_password":{"description":"Новый пароль (минимум 8 символов)","example":"newpassword123","format":"password","minLength":8,"type":"string"},"old_password":{"description":"Текущий пароль","example":"oldpassword123","format":"password","type":"string"}},"required":["old_password","new_password"],"type":"object"},"Company":{"properties":{"company_id":{"format":"uuid","type":"string"},"created_at":{"format":"date-time","type":"string"},"description":{"additionalProperties":true,"type":"object"},"name":{"type":"string"},"owner_user_id":{"format":"uuid","type":"string"},"published":{"type":"boolean"},"status":{"type":"string"}},"type":"object"},"CompanyUser":{"properties":{"allow_add_employees":{"type":"boolean"},"allow_applications_edit":{"type":"boolean"},"allow_company_edit":{"type":"boolean"},"allow_events_edit":{"type":"boolean"},"allow_products_edit":{"type":"boolean"},"comment":{"nullable":true,"type":"string"},"company_id":{"format":"uuid","type":"string"},"invited_by":{"format":"uuid","nullable":true,"type":"string"},"invited_time":{"format":"date-time","nullable":true,"type":"string"},"is_owner":{"description":"Является ли пользователь владельцем компании","type":"boolean"},"user_id":{"format":"uuid","type":"string"}},"type":"object"},"ConfirmEmailChangeByCodeRequest":{"properties":{"code":{"type":"string"}},"required":["code"],"type":"object"},"CreateCompanyRequest":{"properties":{"description":{"additionalProperties":true,"type":"object"},"name":{"example":"My Company","type":"string"}},"required":["name"],"type":"object"},"CreateEventRequest":{"properties":{"category_id":{"format":"uuid","type":"string"},"currency_id":{"format":"uuid","type":"string"},"description":{"type":"object"},"is_online":{"type":"boolean"},"price":{"type":"number"},"published":{"type":"boolean"}},"type":"object"},"CreateEventSlotRequest":{"properties":{"capacity":{"type":"integer"},"ends_at":{"format":"date-time","type":"string"},"starts_at":{"format":"date-time","type":"string"}},"required":["starts_at","ends_at","capacity"],"type":"object"},"CreateEventSlotsBatchRequest":{"properties":{"slots":{"items":{"$ref":"#/components/schemas/CreateEventSlotRequest"},"type":"array"}},"required":["slots"],"type":"object"},"CreateScheduleRequest":{"properties":{"capacity":{"type":"integer"},"date_end":{"format":"date","type":"string"},"date_start":{"format":"date","type":"string"},"period_day":{"type":"string"},"period_week":{"items":{"type":"integer"},"type":"array"},"time_end":{"type":"string"},"time_start":{"type":"string"}},"required":["time_start","time_end","date_start","capacity"],"type":"object"},"Event":{"properties":{"category":{"$ref":"#/components/schemas/EventCategory"},"category_id":{"description":"ID категории события","format":"uuid","nullable":true,"type":"string"},"company_id":{"format":"uuid","type":"string"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"object"},"event_id":{"format":"uuid","type":"string"},"nearest_time":{"description":"Ближайшее время проведения (прошедшие события имеют nearest_time \u003c now)","format":"date-time","nullable":true,"type":"string"},"places":{"description":"Места проведения (при публичном списке/детали)","items":{"$ref":"#/components/schemas/Place"},"type":"array"},"preview_image_id":{"format":"uuid","nullable":true,"type":"string"},"published":{"type":"boolean"},"slots":{"items":{"$ref":"#/components/schemas/EventSlot"},"type":"array"}},"type":"object"},"EventCategory":{"description":"Категория события (мастер-класс, тренинг и т.д.)","properties":{"category_id":{"format":"uuid","type":"string"},"name":{"description":"Название категории","type":"string"}},"type":"object"},"EventListResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/Event"},"type":"array"},"total_count":{"type":"integer"}},"type":"object"},"EventSlot":{"properties":{"capacity":{"type":"integer"},"ends_at":{"format":"date-time","type":"string"},"event_id":{"format":"uuid","type":"string"},"event_slot_id":{"format":"uuid","type":"string"},"participant_count":{"type":"integer"},"starts_at":{"format":"date-time","type":"string"}},"type":"object"},"EventSlotListResponse":{"properties":{"slots":{"items":{"$ref":"#/components/schemas/EventSlot"},"type":"array"},"total_count":{"type":"integer"}},"type":"object"},"File":{"properties":{"created_at":{"format":"date-time","type":"string"},"description":{"nullable":true,"type":"string"},"entity_id":{"format":"uuid","nullable":true,"type":"string"},"entity_type":{"nullable":true,"type":"string"},"file_id":{"format":"uuid","type":"string"},"file_path":{"type":"string"},"file_size":{"type":"integer"},"mime_type":{"type":"string"},"original_name":{"type":"string"},"sort_order":{"nullable":true,"type":"integer"},"stored_name":{"type":"string"}},"type":"object"},"LinkTelegramRequest":{"properties":{"init_data":{"type":"string"}},"required":["init_data"],"type":"object"},"LinkTelegramWidgetRequest":{"properties":{"auth_data":{"additionalProperties":true,"type":"object"}},"required":["auth_data"],"type":"object"},"LoginRequest":{"properties":{"email":{"example":"user@example.com","format":"email","type":"string"},"password":{"example":"password123","format":"password","type":"string"}},"required":["email","password"],"type":"object"},"Order":{"properties":{"company_id":{"format":"uuid","type":"string"},"items":{"type":"array"},"order_id":{"format":"uuid","type":"string"},"status":{"type":"string"}},"type":"object"},"OrderListResponse":{"properties":{"orders":{"items":{"$ref":"#/components/schemas/Order"},"type":"array"},"total_count":{"type":"integer"}},"type":"object"},"Place":{"description":"Место проведения события (адрес из Nominatim/OpenStreetMap)","properties":{"address":{"description":"Структурированный адрес (JSON)","type":"object"},"created_at":{"format":"date-time","type":"string"},"display_name":{"description":"Отображаемое название адреса","example":"Сочи, Краснодарский край, Россия","type":"string"},"event_count":{"description":"Количество опубликованных событий (только для списка мест)","nullable":true,"type":"integer"},"lat":{"description":"Широта","format":"double","type":"number"},"lon":{"description":"Долгота","format":"double","type":"number"},"osm_id":{"description":"ID в OpenStreetMap","format":"int64","type":"integer"},"osm_type":{"description":"Тип OSM объекта (node, way, relation)","example":"relation","type":"string"},"place_id":{"description":"Уникальный ID места","format":"uuid","type":"string"},"updated_at":{"format":"date-time","nullable":true,"type":"string"}},"type":"object"},"Problem":{"properties":{"detail":{"type":"string"},"errors":{"items":{"properties":{"detail":{"type":"string"},"pointer":{"type":"string"},"rule":{"type":"string"}},"type":"object"},"type":"array"},"instance":{"format":"uri","type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"format":"uri","type":"string"}},"type":"object"},"PublicCompany":{"properties":{"categories":{"type":"array"},"code":{"type":"string"},"company_id":{"format":"uuid","type":"string"},"description":{"type":"object"},"logo":{"type":"object"},"name":{"type":"string"}},"type":"object"},"RegisterRequest":{"properties":{"email":{"description":"Email пользователя (обязательно)","example":"user@example.com","format":"email","type":"string"},"first_name":{"description":"Имя пользователя (опционально)","example":"Иван","type":"string"},"password":{"description":"Пароль (опционально). Минимум 8 символов.","example":"password123","format":"password","minLength":8,"type":"string"},"personal_data_consent_accepted":{"description":"Согласие на обработку персональных данных. При активации будет запрошено, если не указано.","example":true,"type":"boolean"},"privacy_policy_accepted":{"description":"Принятие политики конфиденциальности. При активации будет запрошено, если не указано.","example":true,"type":"boolean"}},"required":["email"],"type":"object"},"RequestEmailChangeRequest":{"properties":{"email":{"format":"email","type":"string"}},"required":["email"],"type":"object"},"RequestPasswordResetRequest":{"properties":{"email":{"example":"user@example.com","format":"email","type":"string"}},"required":["email"],"type":"object"},"ResetPasswordRequest":{"properties":{"password":{"example":"newpassword123","format":"password","minLength":8,"type":"string"},"token":{"description":"Токен из письма сброса пароля","type":"string"}},"required":["token","password"],"type":"object"},"Schedule":{"properties":{"capacity":{"type":"integer"},"date_start":{"format":"date","type":"string"},"event_id":{"format":"uuid","type":"string"},"schedule_id":{"format":"uuid","type":"string"},"time_end":{"type":"string"},"time_start":{"type":"string"}},"type":"object"},"ScheduleListResponse":{"properties":{"schedules":{"items":{"$ref":"#/components/schemas/Schedule"},"type":"array"}},"type":"object"},"Session":{"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"ip_address":{"nullable":true,"type":"string"},"is_active":{"type":"boolean"},"session_id":{"format":"uuid","type":"string"},"source":{"nullable":true,"type":"string"},"user_agent":{"nullable":true,"type":"string"}},"type":"object"},"StorageInfo":{"properties":{"free":{"type":"integer"},"limit":{"type":"integer"},"used":{"type":"integer"}},"type":"object"},"TelegramAuthRequest":{"properties":{"init_data":{"description":"initData из Telegram WebApp","type":"string"}},"required":["init_data"],"type":"object"},"TelegramAuthResponse":{"properties":{"expires_at":{"format":"date-time","type":"string"},"is_new_user":{"type":"boolean"},"token":{"type":"string"},"user":{"$ref":"#/components/schemas/User"}},"type":"object"},"TelegramWidgetAuthRequest":{"properties":{"auth_data":{"additionalProperties":true,"description":"auth_data из callback виджета Telegram","type":"object"}},"required":["auth_data"],"type":"object"},"TransferOwnershipRequest":{"properties":{"new_owner_id":{"description":"ID нового владельца","format":"uuid","type":"string"}},"required":["new_owner_id"],"type":"object"},"UpdateCompanyRequest":{"properties":{"code":{"type":"string"},"description":{"additionalProperties":true,"type":"object"},"gallery":{"items":{},"type":"array"},"name":{"type":"string"},"published":{"type":"boolean"}},"type":"object"},"UpdateEventRequest":{"properties":{"description":{"type":"object"},"price":{"type":"number"},"published":{"type":"boolean"}},"type":"object"},"UpdateEventSlotRequest":{"properties":{"capacity":{"type":"integer"},"ends_at":{"format":"date-time","type":"string"},"starts_at":{"format":"date-time","type":"string"}},"type":"object"},"UpdateProfileRequest":{"properties":{"avatar":{"nullable":true,"type":"string"},"first_name":{"nullable":true,"type":"string"},"phone":{"nullable":true,"type":"string"}},"type":"object"},"UpdateScheduleRequest":{"properties":{"capacity":{"type":"integer"},"date_start":{"format":"date","type":"string"},"time_end":{"type":"string"},"time_start":{"type":"string"}},"type":"object"},"UpdateUserPermissionsRequest":{"properties":{"allow_add_employees":{"description":"Право добавлять сотрудников","type":"boolean"},"allow_applications_edit":{"description":"Право редактировать заявки клиентов","type":"boolean"},"allow_company_edit":{"description":"Право редактировать данные компании","type":"boolean"},"allow_events_edit":{"description":"Право редактировать события","type":"boolean"},"allow_products_edit":{"description":"Право редактировать товары","type":"boolean"}},"type":"object"},"User":{"properties":{"avatar":{"nullable":true,"type":"string"},"current_company_id":{"format":"uuid","nullable":true,"type":"string"},"email":{"format":"email","type":"string"},"first_name":{"type":"string"},"phone":{"nullable":true,"type":"string"},"user_id":{"format":"uuid","type":"string"}},"type":"object"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","description":"Аутентификация Bearer токеном. Токен получается при входе/регистрации.","scheme":"bearer","type":"http"}}},"info":{"contact":{"name":"Sochi Events"},"description":"API платформы управления событиями Sochi.\nРегистрация по email с токенами активации. Поддержка политики конфиденциальности и согласия на обработку персональных данных.\nEmail-уведомления на русском языке (язык по заголовку Accept-Language). Аутентификация на основе сессий.\nАвтоматическая активация аккаунта при заполненных согласиях. Автоматическое создание сессии при установке пароля.\n","externalDocs":{"description":"Интерактивная документация API","url":"https://eval.su/docs-api"},"title":"Sochi API","version":"1.0.0"},"openapi":"3.0.0","paths":{"/ai-assistant/create-event":{"post":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"session_id":{"type":"string"}},"required":["session_id"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"edit_url":{"type":"string"},"event":{"type":"object"},"slot":{"type":"object"}},"type":"object"}}},"description":"Событие и слот созданы"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать событие из сессии ИИ","tags":["ai-assistant"],"x-maturity":"production"}},"/ai-assistant/parse":{"post":{"description":"Извлечь данные события из произвольного текста с помощью ИИ.\nПринимает описание (анонс, афиша) и возвращает структурированные поля (название, дата, цена и т.д.).\nПри неполных данных — список вопросов для уточнения.\n","requestBody":{"content":{"application/json":{"schema":{"properties":{"session_id":{"type":"string"},"text":{"type":"string"}},"required":["text"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"event_data":{"type":"object"},"is_complete":{"type":"boolean"},"missing_fields":{"type":"array"},"questions":{"type":"array"},"session_id":{"type":"string"}},"type":"object"}}},"description":"Извлечённые данные события"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Разбор текста события","tags":["ai-assistant"],"x-maturity":"production"}},"/ai-assistant/session/{id}":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Данные сессии"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Сессия ИИ-ассистента","tags":["ai-assistant"],"x-maturity":"production"}},"/auth/activate":{"post":{"description":"Активация аккаунта по токену из письма.\n\n**Процесс:**\n1. Токен проверяется (существует и не истёк)\n2. Аккаунт активируется (is_activated = true, токен очищается)\n3. Если согласия указаны и ещё не сохранены — сохраняются\n4. Если указан пароль — хешируется и сохраняется\n5. **Сессия всегда создаётся** после успешной активации — пользователь автоматически авторизуется\n6. Возвращается AuthResponse с токеном сессии — редирект в профиль\n\n**Согласия:**\n- Сохраняются только если ещё не заполнены\n- Если уже заполнены — переданные значения игнорируются\n\n**Пароль:**\n- Если указан в запросе — хешируется и сохраняется\n- Можно установить позже в профиле\n","requestBody":{"content":{"application/json":{"example":{"password":"mypassword123","personal_data_consent_accepted":true,"privacy_policy_accepted":true,"token":"abc123def456..."},"schema":{"$ref":"#/components/schemas/ActivateRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}},"description":"Аккаунт активирован. Сессия создана, пользователь авторизован.\nВозвращается AuthResponse с токеном — редирект в профиль.\n"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший токен"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Не авторизован — нельзя активировать чужой аккаунт"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации (короткий пароль и т.д.)"}},"security":[],"summary":"Активация аккаунта","tags":["auth"],"x-maturity":"production"}},"/auth/activation-info":{"get":{"description":"Получить информацию о пользователе и статус согласий по токену активации.\nИспользуется для проверки заполненных согласий перед показом чекбоксов на странице активации.\n","parameters":[{"description":"Токен активации из письма","in":"query","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivationInfoResponse"}}},"description":"Информация об активации"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший токен"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Информация об активации","tags":["auth"]}},"/auth/change-email/confirm":{"post":{"description":"Подтвердить смену email кодом из письма","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmEmailChangeByCodeRequest"}}},"required":true},"responses":{"204":{"description":"Email изменён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший код"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Подтвердить смену email по коду","tags":["auth"],"x-maturity":"production"}},"/auth/change-email/request":{"post":{"description":"Запросить смену email, код подтверждения отправится на новый email","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestEmailChangeRequest"}}},"required":true},"responses":{"204":{"description":"Письмо подтверждения отправлено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Email уже используется"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Запросить смену email","tags":["auth"],"x-maturity":"production"}},"/auth/change-email/verify":{"post":{"description":"Подтвердить смену email по токену из ссылки","parameters":[{"description":"Токен из ссылки в письме","in":"query","name":"token","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"204":{"description":"Email изменён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший токен"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Подтвердить смену email по токену","tags":["auth"],"x-maturity":"production"}},"/auth/change-password":{"post":{"description":"Сменить пароль. Пользователь может менять только свой пароль.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"204":{"description":"Пароль успешно изменён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация or invalid old password"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Сменить пароль","tags":["auth"]}},"/auth/link-telegram":{"post":{"description":"Привязать Telegram к текущему пользователю","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkTelegramRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"type":"object"}}},"description":"Telegram привязан"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Telegram уже привязан к другому пользователю"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Привязать Telegram","tags":["auth"],"x-maturity":"production"}},"/auth/link-telegram-widget":{"post":{"description":"Привязать Telegram через виджет auth_data","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkTelegramWidgetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"type":"object"}}},"description":"Telegram привязан"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Telegram уже привязан к другому пользователю"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Привязать Telegram через виджет","tags":["auth"],"x-maturity":"production"}},"/auth/login":{"post":{"description":"Аутентификация пользователя по email и паролю.\n\n**Процесс:**\n1. Пользователь ищется по email (без учёта регистра)\n2. Проверяется статус активации аккаунта (должен быть активирован)\n3. Пароль проверяется через bcrypt\n4. Создаётся сессия (срок действия 30 дней)\n5. Возвращается AuthResponse с токеном сессии\n\n**Требования:**\n- Аккаунт должен быть активирован (is_activated = true)\n- Пароль должен быть верным\n","requestBody":{"content":{"application/json":{"example":{"email":"user@example.com","password":"password123"},"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}},"description":"Успешный вход"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверные учётные данные"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Аккаунт не активирован"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Вход пользователя","tags":["auth"],"x-maturity":"production"}},"/auth/logout":{"post":{"description":"Выход и деактивация текущей сессии","responses":{"204":{"description":"Успешный выход"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Выход","tags":["auth"],"x-maturity":"production"}},"/auth/me":{"get":{"description":"Информация о текущем аутентифицированном пользователе","responses":{"200":{"content":{"application/json":{"example":{"avatar":null,"current_company_id":"660e8400-e29b-41d4-a716-446655440001","email":"user@example.com","first_name":"Иван","phone":null,"user_id":"550e8400-e29b-41d4-a716-446655440000"},"schema":{"$ref":"#/components/schemas/User"}}},"description":"Информация о текущем пользователе"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Текущий пользователь","tags":["auth"],"x-maturity":"production"}},"/auth/password-reset/confirm":{"post":{"description":"Установить новый пароль по токену из письма. Создаётся сессия.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}},"description":"Пароль сброшен, сессия создана"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший токен"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Подтвердить сброс пароля","tags":["auth"],"x-maturity":"production"}},"/auth/password-reset/request":{"post":{"description":"Отправить письмо сброса пароля","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestPasswordResetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"type":"object"}}},"description":"Письмо отправлено (или пользователь не найден)"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Запросить сброс пароля","tags":["auth"],"x-maturity":"production"}},"/auth/password-reset/validate":{"get":{"description":"Проверка токена сброса пароля из ссылки. При валидном токене пользователь автоматически авторизуется (создаётся сессия) и может сменить пароль через `/auth/change-password`.\n\n**Процесс:**\n1. Токен проверяется (существует и не истёк)\n2. Аккаунт активируется, если ещё не активирован\n3. **Создаётся сессия** — пользователь авторизован\n4. Возвращается AuthResponse с токеном — можно сменить пароль\n\n**Использование:**\n- Пользователь переходит по ссылке из письма\n- Фронтенд вызывает эндпоинт с токеном\n- Пользователь автоматически входит\n","parameters":[{"description":"Токен сброса пароля из письма","in":"query","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}},"description":"Токен действителен. Сессия создана, пользователь авторизован.\nВозвращается AuthResponse с токеном — можно сменить пароль.\n"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный или истёкший токен"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Validate password reset token and auto-authorize","tags":["auth"],"x-maturity":"production"}},"/auth/profile":{"patch":{"description":"Обновить профиль текущего пользователя","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileRequest"}}}},"responses":{"204":{"description":"Профиль обновлён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Пользователь не найден"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Обновить профиль","tags":["auth"],"x-maturity":"production"}},"/auth/register":{"post":{"description":"Регистрация нового пользователя по email. Обязателен только email. Пользователь получит письмо активации.\n\n**Процесс:**\n1. Создаётся пользователь с токеном активации (срок 24 часа)\n2. Если указан пароль, он хешируется и сохраняется\n3. Если указаны согласия, они сохраняются с отметками времени\n4. Отправляется письмо активации (язык по заголовку Accept-Language, по умолчанию ru)\n5. Пользователь должен активировать аккаунт по ссылке из письма\n\n**Согласия:**\n- Если согласия указаны при регистрации, они сохраняются сразу\n- Если не указаны, запрос будет при активации\n","requestBody":{"content":{"application/json":{"example":{"email":"user@example.com","first_name":"Иван","password":"password123","personal_data_consent_accepted":true,"privacy_policy_accepted":true},"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"message":{"example":"Регистрация успешна. Пожалуйста, проверьте email для активации аккаунта.","type":"string"}},"type":"object"}}},"description":"Пользователь создан, письмо активации отправлено"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации (неверный формат email или короткий пароль)"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Пользователь уже существует"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Регистрация пользователя","tags":["auth"],"x-maturity":"production"}},"/auth/sessions":{"get":{"description":"Получить все активные сессии текущего пользователя","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"sessions":{"items":{"$ref":"#/components/schemas/Session"},"type":"array"}},"type":"object"}}},"description":"Список активных сессий"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Сессии пользователя","tags":["auth"]}},"/auth/sessions/{id}":{"delete":{"description":"Завершить конкретную сессию. Пользователь может завершать только свои сессии.","parameters":[{"description":"Session ID","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Сессия завершена"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Запрещено — нельзя завершить чужую сессию"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Сессия не найдена"}},"summary":"Завершить сессию","tags":["auth"],"x-maturity":"production"}},"/auth/telegram":{"post":{"description":"Авторизация через Telegram Mini App (init_data из бота)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramAuthRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramAuthResponse"}}},"description":"Авторизован"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверные данные Telegram"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Авторизация Telegram WebApp","tags":["auth"],"x-maturity":"production"}},"/auth/telegram-widget":{"post":{"description":"Авторизация через виджет Telegram (auth_data из callback)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramWidgetAuthRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramAuthResponse"}}},"description":"Авторизован"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверные данные Telegram"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"security":[],"summary":"Авторизация виджета Telegram","tags":["auth"],"x-maturity":"production"}},"/business":{"get":{"description":"Текущий бизнес пользователя с полными данными","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}},"description":"Текущий бизнес"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не выбрана"}},"summary":"Текущий бизнес","tags":["companies"],"x-maturity":"production"},"patch":{"description":"Обновить данные текущего бизнеса","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanyRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}},"description":"Бизнес обновлён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не выбрана"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Обновить бизнес","tags":["companies"],"x-maturity":"production"}},"/companies":{"get":{"description":"Компании текущего пользователя (где он владелец или сотрудник)","responses":{"200":{"content":{"application/json":{"example":{"companies":[{"code":"my-company","company_id":"660e8400-e29b-41d4-a716-446655440001","logo":null,"name":"Моя компания","role":"owner"}]},"schema":{"properties":{"companies":{"items":{"$ref":"#/components/schemas/Company"},"type":"array"}},"type":"object"}}},"description":"Список компаний"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Список компаний","tags":["companies"]},"post":{"description":"Создать новую компанию (организатора событий).\nПользователь станет владельцем.\n","requestBody":{"content":{"application/json":{"example":{"description":{},"name":"Сочи Мастер-классы"},"schema":{"$ref":"#/components/schemas/CreateCompanyRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}},"description":"Компания создана"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Создать компанию","tags":["companies"],"x-maturity":"production"}},"/companies/{id}":{"get":{"description":"Получить компанию по ID","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}},"description":"Данные компании"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"}},"summary":"Получить компанию","tags":["companies"],"x-maturity":"production"},"patch":{"description":"Обновить данные компании","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanyRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}},"description":"Компания обновлена"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Обновить компанию","tags":["companies"],"x-maturity":"production"}},"/companies/{id}/events/export/ical":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"text/calendar":{"schema":{"type":"string"}}},"description":"Файл iCal со всеми событиями компании"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"}},"security":[],"summary":"Экспорт событий компании в iCal","tags":["calendar"],"x-maturity":"production"}},"/companies/{id}/orders":{"get":{"description":"Список заказов (бронирований) компании с фильтрами.","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"page","schema":{"type":"integer"}},{"in":"query","name":"page_size","schema":{"type":"integer"}},{"in":"query","name":"status","schema":{"type":"string"}},{"in":"query","name":"sort_by","schema":{"type":"string"}},{"in":"query","name":"sort_order","schema":{"type":"string"}},{"in":"query","name":"active","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderListResponse"}}},"description":"Список заказов"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Доступ запрещён"}},"summary":"Заказы компании","tags":["orders"],"x-maturity":"production"}},"/companies/{id}/orders/{orderId}":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"orderId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"Данные заказа"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Заказ не найден"}},"summary":"Получить заказ","tags":["orders"],"x-maturity":"production"}},"/companies/{id}/orders/{orderId}/status":{"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"orderId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"status":"confirmed"},"schema":{"properties":{"status":{"description":"Новый статус заказа","type":"string"}},"required":["status"],"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"Заказ обновлён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Заказ не найден"}},"summary":"Обновить статус заказа","tags":["orders"],"x-maturity":"production"}},"/companies/{id}/switch":{"post":{"description":"Переключить текущую компанию пользователя","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Компания переключена"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"}},"summary":"Переключить компанию","tags":["companies"]}},"/companies/{id}/transfer-ownership":{"post":{"description":"Передать владение компанией. Может только текущий владелец.","parameters":[{"description":"ID компании","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnershipRequest"}}},"required":true},"responses":{"204":{"description":"Владение передано"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Запрещено — только владелец может передать владение"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания или пользователь не найдены"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Передать владение компанией","tags":["companies"],"x-maturity":"production"}},"/companies/{id}/users":{"get":{"description":"Список пользователей компании с правами доступа","parameters":[{"description":"ID компании","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"users":{"items":{"$ref":"#/components/schemas/CompanyUser"},"type":"array"}},"type":"object"}}},"description":"Список пользователей компании"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"}},"summary":"Пользователи компании","tags":["companies"],"x-maturity":"production"},"post":{"description":"Добавить пользователя в компанию по email. Если пользователя нет, создаётся новый с токеном активации и отправляется приглашение.","parameters":[{"description":"ID компании","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"email":"user@example.com"},"schema":{"$ref":"#/components/schemas/AddUserRequest"}}},"required":true},"responses":{"204":{"description":"Пользователь добавлен (или отправлено приглашение)"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"},"500":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Внутренняя ошибка сервера"}},"summary":"Добавить пользователя","tags":["companies"],"x-maturity":"production"}},"/companies/{id}/users/{userId}":{"delete":{"description":"Удалить пользователя из компании. Владельца удалить нельзя.","parameters":[{"description":"ID компании","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"description":"ID пользователя","in":"path","name":"userId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Пользователь удалён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Запрещено — нельзя удалить владельца"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания или пользователь не найдены"}},"summary":"Удалить пользователя","tags":["companies"]}},"/companies/{id}/users/{userId}/permissions":{"put":{"description":"Обновить права пользователя в компании. Права владельца изменить нельзя.","parameters":[{"description":"ID компании","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"description":"ID пользователя","in":"path","name":"userId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserPermissionsRequest"}}},"required":true},"responses":{"204":{"description":"Права обновлены"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Запрещено — нельзя редактировать права владельца"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания или пользователь не найдены"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Ошибка валидации"}},"summary":"Обновить права пользователя","tags":["companies"],"x-maturity":"production"}},"/company-categories":{"get":{"description":"Список категорий для компаний (организаторов).\nИспользуется при создании/редактировании компании и для фильтрации.\n","responses":{"200":{"content":{"application/json":{"example":{"categories":[{"category_id":"990e8400-e29b-41d4-a716-446655440000","name":"Образование"}]},"schema":{"properties":{"categories":{"items":{"properties":{"category_id":{"format":"uuid","type":"string"},"name":{"type":"string"}},"type":"object"},"type":"array"}},"required":["categories"],"type":"object"}}},"description":"Список категорий"}},"security":[],"summary":"Категории компаний","tags":["categories"],"x-maturity":"production"}},"/dadata/suggest/address":{"post":{"description":"Подсказки адресов через Dadata API.\nИспользуется для автодополнения при вводе адреса (создание события, места).\nМожно ограничить область поиска параметром `locations`.\n","requestBody":{"content":{"application/json":{"schema":{"properties":{"count":{"description":"Максимум подсказок (по умолчанию ~10)","type":"integer"},"locations":{"description":"Ограничение области поиска","type":"array"},"query":{"description":"Строка поиска (начало адреса)","example":"Сочи, Курорт","type":"string"}},"required":["query"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"array"}}},"description":"Массив подсказок адресов"}},"security":[],"summary":"Подсказки адресов","tags":["dadata"],"x-maturity":"production"}},"/events":{"get":{"description":"События текущей компании с фильтрами и пагинацией.","parameters":[{"in":"query","name":"page","schema":{"type":"integer"}},{"in":"query","name":"page_size","schema":{"type":"integer"}},{"in":"query","name":"published","schema":{"type":"boolean"}},{"in":"query","name":"category_id","schema":{"format":"uuid","type":"string"}},{"in":"query","name":"search","schema":{"type":"string"}},{"in":"query","name":"sort_by","schema":{"type":"string"}},{"in":"query","name":"sort_order","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventListResponse"}}},"description":"Список событий"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Список событий","tags":["events"],"x-maturity":"production"},"post":{"description":"Создать новое событие (мастер-класс, тренинг) в текущей компании.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"description":"Событие создано"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный запрос"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать событие","tags":["events"],"x-maturity":"production"}},"/events/{id}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Событие удалено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"summary":"Удалить событие","tags":["events"],"x-maturity":"production"},"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"description":"Данные события"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"403":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Доступ запрещён"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"summary":"Получить событие","tags":["events"],"x-maturity":"production"},"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"description":"Событие обновлено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"summary":"Обновить событие","tags":["events"],"x-maturity":"production"}},"/events/{id}/export/ical":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"text/calendar":{"schema":{"type":"string"}}},"description":"Файл iCal"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"security":[],"summary":"Экспорт события в iCal","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/export/links":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Ссылки экспорта (Google, Outlook, iCal)"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"security":[],"summary":"Ссылки экспорта события","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/schedules":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleListResponse"}}},"description":"Список расписаний"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Список расписаний","tags":["schedules"],"x-maturity":"production"},"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateScheduleRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}},"description":"Расписание создано"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать расписание","tags":["schedules"],"x-maturity":"production"}},"/events/{id}/schedules/{scheduleId}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"scheduleId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Расписание удалено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Удалить расписание","tags":["schedules"],"x-maturity":"production"},"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"scheduleId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}},"description":"Данные расписания"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Получить расписание","tags":["schedules"],"x-maturity":"production"},"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"scheduleId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}},"description":"Расписание обновлено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Обновить расписание","tags":["schedules"],"x-maturity":"production"}},"/events/{id}/schedules/{scheduleId}/generate":{"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"scheduleId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"date_from":{"format":"date","type":"string"},"date_to":{"format":"date","type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"},"slots":{"type":"array"}},"type":"object"}}},"description":"Слоты сгенерированы"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Сгенерировать слоты из расписания","tags":["schedules"],"x-maturity":"production"}},"/events/{id}/slots":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"date_from","schema":{"format":"date","type":"string"}},{"in":"query","name":"date_to","schema":{"format":"date","type":"string"}},{"in":"query","name":"has_space","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlotListResponse"}}},"description":"Список слотов"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Список слотов","tags":["event-slots"],"x-maturity":"production"},"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventSlotRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlot"}}},"description":"Слот создан"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать событие slot","tags":["event-slots"],"x-maturity":"production"}},"/events/{id}/slots/batch":{"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventSlotsBatchRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"},"slots":{"type":"array"}},"type":"object"}}},"description":"Слоты созданы"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать событие slots batch","tags":["event-slots"],"x-maturity":"production"}},"/events/{id}/slots/quick":{"post":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"capacity":{"type":"integer"},"date":{"format":"date","type":"string"},"end_time":{"type":"string"},"start_time":{"type":"string"}},"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlot"}}},"description":"Слот создан"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Создать событие slot (quick)","tags":["event-slots"],"x-maturity":"production"}},"/events/{id}/slots/upcoming":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"limit","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlotListResponse"}}},"description":"Ближайшие слоты"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Ближайшие слоты","tags":["event-slots"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Слот удалён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Удалить слот","tags":["event-slots"],"x-maturity":"production"},"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlot"}}},"description":"Данные слота"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Получить слот","tags":["event-slots"],"x-maturity":"production"},"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventSlotRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSlot"}}},"description":"Слот обновлён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Обновить слот","tags":["event-slots"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}/export/google":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"redirect","schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"url":{"type":"string"}},"type":"object"}}},"description":"URL добавления в Google Calendar"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот не найден"}},"security":[],"summary":"URL Google Calendar","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}/export/ical":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"text/calendar":{"schema":{"type":"string"}}},"description":"Файл iCal"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот не найден"}},"security":[],"summary":"Экспорт слота в iCal","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}/export/links":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Все ссылки календаря"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот не найден"}},"security":[],"summary":"Все ссылки экспорта слота","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}/export/outlook":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"url":{"type":"string"}},"type":"object"}}},"description":"URL добавления в Outlook"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот не найден"}},"security":[],"summary":"URL Outlook","tags":["calendar"],"x-maturity":"production"}},"/events/{id}/slots/{slotId}/register":{"post":{"description":"Публичная запись на слот события без авторизации.\nКлиент указывает email (обязательно), имя и телефон.\nСоздаётся заказ; при наличии свободных мест — бронирование.\n","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"path","name":"slotId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"email":"client@example.com","first_name":"Анна","phone":"+7 999 123-45-67"},"schema":{"properties":{"email":{"description":"Email для подтверждения записи","example":"client@example.com","format":"email","type":"string"},"first_name":{"description":"Имя участника","example":"Анна","type":"string"},"phone":{"description":"Телефон (опционально)","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"message":{"type":"string"},"order_id":{"type":"string"}},"type":"object"}}},"description":"Регистрация успешна"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот заполнен или неверный"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Слот не найден"}},"security":[],"summary":"Записаться на событие","tags":["registration"],"x-maturity":"production"}},"/files/order":{"patch":{"requestBody":{"content":{"application/json":{"schema":{"properties":{"file_ids":{"items":{"format":"uuid","type":"string"},"type":"array"}},"required":["file_ids"],"type":"object"}}},"required":true},"responses":{"204":{"description":"Порядок обновлён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Обновить порядок файлов","tags":["files"],"x-maturity":"production"}},"/files/storage-info":{"get":{"description":"Использование хранилища пользователя","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageInfo"}}},"description":"Информация о хранилище"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Информация о хранилище","tags":["files"],"x-maturity":"production"}},"/files/upload":{"post":{"description":"Загрузка файла через multipart/form-data.\nПоле `file` — бинарные данные. Опционально `entity_type`, `entity_id` для привязки к сущности.\n","requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"entity_id":{"format":"uuid","type":"string"},"entity_type":{"type":"string"},"file":{"format":"binary","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}},"description":"Файл загружен"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный файл или превышен лимит хранилища"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Загрузить файл","tags":["files"],"x-maturity":"production"}},"/files/upload-from-clipboard":{"post":{"description":"Загрузить base64-данные (например, из вставки из буфера обмена)","requestBody":{"content":{"application/json":{"schema":{"properties":{"data":{"description":"Данные в base64","type":"string"},"entity_id":{"format":"uuid","type":"string"},"entity_type":{"type":"string"},"mime_type":{"type":"string"}},"required":["data","mime_type"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}},"description":"Файл загружен"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверные данные"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Загрузить из буфера","tags":["files"],"x-maturity":"production"}},"/files/upload-from-url":{"post":{"description":"Загрузить файл по URL","requestBody":{"content":{"application/json":{"schema":{"properties":{"entity_id":{"format":"uuid","type":"string"},"entity_type":{"type":"string"},"url":{"example":"https://example.com/logo.png","format":"uri","type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}},"description":"Файл загружен"},"400":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Неверный URL или файл"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"}},"summary":"Загрузить файл from URL","tags":["files"],"x-maturity":"production"}},"/files/{id}":{"delete":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Файл удалён"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Файл не найден"}},"summary":"Удалить файл","tags":["files"],"x-maturity":"production"},"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}},"description":"Метаданные файла"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Файл не найден"}},"summary":"Метаданные файла","tags":["files"],"x-maturity":"production"}},"/files/{id}/description":{"patch":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"type":"string"}},"type":"object"}}}},"responses":{"204":{"description":"Описание обновлено"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Файл не найден"}},"summary":"Обновить описание файла","tags":["files"],"x-maturity":"production"}},"/files/{id}/download":{"get":{"parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/octet-stream":{"schema":{"format":"binary","type":"string"}}},"description":"Содержимое файла"},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Требуется аутентификация"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Файл не найден"}},"summary":"Скачать файл","tags":["files"],"x-maturity":"production"}},"/health":{"get":{"description":"Проверка, что API запущен","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"status":{"example":"ok","type":"string"}},"type":"object"}}},"description":"API работает"}},"security":[],"summary":"Проверка работоспособности","tags":["health"],"x-maturity":"production"}},"/holidays/data":{"get":{"description":"Выходные и праздничные дни за текущий и следующий год.\nИспользуется для генерации слотов событий (исключение выходных).\n","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"current_year":{"properties":{"data":{"description":"Карта дат и типов (holiday, weekend)","type":"object"},"loaded_at":{"format":"date-time","type":"string"},"year":{"example":2026,"type":"integer"}},"type":"object"},"next_year":{"properties":{"data":{"type":"object"},"loaded_at":{"type":"string"},"year":{"type":"integer"}},"type":"object"}},"type":"object"}}},"description":"Данные о праздниках"}},"security":[],"summary":"Данные о праздниках","tags":["holidays"],"x-maturity":"production"}},"/public/companies":{"get":{"description":"Список опубликованных компаний с пагинацией и фильтрами.\nИспользуется для каталога организаторов на публичной странице.\n","parameters":[{"description":"Поиск по названию компании","example":"мастер-класс","in":"query","name":"search","schema":{"type":"string"}},{"description":"Фильтр по категории компании","in":"query","name":"category_id","schema":{"format":"uuid","type":"string"}},{"description":"Номер страницы","in":"query","name":"page","schema":{"default":1,"type":"integer"}},{"description":"Размер страницы","in":"query","name":"limit","schema":{"default":20,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"companies":[{"code":"sochi-events","company_id":"660e8400-e29b-41d4-a716-446655440001","name":"Сочи Ивентс"}],"limit":20,"page":1,"total":15},"schema":{"properties":{"companies":{"items":{"$ref":"#/components/schemas/PublicCompany"},"type":"array"},"limit":{"type":"integer"},"page":{"type":"integer"},"total":{"type":"integer"}},"type":"object"}}},"description":"Список компаний"}},"security":[],"summary":"Список публичных компаний","tags":["public"],"x-maturity":"production"}},"/public/companies/{code}":{"get":{"description":"Получить данные опубликованной компании по её коду (slug).\nКод задаётся в настройках компании и используется в URL публичной страницы.\n","parameters":[{"description":"Код компании (slug)","example":"sochi-events","in":"path","name":"code","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"categories":[],"code":"sochi-events","company_id":"660e8400-e29b-41d4-a716-446655440001","description":{},"logo":null,"name":"Сочи Ивентс"},"schema":{"$ref":"#/components/schemas/PublicCompany"}}},"description":"Данные компании"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Компания не найдена или не опубликована"}},"security":[],"summary":"Публичная компания по коду","tags":["public"],"x-maturity":"production"}},"/public/events":{"get":{"description":"Список опубликованных событий с пагинацией и фильтрами.\nПоддерживает фильтрацию по категории, месту, поиску по названию/описанию.\n","parameters":[{"description":"Только опубликованные (по умолчанию true)","in":"query","name":"published","schema":{"default":true,"type":"boolean"}},{"description":"Фильтр по категории события","in":"query","name":"category_id","schema":{"format":"uuid","type":"string"}},{"description":"Фильтр по месту проведения","in":"query","name":"place_id","schema":{"format":"uuid","type":"string"}},{"description":"Поиск по названию и описанию","in":"query","name":"search","schema":{"type":"string"}},{"in":"query","name":"page","schema":{"default":1,"type":"integer"}},{"in":"query","name":"page_size","schema":{"default":20,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"events":[{"event_id":"770e8400-e29b-41d4-a716-446655440002","nearest_time":"2026-02-15T10:00:00Z","published":true}],"total_count":42},"schema":{"$ref":"#/components/schemas/EventListResponse"}}},"description":"Список событий"}},"security":[],"summary":"Список публичных событий","tags":["public"],"x-maturity":"production"}},"/public/events/{id}":{"get":{"description":"Получить полные данные опубликованного события.\nВключает описание, места, слоты, категорию, превью.\n","parameters":[{"description":"ID события","example":"770e8400-e29b-41d4-a716-446655440002","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}},"description":"Данные события"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено или не опубликовано"}},"security":[],"summary":"Публичное событие по ID","tags":["public"],"x-maturity":"production"}},"/public/events/{id}/slots":{"get":{"description":"Список временных слотов опубликованного события.\nИспользуется для выбора даты/времени записи на событие.\n","parameters":[{"description":"ID события","example":"770e8400-e29b-41d4-a716-446655440002","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"slots":[{"capacity":10,"ends_at":"2026-02-15T12:00:00Z","event_slot_id":"880e8400-e29b-41d4-a716-446655440003","participant_count":3,"starts_at":"2026-02-15T10:00:00Z"}],"total_count":5},"schema":{"$ref":"#/components/schemas/EventSlotListResponse"}}},"description":"Список слотов (время, вместимость, занято)"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Событие не найдено"}},"security":[],"summary":"Публичные слоты события","tags":["public"],"x-maturity":"production"}},"/public/files/{id}/download":{"get":{"description":"Скачать файл без авторизации.\nИспользуется для публичных файлов: логотипы компаний, превью событий, изображения в афишах.\n","parameters":[{"description":"ID файла (file_id)","example":"550e8400-e29b-41d4-a716-446655440000","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/octet-stream":{"schema":{"format":"binary","type":"string"}}},"description":"Содержимое файла (бинарные данные)","headers":{"Content-Disposition":{"description":"Имя файла при сохранении","schema":{"type":"string"}}}},"404":{"content":{"application/problem+json":{"example":{"detail":"Файл не найден","status":404,"title":"Not Found","type":"about:blank"},"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Файл не найден или не публичный"}},"security":[],"summary":"Скачать публичный файл","tags":["public"],"x-maturity":"production"}},"/public/places":{"get":{"description":"Список всех мест с количеством опубликованных событий (event_count).\nМеста — точки проведения событий (адреса из Nominatim/OpenStreetMap).\nИспользуется для фильтрации событий по месту, отображения на карте, выпадающего списка.\n","responses":{"200":{"content":{"application/json":{"example":{"places":[{"display_name":"Сочи, Краснодарский край, Россия","event_count":5,"lat":43.5854723,"lon":39.7230629,"osm_id":12345,"osm_type":"relation","place_id":"550e8400-e29b-41d4-a716-446655440000"},{"display_name":"Красная Поляна, Адлерский район, Сочи","event_count":3,"lat":43.6803,"lon":40.2777,"osm_id":67890,"osm_type":"way","place_id":"660e8400-e29b-41d4-a716-446655440001"}]},"schema":{"properties":{"places":{"items":{"$ref":"#/components/schemas/Place"},"type":"array"}},"required":["places"],"type":"object"}}},"description":"Список мест с количеством событий"}},"security":[],"summary":"Список мест","tags":["public"],"x-maturity":"production"}},"/public/places/{id}":{"get":{"description":"Получить место по ID и список опубликованных событий в этом месте.\nИспользуется для страницы места с календарём предстоящих событий.\n","parameters":[{"description":"ID места (place_id)","example":"550e8400-e29b-41d4-a716-446655440000","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"events":[{"event_id":"770e8400-e29b-41d4-a716-446655440002","published":true}],"place":{"display_name":"Сочи, Краснодарский край, Россия","lat":43.5854723,"lon":39.7230629,"place_id":"550e8400-e29b-41d4-a716-446655440000"}},"schema":{"properties":{"events":{"items":{"$ref":"#/components/schemas/Event"},"type":"array"},"place":{"$ref":"#/components/schemas/Place"}},"required":["place","events"],"type":"object"}}},"description":"Место и его события"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"Место не найдено"}},"security":[],"summary":"Место с событиями","tags":["public"],"x-maturity":"production"}},"/ready":{"get":{"description":"Проверка готовности к обработке запросов (БД, Redis).\nВозвращает 503, если зависимости недоступны.\n","responses":{"200":{"description":"API готов к приёму трафика"},"503":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"API не готов (БД или Redis недоступны)"}},"security":[],"summary":"Проверка готовности","tags":["health"],"x-maturity":"production"}}},"security":[{"bearerAuth":[]}],"servers":[{"description":"Сервер API","url":"https://eval.su/api/v1"}],"tags":[{"description":"Проверка работоспособности и готовности API","name":"health"},{"description":"Регистрация, вход, активация, смена пароля, Telegram","name":"auth"},{"description":"Управление компаниями и сотрудниками","name":"companies"},{"description":"Текущий бизнес пользователя","name":"business"},{"description":"Загрузка и управление файлами","name":"files"},{"description":"Данные о выходных и праздниках","name":"holidays"},{"description":"Категории компаний","name":"categories"},{"description":"Публичные данные без авторизации (события, места, компании)","name":"public"},{"description":"Подсказки адресов через Dadata","name":"dadata"},{"description":"События и мастер-классы","name":"events"},{"description":"Временные слоты событий","name":"event-slots"},{"description":"Расписания для генерации слотов","name":"schedules"},{"description":"Экспорт в календарь (iCal, Google, Outlook)","name":"calendar"},{"description":"Заказы и бронирования","name":"orders"},{"description":"Публичная запись на события","name":"registration"},{"description":"ИИ-помощник для создания событий","name":"ai-assistant"}]}
