Добавьте файлы проекта.

This commit is contained in:
FrigaT
2026-04-13 14:16:44 +03:00
parent b2b5a3945a
commit 37c997dbe0
120 changed files with 5364 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
public class AddTrackRequest
{
[JsonPropertyName("sharedPlaylistToken")]
public string SharedPlaylistToken { get; set; } = null!;
[JsonPropertyName("trackIds")]
public List<string> TrackIds { get; set; } = new();
}

View File

@@ -0,0 +1,32 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Универсальный контейнер ответа API.</summary>
/// <typeparam name="T">Тип данных ответа.</typeparam>
public class ApiResponse<T>
{
/// <summary>Успешен ли запрос.</summary>
[JsonPropertyName("success")]
public bool Success { get; set; }
/// <summary>Данные ответа (при успехе).</summary>
[JsonPropertyName("data")]
public T? Data { get; set; }
/// <summary>Сообщение (опционально).</summary>
[JsonPropertyName("message")]
public string? Message { get; set; }
/// <summary>Ошибка (при неудаче).</summary>
[JsonPropertyName("error")]
public ErrorResponse? Error { get; set; }
/// <summary>Создаёт успешный ответ.</summary>
public static ApiResponse<T> Ok(T data, string? message = null) =>
new() { Success = true, Data = data, Message = message };
/// <summary>Создаёт ответ с ошибкой.</summary>
public static ApiResponse<T> Fail(ErrorResponse error) =>
new() { Success = false, Error = error };
}

View File

@@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Стандартный ответ сервера при ошибке.</summary>
public class ErrorResponse
{
/// <summary>HTTP статус-код.</summary>
[JsonPropertyName("statusCode")]
public int StatusCode { get; set; }
/// <summary>Сообщение об ошибке.</summary>
[JsonPropertyName("message")]
public string Message { get; set; } = null!;
/// <summary>Дополнительные детали (опционально).</summary>
[JsonPropertyName("details")]
public string? Details { get; set; }
}

View File

@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
public class ExternalLoginCallbackRequest
{
[JsonPropertyName("code")]
public string Code { get; set; } = null!;
[JsonPropertyName("state")]
public string State { get; set; } = null!;
}

View File

@@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на вход по паролю.</summary>
public class LoginRequest
{
/// <summary>Имя пользователя (логин).</summary>
[JsonPropertyName("username")]
public string Username { get; set; } = null!;
/// <summary>Пароль.</summary>
[JsonPropertyName("password")]
public string Password { get; set; } = null!;
/// <summary>Запомнить пользователя (продлить сессию).</summary>
[JsonPropertyName("rememberMe")]
public bool RememberMe { get; set; }
}

View File

@@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Ответ после успешного входа.</summary>
public class LoginResponse
{
/// <summary>JWT токен доступа.</summary>
[JsonPropertyName("token")]
public string Token { get; set; } = null!;
/// <summary>Refresh токен для обновления сессии.</summary>
[JsonPropertyName("refreshToken")]
public string RefreshToken { get; set; } = null!;
/// <summary>Время истечения токена (UTC).</summary>
[JsonPropertyName("expiration")]
public DateTime Expiration { get; set; }
}

View File

@@ -0,0 +1,11 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на обновление JWT токена.</summary>
public class RefreshTokenRequest
{
/// <summary>Refresh токен, полученный при входе.</summary>
[JsonPropertyName("refreshToken")]
public string RefreshToken { get; set; } = null!;
}

View File

@@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на регистрацию нового пользователя.</summary>
public class RegisterRequest
{
/// <summary>Имя пользователя (логин).</summary>
[JsonPropertyName("username")]
public string Username { get; set; } = null!;
/// <summary>Email пользователя.</summary>
[JsonPropertyName("email")]
public string Email { get; set; } = null!;
/// <summary>Пароль.</summary>
[JsonPropertyName("password")]
public string Password { get; set; } = null!;
}

View File

@@ -0,0 +1,6 @@
namespace PlaylistShared.Shared.DTO;
public class SetYandexTokenRequest
{
public string Token { get; set; }
}

View File

@@ -0,0 +1,48 @@
using PlaylistShared.Shared.Enums;
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на создание нового шеринг-плейлиста.</summary>
public class SharePlaylistDto
{
/// <summary>Идентификатор плейлиста в Яндекс.Музыке (kind).</summary>
[JsonPropertyName("yandexPlaylistKind")]
public string YandexPlaylistKind { get; set; } = null!;
/// <summary>Идентификатор владельца плейлиста в Яндекс.Музыке (uid).</summary>
[JsonPropertyName("yandexPlaylistOwnerUid")]
public string YandexPlaylistOwnerUid { get; set; } = null!;
/// <summary>Название плейлиста.</summary>
[JsonPropertyName("title")]
public string Title { get; set; } = null!;
/// <summary>Описание плейлиста.</summary>
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>Ссылка на обложку.</summary>
[JsonPropertyName("coverUrl")]
public string? CoverUrl { get; set; }
/// <summary>Дата создания плейлиста.</summary>
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; }
/// <summary>Токен для расшаривания плейлиста.</summary>
[JsonPropertyName("shareToken")]
public string ShareToken { get; set; }
/// <summary>Права на просмотр.</summary>
[JsonPropertyName("viewPermission")]
public ViewPermission ViewPermission { get; set; }
/// <summary>Права на добавление треков.</summary>
[JsonPropertyName("addPermission")]
public EditPermission AddPermission { get; set; }
/// <summary>Права на удаление треков.</summary>
[JsonPropertyName("removePermission")]
public EditPermission RemovePermission { get; set; }
}

View File

@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на добавление или удаление треков.</summary>
public class TrackOperationDto
{
/// <summary>Токен шеринг-плейлиста (для проверки прав).</summary>
[JsonPropertyName("sharedPlaylistToken")]
public string SharedPlaylistToken { get; set; } = null!;
/// <summary>Список идентификаторов треков в Яндекс.Музыке.</summary>
[JsonPropertyName("trackIds")]
public List<string> TrackIds { get; set; } = new();
}

View File

@@ -0,0 +1,20 @@
using PlaylistShared.Shared.Enums;
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Запрос на обновление прав доступа шеринг-плейлиста.</summary>
public class UpdatePermissionsDto
{
/// <summary>Новые права на просмотр.</summary>
[JsonPropertyName("viewPermission")]
public ViewPermission ViewPermission { get; set; }
/// <summary>Новые права на добавление треков.</summary>
[JsonPropertyName("addPermission")]
public EditPermission AddPermission { get; set; }
/// <summary>Новые права на удаление треков.</summary>
[JsonPropertyName("removePermission")]
public EditPermission RemovePermission { get; set; }
}

View File

@@ -0,0 +1,45 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.DTO;
/// <summary>Информация о плейлисте из Яндекс.Музыки (для импорта).</summary>
public class YandexPlaylistInfo
{
/// <summary>Идентификатор плейлиста (kind).</summary>
[JsonPropertyName("kind")]
public string Kind { get; set; } = null!;
/// <summary>Идентификатор владельца плейлиста (uid).</summary>
[JsonPropertyName("ownerUid")]
public string OwnerUid { get; set; } = null!;
/// <summary>Название плейлиста.</summary>
[JsonPropertyName("title")]
public string Title { get; set; } = null!;
/// <summary>Описание плейлиста.</summary>
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>URL обложки.</summary>
[JsonPropertyName("coverUrl")]
public string? CoverUrl { get; set; }
/// <summary>Кол-во треков.</summary>
[JsonPropertyName("trackCount")]
public int TrackCount { get; set; }
/// <summary>Расшаренный</summary>
[JsonPropertyName("isShared")]
public bool IsShared { get; set; }
/// <summary>Расшаренная ссылка</summary>
[JsonPropertyName("shareToken")]
public string? ShareToken { get; set; }
}
public class SharePlaylistRequest
{
public string Kind { get; set; }
public string OwnerUid { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace PlaylistShared.Shared.DTO;
public class YandexTokenStatus
{
public bool HasToken { get; set; }
public bool IsValid { get; set; }
public DateTime ExpiryUtc { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace PlaylistShared.Shared.Enums;
/// <summary>Кто может выполнять действие (добавление/удаление).</summary>
public enum EditPermission
{
/// <summary>Все, включая неавторизованных (но для выполнения действия нужна авторизация, так как API требует токен).</summary>
Everyone,
/// <summary>Только авторизованные пользователи.</summary>
AuthorizedOnly,
/// <summary>Никто, кроме создателя.</summary>
Nobody,
/// <summary>Только тот пользователь, который добавил трек (актуально для удаления).</summary>
AddedByUserOnly,
}

View File

@@ -0,0 +1,11 @@
namespace PlaylistShared.Shared.Enums;
/// <summary>Кто может просматривать плейлист.</summary>
public enum ViewPermission
{
/// <summary>Все, включая неавторизованных.</summary>
Everyone,
/// <summary>Только авторизованные пользователи.</summary>
AuthorizedOnly,
}

View File

@@ -0,0 +1,27 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.Models;
/// <summary>DTO пользователя (без конфиденциальных данных).</summary>
public class ApplicationUserDto
{
/// <summary>Идентификатор пользователя в системе.</summary>
[JsonPropertyName("id")]
public Guid Id { get; set; }
/// <summary>Имя пользователя (логин).</summary>
[JsonPropertyName("userName")]
public string UserName { get; set; } = null!;
/// <summary>Email пользователя.</summary>
[JsonPropertyName("email")]
public string? Email { get; set; }
/// <summary>Идентификатор пользователя в Яндексе (если привязан).</summary>
[JsonPropertyName("yandexId")]
public string? YandexId { get; set; }
/// <summary>Отображаемое имя (можно использовать UserName).</summary>
[JsonPropertyName("displayName")]
public string? DisplayName { get; set; }
}

View File

@@ -0,0 +1,68 @@
using PlaylistShared.Shared.Enums;
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.Models;
/// <summary>DTO шеринг-плейлиста (без навигационных свойств).</summary>
public class SharedPlaylistDto
{
/// <summary>Уникальный идентификатор записи.</summary>
[JsonPropertyName("id")]
public Guid Id { get; set; }
/// <summary>Идентификатор пользователя-создателя (владельца).</summary>
[JsonPropertyName("creatorUserId")]
public Guid CreatorUserId { get; set; }
/// <summary>Идентификатор плейлиста в Яндекс.Музыке (kind).</summary>
[JsonPropertyName("yandexPlaylistKind")]
public string YandexPlaylistKind { get; set; } = null!;
/// <summary>Идентификатор владельца плейлиста в Яндекс.Музыке (uid).</summary>
[JsonPropertyName("yandexPlaylistOwnerUid")]
public string YandexPlaylistOwnerUid { get; set; } = null!;
/// <summary>Название плейлиста.</summary>
[JsonPropertyName("title")]
public string Title { get; set; } = null!;
/// <summary>Описание плейлиста.</summary>
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>URL обложки плейлиста.</summary>
[JsonPropertyName("coverUrl")]
public string? CoverUrl { get; set; }
/// <summary>Дата создания записи.</summary>
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; }
/// <summary>Дата последнего обновления.</summary>
[JsonPropertyName("updatedAt")]
public DateTime UpdatedAt { get; set; }
/// <summary>Признак мягкого удаления.</summary>
[JsonPropertyName("isDeleted")]
public bool IsDeleted { get; set; }
/// <summary>Уникальный токен для публичной ссылки.</summary>
[JsonPropertyName("shareToken")]
public string ShareToken { get; set; } = null!;
/// <summary>Права на просмотр.</summary>
[JsonPropertyName("viewPermission")]
public ViewPermission ViewPermission { get; set; }
/// <summary>Права на добавление треков.</summary>
[JsonPropertyName("addPermission")]
public EditPermission AddPermission { get; set; }
/// <summary>Права на удаление треков.</summary>
[JsonPropertyName("removePermission")]
public EditPermission RemovePermission { get; set; }
/// <summary>Информация о создателе (опционально, подгружается отдельно).</summary>
[JsonPropertyName("creator")]
public ApplicationUserDto? Creator { get; set; }
}

View File

@@ -0,0 +1,27 @@
using System.Text.Json.Serialization;
namespace PlaylistShared.Shared.Models;
/// <summary>DTO лога добавления трека (без навигации).</summary>
public class TrackAdditionLogDto
{
/// <summary>Уникальный идентификатор записи.</summary>
[JsonPropertyName("id")]
public Guid Id { get; set; }
/// <summary>Идентификатор шеринг-плейлиста.</summary>
[JsonPropertyName("sharedPlaylistId")]
public Guid SharedPlaylistId { get; set; }
/// <summary>Идентификатор трека в Яндекс.Музыке.</summary>
[JsonPropertyName("trackId")]
public string TrackId { get; set; } = null!;
/// <summary>Идентификатор пользователя, добавившего трек.</summary>
[JsonPropertyName("addedByUserId")]
public Guid AddedByUserId { get; set; }
/// <summary>Дата и время добавления (UTC).</summary>
[JsonPropertyName("addedAtUtc")]
public DateTime AddedAtUtc { get; set; }
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>