Skip to content

v2.2.0 PR#75

Merged
sphildreth merged 11 commits into
mainfrom
sph.2026-06-22.01
Jul 11, 2026
Merged

v2.2.0 PR#75
sphildreth merged 11 commits into
mainfrom
sph.2026-06-22.01

Conversation

@sphildreth

Copy link
Copy Markdown
Collaborator

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:

  • Migrated the Artist Search Engine database from manual schema creation to EF Core migrations using MigrateAsync(), ensuring versioned, idempotent schema updates and removing hand-written DDL blocks. Added migration tests and a dedicated migrations folder.
  • Fixed local development issues by aligning the model snapshot and database schema, ensuring smooth migration for existing .ddb files.

Dependency Updates:

  • Upgraded DecentDB providers to 2.16.1, SkiaSharp to 4.150.0, Radzen to 11.1.3, and several other runtime, UI, test, and tooling dependencies for improved compatibility and stability. [1] [2] [3] [4]

Admin & Media Artist Features:

  • Added admin health checks that detect DecentDB error 8 and guide users through migration with prebuilt commands and guidance.
  • Enabled export/import of all search-engine artist data as JSON, with full preview and overwrite options.
  • The Doctor health check now auto-creates the ArtistSearch database via EF Core migrations if missing.

Documentation & Migration Guidance:

  • Expanded and clarified DecentDB migration documentation, including new migration dialog examples, step-by-step upgrade procedures, and improved backup/rebuild scripts. [1] [2] [3] [4]

Build & Configuration Improvements:

  • Enabled solution-wide XML documentation output, suppressed missing XML doc warnings, and updated the version to 2.2.0. [1] [2] [3]

Encoded references: [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

…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.
Copilot AI review requested due to automatic review settings July 11, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
};
@sphildreth sphildreth merged commit d91342e into main Jul 11, 2026
14 checks passed
@sphildreth sphildreth deleted the sph.2026-06-22.01 branch July 11, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants