diff --git a/CLI.sln b/CLI.sln
index 182fd88..0e074c4 100644
--- a/CLI.sln
+++ b/CLI.sln
@@ -2,9 +2,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftCli", "DeepDrftCli\DeepDrftCli.csproj", "{84844B37-FD15-4AFC-850B-DD432AA33B4C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Services", "DeepDrftContent.Services\DeepDrftContent.Services.csproj", "{169D5D3E-DAEC-46BE-98EE-CC5EBF5E3E8A}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Data", "DeepDrftContent.Data\DeepDrftContent.Data.csproj", "{169D5D3E-DAEC-46BE-98EE-CC5EBF5E3E8A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftWeb.Services", "DeepDrftWeb.Services\DeepDrftWeb.Services.csproj", "{A3DA341B-589E-4705-AB66-6B22652A9B36}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftData", "DeepDrftData\DeepDrftData.csproj", "{A3DA341B-589E-4705-AB66-6B22652A9B36}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetBlocks", "C:\lib\NetBlocks\NetBlocks.csproj", "{41FC69D0-F60D-41B4-AA41-C2382C83DFE8}"
EndProject
diff --git a/DeepDrftCli/DeepDrftCli.csproj b/DeepDrftCli/DeepDrftCli.csproj
index 6846a07..9a5a905 100644
--- a/DeepDrftCli/DeepDrftCli.csproj
+++ b/DeepDrftCli/DeepDrftCli.csproj
@@ -23,8 +23,8 @@
-
-
+
+
diff --git a/DeepDrftCli/Program.cs b/DeepDrftCli/Program.cs
index 1f086c4..244fa1c 100644
--- a/DeepDrftCli/Program.cs
+++ b/DeepDrftCli/Program.cs
@@ -3,10 +3,11 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
-using DeepDrftWeb.Services.Data;
-using DeepDrftWeb.Services.Repositories;
-using DeepDrftContent.Services.FileDatabase.Services;
-using DeepDrftContent.Services.Processors;
+using DeepDrftData;
+using DeepDrftData.Data;
+using DeepDrftData.Repositories;
+using DeepDrftContent.Data.FileDatabase.Services;
+using DeepDrftContent.Data.Processors;
using DeepDrftCli.Services;
using DeepDrftCli.Models;
using NetBlocks.Utilities.Environment;
@@ -49,11 +50,13 @@ builder.Services.AddSingleton(provider =>
}
});
-// Add services
+// Add services. TrackManager fronts the BlazorBlocks data layer and implements
+// ITrackService for legacy consumers; same scoped instance backs both registrations.
builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped(sp => sp.GetRequiredService());
builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
@@ -72,4 +75,4 @@ else
// Run traditional CLI mode
var cliService = app.Services.GetRequiredService();
await cliService.RunAsync(args);
-}
\ No newline at end of file
+}
diff --git a/DeepDrftCli/Services/CliService.cs b/DeepDrftCli/Services/CliService.cs
index ae26961..d509eca 100644
--- a/DeepDrftCli/Services/CliService.cs
+++ b/DeepDrftCli/Services/CliService.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
-using DeepDrftContent.Services;
+using DeepDrftContent.Data;
using DeepDrftModels.Entities;
using NetBlocks.Models;
using DeepDrftCli.Utils;
@@ -13,13 +13,13 @@ namespace DeepDrftCli.Services;
public class CliService
{
private readonly ILogger _logger;
- private readonly DeepDrftWeb.Services.ITrackService _webTrackService;
- private readonly DeepDrftContent.Services.TrackService _contentTrackService;
+ private readonly DeepDrftData.ITrackService _webTrackService;
+ private readonly DeepDrftContent.Data.TrackService _contentTrackService;
public CliService(
ILogger logger,
- DeepDrftWeb.Services.ITrackService webTrackService,
- DeepDrftContent.Services.TrackService contentTrackService)
+ DeepDrftData.ITrackService webTrackService,
+ DeepDrftContent.Data.TrackService contentTrackService)
{
_logger = logger;
_webTrackService = webTrackService;
diff --git a/DeepDrftCli/Services/GuiService.cs b/DeepDrftCli/Services/GuiService.cs
index 762a094..6af8972 100644
--- a/DeepDrftCli/Services/GuiService.cs
+++ b/DeepDrftCli/Services/GuiService.cs
@@ -11,8 +11,8 @@ namespace DeepDrftCli.Services;
public class GuiService
{
private readonly ILogger _logger;
- private readonly DeepDrftWeb.Services.ITrackService _webTrackService;
- private readonly DeepDrftContent.Services.TrackService _contentTrackService;
+ private readonly DeepDrftData.ITrackService _webTrackService;
+ private readonly DeepDrftContent.Data.TrackService _contentTrackService;
// GUI Components
private Window? _mainWindow;
@@ -24,8 +24,8 @@ public class GuiService
public GuiService(
ILogger logger,
- DeepDrftWeb.Services.ITrackService webTrackService,
- DeepDrftContent.Services.TrackService contentTrackService)
+ DeepDrftData.ITrackService webTrackService,
+ DeepDrftContent.Data.TrackService contentTrackService)
{
_logger = logger;
_webTrackService = webTrackService;
diff --git a/DeepDrftCms/DeepDrftCms.csproj b/DeepDrftCms/DeepDrftCms.csproj
index c484fdc..66c85e7 100644
--- a/DeepDrftCms/DeepDrftCms.csproj
+++ b/DeepDrftCms/DeepDrftCms.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/DeepDrftCms/Pages/Tracks/TrackEdit.razor b/DeepDrftCms/Pages/Tracks/TrackEdit.razor
index 72344cc..5de4bfa 100644
--- a/DeepDrftCms/Pages/Tracks/TrackEdit.razor
+++ b/DeepDrftCms/Pages/Tracks/TrackEdit.razor
@@ -3,7 +3,7 @@
@rendermode InteractiveServer
@using AuthBlocksWeb.HierarchicalAuthorize
@using AuthBlocksWeb.Services
-@using DeepDrftWeb.Services
+@using DeepDrftData
@using System.Net.Http.Headers
@using System.Net.Http.Json
@attribute [HierarchicalRoleAuthorize("Admin")]
diff --git a/DeepDrftCms/Pages/Tracks/TrackList.razor b/DeepDrftCms/Pages/Tracks/TrackList.razor
index a7f66d4..cedd5f9 100644
--- a/DeepDrftCms/Pages/Tracks/TrackList.razor
+++ b/DeepDrftCms/Pages/Tracks/TrackList.razor
@@ -3,7 +3,7 @@
@using System.Net
@using System.Net.Http.Headers
@using AuthBlocksWeb.HierarchicalAuthorize
-@using DeepDrftModels.Models
+@using Models.Common
@attribute [HierarchicalRoleAuthorize("Admin")]
@inject ITrackService TrackService
@inject IHttpClientFactory HttpClientFactory
diff --git a/DeepDrftCms/_Imports.razor b/DeepDrftCms/_Imports.razor
index edc98a0..b0fbed9 100644
--- a/DeepDrftCms/_Imports.razor
+++ b/DeepDrftCms/_Imports.razor
@@ -9,5 +9,6 @@
@using Microsoft.JSInterop
@using DeepDrftCms
@using DeepDrftModels.Entities
-@using DeepDrftWeb.Services
+@using DeepDrftData
+@using Models.Common
@using MudBlazor
diff --git a/DeepDrftContent.Services/Audio/WavOffsetService.cs b/DeepDrftContent.Data/Audio/WavOffsetService.cs
similarity index 99%
rename from DeepDrftContent.Services/Audio/WavOffsetService.cs
rename to DeepDrftContent.Data/Audio/WavOffsetService.cs
index e40a59b..602e48a 100644
--- a/DeepDrftContent.Services/Audio/WavOffsetService.cs
+++ b/DeepDrftContent.Data/Audio/WavOffsetService.cs
@@ -1,6 +1,6 @@
using System.Text;
-namespace DeepDrftContent.Services.Audio;
+namespace DeepDrftContent.Data.Audio;
///
/// Service for creating WAV audio streams starting from a byte offset.
diff --git a/DeepDrftContent.Services/CLAUDE.md b/DeepDrftContent.Data/CLAUDE.md
similarity index 100%
rename from DeepDrftContent.Services/CLAUDE.md
rename to DeepDrftContent.Data/CLAUDE.md
diff --git a/DeepDrftContent.Services/Constants/VaultConstants.cs b/DeepDrftContent.Data/Constants/VaultConstants.cs
similarity index 83%
rename from DeepDrftContent.Services/Constants/VaultConstants.cs
rename to DeepDrftContent.Data/Constants/VaultConstants.cs
index 83a6daf..12d703f 100644
--- a/DeepDrftContent.Services/Constants/VaultConstants.cs
+++ b/DeepDrftContent.Data/Constants/VaultConstants.cs
@@ -1,4 +1,4 @@
-namespace DeepDrftContent.Services.Constants;
+namespace DeepDrftContent.Data.Constants;
///
/// Constants for FileDatabase vault names
diff --git a/DeepDrftContent.Services/DeepDrftContent.Services.csproj b/DeepDrftContent.Data/DeepDrftContent.Data.csproj
similarity index 100%
rename from DeepDrftContent.Services/DeepDrftContent.Services.csproj
rename to DeepDrftContent.Data/DeepDrftContent.Data.csproj
diff --git a/DeepDrftContent.Services/FileDatabase/Abstractions/IIndexFactory.cs b/DeepDrftContent.Data/FileDatabase/Abstractions/IIndexFactory.cs
similarity index 88%
rename from DeepDrftContent.Services/FileDatabase/Abstractions/IIndexFactory.cs
rename to DeepDrftContent.Data/FileDatabase/Abstractions/IIndexFactory.cs
index 8dc59a2..3a63052 100644
--- a/DeepDrftContent.Services/FileDatabase/Abstractions/IIndexFactory.cs
+++ b/DeepDrftContent.Data/FileDatabase/Abstractions/IIndexFactory.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using IndexType = DeepDrftContent.Services.FileDatabase.Services.IndexType;
+using DeepDrftContent.Data.FileDatabase.Models;
+using IndexType = DeepDrftContent.Data.FileDatabase.Services.IndexType;
-namespace DeepDrftContent.Services.FileDatabase.Abstractions;
+namespace DeepDrftContent.Data.FileDatabase.Abstractions;
///
/// Interface for creating index instances
diff --git a/DeepDrftContent.Services/FileDatabase/Abstractions/IMediaTypeRegistry.cs b/DeepDrftContent.Data/FileDatabase/Abstractions/IMediaTypeRegistry.cs
similarity index 93%
rename from DeepDrftContent.Services/FileDatabase/Abstractions/IMediaTypeRegistry.cs
rename to DeepDrftContent.Data/FileDatabase/Abstractions/IMediaTypeRegistry.cs
index f7803bc..5dffb2c 100644
--- a/DeepDrftContent.Services/FileDatabase/Abstractions/IMediaTypeRegistry.cs
+++ b/DeepDrftContent.Data/FileDatabase/Abstractions/IMediaTypeRegistry.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
-namespace DeepDrftContent.Services.FileDatabase.Abstractions;
+namespace DeepDrftContent.Data.FileDatabase.Abstractions;
///
/// Interface for registering media type factories
diff --git a/DeepDrftContent.Services/FileDatabase/Models/IIndex.cs b/DeepDrftContent.Data/FileDatabase/Models/IIndex.cs
similarity index 96%
rename from DeepDrftContent.Services/FileDatabase/Models/IIndex.cs
rename to DeepDrftContent.Data/FileDatabase/Models/IIndex.cs
index c8df40e..f375e65 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/IIndex.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/IIndex.cs
@@ -1,4 +1,4 @@
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Base interface for all index types - minimal contract
diff --git a/DeepDrftContent.Services/FileDatabase/Models/IndexData.cs b/DeepDrftContent.Data/FileDatabase/Models/IndexData.cs
similarity index 97%
rename from DeepDrftContent.Services/FileDatabase/Models/IndexData.cs
rename to DeepDrftContent.Data/FileDatabase/Models/IndexData.cs
index 92acb48..794945c 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/IndexData.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/IndexData.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Utils;
using System.Text.Json.Serialization;
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Base class for index data used in serialization
diff --git a/DeepDrftContent.Services/FileDatabase/Models/MediaFactories.cs b/DeepDrftContent.Data/FileDatabase/Models/MediaFactories.cs
similarity index 96%
rename from DeepDrftContent.Services/FileDatabase/Models/MediaFactories.cs
rename to DeepDrftContent.Data/FileDatabase/Models/MediaFactories.cs
index 80be94a..9ebd177 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/MediaFactories.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/MediaFactories.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Abstractions;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Abstractions;
+using DeepDrftContent.Data.FileDatabase.Services;
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Shared media type registry instance — one allocation for all factory classes in this file.
diff --git a/DeepDrftContent.Services/FileDatabase/Models/MediaModels.cs b/DeepDrftContent.Data/FileDatabase/Models/MediaModels.cs
similarity index 99%
rename from DeepDrftContent.Services/FileDatabase/Models/MediaModels.cs
rename to DeepDrftContent.Data/FileDatabase/Models/MediaModels.cs
index 862fac9..a62d5e5 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/MediaModels.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/MediaModels.cs
@@ -1,4 +1,4 @@
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Parameters for creating a FileBinary
diff --git a/DeepDrftContent.Services/FileDatabase/Models/MediaVaultType.cs b/DeepDrftContent.Data/FileDatabase/Models/MediaVaultType.cs
similarity index 72%
rename from DeepDrftContent.Services/FileDatabase/Models/MediaVaultType.cs
rename to DeepDrftContent.Data/FileDatabase/Models/MediaVaultType.cs
index ba60bd9..bd52ec4 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/MediaVaultType.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/MediaVaultType.cs
@@ -1,4 +1,4 @@
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Enum representing different types of media vaults
diff --git a/DeepDrftContent.Services/FileDatabase/Models/MetaData.cs b/DeepDrftContent.Data/FileDatabase/Models/MetaData.cs
similarity index 96%
rename from DeepDrftContent.Services/FileDatabase/Models/MetaData.cs
rename to DeepDrftContent.Data/FileDatabase/Models/MetaData.cs
index ac9a837..014918c 100644
--- a/DeepDrftContent.Services/FileDatabase/Models/MetaData.cs
+++ b/DeepDrftContent.Data/FileDatabase/Models/MetaData.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace DeepDrftContent.Services.FileDatabase.Models;
+namespace DeepDrftContent.Data.FileDatabase.Models;
///
/// Base metadata for media entries
diff --git a/DeepDrftContent.Services/FileDatabase/README.md b/DeepDrftContent.Data/FileDatabase/README.md
similarity index 100%
rename from DeepDrftContent.Services/FileDatabase/README.md
rename to DeepDrftContent.Data/FileDatabase/README.md
diff --git a/DeepDrftContent.Services/FileDatabase/Services/FileDatabase.cs b/DeepDrftContent.Data/FileDatabase/Services/FileDatabase.cs
similarity index 97%
rename from DeepDrftContent.Services/FileDatabase/Services/FileDatabase.cs
rename to DeepDrftContent.Data/FileDatabase/Services/FileDatabase.cs
index a3b2893..410700e 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/FileDatabase.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/FileDatabase.cs
@@ -1,8 +1,8 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Utils;
using Microsoft.Extensions.Logging;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Main file database class that orchestrates multiple media vaults.
diff --git a/DeepDrftContent.Services/FileDatabase/Services/IndexFactoryService.cs b/DeepDrftContent.Data/FileDatabase/Services/IndexFactoryService.cs
similarity index 93%
rename from DeepDrftContent.Services/FileDatabase/Services/IndexFactoryService.cs
rename to DeepDrftContent.Data/FileDatabase/Services/IndexFactoryService.cs
index 9b88f1b..d8f1a4a 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/IndexFactoryService.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/IndexFactoryService.cs
@@ -1,9 +1,9 @@
-using DeepDrftContent.Services.FileDatabase.Abstractions;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Utils;
-using IndexType = DeepDrftContent.Services.FileDatabase.Services.IndexType;
+using DeepDrftContent.Data.FileDatabase.Abstractions;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Utils;
+using IndexType = DeepDrftContent.Data.FileDatabase.Services.IndexType;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Factory service for creating and managing indexes
diff --git a/DeepDrftContent.Services/FileDatabase/Services/IndexSystem.cs b/DeepDrftContent.Data/FileDatabase/Services/IndexSystem.cs
similarity index 96%
rename from DeepDrftContent.Services/FileDatabase/Services/IndexSystem.cs
rename to DeepDrftContent.Data/FileDatabase/Services/IndexSystem.cs
index 96ba880..74e56a1 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/IndexSystem.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/IndexSystem.cs
@@ -1,9 +1,9 @@
-using DeepDrftContent.Services.FileDatabase.Abstractions;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Abstractions;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Utils;
using Microsoft.Extensions.Logging;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Enum representing different types of indexes
diff --git a/DeepDrftContent.Services/FileDatabase/Services/IndexWatcher.cs b/DeepDrftContent.Data/FileDatabase/Services/IndexWatcher.cs
similarity index 97%
rename from DeepDrftContent.Services/FileDatabase/Services/IndexWatcher.cs
rename to DeepDrftContent.Data/FileDatabase/Services/IndexWatcher.cs
index 2c6e3ec..72e299b 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/IndexWatcher.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/IndexWatcher.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
using Microsoft.Extensions.Logging;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Watches index files for external modifications and triggers reloads.
diff --git a/DeepDrftContent.Services/FileDatabase/Services/MediaVault.cs b/DeepDrftContent.Data/FileDatabase/Services/MediaVault.cs
similarity index 98%
rename from DeepDrftContent.Services/FileDatabase/Services/MediaVault.cs
rename to DeepDrftContent.Data/FileDatabase/Services/MediaVault.cs
index f6a4671..cd39fef 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/MediaVault.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/MediaVault.cs
@@ -1,8 +1,8 @@
using System.Text.RegularExpressions;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Utils;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Abstract base class for media vaults that store and manage media files
diff --git a/DeepDrftContent.Services/FileDatabase/Services/MediaVaultFactory.cs b/DeepDrftContent.Data/FileDatabase/Services/MediaVaultFactory.cs
similarity index 81%
rename from DeepDrftContent.Services/FileDatabase/Services/MediaVaultFactory.cs
rename to DeepDrftContent.Data/FileDatabase/Services/MediaVaultFactory.cs
index 54b0f04..b851e2f 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/MediaVaultFactory.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/MediaVaultFactory.cs
@@ -1,6 +1,6 @@
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Factory for creating media vaults
diff --git a/DeepDrftContent.Services/FileDatabase/Services/SimpleMediaTypeRegistry.cs b/DeepDrftContent.Data/FileDatabase/Services/SimpleMediaTypeRegistry.cs
similarity index 98%
rename from DeepDrftContent.Services/FileDatabase/Services/SimpleMediaTypeRegistry.cs
rename to DeepDrftContent.Data/FileDatabase/Services/SimpleMediaTypeRegistry.cs
index 986cdfd..8af4c7a 100644
--- a/DeepDrftContent.Services/FileDatabase/Services/SimpleMediaTypeRegistry.cs
+++ b/DeepDrftContent.Data/FileDatabase/Services/SimpleMediaTypeRegistry.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Abstractions;
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Abstractions;
+using DeepDrftContent.Data.FileDatabase.Models;
-namespace DeepDrftContent.Services.FileDatabase.Services;
+namespace DeepDrftContent.Data.FileDatabase.Services;
///
/// Simple dictionary-based registry for media type factories
diff --git a/DeepDrftContent.Services/FileDatabase/Utils/FileUtils.cs b/DeepDrftContent.Data/FileDatabase/Utils/FileUtils.cs
similarity index 97%
rename from DeepDrftContent.Services/FileDatabase/Utils/FileUtils.cs
rename to DeepDrftContent.Data/FileDatabase/Utils/FileUtils.cs
index 637478a..02b6353 100644
--- a/DeepDrftContent.Services/FileDatabase/Utils/FileUtils.cs
+++ b/DeepDrftContent.Data/FileDatabase/Utils/FileUtils.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
-namespace DeepDrftContent.Services.FileDatabase.Utils;
+namespace DeepDrftContent.Data.FileDatabase.Utils;
///
/// Utility class for file I/O operations, matching the TypeScript file utilities
diff --git a/DeepDrftContent.Services/FileDatabase/Utils/StructuralMap.cs b/DeepDrftContent.Data/FileDatabase/Utils/StructuralMap.cs
similarity index 98%
rename from DeepDrftContent.Services/FileDatabase/Utils/StructuralMap.cs
rename to DeepDrftContent.Data/FileDatabase/Utils/StructuralMap.cs
index cde98b4..d6748cd 100644
--- a/DeepDrftContent.Services/FileDatabase/Utils/StructuralMap.cs
+++ b/DeepDrftContent.Data/FileDatabase/Utils/StructuralMap.cs
@@ -1,7 +1,7 @@
using System.Collections;
using System.Text.Json;
-namespace DeepDrftContent.Services.FileDatabase.Utils;
+namespace DeepDrftContent.Data.FileDatabase.Utils;
///
/// A map implementation that uses structural equality for keys by serializing them to JSON.
diff --git a/DeepDrftContent.Services/FileDatabase/Utils/StructuralSet.cs b/DeepDrftContent.Data/FileDatabase/Utils/StructuralSet.cs
similarity index 98%
rename from DeepDrftContent.Services/FileDatabase/Utils/StructuralSet.cs
rename to DeepDrftContent.Data/FileDatabase/Utils/StructuralSet.cs
index 6592c20..d7ecc0f 100644
--- a/DeepDrftContent.Services/FileDatabase/Utils/StructuralSet.cs
+++ b/DeepDrftContent.Data/FileDatabase/Utils/StructuralSet.cs
@@ -1,7 +1,7 @@
using System.Collections;
using System.Text.Json;
-namespace DeepDrftContent.Services.FileDatabase.Utils;
+namespace DeepDrftContent.Data.FileDatabase.Utils;
///
/// A set implementation that uses structural equality for values by serializing them to JSON.
diff --git a/DeepDrftContent.Services/Processors/AudioProcessor.cs b/DeepDrftContent.Data/Processors/AudioProcessor.cs
similarity index 98%
rename from DeepDrftContent.Services/Processors/AudioProcessor.cs
rename to DeepDrftContent.Data/Processors/AudioProcessor.cs
index ffac64a..2fc2dec 100644
--- a/DeepDrftContent.Services/Processors/AudioProcessor.cs
+++ b/DeepDrftContent.Data/Processors/AudioProcessor.cs
@@ -1,6 +1,6 @@
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
-namespace DeepDrftContent.Services.Processors;
+namespace DeepDrftContent.Data.Processors;
///
/// Service for processing audio files and extracting metadata
diff --git a/DeepDrftContent.Services/TrackService.cs b/DeepDrftContent.Data/TrackService.cs
similarity index 87%
rename from DeepDrftContent.Services/TrackService.cs
rename to DeepDrftContent.Data/TrackService.cs
index 1906031..1e752cd 100644
--- a/DeepDrftContent.Services/TrackService.cs
+++ b/DeepDrftContent.Data/TrackService.cs
@@ -1,9 +1,9 @@
-using DeepDrftContent.Services.Constants;
-using DeepDrftContent.Services.FileDatabase.Services;
-using DeepDrftContent.Services.Processors;
+using DeepDrftContent.Data.Constants;
+using DeepDrftContent.Data.FileDatabase.Services;
+using DeepDrftContent.Data.Processors;
using DeepDrftModels.Entities;
-namespace DeepDrftContent.Services;
+namespace DeepDrftContent.Data;
///
/// Service for managing tracks in both SQL and FileDatabase
@@ -52,7 +52,7 @@ public class TrackService
// Ensure tracks vault exists
if (!_fileDatabase.HasVault(VaultConstants.Tracks))
{
- await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, DeepDrftContent.Services.FileDatabase.Models.MediaVaultType.Audio);
+ await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, DeepDrftContent.Data.FileDatabase.Models.MediaVaultType.Audio);
}
// Store the audio in FileDatabase
@@ -87,9 +87,9 @@ public class TrackService
///
/// Track ID (EntryKey)
/// Audio binary or null if not found
- public async Task GetAudioBinaryAsync(string trackId)
+ public async Task GetAudioBinaryAsync(string trackId)
{
- return await _fileDatabase.LoadResourceAsync(VaultConstants.Tracks, trackId);
+ return await _fileDatabase.LoadResourceAsync(VaultConstants.Tracks, trackId);
}
///
@@ -107,7 +107,7 @@ public class TrackService
{
if (!_fileDatabase.HasVault(VaultConstants.Tracks))
{
- await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, DeepDrftContent.Services.FileDatabase.Models.MediaVaultType.Audio);
+ await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, DeepDrftContent.Data.FileDatabase.Models.MediaVaultType.Audio);
}
}
-}
\ No newline at end of file
+}
diff --git a/DeepDrftContent/Controllers/TrackController.cs b/DeepDrftContent/Controllers/TrackController.cs
index af2fd8e..0cd7825 100644
--- a/DeepDrftContent/Controllers/TrackController.cs
+++ b/DeepDrftContent/Controllers/TrackController.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.Audio;
-using DeepDrftContent.Services.Constants;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.Audio;
+using DeepDrftContent.Data.Constants;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
using DeepDrftContent.Middleware;
using Microsoft.AspNetCore.Mvc;
@@ -11,7 +11,7 @@ namespace DeepDrftContent.Controllers;
[Route("api/[controller]")]
public class TrackController : ControllerBase
{
- private readonly DeepDrftContent.Services.TrackService _trackService;
+ private readonly DeepDrftContent.Data.TrackService _trackService;
private readonly WavOffsetService _wavOffsetService;
private readonly ILogger _logger;
@@ -19,11 +19,11 @@ public class TrackController : ControllerBase
// AudioBinaryDto over the wire, not a WAV file path. TrackService.AddTrackFromWavAsync is
// file-path-oriented and not applicable here. If a file-upload flow is added in future,
// route it through TrackService instead.
- private readonly DeepDrftContent.Services.FileDatabase.Services.FileDatabase _fileDatabase;
+ private readonly DeepDrftContent.Data.FileDatabase.Services.FileDatabase _fileDatabase;
public TrackController(
- DeepDrftContent.Services.TrackService trackService,
- DeepDrftContent.Services.FileDatabase.Services.FileDatabase fileDatabase,
+ DeepDrftContent.Data.TrackService trackService,
+ DeepDrftContent.Data.FileDatabase.Services.FileDatabase fileDatabase,
WavOffsetService wavOffsetService,
ILogger logger)
{
@@ -245,7 +245,7 @@ public class TrackController : ControllerBase
// Direct FileDatabase write: this endpoint receives an already-processed AudioBinaryDto,
// not a WAV file, so TrackService.AddTrackFromWavAsync does not apply. See constructor comment.
var success = await _fileDatabase.RegisterResourceAsync(
- DeepDrftContent.Services.Constants.VaultConstants.Tracks, trackId, audioBinary);
+ DeepDrftContent.Data.Constants.VaultConstants.Tracks, trackId, audioBinary);
return success ? Ok() : BadRequest("Failed to store audio track");
}
diff --git a/DeepDrftContent/DeepDrftContent.csproj b/DeepDrftContent/DeepDrftContent.csproj
index 732f465..d04b35e 100644
--- a/DeepDrftContent/DeepDrftContent.csproj
+++ b/DeepDrftContent/DeepDrftContent.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/DeepDrftContent/Program.cs b/DeepDrftContent/Program.cs
index bd3aeff..91b3e0f 100644
--- a/DeepDrftContent/Program.cs
+++ b/DeepDrftContent/Program.cs
@@ -1,5 +1,5 @@
using DeepDrftContent;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Services;
using DeepDrftContent.Middleware;
using DeepDrftContent.Models;
using Microsoft.AspNetCore.HttpOverrides;
diff --git a/DeepDrftContent/Startup.cs b/DeepDrftContent/Startup.cs
index 25d2a50..5c3c7f0 100644
--- a/DeepDrftContent/Startup.cs
+++ b/DeepDrftContent/Startup.cs
@@ -1,9 +1,9 @@
-using DeepDrftContent.Services;
-using DeepDrftContent.Services.Audio;
-using DeepDrftContent.Services.Constants;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
-using DeepDrftContent.Services.Processors;
+using DeepDrftContent.Data;
+using DeepDrftContent.Data.Audio;
+using DeepDrftContent.Data.Constants;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
+using DeepDrftContent.Data.Processors;
using DeepDrftContent.Models;
using Microsoft.Extensions.Logging;
using NetBlocks.Utilities.Environment;
diff --git a/DeepDrftWeb.Services/CLAUDE.md b/DeepDrftData/CLAUDE.md
similarity index 100%
rename from DeepDrftWeb.Services/CLAUDE.md
rename to DeepDrftData/CLAUDE.md
diff --git a/DeepDrftData/Data/Configurations/TrackConfiguration.cs b/DeepDrftData/Data/Configurations/TrackConfiguration.cs
new file mode 100644
index 0000000..9da506b
--- /dev/null
+++ b/DeepDrftData/Data/Configurations/TrackConfiguration.cs
@@ -0,0 +1,61 @@
+using Data.Data.Configurations;
+using DeepDrftModels.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace DeepDrftData.Data.Configurations;
+
+public class TrackConfiguration : BaseEntityConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ // Wires up Id PK + audit columns (CreatedAt, UpdatedAt, IsDeleted) and the IsDeleted index.
+ base.Configure(builder);
+
+ builder.ToTable("track");
+
+ // Map the base audit columns to the snake_case naming the rest of the schema uses.
+ builder.Property(e => e.Id).HasColumnName("id");
+ builder.Property(e => e.CreatedAt).HasColumnName("created_at");
+ builder.Property(e => e.UpdatedAt).HasColumnName("updated_at");
+ builder.Property(e => e.IsDeleted).HasColumnName("is_deleted");
+
+ builder.Property(e => e.EntryKey)
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnName("entry_key");
+
+ builder.Property(e => e.TrackName)
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnName("track_name");
+
+ builder.Property(e => e.Artist)
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnName("artist");
+
+ builder.Property(e => e.Album)
+ .HasMaxLength(200)
+ .HasColumnName("album");
+
+ builder.Property(e => e.Genre)
+ .HasMaxLength(100)
+ .HasColumnName("genre");
+
+ builder.Property(e => e.ReleaseDate)
+ .HasColumnName("release_date");
+
+ builder.Property(e => e.ImagePath)
+ .HasMaxLength(500)
+ .HasColumnName("image_path");
+
+ builder.Property(e => e.CreatedByUserId)
+ .HasColumnName("created_by_user_id");
+
+ // Explicit index on is_deleted so soft-delete global query filters are
+ // not full table scans. base.Configure may or may not add this depending
+ // on the BlazorBlocks.Data version; declaring it here guarantees it.
+ builder.HasIndex(e => e.IsDeleted).HasDatabaseName("IX_track_is_deleted");
+ }
+}
diff --git a/DeepDrftWeb.Services/Data/DeepDrftContext.cs b/DeepDrftData/Data/DeepDrftContext.cs
similarity index 82%
rename from DeepDrftWeb.Services/Data/DeepDrftContext.cs
rename to DeepDrftData/Data/DeepDrftContext.cs
index 77017cb..b0839dd 100644
--- a/DeepDrftWeb.Services/Data/DeepDrftContext.cs
+++ b/DeepDrftData/Data/DeepDrftContext.cs
@@ -1,8 +1,8 @@
using DeepDrftModels.Entities;
-using DeepDrftWeb.Services.Data.Configurations;
+using DeepDrftData.Data.Configurations;
using Microsoft.EntityFrameworkCore;
-namespace DeepDrftWeb.Services.Data;
+namespace DeepDrftData.Data;
public class DeepDrftContext : DbContext
{
@@ -15,7 +15,7 @@ public class DeepDrftContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
-
+
modelBuilder.ApplyConfiguration(new TrackConfiguration());
}
-}
\ No newline at end of file
+}
diff --git a/DeepDrftWeb.Services/Data/DeepDrftContextFactory.cs b/DeepDrftData/Data/DeepDrftContextFactory.cs
similarity index 96%
rename from DeepDrftWeb.Services/Data/DeepDrftContextFactory.cs
rename to DeepDrftData/Data/DeepDrftContextFactory.cs
index bb846d4..3d417b7 100644
--- a/DeepDrftWeb.Services/Data/DeepDrftContextFactory.cs
+++ b/DeepDrftData/Data/DeepDrftContextFactory.cs
@@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
-namespace DeepDrftWeb.Services.Data;
+namespace DeepDrftData.Data;
public class DeepDrftContextFactory : IDesignTimeDbContextFactory
{
@@ -19,4 +19,4 @@ public class DeepDrftContextFactory : IDesignTimeDbContextFactory
+
+
diff --git a/DeepDrftWeb.Services/ITrackService.cs b/DeepDrftData/ITrackService.cs
similarity index 90%
rename from DeepDrftWeb.Services/ITrackService.cs
rename to DeepDrftData/ITrackService.cs
index 6d387ef..9b70750 100644
--- a/DeepDrftWeb.Services/ITrackService.cs
+++ b/DeepDrftData/ITrackService.cs
@@ -1,8 +1,8 @@
using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
+using Models.Common;
using NetBlocks.Models;
-namespace DeepDrftWeb.Services;
+namespace DeepDrftData;
public interface ITrackService
{
diff --git a/DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.Designer.cs b/DeepDrftData/Migrations/20260519021400_InitialCreate.Designer.cs
similarity index 77%
rename from DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.Designer.cs
rename to DeepDrftData/Migrations/20260519021400_InitialCreate.Designer.cs
index 4df868a..31111a3 100644
--- a/DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.Designer.cs
+++ b/DeepDrftData/Migrations/20260519021400_InitialCreate.Designer.cs
@@ -1,6 +1,6 @@
//
using System;
-using DeepDrftWeb.Services.Data;
+using DeepDrftData.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
@@ -9,11 +9,11 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace DeepDrftWeb.Migrations
+namespace DeepDrftData.Migrations
{
[DbContext(typeof(DeepDrftContext))]
- [Migration("20260518035137_AddCreatedByUserId")]
- partial class AddCreatedByUserId
+ [Migration("20260519021400_InitialCreate")]
+ partial class InitialCreate
{
///
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -45,6 +45,10 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(200)")
.HasColumnName("artist");
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
b.Property("CreatedByUserId")
.HasColumnType("bigint")
.HasColumnName("created_by_user_id");
@@ -65,6 +69,12 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(500)")
.HasColumnName("image_path");
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("is_deleted");
+
b.Property("ReleaseDate")
.HasColumnType("date")
.HasColumnName("release_date");
@@ -75,8 +85,15 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(200)")
.HasColumnName("track_name");
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
b.HasKey("Id");
+ b.HasIndex("IsDeleted")
+ .HasDatabaseName("IX_track_is_deleted");
+
b.ToTable("track", (string)null);
});
#pragma warning restore 612, 618
diff --git a/DeepDrftWeb.Services/Migrations/20260518025102_Initial.cs b/DeepDrftData/Migrations/20260519021400_InitialCreate.cs
similarity index 70%
rename from DeepDrftWeb.Services/Migrations/20260518025102_Initial.cs
rename to DeepDrftData/Migrations/20260519021400_InitialCreate.cs
index 2662487..1b7040a 100644
--- a/DeepDrftWeb.Services/Migrations/20260518025102_Initial.cs
+++ b/DeepDrftData/Migrations/20260519021400_InitialCreate.cs
@@ -4,10 +4,10 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace DeepDrftWeb.Migrations
+namespace DeepDrftData.Migrations
{
///
- public partial class Initial : Migration
+ public partial class InitialCreate : Migration
{
///
protected override void Up(MigrationBuilder migrationBuilder)
@@ -24,12 +24,21 @@ namespace DeepDrftWeb.Migrations
album = table.Column(type: "character varying(200)", maxLength: 200, nullable: true),
genre = table.Column(type: "character varying(100)", maxLength: 100, nullable: true),
release_date = table.Column(type: "date", nullable: true),
- image_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true)
+ image_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true),
+ created_by_user_id = table.Column(type: "bigint", nullable: true),
+ created_at = table.Column(type: "timestamp with time zone", nullable: false),
+ updated_at = table.Column(type: "timestamp with time zone", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false, defaultValue: false)
},
constraints: table =>
{
table.PrimaryKey("PK_track", x => x.id);
});
+
+ migrationBuilder.CreateIndex(
+ name: "IX_track_is_deleted",
+ table: "track",
+ column: "is_deleted");
}
///
diff --git a/DeepDrftWeb.Services/Migrations/DeepDrftContextModelSnapshot.cs b/DeepDrftData/Migrations/DeepDrftContextModelSnapshot.cs
similarity index 79%
rename from DeepDrftWeb.Services/Migrations/DeepDrftContextModelSnapshot.cs
rename to DeepDrftData/Migrations/DeepDrftContextModelSnapshot.cs
index 76ae3af..ed99ec0 100644
--- a/DeepDrftWeb.Services/Migrations/DeepDrftContextModelSnapshot.cs
+++ b/DeepDrftData/Migrations/DeepDrftContextModelSnapshot.cs
@@ -1,6 +1,6 @@
//
using System;
-using DeepDrftWeb.Services.Data;
+using DeepDrftData.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@@ -8,7 +8,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace DeepDrftWeb.Migrations
+namespace DeepDrftData.Migrations
{
[DbContext(typeof(DeepDrftContext))]
partial class DeepDrftContextModelSnapshot : ModelSnapshot
@@ -42,6 +42,10 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(200)")
.HasColumnName("artist");
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
b.Property("CreatedByUserId")
.HasColumnType("bigint")
.HasColumnName("created_by_user_id");
@@ -62,6 +66,12 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(500)")
.HasColumnName("image_path");
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("is_deleted");
+
b.Property("ReleaseDate")
.HasColumnType("date")
.HasColumnName("release_date");
@@ -72,8 +82,15 @@ namespace DeepDrftWeb.Migrations
.HasColumnType("character varying(200)")
.HasColumnName("track_name");
+ b.Property("UpdatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_at");
+
b.HasKey("Id");
+ b.HasIndex("IsDeleted")
+ .HasDatabaseName("IX_track_is_deleted");
+
b.ToTable("track", (string)null);
});
#pragma warning restore 612, 618
diff --git a/DeepDrftData/Repositories/TrackRepository.cs b/DeepDrftData/Repositories/TrackRepository.cs
new file mode 100644
index 0000000..878163a
--- /dev/null
+++ b/DeepDrftData/Repositories/TrackRepository.cs
@@ -0,0 +1,31 @@
+using Data.Data.Repositories;
+using Data.Errors;
+using DeepDrftData.Data;
+using DeepDrftModels.Entities;
+using Microsoft.Extensions.Logging;
+
+namespace DeepDrftData.Repositories;
+
+public class TrackRepository : Repository
+{
+ public TrackRepository(
+ DeepDrftContext context,
+ ILogger> logger,
+ IDbExceptionClassifier? classifier = null)
+ : base(context, logger, classifier: classifier)
+ {
+ }
+
+ protected override void UpdateEntity(TrackEntity target, TrackEntity source)
+ {
+ base.UpdateEntity(target, source); // copies CreatedAt, UpdatedAt, IsDeleted
+ target.EntryKey = source.EntryKey;
+ target.TrackName = source.TrackName;
+ target.Artist = source.Artist;
+ target.Album = source.Album;
+ target.Genre = source.Genre;
+ target.ReleaseDate = source.ReleaseDate;
+ target.ImagePath = source.ImagePath;
+ target.CreatedByUserId = source.CreatedByUserId;
+ }
+}
diff --git a/DeepDrftData/TrackConverter.cs b/DeepDrftData/TrackConverter.cs
new file mode 100644
index 0000000..30e7173
--- /dev/null
+++ b/DeepDrftData/TrackConverter.cs
@@ -0,0 +1,44 @@
+using DeepDrftModels.DTOs;
+using DeepDrftModels.Entities;
+using Models.Converters;
+
+namespace DeepDrftData;
+
+///
+/// Static entity ↔ DTO converter consumed by the BlazorBlocks Manager base class.
+/// The DTO side mirrors the entity field-for-field; the audit columns
+/// (CreatedAt, UpdatedAt) come from BaseEntity / BaseModel.
+/// IsDeleted does not round-trip — soft-deleted rows are not exposed via the model.
+///
+public class TrackConverter : IEntityToModelConverter
+{
+ public static TrackDto Convert(TrackEntity entity) => new()
+ {
+ Id = entity.Id,
+ CreatedAt = entity.CreatedAt,
+ UpdatedAt = entity.UpdatedAt,
+ EntryKey = entity.EntryKey,
+ TrackName = entity.TrackName,
+ Artist = entity.Artist,
+ Album = entity.Album,
+ Genre = entity.Genre,
+ ReleaseDate = entity.ReleaseDate,
+ ImagePath = entity.ImagePath,
+ CreatedByUserId = entity.CreatedByUserId
+ };
+
+ public static TrackEntity Convert(TrackDto model) => new()
+ {
+ Id = model.Id,
+ CreatedAt = model.CreatedAt,
+ UpdatedAt = model.UpdatedAt,
+ EntryKey = model.EntryKey,
+ TrackName = model.TrackName,
+ Artist = model.Artist,
+ Album = model.Album,
+ Genre = model.Genre,
+ ReleaseDate = model.ReleaseDate,
+ ImagePath = model.ImagePath,
+ CreatedByUserId = model.CreatedByUserId
+ };
+}
diff --git a/DeepDrftData/TrackManager.cs b/DeepDrftData/TrackManager.cs
new file mode 100644
index 0000000..bf5984b
--- /dev/null
+++ b/DeepDrftData/TrackManager.cs
@@ -0,0 +1,137 @@
+using Data.Managers;
+using DeepDrftData.Repositories;
+using DeepDrftModels.DTOs;
+using DeepDrftModels.Entities;
+using Microsoft.Extensions.Logging;
+using Models.Common;
+using NetBlocks.Models;
+
+namespace DeepDrftData;
+
+///
+/// SQL-side track orchestrator built on the BlazorBlocks Manager base. Two surfaces coexist:
+///
+/// - The DTO-shaped IManager surface (GetById → TrackDto, etc.) inherited from Manager<>.
+/// - The entity-shaped ITrackService surface retained for backward compatibility with the
+/// web host, CMS, and CLI — all existing controllers and pages inject ITrackService and
+/// expect TrackEntity-typed results. The two GetById overloads conflict on signature, so
+/// ITrackService.GetById is implemented explicitly; the base Manager.Delete satisfies
+/// both interfaces because the signatures align.
+///
+public class TrackManager
+ : Manager, ITrackService
+{
+ public TrackManager(
+ TrackRepository repository,
+ ILogger> logger)
+ : base(repository, logger)
+ {
+ }
+
+ // --- ITrackService implementation (entity-space; calls Repository directly) ---
+
+ // Explicit interface implementation — IManager.GetById returns ResultContainer
+ // (inherited from Manager<>), so this entity-typed overload cannot coexist as a public
+ // member with the same name. Callers always inject ITrackService, so the explicit impl
+ // resolves correctly at the call site.
+ async Task> ITrackService.GetById(long id)
+ {
+ try
+ {
+ var entity = await Repository.GetByIdAsync(id);
+ return ResultContainer.CreatePassResult(entity);
+ }
+ catch (Exception e)
+ {
+ return ResultContainer.CreateFailResult(e.Message);
+ }
+ }
+
+ public async Task>> GetAll()
+ {
+ try
+ {
+ var entities = await Repository.GetAllAsync();
+ return ResultContainer>.CreatePassResult(entities.ToList());
+ }
+ catch (Exception e)
+ {
+ return ResultContainer>.CreateFailResult(e.Message);
+ }
+ }
+
+ public async Task>> GetPaged(
+ int pageNumber,
+ int pageSize,
+ string? sortColumn,
+ bool sortDescending,
+ CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ var parameters = new PagingParameters
+ {
+ Page = pageNumber,
+ PageSize = pageSize,
+ IsDescending = sortDescending,
+ OrderBy = sortColumn switch
+ {
+ "TrackName" => e => e.TrackName,
+ "Artist" => e => e.Artist,
+ "Album" => e => (object)(e.Album ?? string.Empty),
+ "Genre" => e => (object)(e.Genre ?? string.Empty),
+ "ReleaseDate" => e => (object)(e.ReleaseDate ?? DateOnly.MaxValue),
+ _ => e => e.Id
+ }
+ };
+
+ var page = await Repository.GetPagedAsync(parameters);
+ return ResultContainer>.CreatePassResult(page);
+ }
+ catch (Exception e)
+ {
+ return ResultContainer>.CreateFailResult(e.Message);
+ }
+ }
+
+ public async Task> Create(TrackEntity newTrack)
+ {
+ try
+ {
+ var added = await Repository.AddAsync(newTrack);
+ return ResultContainer.CreatePassResult(added);
+ }
+ catch (Exception e)
+ {
+ return ResultContainer.CreateFailResult(e.Message);
+ }
+ }
+
+ // Manager<>.Update takes TrackDto and returns Result; this Update keeps the
+ // entity-typed contract callers expect and returns the post-update entity for the
+ // existing CMS edit flow that reads back the persisted values.
+ ///
+ /// Updates the track's metadata fields and returns the DB-authoritative entity.
+ /// The caller's object has its UpdatedAt field
+ /// mutated in place by ; do not reuse it.
+ ///
+ public async Task> Update(TrackEntity track)
+ {
+ try
+ {
+ await Repository.UpdateAsync(track);
+ var updated = await Repository.GetByIdAsync(track.Id);
+ return updated is not null
+ ? ResultContainer.CreatePassResult(updated)
+ : ResultContainer.CreateFailResult("Track not found after update.");
+ }
+ catch (Exception e)
+ {
+ return ResultContainer.CreateFailResult(e.Message);
+ }
+ }
+
+ // Delete(long) is inherited from Manager<> — its Task signature already
+ // satisfies ITrackService.Delete, and the base implementation performs the soft delete
+ // via Repository.DeleteAsync. No override needed.
+}
diff --git a/DeepDrftHome.sln b/DeepDrftHome.sln
index 3f17d88..b214d54 100644
--- a/DeepDrftHome.sln
+++ b/DeepDrftHome.sln
@@ -14,9 +14,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftTests", "DeepDrftTe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftCli", "DeepDrftCli\DeepDrftCli.csproj", "{E4C0ADD6-1264-47A5-98E1-0843AD14B7F9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftWeb.Services", "DeepDrftWeb.Services\DeepDrftWeb.Services.csproj", "{1D1CE905-DAD0-4E93-9B09-326E8EC05877}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftData", "DeepDrftData\DeepDrftData.csproj", "{1D1CE905-DAD0-4E93-9B09-326E8EC05877}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Services", "DeepDrftContent.Services\DeepDrftContent.Services.csproj", "{4D025326-7F27-4C42-BE0F-92C1E64E0696}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Data", "DeepDrftContent.Data\DeepDrftContent.Data.csproj", "{4D025326-7F27-4C42-BE0F-92C1E64E0696}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftCms", "DeepDrftCms\DeepDrftCms.csproj", "{81F1D47F-F892-45FB-9E35-D7775805FFD3}"
EndProject
diff --git a/DeepDrftModels/DTOs/TrackDto.cs b/DeepDrftModels/DTOs/TrackDto.cs
index f63d8ed..c368262 100644
--- a/DeepDrftModels/DTOs/TrackDto.cs
+++ b/DeepDrftModels/DTOs/TrackDto.cs
@@ -1,13 +1,21 @@
-namespace DeepDrftModels.DTOs;
+using Models.Models;
-public class TrackDto
+namespace DeepDrftModels.DTOs;
+
+// Inherits Id, CreatedAt, UpdatedAt from BaseModel (Cerebellum.BlazorBlocks.Models).
+// BlazorBlocks's Manager<> generic constraint requires `new()` on the model type, which
+// disqualifies `required` properties (the `new()` constraint and required members do not
+// compose). EntryKey/TrackName/Artist therefore drop `required` here — the TrackEntity
+// side remains required, and TrackConverter assigns every field on the round-trip so an
+// empty default is never observable in production code paths.
+public class TrackDto : BaseModel
{
- public long Id { get; set; }
- public required string EntryKey { get; set; }
- public required string TrackName { get; set; }
- public required string Artist { get; set; }
+ public string EntryKey { get; set; } = string.Empty;
+ public string TrackName { get; set; } = string.Empty;
+ public string Artist { get; set; } = string.Empty;
public string? Album { get; set; }
public string? Genre { get; set; }
public DateOnly? ReleaseDate { get; set; }
public string? ImagePath { get; set; }
-}
\ No newline at end of file
+ public long? CreatedByUserId { get; set; }
+}
diff --git a/DeepDrftModels/DeepDrftModels.csproj b/DeepDrftModels/DeepDrftModels.csproj
index b1a2a1c..bd54bcb 100644
--- a/DeepDrftModels/DeepDrftModels.csproj
+++ b/DeepDrftModels/DeepDrftModels.csproj
@@ -1,4 +1,4 @@
-
+
net10.0
@@ -8,6 +8,7 @@
+
diff --git a/DeepDrftModels/Entities/TrackEntity.cs b/DeepDrftModels/Entities/TrackEntity.cs
index 042e5ff..28d8b14 100644
--- a/DeepDrftModels/Entities/TrackEntity.cs
+++ b/DeepDrftModels/Entities/TrackEntity.cs
@@ -1,8 +1,12 @@
-namespace DeepDrftModels.Entities;
+using Models.Entities;
-public class TrackEntity
+namespace DeepDrftModels.Entities;
+
+// Inherits Id, CreatedAt, UpdatedAt, IsDeleted from BaseEntity (Cerebellum.BlazorBlocks.Models).
+// BaseEntity ships the audit columns but does not declare IEntity itself, so subclasses
+// declare it explicitly to satisfy the generic constraints on Repository<>/Manager<>/etc.
+public class TrackEntity : BaseEntity, IEntity
{
- public long Id { get; set; }
public required string EntryKey { get; set; }
public required string TrackName { get; set; }
public required string Artist { get; set; }
@@ -11,4 +15,4 @@ public class TrackEntity
public DateOnly? ReleaseDate { get; set; }
public string? ImagePath { get; set; }
public long? CreatedByUserId { get; set; }
-}
\ No newline at end of file
+}
diff --git a/DeepDrftModels/Models/PagedResult.cs b/DeepDrftModels/Models/PagedResult.cs
deleted file mode 100644
index 46ab081..0000000
--- a/DeepDrftModels/Models/PagedResult.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace DeepDrftModels.Models;
-
-public class PagedResult
-{
- public IEnumerable Items { get; set; } = new List();
- public int TotalCount { get; set; }
- public int Page { get; set; }
- public int PageSize { get; set; }
- public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)TotalCount / PageSize) : 0;
- public bool HasNextPage => Page < TotalPages;
- public bool HasPreviousPage => Page > 1;
-
- public PagedResult()
- {
- }
-
- public static PagedResult From(PagedResult other, IEnumerable items)
- {
- return new PagedResult()
- {
- Items = items.ToList(),
- Page = other.Page,
- PageSize = other.PageSize,
- TotalCount = other.TotalCount,
- };
- }
-
- public PagedResult(IEnumerable items, int totalCount, int page, int pageSize)
- {
- Items = items.ToList();
- TotalCount = totalCount;
- Page = page;
- PageSize = pageSize;
- }
-}
\ No newline at end of file
diff --git a/DeepDrftModels/Models/PagingParameters.cs b/DeepDrftModels/Models/PagingParameters.cs
deleted file mode 100644
index 55c2dd0..0000000
--- a/DeepDrftModels/Models/PagingParameters.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Linq.Expressions;
-
-namespace DeepDrftModels.Models;
-
-public class PagingParameters
-{
- private const int _maxPageSize = 100;
- private int _pageSize = 20;
-
- public int Page { get; set; } = 1;
-
- public int PageSize
- {
- get => _pageSize;
- set => _pageSize = value > _maxPageSize ? _maxPageSize : value;
- }
-}
-
-public class PagingParameters : PagingParameters
-{
- public Expression>? OrderBy { get; set; }
- public bool IsDescending { get; set; } = false;
-
- public int Skip => (Page - 1) * PageSize;
-}
\ No newline at end of file
diff --git a/DeepDrftTests/DeepDrftTests.csproj b/DeepDrftTests/DeepDrftTests.csproj
index 91d257c..46c6831 100644
--- a/DeepDrftTests/DeepDrftTests.csproj
+++ b/DeepDrftTests/DeepDrftTests.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/DeepDrftTests/FileDatabaseTests.cs b/DeepDrftTests/FileDatabaseTests.cs
index 206266c..7d42fc8 100644
--- a/DeepDrftTests/FileDatabaseTests.cs
+++ b/DeepDrftTests/FileDatabaseTests.cs
@@ -1,5 +1,5 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/IndexSystemTests.cs b/DeepDrftTests/IndexSystemTests.cs
index 5320fd9..552b031 100644
--- a/DeepDrftTests/IndexSystemTests.cs
+++ b/DeepDrftTests/IndexSystemTests.cs
@@ -1,7 +1,7 @@
-using DeepDrftContent.Services.FileDatabase.Abstractions;
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Abstractions;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Utils;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/MediaVaultFactoryTests.cs b/DeepDrftTests/MediaVaultFactoryTests.cs
index b743620..a4f4f10 100644
--- a/DeepDrftTests/MediaVaultFactoryTests.cs
+++ b/DeepDrftTests/MediaVaultFactoryTests.cs
@@ -1,5 +1,5 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/MediaVaultTests.cs b/DeepDrftTests/MediaVaultTests.cs
index ff28ffe..0d07b07 100644
--- a/DeepDrftTests/MediaVaultTests.cs
+++ b/DeepDrftTests/MediaVaultTests.cs
@@ -1,6 +1,6 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Utils;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/ModelTests.cs b/DeepDrftTests/ModelTests.cs
index 1fb7710..3d5a406 100644
--- a/DeepDrftTests/ModelTests.cs
+++ b/DeepDrftTests/ModelTests.cs
@@ -1,4 +1,4 @@
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/SimpleMediaTypeRegistryTests.cs b/DeepDrftTests/SimpleMediaTypeRegistryTests.cs
index 62849d3..8401be4 100644
--- a/DeepDrftTests/SimpleMediaTypeRegistryTests.cs
+++ b/DeepDrftTests/SimpleMediaTypeRegistryTests.cs
@@ -1,5 +1,5 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Services;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Services;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/TestData.cs b/DeepDrftTests/TestData.cs
index 2464862..00af156 100644
--- a/DeepDrftTests/TestData.cs
+++ b/DeepDrftTests/TestData.cs
@@ -1,4 +1,4 @@
-using DeepDrftContent.Services.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Models;
namespace DeepDrftTests;
diff --git a/DeepDrftTests/UtilityTests.cs b/DeepDrftTests/UtilityTests.cs
index 876e4ef..daade11 100644
--- a/DeepDrftTests/UtilityTests.cs
+++ b/DeepDrftTests/UtilityTests.cs
@@ -1,5 +1,5 @@
-using DeepDrftContent.Services.FileDatabase.Models;
-using DeepDrftContent.Services.FileDatabase.Utils;
+using DeepDrftContent.Data.FileDatabase.Models;
+using DeepDrftContent.Data.FileDatabase.Utils;
namespace DeepDrftTests;
diff --git a/DeepDrftWeb.Client/Clients/TrackClient.cs b/DeepDrftWeb.Client/Clients/TrackClient.cs
index eba3f18..299dba8 100644
--- a/DeepDrftWeb.Client/Clients/TrackClient.cs
+++ b/DeepDrftWeb.Client/Clients/TrackClient.cs
@@ -1,5 +1,5 @@
using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
+using Models.Common;
using NetBlocks.Models;
using System.Text.Json;
using System.Web;
diff --git a/DeepDrftWeb.Client/Pages/TracksView.razor.cs b/DeepDrftWeb.Client/Pages/TracksView.razor.cs
index e0efc9f..5075afc 100644
--- a/DeepDrftWeb.Client/Pages/TracksView.razor.cs
+++ b/DeepDrftWeb.Client/Pages/TracksView.razor.cs
@@ -1,8 +1,8 @@
using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
using DeepDrftWeb.Client.Services;
using DeepDrftWeb.Client.ViewModels;
using Microsoft.AspNetCore.Components;
+using Models.Common;
namespace DeepDrftWeb.Client.Pages;
diff --git a/DeepDrftWeb.Client/ViewModels/TracksViewModel.cs b/DeepDrftWeb.Client/ViewModels/TracksViewModel.cs
index 7baae2d..0691c43 100644
--- a/DeepDrftWeb.Client/ViewModels/TracksViewModel.cs
+++ b/DeepDrftWeb.Client/ViewModels/TracksViewModel.cs
@@ -1,6 +1,6 @@
using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
using DeepDrftWeb.Client.Clients;
+using Models.Common;
namespace DeepDrftWeb.Client.ViewModels;
diff --git a/DeepDrftWeb.Services/Data/Configurations/TrackConfiguration.cs b/DeepDrftWeb.Services/Data/Configurations/TrackConfiguration.cs
deleted file mode 100644
index 3f11d84..0000000
--- a/DeepDrftWeb.Services/Data/Configurations/TrackConfiguration.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using DeepDrftModels.Entities;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Metadata.Builders;
-
-namespace DeepDrftWeb.Services.Data.Configurations;
-
-public class TrackConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable("track");
-
- builder.HasKey(x => x.Id);
-
- builder.Property(x => x.Id)
- .HasColumnName("id")
- .IsRequired();
-
- builder.Property(x => x.EntryKey)
- .HasColumnName("entry_key")
- .IsRequired()
- .HasMaxLength(100);
-
- builder.Property(x => x.TrackName)
- .HasColumnName("track_name")
- .IsRequired()
- .HasMaxLength(200);
-
- builder.Property(x => x.Artist)
- .HasColumnName("artist")
- .IsRequired()
- .HasMaxLength(200);
-
- builder.Property(x => x.Album)
- .HasColumnName("album")
- .HasMaxLength(200);
-
- builder.Property(x => x.Genre)
- .HasColumnName("genre")
- .HasMaxLength(100);
-
- builder.Property(x => x.ReleaseDate)
- .HasColumnName("release_date");
-
- builder.Property(x => x.ImagePath)
- .HasColumnName("image_path")
- .HasMaxLength(500);
-
- builder.Property(x => x.CreatedByUserId)
- .HasColumnName("created_by_user_id");
- }
-}
\ No newline at end of file
diff --git a/DeepDrftWeb.Services/Migrations/20260518025102_Initial.Designer.cs b/DeepDrftWeb.Services/Migrations/20260518025102_Initial.Designer.cs
deleted file mode 100644
index 1be11d7..0000000
--- a/DeepDrftWeb.Services/Migrations/20260518025102_Initial.Designer.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-//
-using System;
-using DeepDrftWeb.Services.Data;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace DeepDrftWeb.Migrations
-{
- [DbContext(typeof(DeepDrftContext))]
- [Migration("20260518025102_Initial")]
- partial class Initial
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.4")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("DeepDrftModels.Entities.TrackEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("bigint")
- .HasColumnName("id");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
-
- b.Property("Album")
- .HasMaxLength(200)
- .HasColumnType("character varying(200)")
- .HasColumnName("album");
-
- b.Property("Artist")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)")
- .HasColumnName("artist");
-
- b.Property("EntryKey")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)")
- .HasColumnName("entry_key");
-
- b.Property("Genre")
- .HasMaxLength(100)
- .HasColumnType("character varying(100)")
- .HasColumnName("genre");
-
- b.Property("ImagePath")
- .HasMaxLength(500)
- .HasColumnType("character varying(500)")
- .HasColumnName("image_path");
-
- b.Property("ReleaseDate")
- .HasColumnType("date")
- .HasColumnName("release_date");
-
- b.Property("TrackName")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)")
- .HasColumnName("track_name");
-
- b.HasKey("Id");
-
- b.ToTable("track", (string)null);
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.cs b/DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.cs
deleted file mode 100644
index d1a16a7..0000000
--- a/DeepDrftWeb.Services/Migrations/20260518035137_AddCreatedByUserId.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace DeepDrftWeb.Migrations
-{
- ///
- public partial class AddCreatedByUserId : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn(
- name: "created_by_user_id",
- table: "track",
- type: "bigint",
- nullable: true);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropColumn(
- name: "created_by_user_id",
- table: "track");
- }
- }
-}
diff --git a/DeepDrftWeb.Services/Repositories/TrackRepository.cs b/DeepDrftWeb.Services/Repositories/TrackRepository.cs
deleted file mode 100644
index 8399d4e..0000000
--- a/DeepDrftWeb.Services/Repositories/TrackRepository.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
-using Microsoft.EntityFrameworkCore;
-using DeepDrftWeb.Services.Data;
-
-namespace DeepDrftWeb.Services.Repositories;
-
-public class TrackRepository
-{
- private readonly DeepDrftContext _db;
-
- public TrackRepository(DeepDrftContext db)
- {
- _db = db;
- }
-
- public async Task GetById(long id)
- {
- return await _db.Tracks.FindAsync(id);
- }
-
- public async Task> GetAll()
- {
- return await _db.Tracks.ToListAsync();
- }
-
- public async Task> GetPage(PagingParameters pageParameters, CancellationToken cancellationToken = default)
- {
- // Two separate queries with no transaction: count and page can be momentarily inconsistent
- // under concurrent writes. Acceptable — write volume is low and the UI is read-only.
- // If filtering is added, the count query must be updated to apply the same filter.
- var count = await _db.Tracks.CountAsync(cancellationToken);
-
- var orderBy = pageParameters.OrderBy ?? (t => t.Id);
- var ordered = pageParameters.IsDescending
- ? _db.Tracks.OrderByDescending(orderBy)
- : _db.Tracks.OrderBy(orderBy);
-
- var page = await ordered
- .Skip(pageParameters.Skip)
- .Take(pageParameters.PageSize)
- .ToListAsync(cancellationToken);
-
- return new PagedResult(page, count, pageParameters.Page, pageParameters.PageSize);
- }
-
- public async Task Create(TrackEntity newTrack)
- {
- var track = _db.Tracks.Add(newTrack);
- await _db.SaveChangesAsync();
- return track.Entity;
- }
-
- public async Task Update(TrackEntity track)
- {
- var trackEntity = await GetById(track.Id);
-
- if (trackEntity == null)
- {
- throw new InvalidOperationException($"Track not found: {track.Id}");
- }
-
- trackEntity.Album = track.Album;
- trackEntity.Artist = track.Artist;
- trackEntity.Genre = track.Genre;
- trackEntity.ImagePath = track.ImagePath;
- trackEntity.EntryKey = track.EntryKey;
- trackEntity.ReleaseDate = track.ReleaseDate;
- trackEntity.TrackName = track.TrackName;
-
- await _db.SaveChangesAsync();
- return trackEntity;
- }
-
- public async Task Delete(long id)
- {
- var track = await GetById(id);
- if (track != null)
- {
- _db.Tracks.Remove(track);
- await _db.SaveChangesAsync();
- }
- }
-}
\ No newline at end of file
diff --git a/DeepDrftWeb.Services/TrackService.cs b/DeepDrftWeb.Services/TrackService.cs
deleted file mode 100644
index e1cd6ad..0000000
--- a/DeepDrftWeb.Services/TrackService.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
-using DeepDrftWeb.Services.Data;
-using DeepDrftWeb.Services.Repositories;
-using NetBlocks.Models;
-
-namespace DeepDrftWeb.Services;
-
-public class TrackService : ITrackService
-{
- private readonly TrackRepository _repository;
-
- public TrackService(TrackRepository repository)
- {
- _repository = repository;
- }
-
- public async Task> GetById(long id)
- {
- try
- {
- var track = await _repository.GetById(id);
- return ResultContainer.CreatePassResult(track);
- }
- catch (Exception e)
- {
- return ResultContainer.CreateFailResult(e.Message);
- }
- }
-
- public async Task>> GetAll()
- {
- try
- {
- var tracks = await _repository.GetAll();
- return ResultContainer>.CreatePassResult(tracks);
- }
- catch (Exception e)
- {
- return ResultContainer>.CreateFailResult(e.Message);
- }
- }
-
- public async Task>> GetPaged(int pageNumber, int pageSize, string? sortColumn, bool sortDescending, CancellationToken cancellationToken = default)
- {
- try
- {
- var parameters = new PagingParameters()
- {
- Page = pageNumber,
- PageSize = pageSize,
- IsDescending = sortDescending
- };
-
- if (sortColumn != null)
- {
- switch (sortColumn)
- {
- case "TrackName":
- parameters.OrderBy = entity => entity.TrackName;
- break;
- case "Artist":
- parameters.OrderBy = entity => entity.Artist;
- break;
- case "Album":
- parameters.OrderBy = entity => entity.Album ?? "";
- break;
- case "ReleaseDate":
- parameters.OrderBy = entity => entity.ReleaseDate ?? DateOnly.MaxValue;
- break;
- case "Genre":
- parameters.OrderBy = entity => entity.Genre ?? "";
- break;
-
- }
- }
-
- var page = await _repository.GetPage(parameters, cancellationToken);
- return ResultContainer>.CreatePassResult(page);
- }
- catch (Exception e)
- {
- return ResultContainer>.CreateFailResult(e.Message);
- }
- }
-
- public async Task> Create(TrackEntity newTrack)
- {
- try
- {
- var track = await _repository.Create(newTrack);
- return ResultContainer.CreatePassResult(track);
- }
- catch (Exception e)
- {
- return ResultContainer.CreateFailResult(e.Message);
- }
- }
-
- public async Task> Update(TrackEntity track)
- {
- try
- {
- var updatedTrack = await _repository.Update(track);
- return ResultContainer.CreatePassResult(updatedTrack);
- }
- catch (Exception e)
- {
- return ResultContainer.CreateFailResult(e.Message);
- }
- }
-
- public async Task Delete(long id)
- {
- try
- {
- await _repository.Delete(id);
- return Result.CreatePassResult();
- }
- catch (Exception e)
- {
- return Result.CreateFailResult(e.Message);
- }
- }
-}
\ No newline at end of file
diff --git a/DeepDrftWeb/Controllers/CmsDeleteController.cs b/DeepDrftWeb/Controllers/CmsDeleteController.cs
index 943c765..269fe94 100644
--- a/DeepDrftWeb/Controllers/CmsDeleteController.cs
+++ b/DeepDrftWeb/Controllers/CmsDeleteController.cs
@@ -1,4 +1,4 @@
-using DeepDrftWeb.Services;
+using DeepDrftData;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
diff --git a/DeepDrftWeb/Controllers/CmsEditController.cs b/DeepDrftWeb/Controllers/CmsEditController.cs
index d9d088b..49667b0 100644
--- a/DeepDrftWeb/Controllers/CmsEditController.cs
+++ b/DeepDrftWeb/Controllers/CmsEditController.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
+using DeepDrftData;
using DeepDrftModels.Entities;
-using DeepDrftWeb.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NetBlocks.Models;
diff --git a/DeepDrftWeb/Controllers/CmsUploadController.cs b/DeepDrftWeb/Controllers/CmsUploadController.cs
index 2bc617f..82f327d 100644
--- a/DeepDrftWeb/Controllers/CmsUploadController.cs
+++ b/DeepDrftWeb/Controllers/CmsUploadController.cs
@@ -1,7 +1,7 @@
using System.Net.Http.Headers;
using System.Security.Claims;
+using DeepDrftData;
using DeepDrftModels.Entities;
-using DeepDrftWeb.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -10,7 +10,7 @@ namespace DeepDrftWeb.Controllers;
///
/// CMS upload surface. Proxies a WAV + metadata multipart form to DeepDrftContent's
/// POST api/track/upload, then persists the returned unpersisted TrackEntity to SQL via
-/// ITrackService.Create. DeepDrftWeb intentionally does not reference DeepDrftContent.Services
+/// ITrackService.Create. DeepDrftWeb intentionally does not reference DeepDrftContent.Data
/// (CMS-PLAN §5, Option B) — all vault access is over HTTP.
///
[ApiController]
diff --git a/DeepDrftWeb/Controllers/TrackController.cs b/DeepDrftWeb/Controllers/TrackController.cs
index 1bbe995..d4c7f0a 100644
--- a/DeepDrftWeb/Controllers/TrackController.cs
+++ b/DeepDrftWeb/Controllers/TrackController.cs
@@ -1,7 +1,7 @@
-using DeepDrftModels.Entities;
-using DeepDrftModels.Models;
-using DeepDrftWeb.Services;
+using DeepDrftData;
+using DeepDrftModels.Entities;
using Microsoft.AspNetCore.Mvc;
+using Models.Common;
using NetBlocks.Models;
namespace DeepDrftWeb.Controllers;
diff --git a/DeepDrftWeb/DeepDrftWeb.csproj b/DeepDrftWeb/DeepDrftWeb.csproj
index 5dd4e98..b64ef6f 100644
--- a/DeepDrftWeb/DeepDrftWeb.csproj
+++ b/DeepDrftWeb/DeepDrftWeb.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/DeepDrftWeb/Startup.cs b/DeepDrftWeb/Startup.cs
index 2e03d45..1331bb7 100644
--- a/DeepDrftWeb/Startup.cs
+++ b/DeepDrftWeb/Startup.cs
@@ -1,6 +1,7 @@
-using DeepDrftWeb.Services.Data;
-using DeepDrftWeb.Services.Repositories;
-using DeepDrftWeb.Services;
+using DeepDrftData;
+using DeepDrftData.Data;
+using DeepDrftData.Repositories;
+using DeepDrftWeb.Services; // DarkModeService namespace (within this host project)
using Microsoft.EntityFrameworkCore;
namespace DeepDrftWeb;
@@ -26,10 +27,14 @@ public static class Startup
.AddHttpContextAccessor()
.AddScoped();
- // Add Track services
+ // Add Track services. TrackManager implements ITrackService for backward compatibility
+ // with controllers and CMS pages that inject the interface; resolving ITrackService
+ // returns the same scoped TrackManager instance so the manager surface (DTO-space)
+ // and the service surface (entity-space) share state.
builder.Services
.AddScoped()
- .AddScoped();
+ .AddScoped()
+ .AddScoped(sp => sp.GetRequiredService());
// CMS → DeepDrftContent client. The API key is required up front (no lazy resolution)
// so a misconfiguration surfaces at startup instead of on the first delete attempt.
@@ -44,13 +49,13 @@ public static class Startup
client.DefaultRequestHeaders.Add("ApiKey", contentApiKey);
});
}
-
+
public static string GetKestrelUrl(this WebApplicationBuilder builder)
{
// Check all the places Kestrel URL can be configured
- var urls = builder.Configuration["ASPNETCORE_URLS"]
+ var urls = builder.Configuration["ASPNETCORE_URLS"]
?? builder.Configuration["urls"];
-
+
if (!string.IsNullOrEmpty(urls))
{
return urls.Split(';')[0].Trim();
@@ -60,15 +65,15 @@ public static class Startup
var kestrelSection = builder.Configuration.GetSection("Kestrel:Endpoints");
var firstEndpoint = kestrelSection.GetChildren().FirstOrDefault();
var endpointUrl = firstEndpoint?["Url"];
-
+
if (!string.IsNullOrEmpty(endpointUrl))
{
return endpointUrl;
}
// ASP.NET Core defaults
- return builder.Environment.IsDevelopment()
- ? "https://localhost:5001"
+ return builder.Environment.IsDevelopment()
+ ? "https://localhost:5001"
: "http://localhost:5000";
}
-}
\ No newline at end of file
+}
diff --git a/NuGet.Config b/NuGet.Config
index db26aa3..7bde569 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -4,5 +4,6 @@
+
diff --git a/WebAPI.sln b/WebAPI.sln
index b4ec7f9..e53d5c2 100644
--- a/WebAPI.sln
+++ b/WebAPI.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Services", "DeepDrftContent.Services\DeepDrftContent.Services.csproj", "{9C5D844B-46A6-4C70-B5A7-3A028795629C}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent.Data", "DeepDrftContent.Data\DeepDrftContent.Data.csproj", "{9C5D844B-46A6-4C70-B5A7-3A028795629C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftContent", "DeepDrftContent\DeepDrftContent.csproj", "{91F52E3A-D36D-47C3-924B-2A3CE3606B03}"
EndProject
diff --git a/WebUI.sln b/WebUI.sln
index 2571ef6..e7bf1bf 100644
--- a/WebUI.sln
+++ b/WebUI.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftWeb.Services", "DeepDrftWeb.Services\DeepDrftWeb.Services.csproj", "{0B1ABD2E-ACC4-40B2-A80E-CC47CF209C74}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftData", "DeepDrftData\DeepDrftData.csproj", "{0B1ABD2E-ACC4-40B2-A80E-CC47CF209C74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftModels", "DeepDrftModels\DeepDrftModels.csproj", "{2507F960-A210-40A3-999D-368A6D067350}"
EndProject