Design Prot Merge #1
@@ -49,10 +49,13 @@ namespace Musify.Application.PlayLists
|
|||||||
return Error.Conflict(description: "Track is already in the playlist.");
|
return Error.Conflict(description: "Track is already in the playlist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextPosition = await database.PlayListHasTracks
|
var playListTracksQuery = database.PlayListHasTracks
|
||||||
.Where(plt => plt.PlayListId == request.PlayListId)
|
.Where(plt => plt.PlayListId == request.PlayListId);
|
||||||
.Select(plt => (int?)plt.Position)
|
|
||||||
.MaxAsync(cancellationToken) + 1 ?? 0;
|
var hasTracks = await playListTracksQuery.AnyAsync(cancellationToken);
|
||||||
|
var nextPosition = hasTracks
|
||||||
|
? await playListTracksQuery.MaxAsync(plt => plt.Position, cancellationToken) + 1
|
||||||
|
: 0;
|
||||||
|
|
||||||
await database.PlayListHasTracks.AddAsync(new PlayListHasTrack
|
await database.PlayListHasTracks.AddAsync(new PlayListHasTrack
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace Musify.Application.PlayLists
|
|||||||
|
|
||||||
var track = provisionResult.Value.Track;
|
var track = provisionResult.Value.Track;
|
||||||
|
|
||||||
var failed = track.Audio.TranscodeStatus == ProcessingStatus.Failed;
|
var failed = track.Audio.IsFailed;
|
||||||
var neverQueued = !track.Audio.DownloadRequested && !track.Audio.IsProcessed;
|
var neverQueued = !track.Audio.DownloadRequested && !track.Audio.IsProcessed;
|
||||||
if (failed || neverQueued)
|
if (failed || neverQueued)
|
||||||
{
|
{
|
||||||
@@ -82,10 +82,13 @@ namespace Musify.Application.PlayLists
|
|||||||
return Error.Conflict(description: "Track is already in the playlist.");
|
return Error.Conflict(description: "Track is already in the playlist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextPosition = await database.PlayListHasTracks
|
var playListTracksQuery = database.PlayListHasTracks
|
||||||
.Where(plt => plt.PlayListId == request.PlayListId)
|
.Where(plt => plt.PlayListId == request.PlayListId);
|
||||||
.Select(plt => (int?)plt.Position)
|
|
||||||
.MaxAsync(cancellationToken) + 1 ?? 0;
|
var hasTracks = await playListTracksQuery.AnyAsync(cancellationToken);
|
||||||
|
var nextPosition = hasTracks
|
||||||
|
? await playListTracksQuery.MaxAsync(plt => plt.Position, cancellationToken) + 1
|
||||||
|
: 0;
|
||||||
|
|
||||||
await database.PlayListHasTracks.AddAsync(new PlayListHasTrack
|
await database.PlayListHasTracks.AddAsync(new PlayListHasTrack
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Musify.Application.Events;
|
|||||||
using Musify.Application.PlayLists.Responses;
|
using Musify.Application.PlayLists.Responses;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
|
|
||||||
namespace Musify.Application.PlayLists
|
namespace Musify.Application.PlayLists
|
||||||
@@ -65,10 +66,13 @@ namespace Musify.Application.PlayLists
|
|||||||
Name = request.Name,
|
Name = request.Name,
|
||||||
NormalizedName = request.Name.Trim().ToUpperInvariant(),
|
NormalizedName = request.Name.Trim().ToUpperInvariant(),
|
||||||
Description = request.Description,
|
Description = request.Description,
|
||||||
OriginalPictureName = originalPictureName,
|
Pictures = new PlayListPictures
|
||||||
SmallPictureName = playListConfiguration.Routes.PresetSmallPicture,
|
{
|
||||||
MediumPictureName = playListConfiguration.Routes.PresetMediumPicture,
|
OriginalName = originalPictureName,
|
||||||
LargePictureName = playListConfiguration.Routes.PresetLargePicture
|
SmallName = playListConfiguration.Routes.PresetSmallPicture,
|
||||||
|
MediumName = playListConfiguration.Routes.PresetMediumPicture,
|
||||||
|
LargeName = playListConfiguration.Routes.PresetLargePicture
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await database.PlayLists.AddAsync(playList, cancellationToken);
|
await database.PlayLists.AddAsync(playList, cancellationToken);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Musify.Application.PlayLists
|
|||||||
{
|
{
|
||||||
var playList = await database.PlayLists.AsNoTracking()
|
var playList = await database.PlayLists.AsNoTracking()
|
||||||
.Where(p => p.Id == request.PlayListId)
|
.Where(p => p.Id == request.PlayListId)
|
||||||
.Select(p => new { p.SmallPictureName, p.MediumPictureName, p.LargePictureName })
|
.Select(p => new { p.Pictures.SmallName, p.Pictures.MediumName, p.Pictures.LargeName })
|
||||||
.SingleOrDefaultAsync(cancellationToken);
|
.SingleOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
if (playList == null)
|
if (playList == null)
|
||||||
@@ -31,9 +31,9 @@ namespace Musify.Application.PlayLists
|
|||||||
var routes = playListConfiguration.Routes;
|
var routes = playListConfiguration.Routes;
|
||||||
var (name, key, presetName) = request.Size.ToLowerInvariant() switch
|
var (name, key, presetName) = request.Size.ToLowerInvariant() switch
|
||||||
{
|
{
|
||||||
"small" => (playList.SmallPictureName, BuildKey(routes.BuildSmallPicturePath, playList.SmallPictureName), routes.PresetSmallPicture),
|
"small" => (playList.SmallName, BuildKey(routes.BuildSmallPicturePath, playList.SmallName), routes.PresetSmallPicture),
|
||||||
"large" => (playList.LargePictureName, BuildKey(routes.BuildLargePicturePath, playList.LargePictureName), routes.PresetLargePicture),
|
"large" => (playList.LargeName, BuildKey(routes.BuildLargePicturePath, playList.LargeName), routes.PresetLargePicture),
|
||||||
_ => (playList.MediumPictureName, BuildKey(routes.BuildMediumPicturePath, playList.MediumPictureName), routes.PresetMediumPicture)
|
_ => (playList.MediumName, BuildKey(routes.BuildMediumPicturePath, playList.MediumName), routes.PresetMediumPicture)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(key) || name == presetName)
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(key) || name == presetName)
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ namespace Musify.Application.PlayLists.Responses
|
|||||||
playList.Id,
|
playList.Id,
|
||||||
playList.Name,
|
playList.Name,
|
||||||
playList.Description,
|
playList.Description,
|
||||||
playList.SmallPictureName,
|
playList.Pictures.SmallName,
|
||||||
playList.MediumPictureName,
|
playList.Pictures.MediumName,
|
||||||
playList.LargePictureName,
|
playList.Pictures.LargeName,
|
||||||
playList.CreatedAt,
|
playList.CreatedAt,
|
||||||
playList.UpdatedAt);
|
playList.UpdatedAt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace Musify.Application.PlayLists
|
|||||||
return validation.Errors;
|
return validation.Errors;
|
||||||
|
|
||||||
pictureIntent = validation.Value;
|
pictureIntent = validation.Value;
|
||||||
playListEntity.OriginalPictureName = pictureIntent.ObjectName;
|
playListEntity.Pictures.OriginalName = pictureIntent.ObjectName;
|
||||||
finalPictureKey = playListConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName);
|
finalPictureKey = playListConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ public sealed class UploadIntentValidator(
|
|||||||
if (intent is null || intent.UserId != userId)
|
if (intent is null || intent.UserId != userId)
|
||||||
return Error.NotFound(description: "Upload intent not found or not accessible.");
|
return Error.NotFound(description: "Upload intent not found or not accessible.");
|
||||||
|
|
||||||
if (intent.Status == UploadIntentStatus.Consumed)
|
if (intent.IsConsumed)
|
||||||
return Error.Conflict(description: "Upload intent has already been consumed.");
|
return Error.Conflict(description: "Upload intent has already been consumed.");
|
||||||
|
|
||||||
if (intent.Status == UploadIntentStatus.Expired || intent.ExpiresAt < DateTime.UtcNow)
|
if (intent.IsExpired)
|
||||||
return Error.Validation(description: "Upload intent has expired.");
|
return Error.Validation(description: "Upload intent has expired.");
|
||||||
|
|
||||||
var metadata = await storageService.HeadObjectAsync(intent.Bucket, intent.Key, cancellationToken);
|
var metadata = await storageService.HeadObjectAsync(intent.Bucket, intent.Key, cancellationToken);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public sealed class YouTubeTrackProvisioner(
|
|||||||
NormalizedTitle = title.ToUpperInvariant(),
|
NormalizedTitle = title.ToUpperInvariant(),
|
||||||
Source = TrackSource.YouTube,
|
Source = TrackSource.YouTube,
|
||||||
ExternalId = videoId,
|
ExternalId = videoId,
|
||||||
Duration = song.DurationSeconds,
|
DurationSeconds = song.DurationSeconds,
|
||||||
Pictures = new TrackPictures
|
Pictures = new TrackPictures
|
||||||
{
|
{
|
||||||
SmallName = trackConfiguration.Routes.PresetSmallPicture,
|
SmallName = trackConfiguration.Routes.PresetSmallPicture,
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ namespace Musify.Application.Tracks
|
|||||||
return Error.Unauthorized();
|
return Error.Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track.Audio.TranscodeStatus == ProcessingStatus.Processing
|
if (track.Audio.IsInProgress)
|
||||||
|| track.Audio.TranscodeStatus == ProcessingStatus.Pending)
|
|
||||||
{
|
{
|
||||||
logger.LogWarning("Track {TrackId} is currently being processed and cannot be deleted", request.TrackId);
|
logger.LogWarning("Track {TrackId} is currently being processed and cannot be deleted", request.TrackId);
|
||||||
return Error.Conflict(description: "Track is currently being processed and cannot be deleted");
|
return Error.Conflict(description: "Track is currently being processed and cannot be deleted");
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Application.Services;
|
using Musify.Application.Services;
|
||||||
using Musify.Application.Tracks.Responses;
|
using Musify.Application.Tracks.Responses;
|
||||||
using Musify.Domain.ValueObjects;
|
|
||||||
|
|
||||||
namespace Musify.Application.Tracks
|
namespace Musify.Application.Tracks
|
||||||
{
|
{
|
||||||
@@ -22,20 +21,19 @@ namespace Musify.Application.Tracks
|
|||||||
{
|
{
|
||||||
var track = await database.Tracks.AsNoTracking()
|
var track = await database.Tracks.AsNoTracking()
|
||||||
.Where(t => t.Id == request.TrackId)
|
.Where(t => t.Id == request.TrackId)
|
||||||
.Select(t => new { t.Id, t.Audio.TranscodeStatus, t.Audio.FolderName } )
|
.Select(t => new { t.Id, t.Audio })
|
||||||
.SingleOrDefaultAsync(cancellationToken);
|
.SingleOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
if (track == null)
|
if (track == null)
|
||||||
return Error.NotFound();
|
return Error.NotFound();
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(track.FolderName)
|
if (!track.Audio.IsProcessed)
|
||||||
|| track.TranscodeStatus != ProcessingStatus.Completed)
|
|
||||||
{
|
{
|
||||||
logger.LogInformation("Stream requested for track {TrackId} but audio is not ready", request.TrackId);
|
logger.LogInformation("Stream requested for track {TrackId} but audio is not ready", request.TrackId);
|
||||||
return Error.Conflict(description: "Track audio is not available for streaming yet.");
|
return Error.Conflict(description: "Track audio is not available for streaming yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = await streamIssuer.IssueAsync(track.Id, track.FolderName, request.UserId, cancellationToken);
|
var response = await streamIssuer.IssueAsync(track.Id, track.Audio.FolderName, request.UserId, cancellationToken);
|
||||||
|
|
||||||
logger.LogInformation("Issued stream ticket for track {TrackId} to user {UserId}", request.TrackId, request.UserId);
|
logger.LogInformation("Issued stream ticket for track {TrackId} to user {UserId}", request.TrackId, request.UserId);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Musify.Application.Tracks.Responses
|
|||||||
track.Source,
|
track.Source,
|
||||||
track.ExternalId,
|
track.ExternalId,
|
||||||
track.Audio.TranscodeStatus,
|
track.Audio.TranscodeStatus,
|
||||||
track.Duration,
|
track.DurationSeconds,
|
||||||
listensCount,
|
listensCount,
|
||||||
track.OwnerUserId,
|
track.OwnerUserId,
|
||||||
track.CreatedAt,
|
track.CreatedAt,
|
||||||
|
|||||||
@@ -26,23 +26,9 @@ namespace Musify.Domain.Entities
|
|||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(256)]
|
[MaxLength(256)]
|
||||||
public required string Description { get; set; } = "No description was provided.";
|
public string Description { get; set; } = "No description was provided.";
|
||||||
|
|
||||||
[Required]
|
public required PlayListPictures Pictures { get; set; }
|
||||||
[MaxLength(64)]
|
|
||||||
public required string OriginalPictureName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[MaxLength(64)]
|
|
||||||
public required string SmallPictureName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[MaxLength(64)]
|
|
||||||
public required string MediumPictureName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[MaxLength(64)]
|
|
||||||
public required string LargePictureName { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public LifeCycleStatus LifeCycleStatus { get; set; } = LifeCycleStatus.Active;
|
public LifeCycleStatus LifeCycleStatus { get; set; } = LifeCycleStatus.Active;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Musify.Domain.Entities
|
|||||||
public required string NormalizedTitle { get; set; }
|
public required string NormalizedTitle { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public int Duration { get; set; }
|
public int DurationSeconds { get; set; }
|
||||||
|
|
||||||
public long? OwnerUserId { get; set; }
|
public long? OwnerUserId { get; set; }
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ namespace Musify.Domain.Entities
|
|||||||
|
|
||||||
public TrackAudio Audio { get; set; } = new();
|
public TrackAudio Audio { get; set; } = new();
|
||||||
|
|
||||||
[ForeignKey(nameof(OwnerUserId))]
|
[ForeignKey(nameof(OwnerUserId)) ]
|
||||||
public User? Owner { get; set; }
|
public User? Owner { get; set; }
|
||||||
|
|
||||||
public ICollection<UserHasTrack> UserTracks { get; set; } = new List<UserHasTrack>();
|
public ICollection<UserHasTrack> UserTracks { get; set; } = new List<UserHasTrack>();
|
||||||
@@ -53,5 +53,8 @@ namespace Musify.Domain.Entities
|
|||||||
public ICollection<ListeningHistory> ListeningHistories { get; set; } = new List<ListeningHistory>();
|
public ICollection<ListeningHistory> ListeningHistories { get; set; } = new List<ListeningHistory>();
|
||||||
|
|
||||||
public ICollection<TrackArtist> TrackArtists { get; set; } = new List<TrackArtist>();
|
public ICollection<TrackArtist> TrackArtists { get; set; } = new List<TrackArtist>();
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsExternal => Source != TrackSource.Local;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,12 @@ namespace Musify.Domain.Entities
|
|||||||
[Required]
|
[Required]
|
||||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsConsumed => Status == UploadIntentStatus.Consumed;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsExpired => Status == UploadIntentStatus.Expired || ExpiresAt < DateTime.UtcNow;
|
||||||
|
|
||||||
[ForeignKey(nameof(UserId)) ]
|
[ForeignKey(nameof(UserId)) ]
|
||||||
public User User { get; set; } = null!;
|
public User User { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace Musify.Domain.ValueObjects
|
||||||
|
{
|
||||||
|
public class PlayListPictures
|
||||||
|
{
|
||||||
|
public required string OriginalName { get; set; }
|
||||||
|
|
||||||
|
public required string SmallName { get; set; }
|
||||||
|
|
||||||
|
public required string MediumName { get; set; }
|
||||||
|
|
||||||
|
public required string LargeName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,5 +19,9 @@ namespace Musify.Domain.ValueObjects
|
|||||||
|
|
||||||
[MemberNotNullWhen(true, nameof(FolderName))]
|
[MemberNotNullWhen(true, nameof(FolderName))]
|
||||||
public bool IsProcessed => TranscodeStatus == ProcessingStatus.Completed;
|
public bool IsProcessed => TranscodeStatus == ProcessingStatus.Completed;
|
||||||
|
|
||||||
|
public bool IsFailed => TranscodeStatus == ProcessingStatus.Failed;
|
||||||
|
|
||||||
|
public bool IsInProgress => TranscodeStatus is ProcessingStatus.Pending or ProcessingStatus.Processing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -53,10 +53,10 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
|
|||||||
var log = new UpdateTrackAudioLog(
|
var log = new UpdateTrackAudioLog(
|
||||||
track.Id,
|
track.Id,
|
||||||
track.Audio.FolderName,
|
track.Audio.FolderName,
|
||||||
track.Duration);
|
track.DurationSeconds);
|
||||||
|
|
||||||
track.Audio.FolderName = Path.GetFileName(audioFolderKey);
|
track.Audio.FolderName = Path.GetFileName(audioFolderKey);
|
||||||
track.Duration = durationSeconds;
|
track.DurationSeconds = durationSeconds;
|
||||||
track.Audio.TranscodeStatus = ProcessingStatus.Completed;
|
track.Audio.TranscodeStatus = ProcessingStatus.Completed;
|
||||||
await database.SaveChangesAsync(executeContext.CancellationToken);
|
await database.SaveChangesAsync(executeContext.CancellationToken);
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ namespace Musify.Infrastructure.MassTransit.Activities.Audio
|
|||||||
throw new InvalidOperationException($"Track with id {compensateContext.Log.TrackId} not found");
|
throw new InvalidOperationException($"Track with id {compensateContext.Log.TrackId} not found");
|
||||||
|
|
||||||
track.Audio.FolderName = compensateContext.Log.PreviousAudioFolderName;
|
track.Audio.FolderName = compensateContext.Log.PreviousAudioFolderName;
|
||||||
track.Duration = compensateContext.Log.PreviousDuration;
|
track.DurationSeconds = compensateContext.Log.PreviousDurationSeconds;
|
||||||
track.Audio.TranscodeStatus = ProcessingStatus.Failed;
|
track.Audio.TranscodeStatus = ProcessingStatus.Failed;
|
||||||
await database.SaveChangesAsync(compensateContext.CancellationToken);
|
await database.SaveChangesAsync(compensateContext.CancellationToken);
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -39,15 +39,15 @@ namespace Musify.Infrastructure.MassTransit.Activities.Pictures
|
|||||||
|
|
||||||
var log = new UpdatePlayListPictureLog(
|
var log = new UpdatePlayListPictureLog(
|
||||||
playList.Id,
|
playList.Id,
|
||||||
playList.OriginalPictureName,
|
playList.Pictures.OriginalName,
|
||||||
playList.SmallPictureName,
|
playList.Pictures.SmallName,
|
||||||
playList.MediumPictureName,
|
playList.Pictures.MediumName,
|
||||||
playList.LargePictureName);
|
playList.Pictures.LargeName);
|
||||||
|
|
||||||
playList.OriginalPictureName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey);
|
playList.Pictures.OriginalName = Path.GetFileName(executeContext.Arguments.OriginalPictureKey);
|
||||||
playList.SmallPictureName = Path.GetFileName(smallResizedVariable);
|
playList.Pictures.SmallName = Path.GetFileName(smallResizedVariable);
|
||||||
playList.MediumPictureName = Path.GetFileName(mediumResizedVariable);
|
playList.Pictures.MediumName = Path.GetFileName(mediumResizedVariable);
|
||||||
playList.LargePictureName = Path.GetFileName(largeResizedVariable);
|
playList.Pictures.LargeName = Path.GetFileName(largeResizedVariable);
|
||||||
|
|
||||||
database.PlayLists.Update(playList);
|
database.PlayLists.Update(playList);
|
||||||
await database.SaveChangesAsync(executeContext.CancellationToken);
|
await database.SaveChangesAsync(executeContext.CancellationToken);
|
||||||
@@ -82,10 +82,10 @@ namespace Musify.Infrastructure.MassTransit.Activities.Pictures
|
|||||||
return compensateContext.Compensated();
|
return compensateContext.Compensated();
|
||||||
}
|
}
|
||||||
|
|
||||||
playList.OriginalPictureName = compensateContext.Log.PreviousOriginalPictureKey;
|
playList.Pictures.OriginalName = compensateContext.Log.PreviousOriginalPictureKey;
|
||||||
playList.SmallPictureName = compensateContext.Log.PreviousSmallPictureKey;
|
playList.Pictures.SmallName = compensateContext.Log.PreviousSmallPictureKey;
|
||||||
playList.MediumPictureName = compensateContext.Log.PreviousMediumPictureKey;
|
playList.Pictures.MediumName = compensateContext.Log.PreviousMediumPictureKey;
|
||||||
playList.LargePictureName = compensateContext.Log.PreviousLargePictureKey;
|
playList.Pictures.LargeName = compensateContext.Log.PreviousLargePictureKey;
|
||||||
|
|
||||||
database.PlayLists.Update(playList);
|
database.PlayLists.Update(playList);
|
||||||
await database.SaveChangesAsync(compensateContext.CancellationToken);
|
await database.SaveChangesAsync(compensateContext.CancellationToken);
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
public record UpdateTrackAudioLog(
|
public record UpdateTrackAudioLog(
|
||||||
Guid TrackId,
|
Guid TrackId,
|
||||||
string? PreviousAudioFolderName,
|
string? PreviousAudioFolderName,
|
||||||
int PreviousDuration);
|
int PreviousDurationSeconds);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -42,44 +42,44 @@ namespace Musify.Infrastructure.MassTransit.RoutingSlip.Builders
|
|||||||
var bucket = storageConfiguration.Bucket;
|
var bucket = storageConfiguration.Bucket;
|
||||||
var routes = playListConfiguration.Routes;
|
var routes = playListConfiguration.Routes;
|
||||||
|
|
||||||
if (playList.OriginalPictureName != routes.PresetOriginalPicture)
|
if (playList.Pictures.OriginalName != routes.PresetOriginalPicture)
|
||||||
{
|
{
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
ActivityNames.RemovePlayListOriginalPicture,
|
ActivityNames.RemovePlayListOriginalPicture,
|
||||||
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
||||||
new RemoveFileFromBucketArguments(
|
new RemoveFileFromBucketArguments(
|
||||||
bucket,
|
bucket,
|
||||||
routes.BuildOriginalPicturePath(userId, playList.OriginalPictureName)));
|
routes.BuildOriginalPicturePath(userId, playList.Pictures.OriginalName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playList.SmallPictureName != routes.PresetSmallPicture)
|
if (playList.Pictures.SmallName != routes.PresetSmallPicture)
|
||||||
{
|
{
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
ActivityNames.RemovePlayListSmallPicture,
|
ActivityNames.RemovePlayListSmallPicture,
|
||||||
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
||||||
new RemoveFileFromBucketArguments(
|
new RemoveFileFromBucketArguments(
|
||||||
bucket,
|
bucket,
|
||||||
routes.BuildSmallPicturePath(playList.SmallPictureName)));
|
routes.BuildSmallPicturePath(playList.Pictures.SmallName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playList.MediumPictureName != routes.PresetMediumPicture)
|
if (playList.Pictures.MediumName != routes.PresetMediumPicture)
|
||||||
{
|
{
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
ActivityNames.RemovePlayListMediumPicture,
|
ActivityNames.RemovePlayListMediumPicture,
|
||||||
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
||||||
new RemoveFileFromBucketArguments(
|
new RemoveFileFromBucketArguments(
|
||||||
bucket,
|
bucket,
|
||||||
routes.BuildMediumPicturePath(playList.MediumPictureName)));
|
routes.BuildMediumPicturePath(playList.Pictures.MediumName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playList.LargePictureName != routes.PresetLargePicture)
|
if (playList.Pictures.LargeName != routes.PresetLargePicture)
|
||||||
{
|
{
|
||||||
routingSlipBuilder.AddActivity(
|
routingSlipBuilder.AddActivity(
|
||||||
ActivityNames.RemovePlayListLargePicture,
|
ActivityNames.RemovePlayListLargePicture,
|
||||||
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
EndpointHelper.BuildExecuteActivityUri(RemoveFileFromBucketActivity.ExecuteEndpointName),
|
||||||
new RemoveFileFromBucketArguments(
|
new RemoveFileFromBucketArguments(
|
||||||
bucket,
|
bucket,
|
||||||
routes.BuildLargePicturePath(playList.LargePictureName)));
|
routes.BuildLargePicturePath(playList.Pictures.LargeName)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,16 @@ namespace Musify.Infrastructure.Persistence
|
|||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasFilter("\"ExternalId\" IS NULL AND \"UserId\" IS NULL");
|
.HasFilter("\"ExternalId\" IS NULL AND \"UserId\" IS NULL");
|
||||||
|
|
||||||
|
modelBuilder.Entity<PlayList>()
|
||||||
|
.OwnsOne(playList => playList.Pictures, pictures =>
|
||||||
|
{
|
||||||
|
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64);
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<PlayList>().Navigation(playList => playList.Pictures).IsRequired();
|
||||||
|
|
||||||
var playListProcessing = modelBuilder.Entity<PlayListProcessingState>();
|
var playListProcessing = modelBuilder.Entity<PlayListProcessingState>();
|
||||||
playListProcessing.HasKey(state => state.CorrelationId);
|
playListProcessing.HasKey(state => state.CorrelationId);
|
||||||
playListProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
playListProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
||||||
|
|||||||
+885
@@ -0,0 +1,885 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Musify.Infrastructure.Persistence;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(Database))]
|
||||||
|
[Migration("20260717164632_MovePlayListPicturesToOwnedType")]
|
||||||
|
partial class MovePlayListPicturesToOwnedType
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.8")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.InboxState", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Consumed")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("ConsumerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Delivered")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ExpirationTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("LastSequenceNumber")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<Guid>("LockId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("MessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("ReceiveCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Received")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<byte[]>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Delivered");
|
||||||
|
|
||||||
|
b.ToTable("InboxState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("SequenceNumber")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("SequenceNumber"));
|
||||||
|
|
||||||
|
b.Property<string>("Body")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ConversationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("DestinationAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("EnqueueTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ExpirationTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("FaultAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Headers")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InboxConsumerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InboxMessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InitiatorId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("MessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("MessageType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("OutboxId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Properties")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("RequestId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("ResponseAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("SentTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("SourceAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("SequenceNumber");
|
||||||
|
|
||||||
|
b.HasIndex("EnqueueTime");
|
||||||
|
|
||||||
|
b.HasIndex("ExpirationTime");
|
||||||
|
|
||||||
|
b.HasIndex("OutboxId", "SequenceNumber")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("InboxMessageId", "InboxConsumerId", "SequenceNumber")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("OutboxMessage");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("OutboxId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Delivered")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("LastSequenceNumber")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<Guid>("LockId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<byte[]>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea");
|
||||||
|
|
||||||
|
b.HasKey("OutboxId");
|
||||||
|
|
||||||
|
b.HasIndex("Created");
|
||||||
|
|
||||||
|
b.ToTable("OutboxState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("\"ExternalId\" IS NULL AND \"UserId\" IS NULL");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Artists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.ListeningHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ListenedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("ListeningHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<int>("LifeCycleStatus")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("PlayLists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayListHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("PlayListId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlayListId");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.ToTable("PlayListHasTrack");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int>("Duration")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasMaxLength(16)
|
||||||
|
.HasColumnType("character varying(16)");
|
||||||
|
|
||||||
|
b.Property<int>("LifeCycleStatus")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedTitle")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<long?>("OwnerUserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("Source")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerUserId");
|
||||||
|
|
||||||
|
b.HasIndex("Source", "ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Tracks", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("CK_Tracks_OwnerUserId_Source", "(\"OwnerUserId\" IS NOT NULL) = (\"Source\" = 0)");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("ArtistId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("TrackId", "ArtistId");
|
||||||
|
|
||||||
|
b.HasIndex("ArtistId");
|
||||||
|
|
||||||
|
b.ToTable("TrackArtist");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Upload", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("State")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Upload");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UploadIntent", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("ExpectedSizeBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(512)
|
||||||
|
.HasColumnType("character varying(512)");
|
||||||
|
|
||||||
|
b.Property<string>("ObjectName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<int>("Purpose")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("UploadIntents");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName")
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("ProfilePictureUrl")
|
||||||
|
.HasMaxLength(2048)
|
||||||
|
.HasColumnType("character varying(2048)");
|
||||||
|
|
||||||
|
b.Property<string>("SecondName")
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UserHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("UserHasTrack");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Infrastructure.MassTransit.Sagas.PlayListProcessingState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("CurrentState")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("PictureKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("CorrelationId");
|
||||||
|
|
||||||
|
b.ToTable("PlayListProcessingState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Infrastructure.MassTransit.Sagas.TrackProcessingState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AudioKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("AudioProcessed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("CurrentState")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("PictureKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("PictureProcessed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("CorrelationId");
|
||||||
|
|
||||||
|
b.ToTable("TrackProcessingState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MassTransit.EntityFrameworkCoreIntegration.OutboxState", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OutboxId");
|
||||||
|
|
||||||
|
b.HasOne("MassTransit.EntityFrameworkCoreIntegration.InboxState", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InboxMessageId", "InboxConsumerId")
|
||||||
|
.HasPrincipalKey("MessageId", "ConsumerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.ListeningHistory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("ListeningHistories")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("ListeningHistories")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("PlayLists")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.PlayListPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("PlayListId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("PlayListId");
|
||||||
|
|
||||||
|
b1.ToTable("PlayLists");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("PlayListId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayListHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.PlayList", "PlayList")
|
||||||
|
.WithMany("PlayListTracks")
|
||||||
|
.HasForeignKey("PlayListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("PlayListTracks")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("PlayList");
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackAudio", "Audio", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<bool>("DownloadRequested")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("DownloadRequested");
|
||||||
|
|
||||||
|
b1.Property<string>("FolderName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("AudioFolderName");
|
||||||
|
|
||||||
|
b1.Property<DateTime?>("LastRetryAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("LastRetryAt");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalAudioName");
|
||||||
|
|
||||||
|
b1.Property<int>("RetryCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("RetryCount");
|
||||||
|
|
||||||
|
b1.Property<int>("TranscodeStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("AudioTranscodeProcessingStatus");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<int>("ProcessingStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("PicturesProcessingStatus");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Audio")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Artist", "Artist")
|
||||||
|
.WithMany("TrackArtists")
|
||||||
|
.HasForeignKey("ArtistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("TrackArtists")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Artist");
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UploadIntent", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UserHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("UserTracks")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("UserTracks")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("TrackArtists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PlayListTracks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ListeningHistories");
|
||||||
|
|
||||||
|
b.Navigation("PlayListTracks");
|
||||||
|
|
||||||
|
b.Navigation("TrackArtists");
|
||||||
|
|
||||||
|
b.Navigation("UserTracks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ListeningHistories");
|
||||||
|
|
||||||
|
b.Navigation("PlayLists");
|
||||||
|
|
||||||
|
b.Navigation("UserTracks");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class MovePlayListPicturesToOwnedType : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+885
@@ -0,0 +1,885 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Musify.Infrastructure.Persistence;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(Database))]
|
||||||
|
[Migration("20260717164812_RenameTrackDurationToDurationSeconds")]
|
||||||
|
partial class RenameTrackDurationToDurationSeconds
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.8")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.InboxState", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Consumed")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("ConsumerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Delivered")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ExpirationTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("LastSequenceNumber")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<Guid>("LockId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("MessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("ReceiveCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Received")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<byte[]>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Delivered");
|
||||||
|
|
||||||
|
b.ToTable("InboxState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("SequenceNumber")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("SequenceNumber"));
|
||||||
|
|
||||||
|
b.Property<string>("Body")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ConversationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("DestinationAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("EnqueueTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ExpirationTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("FaultAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Headers")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InboxConsumerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InboxMessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid?>("InitiatorId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("MessageId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("MessageType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("OutboxId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Properties")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid?>("RequestId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("ResponseAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("SentTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("SourceAddress")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("SequenceNumber");
|
||||||
|
|
||||||
|
b.HasIndex("EnqueueTime");
|
||||||
|
|
||||||
|
b.HasIndex("ExpirationTime");
|
||||||
|
|
||||||
|
b.HasIndex("OutboxId", "SequenceNumber")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("InboxMessageId", "InboxConsumerId", "SequenceNumber")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("OutboxMessage");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("OutboxId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Delivered")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("LastSequenceNumber")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<Guid>("LockId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<byte[]>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea");
|
||||||
|
|
||||||
|
b.HasKey("OutboxId");
|
||||||
|
|
||||||
|
b.HasIndex("Created");
|
||||||
|
|
||||||
|
b.ToTable("OutboxState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("\"ExternalId\" IS NULL AND \"UserId\" IS NULL");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Artists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.ListeningHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ListenedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("ListeningHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<int>("LifeCycleStatus")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("PlayLists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayListHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("AddedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("PlayListId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PlayListId");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.ToTable("PlayListHasTrack");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int>("DurationSeconds")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.HasMaxLength(16)
|
||||||
|
.HasColumnType("character varying(16)");
|
||||||
|
|
||||||
|
b.Property<int>("LifeCycleStatus")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedTitle")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<long?>("OwnerUserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("Source")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerUserId");
|
||||||
|
|
||||||
|
b.HasIndex("Source", "ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Tracks", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("CK_Tracks_OwnerUserId_Source", "(\"OwnerUserId\" IS NOT NULL) = (\"Source\" = 0)");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("ArtistId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<int>("Position")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("TrackId", "ArtistId");
|
||||||
|
|
||||||
|
b.HasIndex("ArtistId");
|
||||||
|
|
||||||
|
b.ToTable("TrackArtist");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Upload", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("State")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Upload");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UploadIntent", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<string>("ContentType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<long?>("ExpectedSizeBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(512)
|
||||||
|
.HasColumnType("character varying(512)");
|
||||||
|
|
||||||
|
b.Property<string>("ObjectName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("character varying(128)");
|
||||||
|
|
||||||
|
b.Property<int>("Purpose")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int>("Status")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("UploadIntents");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("FirstName")
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<string>("ProfilePictureUrl")
|
||||||
|
.HasMaxLength(2048)
|
||||||
|
.HasColumnType("character varying(2048)");
|
||||||
|
|
||||||
|
b.Property<string>("SecondName")
|
||||||
|
.HasMaxLength(48)
|
||||||
|
.HasColumnType("character varying(48)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UserHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TrackId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("UserHasTrack");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Infrastructure.MassTransit.Sagas.PlayListProcessingState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("CurrentState")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("PictureKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("CorrelationId");
|
||||||
|
|
||||||
|
b.ToTable("PlayListProcessingState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Infrastructure.MassTransit.Sagas.TrackProcessingState", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("CorrelationId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AudioKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("AudioProcessed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("Bucket")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("CurrentState")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)");
|
||||||
|
|
||||||
|
b.Property<string>("PictureKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("PictureProcessed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("CorrelationId");
|
||||||
|
|
||||||
|
b.ToTable("TrackProcessingState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MassTransit.EntityFrameworkCoreIntegration.OutboxMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MassTransit.EntityFrameworkCoreIntegration.OutboxState", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OutboxId");
|
||||||
|
|
||||||
|
b.HasOne("MassTransit.EntityFrameworkCoreIntegration.InboxState", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InboxMessageId", "InboxConsumerId")
|
||||||
|
.HasPrincipalKey("MessageId", "ConsumerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.ListeningHistory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("ListeningHistories")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("ListeningHistories")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("PlayLists")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.PlayListPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("PlayListId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("PlayListId");
|
||||||
|
|
||||||
|
b1.ToTable("PlayLists");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("PlayListId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayListHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.PlayList", "PlayList")
|
||||||
|
.WithMany("PlayListTracks")
|
||||||
|
.HasForeignKey("PlayListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("PlayListTracks")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("PlayList");
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackAudio", "Audio", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<bool>("DownloadRequested")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("DownloadRequested");
|
||||||
|
|
||||||
|
b1.Property<string>("FolderName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("AudioFolderName");
|
||||||
|
|
||||||
|
b1.Property<DateTime?>("LastRetryAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("LastRetryAt");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalAudioName");
|
||||||
|
|
||||||
|
b1.Property<int>("RetryCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("RetryCount");
|
||||||
|
|
||||||
|
b1.Property<int>("TranscodeStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("AudioTranscodeProcessingStatus");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<int>("ProcessingStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("PicturesProcessingStatus");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Audio")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Artist", "Artist")
|
||||||
|
.WithMany("TrackArtists")
|
||||||
|
.HasForeignKey("ArtistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("TrackArtists")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Artist");
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UploadIntent", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.UserHasTrack", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Musify.Domain.Entities.Track", "Track")
|
||||||
|
.WithMany("UserTracks")
|
||||||
|
.HasForeignKey("TrackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Musify.Domain.Entities.User", "User")
|
||||||
|
.WithMany("UserTracks")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Track");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Artist", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("TrackArtists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.PlayList", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PlayListTracks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.Track", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ListeningHistories");
|
||||||
|
|
||||||
|
b.Navigation("PlayListTracks");
|
||||||
|
|
||||||
|
b.Navigation("TrackArtists");
|
||||||
|
|
||||||
|
b.Navigation("UserTracks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Musify.Domain.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ListeningHistories");
|
||||||
|
|
||||||
|
b.Navigation("PlayLists");
|
||||||
|
|
||||||
|
b.Navigation("UserTracks");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class RenameTrackDurationToDurationSeconds : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "Duration",
|
||||||
|
table: "Tracks",
|
||||||
|
newName: "DurationSeconds");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "DurationSeconds",
|
||||||
|
table: "Tracks",
|
||||||
|
newName: "Duration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -272,19 +272,9 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("character varying(256)");
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
b.Property<string>("LargePictureName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<int>("LifeCycleStatus")
|
b.Property<int>("LifeCycleStatus")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("MediumPictureName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(50)
|
.HasMaxLength(50)
|
||||||
@@ -295,16 +285,6 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.HasMaxLength(50)
|
.HasMaxLength(50)
|
||||||
.HasColumnType("character varying(50)");
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
b.Property<string>("OriginalPictureName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<string>("SmallPictureName")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("UpdatedAt")
|
b.Property<DateTime>("UpdatedAt")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
@@ -351,66 +331,27 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
b.Property<string>("AudioFolderName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<int>("AudioTranscodeProcessingStatus")
|
|
||||||
.HasColumnType("integer");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
b.Property<DateTime>("CreatedAt")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
b.Property<bool>("DownloadRequested")
|
b.Property<int>("DurationSeconds")
|
||||||
.HasColumnType("boolean");
|
|
||||||
|
|
||||||
b.Property<int>("Duration")
|
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("ExternalId")
|
b.Property<string>("ExternalId")
|
||||||
.HasMaxLength(16)
|
.HasMaxLength(16)
|
||||||
.HasColumnType("character varying(16)");
|
.HasColumnType("character varying(16)");
|
||||||
|
|
||||||
b.Property<string>("LargePictureName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<DateTime?>("LastRetryAt")
|
|
||||||
.HasColumnType("timestamp with time zone");
|
|
||||||
|
|
||||||
b.Property<int>("LifeCycleStatus")
|
b.Property<int>("LifeCycleStatus")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("MediumPictureName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedTitle")
|
b.Property<string>("NormalizedTitle")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(50)
|
.HasMaxLength(50)
|
||||||
.HasColumnType("character varying(50)");
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
b.Property<string>("OriginalAudioName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<string>("OriginalPictureName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<long?>("OwnerUserId")
|
b.Property<long?>("OwnerUserId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
b.Property<int>("PicturesProcessingStatus")
|
|
||||||
.HasColumnType("integer");
|
|
||||||
|
|
||||||
b.Property<int>("RetryCount")
|
|
||||||
.HasColumnType("integer");
|
|
||||||
|
|
||||||
b.Property<string>("SmallPictureName")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)");
|
|
||||||
|
|
||||||
b.Property<int>("Source")
|
b.Property<int>("Source")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
@@ -703,6 +644,46 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.PlayListPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("PlayListId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("PlayListId");
|
||||||
|
|
||||||
|
b1.ToTable("PlayLists");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("PlayListId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -732,7 +713,89 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
|||||||
.HasForeignKey("OwnerUserId")
|
.HasForeignKey("OwnerUserId")
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackAudio", "Audio", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<bool>("DownloadRequested")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("DownloadRequested");
|
||||||
|
|
||||||
|
b1.Property<string>("FolderName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("AudioFolderName");
|
||||||
|
|
||||||
|
b1.Property<DateTime?>("LastRetryAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("LastRetryAt");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalAudioName");
|
||||||
|
|
||||||
|
b1.Property<int>("RetryCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("RetryCount");
|
||||||
|
|
||||||
|
b1.Property<int>("TranscodeStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("AudioTranscodeProcessingStatus");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("Musify.Domain.ValueObjects.TrackPictures", "Pictures", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<Guid>("TrackId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b1.Property<string>("LargeName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("LargePictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("MediumName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("MediumPictureName");
|
||||||
|
|
||||||
|
b1.Property<string>("OriginalName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("OriginalPictureName");
|
||||||
|
|
||||||
|
b1.Property<int>("ProcessingStatus")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("PicturesProcessingStatus");
|
||||||
|
|
||||||
|
b1.Property<string>("SmallName")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("SmallPictureName");
|
||||||
|
|
||||||
|
b1.HasKey("TrackId");
|
||||||
|
|
||||||
|
b1.ToTable("Tracks");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("TrackId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Audio")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("Owner");
|
b.Navigation("Owner");
|
||||||
|
|
||||||
|
b.Navigation("Pictures")
|
||||||
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
modelBuilder.Entity("Musify.Domain.Entities.TrackArtist", b =>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AWSSDK.S3" />
|
<PackageReference Include="AWSSDK.S3" />
|
||||||
<PackageReference Include="DispatchR.Mediator" />
|
|
||||||
<PackageReference Include="MassTransit" />
|
<PackageReference Include="MassTransit" />
|
||||||
<PackageReference Include="MassTransit.RabbitMQ" />
|
<PackageReference Include="MassTransit.RabbitMQ" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<form method="POST" action="/logout">
|
<form method="POST" action="/logout">
|
||||||
<button
|
<button
|
||||||
class="rounded-full border border-white/20 px-4 py-2 text-sm font-semibold text-white backdrop-blur-md transition hover:bg-white/5"
|
class="rounded-full border border-white/10 px-4 py-2 text-sm text-white/65 transition hover:bg-white/2.5"
|
||||||
>
|
>
|
||||||
Salir
|
Salir
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -30,11 +30,11 @@
|
|||||||
const mainLinks = [
|
const mainLinks = [
|
||||||
{ href: '/', label: 'Inicio', icon: Home },
|
{ href: '/', label: 'Inicio', icon: Home },
|
||||||
{ href: '/explore', label: 'Buscar', icon: Search },
|
{ href: '/explore', label: 'Buscar', icon: Search },
|
||||||
{ href: '/playlists', label: 'Mis listas', icon: ListMusic }
|
{ href: '/playlists', label: 'Listas', icon: ListMusic }
|
||||||
];
|
];
|
||||||
|
|
||||||
const secondaryLinks = [
|
const secondaryLinks = [
|
||||||
{ href: '/library', label: 'Tus canciones subidas', icon: Library },
|
{ href: '/library', label: 'Canciones subidas', icon: Library },
|
||||||
{ href: '/upload', label: 'Subir música', icon: Upload }
|
{ href: '/upload', label: 'Subir música', icon: Upload }
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<a
|
<a
|
||||||
href={link.href}
|
href={link.href}
|
||||||
data-active={active}
|
data-active={active}
|
||||||
class="relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 text-[14px] font-semibold transition-colors duration-100 {active
|
class="relative flex items-center gap-3 rounded-[10px] px-3 py-2.5 font-semibold transition-colors duration-100 {active
|
||||||
? 'text-[var(--mf-text)]'
|
? 'text-[var(--mf-text)]'
|
||||||
: 'text-[var(--mf-text-2)] hover:bg-white/5 hover:text-[var(--mf-text)]'}"
|
: 'text-[var(--mf-text-2)] hover:bg-white/5 hover:text-[var(--mf-text)]'}"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -396,17 +396,16 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => addToQueue(contextMenu)}
|
onclick={() => addToQueue(contextMenu)}
|
||||||
class="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm font-semibold text-[var(--mf-text-2)] transition hover:bg-white/5"
|
class="flex w-full items-center gap-3 rounded-lg px-2 py-2.5 text-left text-sm text-[var(--mf-text-2)] transition hover:bg-white/5"
|
||||||
>
|
>
|
||||||
<ListPlus class="h-[18px] w-[18px] shrink-0" strokeWidth={2} />
|
<ListPlus class="h-6 w-6 shrink-0" strokeWidth={2} />
|
||||||
<span class="text-base">Añadir a la cola</span>
|
<span class="text-base">Añadir a la cola</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="group/addmenu relative">
|
<div class="group/addmenu relative">
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-semibold text-[var(--mf-text-2)] transition group-hover/addmenu:bg-white/5"
|
class="flex items-center gap-3 rounded-lg px-2 py-2.5 text-sm text-[var(--mf-text-2)] transition group-hover/addmenu:bg-white/5"
|
||||||
>
|
>
|
||||||
<ListMusic class="h-[18px] w-[18px] shrink-0" strokeWidth={2} />
|
<span class="flex-1 text-base cursor-default">Añadir a una playlist</span>
|
||||||
<span class="flex-1">Añadir a una playlist</span>
|
|
||||||
<ChevronRight class="h-4 w-4 shrink-0 text-[var(--mf-text-3)]" />
|
<ChevronRight class="h-4 w-4 shrink-0 text-[var(--mf-text-3)]" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -445,9 +444,9 @@
|
|||||||
trackIds={[]}
|
trackIds={[]}
|
||||||
hue={hueFor(playlist.id)}
|
hue={hueFor(playlist.id)}
|
||||||
size="small"
|
size="small"
|
||||||
class="h-11 w-11 flex-shrink-0 rounded-lg"
|
class="h-8 w-8 flex-shrink-0 rounded-lg"
|
||||||
/>
|
/>
|
||||||
<span class="truncate">{playlist.name}</span>
|
<span class="truncate text-base text-[var(--mf-text-2)]">{playlist.name}</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad, Actions } from './$types';
|
||||||
import { error } from '@sveltejs/kit';
|
import { error, fail } from '@sveltejs/kit';
|
||||||
import { createApiClient } from '$lib/server/api';
|
import { createApiClient } from '$lib/server/api';
|
||||||
|
|
||||||
const PAGE_SIZE = 50;
|
const PAGE_SIZE = 50;
|
||||||
@@ -16,3 +16,18 @@ export const load: PageServerLoad = async ({ locals, fetch }) => {
|
|||||||
|
|
||||||
return { tracks: data };
|
return { tracks: data };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
deleteTrack: async ({ request, locals, fetch }) => {
|
||||||
|
if (!locals.accessToken) return fail(401, { message: 'Inicia sesión.' });
|
||||||
|
const trackId = String((await request.formData()).get('trackId') ?? '');
|
||||||
|
if (!trackId) return fail(400, { message: 'Falta la canción.' });
|
||||||
|
|
||||||
|
const api = createApiClient({ fetch, accessToken: locals.accessToken });
|
||||||
|
const { error: err } = await api.DELETE('/tracks/{trackId}', {
|
||||||
|
params: { path: { trackId } }
|
||||||
|
});
|
||||||
|
if (err) return fail(502, { message: 'No se pudo borrar la canción.' });
|
||||||
|
return { deleted: true };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
import Upload from '@lucide/svelte/icons/upload';
|
import Upload from '@lucide/svelte/icons/upload';
|
||||||
import Headphones from '@lucide/svelte/icons/headphones';
|
import Play from '@lucide/svelte/icons/play';
|
||||||
import Clock from '@lucide/svelte/icons/clock';
|
import X from '@lucide/svelte/icons/x';
|
||||||
import { player } from '$lib/player/player.svelte';
|
import { player, queueIdForTrack, toQueueItems } from '$lib/player/player.svelte';
|
||||||
import { HUES, fmtTime } from '$lib/theme/color';
|
import { HUES, fmtTime } from '$lib/theme/color';
|
||||||
import Cover from '$lib/components/ui/Cover.svelte';
|
import Cover from '$lib/components/ui/Cover.svelte';
|
||||||
import NowPlaying from '$lib/components/ui/NowPlaying.svelte';
|
import NowPlaying from '$lib/components/ui/NowPlaying.svelte';
|
||||||
@@ -22,8 +23,8 @@
|
|||||||
|
|
||||||
function togglePlay(index: number) {
|
function togglePlay(index: number) {
|
||||||
const track = items[index];
|
const track = items[index];
|
||||||
if (player.current.id === track.id) player.toggle();
|
if (player.current.id === queueIdForTrack(track)) player.toggle();
|
||||||
else player.playQueue(items, index);
|
else player.playQueue(toQueueItems(items), index);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -53,50 +54,66 @@
|
|||||||
{#if items.length > 0}
|
{#if items.length > 0}
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-[1fr_120px_160px] items-center gap-6 border-b border-[var(--mf-border)] px-3 pb-3 text-xs font-semibold uppercase tracking-wide text-[var(--mf-text-3)]"
|
class="grid grid-cols-[32px_1fr_100px_100px_64px_36px] items-center gap-8 border-b border-white/10 px-3 pb-2 text-xs uppercase tracking-wide text-neutral-500"
|
||||||
>
|
>
|
||||||
|
<span class="text-center">#</span>
|
||||||
<span>Título</span>
|
<span>Título</span>
|
||||||
<span class="flex items-center justify-end gap-1.5"><Clock class="h-3.5 w-3.5" /> Duración</span>
|
<span class="text-center">Subida</span>
|
||||||
<span class="flex items-center gap-1.5"><Headphones class="h-3.5 w-3.5" /> Escuchas</span>
|
<span class="text-center">Escuchas</span>
|
||||||
|
<span class="text-center">Duración</span>
|
||||||
|
<span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 flex flex-col">
|
<div class="mt-1 flex flex-col">
|
||||||
{#each items as track, i (track.id)}
|
{#each items as track, i (track.id)}
|
||||||
<div
|
<div
|
||||||
class="group grid animate-enter grid-cols-[1fr_120px_160px] items-center gap-6 rounded-[10px] px-3 py-4 transition duration-100 hover:bg-[var(--mf-surface-hover)]"
|
class="group grid grid-cols-[32px_1fr_100px_100px_64px_36px] items-center gap-8 rounded-[10px] px-3 py-[9px] transition hover:bg-neutral-900/60"
|
||||||
style="animation-delay:{i * 35}ms"
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => togglePlay(i)}
|
onclick={() => togglePlay(i)}
|
||||||
class="flex min-w-0 items-center gap-3.5 text-left active:scale-[0.99]"
|
aria-label={player.current.id === track.id && player.playing ? 'Pausar' : 'Reproducir'}
|
||||||
|
class="relative grid h-8 w-8 place-items-center overflow-hidden rounded text-sm text-neutral-500"
|
||||||
|
>
|
||||||
|
{#if player.current.id === track.id}
|
||||||
|
<NowPlaying paused={!player.playing} />
|
||||||
|
{:else}
|
||||||
|
<span class="group-hover:hidden">{i + 1}</span>
|
||||||
|
<Play class="hidden h-3.5 w-3.5 text-white group-hover:block" fill="currentColor" />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => togglePlay(i)}
|
||||||
|
class="flex min-w-0 items-center gap-3.5 text-left"
|
||||||
>
|
>
|
||||||
<Cover
|
<Cover
|
||||||
trackId={track.id}
|
trackId={track.id}
|
||||||
hue={hueFor(track.id)}
|
hue={hueFor(track.id)}
|
||||||
size="small"
|
size="small"
|
||||||
alt={track.title}
|
alt={track.title}
|
||||||
class="h-[46px] w-[46px] flex-shrink-0 rounded-md"
|
class="h-[42px] w-[42px] flex-shrink-0 rounded-md"
|
||||||
>
|
/>
|
||||||
{#if player.current.id === track.id}
|
<div class="min-w-0 truncate text-[14.5px] font-semibold text-neutral-100">{track.title}</div>
|
||||||
<NowPlaying paused={!player.playing} />
|
</button>
|
||||||
{/if}
|
<div class="truncate text-center text-[12.5px] text-neutral-500">
|
||||||
</Cover>
|
|
||||||
<div class="min-w-0 flex-1">
|
|
||||||
<div class="truncate text-[14.5px] font-semibold text-[var(--mf-text)]">
|
|
||||||
{track.title}
|
|
||||||
</div>
|
|
||||||
<div class="truncate text-[12.5px] text-[var(--mf-text-3)]">
|
|
||||||
{dateFormatter.format(new Date(track.createdAt))}
|
{dateFormatter.format(new Date(track.createdAt))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<span class="text-center text-[12.5px] tabular-nums text-neutral-500">
|
||||||
</button>
|
{Number(track.listensCount)}
|
||||||
<span class="text-right text-[12.5px] tabular-nums text-[var(--mf-text-3)]">
|
</span>
|
||||||
|
<span class="text-center text-[12.5px] tabular-nums text-neutral-500">
|
||||||
{fmtTime(Number(track.duration))}
|
{fmtTime(Number(track.duration))}
|
||||||
</span>
|
</span>
|
||||||
<div class="flex items-center gap-1.5 text-[12.5px] tabular-nums text-[var(--mf-text-3)]">
|
<form method="POST" action="?/deleteTrack" use:enhance={() => async ({ update }) => update()}>
|
||||||
<Headphones class="h-3.5 w-3.5" />
|
<input type="hidden" name="trackId" value={track.id} />
|
||||||
{Number(track.listensCount)}
|
<button
|
||||||
</div>
|
type="submit"
|
||||||
|
aria-label="Borrar canción"
|
||||||
|
class="grid h-7 w-7 place-items-center rounded-lg text-neutral-500 opacity-0 transition hover:bg-white/5 hover:text-white group-hover:opacity-100"
|
||||||
|
>
|
||||||
|
<X class="h-3.5 w-3.5" />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -130,14 +130,14 @@
|
|||||||
if (e.key === 'Escape') creating = false;
|
if (e.key === 'Escape') creating = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="animate-pop w-full max-w-2xl rounded-2xl bg-[var(--mf-bg)] p-6 shadow-2xl">
|
<div class="animate-pop w-full max-w-2xl rounded-lg bg-[var(--mf-bg)] p-6 shadow-2xl">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h2 class="text-2xl font-bold tracking-tight">Nueva lista</h2>
|
<h2 class="text-2xl font-bold tracking-tight">Nueva lista</h2>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => (creating = false)}
|
onclick={() => (creating = false)}
|
||||||
aria-label="Cerrar"
|
aria-label="Cerrar"
|
||||||
class="grid h-8 w-8 place-items-center rounded-full text-neutral-400 transition hover:bg-white/5 hover:text-white"
|
class="grid h-8 w-8 place-items-center rounded-lg text-neutral-400 transition hover:bg-white/5 hover:text-white"
|
||||||
>
|
>
|
||||||
<X class="h-4 w-4" />
|
<X class="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
@@ -222,7 +222,7 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => (creating = false)}
|
onclick={() => (creating = false)}
|
||||||
class="rounded-lg border border-white/15 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-white/5"
|
class="rounded-lg border border-white/10 px-5 py-2.5 text-sm text-white/65 transition hover:bg-white/2.5"
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const load: PageServerLoad = async ({ params, locals, fetch }) => {
|
|||||||
params: { path: { playlistId: params.id }, query: { pageNumber: 1, pageSize: 200 } }
|
params: { path: { playlistId: params.id }, query: { pageNumber: 1, pageSize: 200 } }
|
||||||
}),
|
}),
|
||||||
api.GET('/tracks/users/{userId}', {
|
api.GET('/tracks/users/{userId}', {
|
||||||
params: { path: { userId: locals.user.sub }, query: { pageNumber: 1, pageSize: 200 } }
|
params: { path: { userId: locals.user.sub }, query: { pageNumber: 1, pageSize: 50 } }
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={reset}
|
onclick={reset}
|
||||||
class="rounded-lg border border-white/20 px-8 py-3.5 text-base font-semibold text-white backdrop-blur-md transition hover:bg-white/5"
|
class="rounded-lg border border-white/10 px-8 py-3.5 text-base text-white/65 transition hover:bg-white/2.5"
|
||||||
>
|
>
|
||||||
Subir otra
|
Subir otra
|
||||||
</button>
|
</button>
|
||||||
@@ -311,7 +311,7 @@
|
|||||||
<div class="flex items-center justify-end gap-4">
|
<div class="flex items-center justify-end gap-4">
|
||||||
<a
|
<a
|
||||||
href="/explore"
|
href="/explore"
|
||||||
class="rounded-lg border border-white/20 px-8 py-3.5 text-base font-semibold text-white backdrop-blur-md transition hover:bg-white/5"
|
class="rounded-lg border border-white/10 px-8 py-3.5 text-base text-white/65 transition hover:bg-white/2.5"
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user