v2.2.0 PR#75
Merged
Merged
Conversation
…ne schema - Replaced `EnsureCreatedAsync` with `MigrateAsync` across the project to enable schema versioning and proper migration tracking. - Added baseline migration matching the existing schema and ensured compatibility with production `.ddb` files. - Introduced new design-time DbContext factory and migration tests to validate schema initialization and updates. - Simplified startup logic by removing hand-rolled DDL methods, consolidating schema creation into migrations. - Updated health checks and CLI tools to align with the migration-based approach.
- Implemented `MediaArtistExportService` and `MediaArtistImportService` for JSON-based export and import of artist data. - Added import/export buttons and preview logic to the Admin Media Artists UI. - Extended localization files (e.g., DE, CN, NL, PL, IT) with new translations for import/export-related resources. - Updated UI to support overwriting existing artists and provide detailed import/export summaries.
…ID column types - Fixed discrepancies in `MusicBrainzId` and `MusicBrainzReleaseGroupId` column types by syncing them to `UUID`. - Refactored initial migrations for consistency and compatibility with schema updates.
… and sync column types - Replaced prior initial schema migrations with a single unified version. - Corrected `MusicBrainzId` and `MusicBrainzReleaseGroupId` column type discrepancies by reverting to `BLOB`. - Improved consistency across initial migration scripts for better manageability.
- Rearranged the execution order of paged and count queries to prevent unbound parameter errors caused by DecentDB's sequential parameter numbering.
… for edits - Updated routing, parameters, and related services to utilize `ApiKey` in place of `ChartId`. - Adjusted CSV parsing and ChartService methods to support the new identifier. - Improved normalization logic for artist and album matching by removing accents.
…oss components - Updated `UserDetail`, `PodcastDetail`, and `UserGroupDetail` to use `Guid` for `ApiKey` parameters instead of `string`. - Adjusted route definitions to ensure `ApiKey` is validated as a GUID. - Removed obsolete API key parsing methods.
- Implemented `DecentDbMigrationDialog` to guide users through the migration process for unsupported DecentDB files. - Added migration step-by-step UI, including download links, migration commands, and error details. - Introduced `DecentDbMigrationInstructionsBuilder` to generate migration-related paths and commands dynamically for Windows and POSIX environments. - Updated `Dashboard` and `Doctor` views to surface DecentDB issues and open the migration dialog when needed. - Added unit tests for migration instruction generation across various scenarios.
… OpenAPI support - Improved parameter XML documentation across multiple models and services (e.g., `Child`, `ScrobbleInfo`, `FilterOperatorInfo`, `ArtistReadModel`, `Directory`). - Adjusted `ImageProcessor` to use a default sampling option for bitmap rendering. - Updated `.editorconfig` to handle specific migration files and enforce newline consistency. - Added `Microsoft.OpenApi` dependencies to support OpenAPI features in `Melodee.Blazor`. - Enabled XML documentation file generation and suppressed `CS1591` warnings. - Corrected minor typos in comments and refined string formatting for clarity.
…mprove ArtistSearch initialization - Updated to version 2.2.0 across all projects and documentation. - Adjusted changelog logic to prevent relocation of the `[Unreleased]` section above Jekyll front matter. - Enhanced ArtistSearch initialization to support relational migrations and schema creation for non-relational providers.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR rolls the Artist Search Engine DecentDB schema over to EF Core migrations, improves DecentDB upgrade diagnostics/remediation UX, adds media-artist export/import tooling, and bumps the solution version/dependencies to 2.2.0.
Changes:
- Switched ArtistSearchEngine initialization/creation paths to use EF Core migrations (
MigrateAsync) and added migration tests + migration artifacts. - Added DecentDB “unsupported format” (error 8) detection and an in-app migration dialog with generated commands/scripts.
- Added admin Media Artists export/import (JSON) and updated several routes to bind GUID API keys directly.
Reviewed changes
Copilot reviewed 77 out of 79 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Melodee.Tests.Common/Services/SearchEngines/ArtistSearchEngineServiceTests.cs | Adds coverage for non-relational provider initialization behavior. |
| tests/Melodee.Tests.Common/Data/ArtistSearchEngineServiceDbContextMigrationTests.cs | New tests validating migrations on fresh/existing/production-copy .ddb files. |
| tests/Melodee.Tests.Blazor/Services/DoctorServiceTests.cs | Updates tests to assert DecentDB error-8 guidance/details. |
| tests/Melodee.Tests.Blazor/Components/DecentDbMigrationInstructionsBuilderTests.cs | New tests for generated migration instructions/quoting behavior. |
| tests/Melodee.Tests.Blazor/Components/DashboardHealthWarningEvaluatorTests.cs | Extends evaluator tests for DecentDB error-8 detection/filtering. |
| src/Melodee.Mql/Melodee.Mql.csproj | Bumps version prefix to 2.2.0. |
| src/Melodee.Common/Services/StreamingLimiter.cs | Minor XML doc cleanup/encoding fix. |
| src/Melodee.Common/Services/SearchEngines/ArtistSearchEngineService.cs | Uses migrations for relational DB init and adjusts paging/count query ordering. |
| src/Melodee.Common/Services/PlaylistService.cs | Improves XML doc param coverage for CreatePlaylistAsync. |
| src/Melodee.Common/Services/Models/ArtistDuplicate/ArtistReadModel.cs | Aligns record param docs with actual parameter name. |
| src/Melodee.Common/Services/MediaArtistExportService.cs | New service exporting search-engine artists/albums/aliases to JSON. |
| src/Melodee.Common/Services/ChartService.cs | Makes missing-album identification accent-insensitive (currently via in-memory filtering). |
| src/Melodee.Common/Models/SearchEngines/ArtistSearchEngineServiceData/ArtistSearchEngineServiceDbContext.cs | Adds IsLocked conversion to match DecentDB storage expectations. |
| src/Melodee.Common/Models/Scrobbling/ScrobbleInfo.cs | Improves XML doc coverage for record parameters. |
| src/Melodee.Common/Models/OpenSubsonic/Requests/ApiRequest.cs | Fixes malformed XML docs (<para> → <param>, removes stray text). |
| src/Melodee.Common/Models/OpenSubsonic/Directory.cs | Fixes malformed XML docs (<para> → <param>). |
| src/Melodee.Common/Models/OpenSubsonic/Child.cs | Adds missing XML doc entries for additional parameters. |
| src/Melodee.Common/Models/OpenSubsonic/Artist.cs | Adds missing XML doc entry for Album parameter. |
| src/Melodee.Common/Migrations/ArtistSearchEngine/ArtistSearchEngineServiceDbContextModelSnapshot.cs | Adds EF Core model snapshot for ArtistSearchEngine migrations. |
| src/Melodee.Common/Migrations/ArtistSearchEngine/20260622225002_SyncMusicBrainzUuidColumns.Designer.cs | Adds migration designer metadata for no-op UUID sync migration. |
| src/Melodee.Common/Migrations/ArtistSearchEngine/20260622225002_SyncMusicBrainzUuidColumns.cs | Adds no-op migration to stabilize EF migration chain with DecentDB limitations. |
| src/Melodee.Common/Migrations/ArtistSearchEngine/20260622224939_InitialArtistSearchEngineSchema.Designer.cs | Adds initial migration designer metadata for the ArtistSearchEngine schema. |
| src/Melodee.Common/Migrations/ArtistSearchEngine/20260622224939_InitialArtistSearchEngineSchema.cs | Adds idempotent initial schema creation for ArtistSearchEngine DecentDB via SQL. |
| src/Melodee.Common/Melodee.Common.csproj | Bumps version prefix to 2.2.0. |
| src/Melodee.Common/Imaging/ImageProcessor.cs | Updates SkiaSharp API usage (sampling options) for newer SkiaSharp. |
| src/Melodee.Common/Imaging/ImageHasher.cs | Fixes XML doc formatting/see cref markup. |
| src/Melodee.Common/Filtering/FilterOperatorInfo.cs | Documents new/updated parameter purpose in XML docs. |
| src/Melodee.Common/Extensions/StringExtensions.cs | Clarifies XML doc text for Irish prefix normalization. |
| src/Melodee.Common/Data/ArtistSearchEngineServiceDbContextFactory.cs | Adds design-time DbContext factory for dotnet ef migrations. |
| src/Melodee.Cli/Melodee.Cli.csproj | Bumps version prefix to 2.2.0. |
| src/Melodee.Cli/Command/DoctorCommand.cs | Uses MigrateAsync for creating ArtistSearchEngine DB instead of EnsureCreatedAsync. |
| src/Melodee.Cli/Command/CommandBase.cs | Points ArtistSearchEngine DbContext to migrations assembly. |
| src/Melodee.Blazor/Services/DoctorService.cs | Enhances DecentDB unsupported-format detection and auto-create ArtistSearchEngine DB via migrations. |
| src/Melodee.Blazor/Resources/SharedResources.uk-UA.resx | Adds/updates localization keys related to DecentDB migration dialog + media artists UI. |
| src/Melodee.Blazor/Resources/SharedResources.resx | Adds/updates base localization keys related to DecentDB migration dialog + media artists UI. |
| src/Melodee.Blazor/Resources/SharedResources.id-ID.resx | Adds/updates localization keys related to DecentDB migration dialog + media artists UI. |
| src/Melodee.Blazor/Resources/SharedResources.de-DE.resx | Adds/updates localization keys related to DecentDB migration dialog + media artists UI. |
| src/Melodee.Blazor/Resources/SharedResources.ar-SA.resx | Adds/updates localization keys related to DecentDB migration dialog + media artists UI. |
| src/Melodee.Blazor/Program.cs | Points ArtistSearchEngine DbContext to migrations assembly. |
| src/Melodee.Blazor/Melodee.Blazor.csproj | Bumps version prefix and adds Microsoft.OpenApi reference. |
| src/Melodee.Blazor/Extensions/DialogServiceExtensions.cs | Adds dialog extension to open DecentDB migration remediation dialog. |
| src/Melodee.Blazor/Components/Pages/UserGroupDetail.razor | Switches route binding to GUID and removes custom API key parsing. |
| src/Melodee.Blazor/Components/Pages/UserDetail.razor | Switches route binding to GUID and removes custom API key parsing. |
| src/Melodee.Blazor/Components/Pages/Media/Artists.razor | Adds media-artist export/import UI and preview/apply workflow. |
| src/Melodee.Blazor/Components/Pages/Data/PodcastDetail.razor | Switches route binding to GUID and avoids string comparisons for ApiKey. |
| src/Melodee.Blazor/Components/Pages/Data/ChartsMissingReport.razor | Makes key generation accent-insensitive for missing report grouping. |
| src/Melodee.Blazor/Components/Pages/Data/Charts.razor | Updates chart edit navigation to use chart API key. |
| src/Melodee.Blazor/Components/Pages/DashboardHealthWarningEvaluator.cs | Adds structured unsupported-DecentDB detection and returns affected issues list. |
| src/Melodee.Blazor/Components/Pages/Dashboard.razor | Replaces external guide link with in-app DecentDB migration dialog flow. |
| src/Melodee.Blazor/Components/Pages/Admin/Doctor.razor | Surfaces DecentDB migration issues and provides in-app remediation dialog. |
| src/Melodee.Blazor/Components/Pages/Admin/Dashboard.razor | Adds in-app DecentDB migration dialog entry point for admins. |
| src/Melodee.Blazor/Components/Pages/Admin/ChartEditor.razor | Switches chart editing route to GUID API key and updates navigation. |
| src/Melodee.Blazor/Components/Dialogs/DecentDbMigrationInstructionsBuilder.cs | New builder for platform-specific migration commands/scripts. |
| src/Melodee.Blazor/Components/Dialogs/DecentDbMigrationDialog.razor.css | New styles for DecentDB migration dialog layout/scrolling. |
| scripts/bump_version.sh | Keeps Unreleased section in-place to preserve Jekyll front matter position. |
| docs/VERSION | Updates docs version to 2.2.0. |
| docs/pages/decentdb.md | Expands DecentDB migration/upgrade documentation and scripts (sidecars, steps). |
| docs/pages/changelog.md | Adds 2.2.0 release notes entry. |
| Directory.Packages.props | Updates dependencies (DecentDB, SkiaSharp, Radzen, etc.) and adds Microsoft.OpenApi version. |
| Directory.Build.props | Enables XML docs generation and suppresses missing-doc warnings. |
| design/docs/20260622-artist-search-engine-ef-core-migrations-changes.md | Adds internal release/implementation notes for migration changes. |
| .editorconfig | Preserves encoding/newline behavior for generated migration source files. |
Files not reviewed (2)
- src/Melodee.Common/Migrations/ArtistSearchEngine/20260622224939_InitialArtistSearchEngineSchema.Designer.cs: Generated file
- src/Melodee.Common/Migrations/ArtistSearchEngine/20260622225002_SyncMusicBrainzUuidColumns.Designer.cs: Generated file
Comment on lines
22
to
56
| <PageTitle>Search Engine Artists</PageTitle> | ||
|
|
||
| <RadzenStack Style="height: 100%"> | ||
| <RadzenBreadCrumb Class="rz-pb-5"> | ||
| <RadzenBreadCrumbItem Path="/" Text="Dashboard"/> | ||
| <RadzenBreadCrumbItem Icon="artist" Text="Artists"/> | ||
| </RadzenBreadCrumb> | ||
| <RadzenRow AlignItems="AlignItems.Center"> | ||
| <RadzenColumn Size="12" SizeMD="6"> | ||
| <RadzenText Text="Media Artists" TextStyle="TextStyle.DisplayH6" TagName="TagName.H1" style="margin: 0"/> | ||
| </RadzenColumn> | ||
| <RadzenColumn Size="12" SizeMD="6" Visible="CurrentUser?.IsEditor() ?? false"> | ||
| <RadzenStack | ||
| Orientation="Orientation.Horizontal" | ||
| AlignItems="AlignItems.Center" | ||
| JustifyContent="JustifyContent.End" | ||
| Gap="0.5rem"> | ||
| <RadzenButton Icon="add_circle_outline" Text="Add" | ||
| Size="ButtonSize.Small" | ||
| Click="@AddButtonClick"/> | ||
| <RadzenButton Icon="download" Text="@L("MediaArtists.Export")" | ||
| Size="ButtonSize.Small" | ||
| Click="@ExportArtists" | ||
| IsBusy="@_isExporting" | ||
| ButtonStyle="ButtonStyle.Secondary"/> | ||
| <RadzenFileInput @bind-Value="_importFile" | ||
| ChooseText="@L("MediaArtists.Import")" | ||
| Accept=".json" | ||
| MaxFileSize="104857600" | ||
| Style="width: 200px;" | ||
| TValue="string" | ||
| Change="@OnImportFileChanged"/> | ||
| <RadzenButton Icon="refresh" Text="Refresh Albums" | ||
| Size="ButtonSize.Small" | ||
| Click="@RefreshAlbumsButtonClick"/> |
Comment on lines
+371
to
+377
| var fileName = $"melodee-media-artists-{DateTime.UtcNow:yyyy-MM-dd}.json"; | ||
| var bytes = System.Text.Encoding.UTF8.GetBytes(result.Json!); | ||
| var base64 = Convert.ToBase64String(bytes); | ||
| await JSRuntime.InvokeVoidAsync("downloadFile", fileName, base64, "application/json"); | ||
|
|
||
| _importMessage = $"Exported {result.ArtistsCount} artists, {result.AlbumsCount} albums, {result.AliasesCount} aliases"; | ||
| _importSuccess = true; |
Comment on lines
+359
to
+362
| try | ||
| { | ||
| var exportService = new MediaArtistExportService(Logger, ArtistSearchEngineDbContextFactory); | ||
| var result = await exportService.ExportAsync(); |
Comment on lines
808
to
+823
| var linkedStatus = (short)ChartItemLinkStatus.Linked; | ||
|
|
||
| var matchingItems = await scopedContext.ChartItems | ||
| var allUnlinkedItems = await scopedContext.ChartItems | ||
| .Include(i => i.Chart) | ||
| .Where(i => i.ArtistName.ToUpper() == normalizedArtistName && | ||
| i.AlbumTitle.ToUpper() == normalizedAlbumTitle && | ||
| i.LinkStatus != linkedStatus) | ||
| .Where(i => i.LinkStatus != linkedStatus) | ||
| .ToListAsync(cancellationToken) | ||
| .ConfigureAwait(false); | ||
|
|
||
| var normalizedInputArtist = artistName.RemoveAccents(); | ||
| var normalizedInputAlbum = albumTitle.RemoveAccents(); | ||
|
|
||
| var matchingItems = allUnlinkedItems | ||
| .Where(i => string.Equals(i.ArtistName.RemoveAccents(), normalizedInputArtist, StringComparison.OrdinalIgnoreCase) && | ||
| string.Equals(i.AlbumTitle.RemoveAccents(), normalizedInputAlbum, StringComparison.OrdinalIgnoreCase)) | ||
| .ToList(); | ||
|
|
Comment on lines
433
to
465
| @@ -495,15 +455,13 @@ public async Task<PagedResult<Artist>> ListAsync( | |||
| LastRefreshed = x.LastRefreshed | |||
| }) | |||
| .Skip(pagedRequest.SkipValue) | |||
| .Take(pageProbeSize) | |||
| .Take(pagedRequest.TakeValue) | |||
| .ToArrayAsync(cancellationToken) | |||
| .ConfigureAwait(false); | |||
|
|
|||
| var hasMoreRows = page.Length > pagedRequest.TakeValue; | |||
| artists = page.Take(pagedRequest.TakeValue).ToArray(); | |||
| totalCount = artists.Length == 0 && pagedRequest.SkipValue == 0 | |||
| ? 0 | |||
| : pagedRequest.SkipValue + artists.Length + (hasMoreRows ? 1 : 0); | |||
| artists = page; | |||
|
|
|||
| totalCount = await query.CountAsync(cancellationToken).ConfigureAwait(false); | |||
|
|
|||
Comment on lines
+69
to
+74
| var exportData = new MediaArtistExportData | ||
| { | ||
| SchemaVersion = SchemaVersion, | ||
| ExportedAt = DateTimeOffset.UtcNow.ToString("O"), | ||
| Artists = exportedArtists | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces EF Core migrations for the Artist Search Engine database, updates several dependencies, improves DecentDB migration support, and adds new admin and media artist features. The release also includes fixes for schema compatibility, improved health checks, and enhanced documentation for DecentDB migration and upgrade procedures.
EF Core Migrations & Database Initialization:
MigrateAsync(), ensuring versioned, idempotent schema updates and removing hand-written DDL blocks. Added migration tests and a dedicated migrations folder..ddbfiles.Dependency Updates:
2.16.1, SkiaSharp to4.150.0, Radzen to11.1.3, and several other runtime, UI, test, and tooling dependencies for improved compatibility and stability. [1] [2] [3] [4]Admin & Media Artist Features:
Documentation & Migration Guidance:
Build & Configuration Improvements:
2.2.0. [1] [2] [3]Encoded references: [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]