diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..8425170 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,52 @@ +{ + "permissions": { + "allow": [ + "Read(/F:\\Development\\DeepDrftHome/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\FileDatabase/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\Controllers/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\FileDatabase\\Services/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb\\Data/**)", + "Read(/F:\\Development\\DeepDrftHome/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\environment/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb\\Data/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels\\Entities/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb\\Services/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb\\Data\\Repositories/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client\\Clients/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client\\ViewModels/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftWeb.Client\\Controls/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\Middleware/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\Middleware/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftContent\\FileDatabase\\Services/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels\\Models/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels\\Models/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftModels\\DTOs/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)", + "Read(/F:\\Development\\DeepDrftHome\\DeepDrftTests/**)" + ], + "deny": [], + "ask": [] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 963d0cb..d707a59 100644 --- a/.gitignore +++ b/.gitignore @@ -299,4 +299,7 @@ __pycache__/ **/deepdrft.db* # NetBlocks symlink for tool-assisted library code search -**/NetBlocks \ No newline at end of file +**/NetBlocks + +# File Database files +Database/Vaults/* \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..13c8239 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,113 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Architecture Overview + +DeepDrftHome is a .NET 9 solution consisting of multiple projects that implement a dual-database media management system: + +### Core Projects +- **DeepDrftWeb**: Blazor Server/WebAssembly hybrid web application using MudBlazor UI framework +- **DeepDrftWeb.Client**: Blazor WebAssembly client components +- **DeepDrftContent**: Web API project providing content management endpoints with API key authentication +- **DeepDrftModels**: Shared data models and entities +- **DeepDrftTests**: NUnit test project with comprehensive FileDatabase tests +- **NetBlocks**: External dependency located at `C:\lib\NetBlocks\` + +### Database Architecture + +The application uses a **dual-database approach**: + +1. **SQL Database (SQLite)**: Stores metadata and track information via Entity Framework + - Located: `../Database/deepdrft.db` + - Entity: `TrackEntity` with fields for MediaPath, TrackName, Artist, Album, Genre, etc. + - Context: `DeepDrftContext` with SQLite provider + +2. **FileDatabase**: Custom file-based storage system for binary media content + - Located: `../Database/Vaults` (configurable via `filedatabase.json`) + - Manages **MediaVaults** with different types: Media, Image, Audio + - Supports structured binary storage with metadata (duration, bitrate, aspect ratio) + +### FileDatabase System Details + +The FileDatabase is the core innovation of this project: + +- **Vault-based Organization**: Content organized into typed vaults (MediaVaultType: Media, Image, Audio) +- **Index System**: Uses JSON-based indexing with DirectoryIndex and VaultIndex structures +- **Media Types**: + - `AudioBinary`: Buffer + Duration + Bitrate + Extension + - `ImageBinary`: Buffer + AspectRatio + Extension + - `MediaBinary`: Base buffer + Extension + MIME type support +- **Factory Pattern**: `MediaVaultFactory` creates appropriate vault types +- **Async Operations**: All database operations are async with error swallowing + +## Development Commands + +### Build and Test +```bash +# Build entire solution +dotnet build DeepDrftHome.sln + +# Run all tests +dotnet test DeepDrftTests/ + +# Run specific test class +dotnet test DeepDrftTests/ --filter "FileDatabaseTests" + +# Build specific project +dotnet build DeepDrftWeb/ +dotnet build DeepDrftContent/ +``` + +### Running Applications +```bash +# Run main web application +dotnet run --project DeepDrftWeb + +# Run content API +dotnet run --project DeepDrftContent +``` + +### Entity Framework (SQL Database) +```bash +# Add migration +dotnet ef migrations add MigrationName --project DeepDrftWeb + +# Update database +dotnet ef database update --project DeepDrftWeb +``` + +## Key Configuration Files + +- `DeepDrftWeb/appsettings.json`: SQL connection string, logging configuration +- `DeepDrftContent/environment/filedatabase.json`: FileDatabase vault path configuration +- `DeepDrftContent/environment/apikey.json`: API authentication (not in repo) + +## Important Patterns + +### FileDatabase Usage +```csharp +// Initialize FileDatabase +var fileDatabase = await FileDatabase.FromAsync(rootPath); + +// Register audio content +await fileDatabase.RegisterResourceAsync("tracks", trackId, audioBinary); + +// Load audio content +var audio = await fileDatabase.LoadResourceAsync("tracks", trackId); +``` + +### Dependency Injection +- FileDatabase service registration occurs in startup configuration +- SQL context registered via `AddDbContext` +- Repository pattern with `TrackRepository` and `TrackService` + +### Testing Strategy +- Comprehensive FileDatabase integration tests with temporary directories +- Uses NUnit framework with async test patterns +- Test isolation via unique temp directories per test +- Covers vault creation, media storage, and retrieval scenarios + +## Project Dependencies + +External dependencies include Entity Framework Core (SQLite), MudBlazor, and the custom NetBlocks library. The FileDatabase system is entirely custom-built and forms the backbone of the media storage architecture. \ No newline at end of file diff --git a/DeepDrftCli/CLAUDE.md b/DeepDrftCli/CLAUDE.md new file mode 100644 index 0000000..297aa22 --- /dev/null +++ b/DeepDrftCli/CLAUDE.md @@ -0,0 +1,192 @@ +# CLAUDE.md - DeepDrftCli + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftCli project. + +## Project Overview + +DeepDrftCli is a **console application** for managing audio tracks in the DeepDrft system. It provides command-line interface for adding WAV files to both the SQL database and FileDatabase, leveraging services from both DeepDrftWeb and DeepDrftContent projects. + +## Architecture + +### Technology Stack +- **.NET 9.0 Console Application**: Command-line interface +- **Microsoft.Extensions.Hosting**: Dependency injection and configuration +- **Entity Framework Core**: SQL database operations via DeepDrftWeb +- **FileDatabase**: Binary storage via DeepDrftContent + +### Project Structure +``` +DeepDrftCli/ +├── Services/ +│ ├── CliService.cs # Main CLI command handler +│ └── [Processors moved to DeepDrftContent] +├── Program.cs # Application entry point with DI setup +├── appsettings.json # Configuration +└── DeepDrftCli.csproj # Project file with references +``` + +### Service Dependencies +- **DeepDrftWeb**: SQL database operations, TrackService, TrackRepository +- **DeepDrftContent**: FileDatabase, AudioProcessor (in /Processors) +- **DeepDrftModels**: Shared entities and DTOs +- **NetBlocks**: Result pattern (ResultContainer) + +## Audio Processing Architecture + +### AudioProcessor (DeepDrftContent/Processors/) +Handles WAV file processing with full metadata extraction: +```csharp +public async Task ProcessWavFileAsync(string filePath) +{ + // WAV header parsing for duration, bitrate, sample rate + // Creates AudioBinary with extracted metadata +} +``` + +### TrackService (DeepDrftContent/Services/) +Orchestrates dual-database operations: +```csharp +public async Task AddTrackFromWavAsync( + string wavFilePath, string trackName, string artist, ...) +{ + // 1. Process WAV file → AudioBinary + // 2. Store in FileDatabase → get trackId + // 3. Create TrackEntity with MediaPath = trackId + // 4. Return entity for SQL storage +} +``` + +## Command-Line Interface + +### Available Commands + +#### Add Track +```bash +DeepDrftCli add [album] [genre] [release-date] +``` +**Example:** +```bash +DeepDrftCli add "mysong.wav" "My Song" "Artist Name" "Album" "Rock" "2024-01-01" +``` + +#### List Tracks +```bash +DeepDrftCli list +``` +Shows all tracks from SQL database with formatted table output. + +#### Help +```bash +DeepDrftCli help +# or +DeepDrftCli --help +# or +DeepDrftCli -h +``` + +## Development Commands + +### Building +```bash +# Build CLI project +dotnet build DeepDrftCli/ + +# Build entire solution +dotnet build DeepDrftHome.sln +``` + +### Running +```bash +# Run from project directory +cd DeepDrftCli +dotnet run -- add "song.wav" "Track Name" "Artist" + +# Run from solution root +dotnet run --project DeepDrftCli -- list + +# Run built executable +./DeepDrftCli/bin/Debug/net9.0/DeepDrftCli.exe add "song.wav" "Track" "Artist" +``` + +### Database Requirements +Ensure databases exist and are accessible: +```bash +# SQL Database: ../Database/deepdrft.db +# FileDatabase: ../Database/Vaults +``` + +## Configuration + +### appsettings.json +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=../Database/deepdrft.db" + }, + "FileDatabaseSettings": { + "VaultPath": "../Database/Vaults" + } +} +``` + +### Dependency Injection Setup +Program.cs configures full DI container: +- **SQL Context**: DeepDrftContext with SQLite +- **FileDatabase**: Singleton initialized from vault path +- **Services**: TrackRepository, TrackServices (both Web and Content), AudioProcessor +- **Logging**: Console logging for development + +## Important Patterns + +### Result Pattern (NetBlocks) +All service operations return ResultContainer: +```csharp +var result = await _webTrackService.Create(trackEntity); +if (result.Success && result.Value != null) +{ + // Success handling +} +else +{ + var errorMessage = result.Messages.FirstOrDefault()?.Message ?? "Unknown error"; + // Error handling +} +``` + +### Dual Database Strategy +1. **Process WAV** → AudioBinary (metadata + buffer) +2. **Store in FileDatabase** → generates unique trackId +3. **Create TrackEntity** with MediaPath = trackId +4. **Store in SQL** → gets database ID and full entity + +### WAV File Processing +- **RIFF/WAVE format parsing**: Header validation and chunk parsing +- **Metadata extraction**: Duration, bitrate, sample rate, channels +- **Fallback handling**: Default values if parsing fails +- **Binary preservation**: Full WAV file stored as-is + +### Error Handling +- **File validation**: Existence and .wav extension checking +- **Graceful degradation**: Default metadata if parsing fails +- **User-friendly messages**: Clear error reporting for CLI users +- **Logging integration**: Structured logging for debugging + +## CLI Usage Notes + +### File Path Handling +- Supports absolute and relative paths +- Arguments with spaces must be quoted +- Only .wav files are supported currently + +### Date Format +Release dates must be in YYYY-MM-DD format: +```bash +DeepDrftCli add "song.wav" "Title" "Artist" "Album" "Genre" "2024-01-01" +``` + +### Output Format +- Success: Detailed track information display +- List: Formatted table with ID, Name, Artist, Album, Genre +- Errors: Clear, actionable error messages + +When working with this project, focus on maintaining the dual-database consistency and the established patterns for CLI argument handling and user feedback. \ No newline at end of file diff --git a/DeepDrftContent/CLAUDE.md b/DeepDrftContent/CLAUDE.md new file mode 100644 index 0000000..be173f3 --- /dev/null +++ b/DeepDrftContent/CLAUDE.md @@ -0,0 +1,187 @@ +# CLAUDE.md - DeepDrftContent + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftContent project. + +## Project Overview + +DeepDrftContent is a **Web API project** that serves as the content management backend for the DeepDrft system. It provides secure API endpoints for managing the FileDatabase system and handles binary media content storage and retrieval. + +## Architecture + +### Technology Stack +- **ASP.NET Core Web API 9.0**: RESTful API framework +- **Custom FileDatabase System**: Binary file storage with vault management +- **API Key Authentication**: Secure endpoint protection +- **OpenAPI/Swagger**: Development API documentation + +### Project Structure +``` +DeepDrftContent/ +├── Controllers/ # API endpoint controllers +│ ├── TrackController.cs # Track media management +│ └── WeatherForecastController.cs # Demo endpoint +├── FileDatabase/ # Core FileDatabase implementation +│ ├── Services/ # Database and vault services +│ ├── Models/ # Data models and DTOs +│ ├── Utils/ # Utility classes +│ └── Abstractions/ # Interfaces and contracts +├── Middleware/ # Custom middleware +│ ├── ApiKeyAuthenticationMiddleware.cs +│ └── ApiKeyAuthorizeAttribute.cs +├── Models/ # Application models +├── environment/ # Configuration files +│ ├── filedatabase.json # FileDatabase settings +│ └── apikey.json # API authentication (not in repo) +└── Program.cs # Application entry point +``` + +## Core FileDatabase System + +### Key Components + +#### FileDatabase Service +Main orchestration class managing multiple MediaVaults: +```csharp +public class FileDatabase : DirectoryIndexDirectory +{ + // Factory creation + public static async Task FromAsync(string rootPath) + + // Vault management + public async Task CreateVaultAsync(string vaultId, MediaVaultType vaultType) + public MediaVault? GetVault(string vaultId) + + // Resource operations + public async Task LoadResourceAsync(string vaultId, string entryId) where T : FileBinary + public async Task RegisterResourceAsync(string vaultId, string entryId, FileBinary media) +} +``` + +#### MediaVault Types +- **MediaVaultType.Media**: General binary media storage +- **MediaVaultType.Audio**: Audio-specific storage with duration/bitrate +- **MediaVaultType.Image**: Image storage with aspect ratio + +#### Media Models Hierarchy +``` +FileBinary (base) +├── MediaBinary (+ Extension, MIME type) + ├── AudioBinary (+ Duration, Bitrate) + └── ImageBinary (+ AspectRatio) +``` + +### Index System +- **DirectoryIndex**: Manages vault organization +- **VaultIndex**: Individual vault metadata and type information +- **JSON-based storage**: All indexes stored as JSON files + +## API Authentication + +### Custom API Key Middleware +```csharp +// Usage in controllers +[ApiKeyAuthorize] +[HttpPut("{trackId}")] +public async Task PutTrack([FromQuery] string trackId, [FromBody] AudioBinaryDto track) +``` + +### Authentication Flow +1. Client sends request with `ApiKey` header +2. `ApiKeyAuthenticationMiddleware` validates against configured key +3. Endpoints marked with `[ApiKeyAuthorize]` require valid API key +4. Returns 401 for missing/invalid keys + +## Development Commands + +### Running the API +```bash +# Run development server +dotnet run --project DeepDrftContent + +# Run with specific environment +dotnet run --project DeepDrftContent --environment Development +``` + +### Building +```bash +# Build project +dotnet build DeepDrftContent + +# Publish for deployment +dotnet publish DeepDrftContent -c Release +``` + +### Testing FileDatabase +```bash +# Run FileDatabase-specific tests +dotnet test DeepDrftTests/ --filter "FileDatabaseTests" +``` + +## Configuration + +### FileDatabase Settings +`environment/filedatabase.json`: +```json +{ + "FileDatabaseSettings": { + "VaultPath": "../Database/Vaults" + } +} +``` + +### API Key Configuration +`environment/apikey.json` (not in repository): +```json +{ + "ApiKeySettings": { + "ApiKey": "your-secret-api-key" + } +} +``` + +## Key Patterns + +### Factory Pattern +MediaVault creation uses factory pattern: +```csharp +var directoryVault = await MediaVaultFactory.From(path, vaultType); +``` + +### Async/Await Throughout +All FileDatabase operations are async with consistent error handling: +```csharp +// Swallow exceptions and return null/false for failed operations +try { /* operation */ } +catch { return null; } // or return false; +``` + +### Type-Safe Media Handling +Generic methods ensure type safety for media operations: +```csharp +var audio = await fileDatabase.LoadResourceAsync("tracks", trackId); +``` + +### MIME Type Management +Automatic extension/MIME type conversion via `MimeTypeExtensions`: +```csharp +// Supported audio formats: mp3, wav, flac, aac, ogg, m4a +// Supported image formats: jpg, png, gif, webp, svg, bmp +``` + +## Important Notes + +### Vault Organization +- Each vault is a directory with its own index +- Entry IDs are sanitized to create safe filenames +- Media keys generated via regex: `[^a-zA-Z0-9]` → `-` + +### Error Handling Philosophy +FileDatabase uses "swallow and return null" pattern to match TypeScript behavior: +- Failed operations return `null` or `false` +- No exceptions propagated to callers +- Consistent behavior across all async operations + +### Binary Data Handling +All media stored as `byte[]` buffers with associated metadata (size, extension, duration, etc.) + +When working with this project, focus on the FileDatabase system architecture and maintain the established patterns for vault management, async operations, and API security. \ No newline at end of file diff --git a/DeepDrftModels/CLAUDE.md b/DeepDrftModels/CLAUDE.md new file mode 100644 index 0000000..430ca0c --- /dev/null +++ b/DeepDrftModels/CLAUDE.md @@ -0,0 +1,163 @@ +# CLAUDE.md - DeepDrftModels + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftModels project. + +## Project Overview + +DeepDrftModels is a **shared models library** that defines common data structures, entities, DTOs, and model classes used across the entire DeepDrft solution. It serves as the data contract layer between all projects. + +## Architecture + +### Technology Stack +- **.NET 9.0 Class Library**: Shared library targeting .NET 9 +- **Entity Framework Compatible**: Entities work with EF Core +- **JSON Serializable**: Models support JSON serialization for APIs + +### Project Structure +``` +DeepDrftModels/ +├── Entities/ # Database entities +│ └── TrackEntity.cs # Core track data model +├── DTOs/ # Data Transfer Objects +│ └── TrackDto.cs # Track DTO for API transfers +├── Models/ # Shared model classes +│ ├── PagingParameters.cs # Pagination configuration +│ └── PagedResult.cs # Paginated result wrapper +└── DeepDrftModels.csproj # Project file +``` + +## Core Models + +### TrackEntity +Primary database entity for track metadata: +```csharp +public class TrackEntity +{ + public long Id { get; set; } // Primary key + public required string MediaPath { get; set; } // FileDatabase vault reference + public required string TrackName { get; set; } // Track title + public required string Artist { get; set; } // Artist name + public string? Album { get; set; } // Optional album + public string? Genre { get; set; } // Optional genre + public DateOnly? ReleaseDate { get; set; } // Optional release date + public string? ImagePath { get; set; } // Optional cover image path +} +``` + +### TrackDto +Data transfer object matching TrackEntity structure for API operations: +- Mirrors all TrackEntity properties +- Used for JSON serialization/deserialization +- Client-server data exchange + +## Pagination System + +### PagingParameters +Generic pagination configuration with LINQ expression support: +```csharp +public class PagingParameters : PagingParameters +{ + public Expression>? OrderBy { get; set; } // Sorting expression + public bool IsDescending { get; set; } = false; // Sort direction + public int Skip => (Page - 1) * PageSize; // Calculated skip count +} +``` + +### PagingParameters +Base pagination class with size constraints: +```csharp +public class PagingParameters +{ + public int Page { get; set; } = 1; // Current page (1-based) + public int PageSize { get; set; } = 20; // Items per page (max 100) +} +``` + +### PagedResult +Container for paginated data with metadata: +```csharp +public class PagedResult +{ + public IEnumerable Items { get; set; } // Page items + public int TotalCount { get; set; } // Total items available + public int Page { get; set; } // Current page + public int PageSize { get; set; } // Items per page + + // Calculated properties + public int TotalPages { get; } // Total pages available + public bool HasNextPage { get; } // Can navigate forward + public bool HasPreviousPage { get; } // Can navigate backward +} +``` + +## Key Patterns + +### Required Properties +Uses C# required modifier for essential properties: +```csharp +public required string MediaPath { get; set; } // Compile-time requirement +``` + +### Nullable Reference Types +Explicit nullability throughout: +```csharp +public string? Album { get; set; } // Optional nullable +public required string Artist { get; set; } // Required non-null +``` + +### Generic Type Conversion +PagedResult supports type transformation: +```csharp +public static PagedResult From(PagedResult other, IEnumerable items) +``` + +### Expression-Based Sorting +Type-safe LINQ expressions for dynamic sorting: +```csharp +parameters.OrderBy = entity => entity.TrackName; // Compile-time checked +``` + +## Integration Points + +### Entity Framework +- `TrackEntity` configured for EF Core in `DeepDrftWeb.Data.Configurations` +- Long Id as primary key for SQLite compatibility +- DateOnly support for release dates + +### API Serialization +- All models JSON-serializable for web API usage +- DTO pattern separates data transfer from domain models + +### Cross-Project Usage +Referenced by: +- **DeepDrftWeb**: Entity Framework, services, repositories +- **DeepDrftWeb.Client**: API client communication +- **DeepDrftContent**: API DTOs (potential future usage) +- **DeepDrftTests**: Test data and assertions + +## External Dependencies + +### NetBlocks Library +Some projects reference `NetBlocks.Models` for: +- `ResultContainer`: Consistent result handling pattern +- `ApiResult`: API response wrapper +- `Result`: Simple operation result + +## Development Notes + +### Page Size Limits +Maximum page size enforced at 100 items to prevent performance issues: +```csharp +set => _pageSize = value > _maxPageSize ? _maxPageSize : value; +``` + +### 1-Based Pagination +Page numbers start at 1 (not 0) following common UI patterns: +```csharp +public int Skip => (Page - 1) * PageSize; // Convert to 0-based for queries +``` + +### Immutable Design +Models favor immutability where possible, using init-only properties and required fields. + +When working with this project, maintain consistency in data models across the solution and preserve the established patterns for pagination, nullability, and type safety. \ No newline at end of file diff --git a/DeepDrftTests/CLAUDE.md b/DeepDrftTests/CLAUDE.md new file mode 100644 index 0000000..24505e8 --- /dev/null +++ b/DeepDrftTests/CLAUDE.md @@ -0,0 +1,217 @@ +# CLAUDE.md - DeepDrftTests + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftTests project. + +## Project Overview + +DeepDrftTests is a **comprehensive test suite** using **NUnit framework** that validates the FileDatabase system and related components. The tests follow SOLID principles and provide extensive coverage of the custom FileDatabase functionality. + +## Architecture + +### Technology Stack +- **NUnit 4.2.2**: Testing framework with modern async support +- **NUnit3TestAdapter**: Visual Studio test adapter +- **.NET 9.0**: Latest framework features +- **Coverlet**: Code coverage collection + +### Project Structure +``` +DeepDrftTests/ +├── FileDatabaseTests.cs # Main FileDatabase integration tests +├── MediaVaultTests.cs # MediaVault component tests +├── MediaVaultFactoryTests.cs # Factory pattern tests +├── IndexSystemTests.cs # Index management tests +├── SimpleMediaTypeRegistryTests.cs # Media type registry tests +├── UtilityTests.cs # Utility class tests +├── ModelTests.cs # Model validation tests +├── TestData.cs # Shared test data and helpers +├── environment/ # Test configuration files +│ └── filedatabase.json # FileDatabase test settings +└── DeepDrftTests.csproj # Project configuration +``` + +## Test Organization + +### SOLID Principles Implementation +Tests follow SOLID design principles: + +- **Single Responsibility**: Each test class focuses on one component +- **Open/Closed**: Base test classes allow extension without modification +- **Liskov Substitution**: All vault implementations tested consistently +- **Interface Segregation**: Tests through abstractions where possible +- **Dependency Inversion**: Tests depend on abstractions, not concretions + +### DRY Pattern with Base Classes +```csharp +// Base class eliminates test setup duplication +public abstract class MediaVaultTestBase +{ + protected string TestDirectory { get; private set; } + + [SetUp] public virtual void SetUp() { /* Common setup */ } + [TearDown] public virtual void TearDown() { /* Common cleanup */ } +} +``` + +## Key Test Classes + +### FileDatabaseTests +**Core integration tests** for the main FileDatabase functionality: +- Database creation and initialization +- Vault management (create, retrieve, check existence) +- Resource operations (register, load, type safety) +- Multi-vault scenarios and error handling + +### MediaVaultTests +**Component tests** for individual MediaVault implementations: +- Entry storage and retrieval +- Media type handling (Audio, Image, Media) +- File path sanitization +- Index maintenance + +### IndexSystemTests +**Index management** validation: +- DirectoryIndex creation and persistence +- VaultIndex type management +- JSON serialization/deserialization +- Index factory service operations + +### MediaVaultFactoryTests +**Factory pattern** validation: +- Vault creation for different MediaVaultTypes +- Path handling and directory creation +- Type-specific vault instantiation + +## Test Data Management + +### TestData Class +Centralized test data and helper methods: + +```csharp +public static class TestData +{ + // Real PNG bytes for authentic image testing + public static readonly byte[] TestPngBytes = [...]; + + // Factory methods for test objects + public static ImageBinary CreateTestImageBinary(double aspectRatio = 1.0) + public static AudioBinary CreateTestAudioBinary(double duration = 120.0, int bitrate = 320) + + // Consistent test keys + public static class TestKeys + { + public const string TestImageEntry = "test"; + public const string ImageVaultKey = "img"; + public const MediaVaultType ImageVaultType = MediaVaultType.Image; + } +} +``` + +## Development Commands + +### Running All Tests +```bash +# Run entire test suite +dotnet test DeepDrftTests/ + +# Run with detailed output +dotnet test DeepDrftTests/ --verbosity normal + +# Run with code coverage +dotnet test DeepDrftTests/ --collect:"XPlat Code Coverage" +``` + +### Running Specific Tests +```bash +# Run FileDatabase tests only +dotnet test DeepDrftTests/ --filter "FileDatabaseTests" + +# Run specific test method +dotnet test DeepDrftTests/ --filter "FileDatabase_CanBeCreatedAtSpecifiedLocation" + +# Run tests by category +dotnet test DeepDrftTests/ --filter "Category=Integration" +``` + +### Build and Clean +```bash +# Build test project +dotnet build DeepDrftTests/ + +# Clean test outputs +dotnet clean DeepDrftTests/ +``` + +## Test Isolation Strategy + +### Temporary Directory Management +Each test uses isolated temporary directories: +```csharp +_testDatabasePath = Path.Combine(Path.GetTempPath(), "DeepDrftTests", Guid.NewGuid().ToString()); +``` + +### Setup and Cleanup Pattern +```csharp +[SetUp] +public void SetUp() +{ + // Create unique test directory + Directory.CreateDirectory(_testDatabasePath); +} + +[TearDown] +public void TearDown() +{ + // Clean up test directory (with error tolerance) + try { Directory.Delete(_testDatabasePath, true); } + catch { /* Ignore cleanup errors */ } +} +``` + +## Testing Patterns + +### Async Test Methods +All database operations tested with async/await: +```csharp +[Test] +public async Task FileDatabase_CanRegisterAndRetrieveAudio() +{ + var fileDatabase = await FileDatabase.FromAsync(_testDatabasePath); + // ... async operations +} +``` + +### Type-Safe Media Testing +Generic type parameters ensure type safety: +```csharp +var audio = await fileDatabase.LoadResourceAsync("tracks", trackId); +Assert.That(audio, Is.Not.Null); +Assert.That(audio.Duration, Is.EqualTo(120.0)); +``` + +### Error Scenario Coverage +Tests validate error handling patterns: +- Non-existent vaults return null +- Invalid entry IDs return null +- File system errors are handled gracefully + +## Important Testing Principles + +### Authentic Test Data +Uses real PNG bytes instead of mock data for realistic testing scenarios. + +### Comprehensive Coverage +Tests cover: +- Happy path scenarios +- Edge cases and error conditions +- Type safety and generics +- Async operation patterns +- File system interactions + +### Performance Considerations +Tests are designed for speed: +- Minimal test data sizes +- Parallel test execution support +- Efficient cleanup strategies + +When working with this test project, maintain the established patterns for test isolation, async operations, and comprehensive coverage of the FileDatabase system. \ No newline at end of file diff --git a/DeepDrftWeb.Client/CLAUDE.md b/DeepDrftWeb.Client/CLAUDE.md new file mode 100644 index 0000000..02b8724 --- /dev/null +++ b/DeepDrftWeb.Client/CLAUDE.md @@ -0,0 +1,146 @@ +# CLAUDE.md - DeepDrftWeb.Client + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftWeb.Client project. + +## Project Overview + +DeepDrftWeb.Client is a **Blazor WebAssembly** client project that provides interactive UI components for the DeepDrft music management system. It runs in the browser and communicates with the server-side DeepDrftWeb application. + +## Architecture + +### Technology Stack +- **Blazor WebAssembly**: Client-side .NET runtime in browser +- **MudBlazor**: Material Design UI components +- **HttpClient**: API communication with server +- **ASP.NET Core 9.0**: Framework components + +### Project Structure +``` +DeepDrftWeb.Client/ +├── Pages/ # Routable page components +│ ├── Home.razor # Home page +│ ├── Counter.razor # Demo counter page +│ ├── Weather.razor # Demo weather page +│ └── TracksView.razor # Main tracks interface +├── Controls/ # Reusable UI components +│ ├── TracksGallery.razor # Grid layout for tracks +│ └── TrackPlayer.razor # Individual track player +├── Layout/ # Layout components +│ ├── MainLayout.razor # Primary layout +│ └── NavMenu.razor # Navigation menu +├── Clients/ # HTTP API clients +├── ViewModels/ # Component view models +├── wwwroot/ # Static web assets +└── Program.cs # WebAssembly entry point +``` + +## Key Patterns + +### MVVM Pattern +Components use ViewModels for data management and business logic separation: +```csharp +// TracksViewModel.cs - Manages tracks data and pagination +public class TracksViewModel +{ + public PagedResult? Page { get; set; } + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } + public string SortBy { get; set; } + public bool IsDescending { get; set; } +} +``` + +### HTTP Client Pattern +API communication through dedicated client classes: +```csharp +// TrackClient.cs - Handles track-related API calls +public async Task>> GetPage( + int pageNumber, int pageSize, string? sortColumn = null, bool sortDescending = false) +``` + +### Component Architecture +- **Pages**: Routable components (URL endpoints) +- **Controls**: Reusable components with parameters +- **Layout**: Shared layout structures + +## Key Components + +### TracksGallery.razor +Grid-based track display using MudBlazor responsive grid: +```razor + + @foreach (var track in Tracks) + { + + + + } + +``` + +### TrackPlayer.razor +Individual track player component with audio controls and track information display. + +### TracksView.razor +Main tracks management interface combining gallery view with pagination and sorting controls. + +## Development Commands + +### Building +```bash +# Build WebAssembly project +dotnet build DeepDrftWeb.Client + +# Publish for production +dotnet publish DeepDrftWeb.Client -c Release +``` + +### Running +The client runs as part of the DeepDrftWeb host application: +```bash +# Run from DeepDrftWeb (hosts the client) +dotnet run --project DeepDrftWeb +``` + +## Configuration + +### Service Registration +Services registered in `Startup.ConfigureDomainServices()`: +```csharp +// Clients for API communication +builder.Services.AddTransient(); + +// ViewModels for component state management +builder.Services.AddTransient(); +``` + +### HTTP Client Setup +Configured to communicate with the hosting DeepDrftWeb server: +- Uses dependency injection for HttpClient +- JSON serialization with case-insensitive property matching +- Query string building for API parameters + +## Important Patterns + +### API Communication +All API calls use the established result pattern: +- `ApiResult` for typed responses +- JSON deserialization with `JsonSerializer` +- Query string construction for GET parameters + +### MudBlazor Integration +- Responsive grid system (`MudGrid`, `MudItem`) +- Breakpoint-aware layout (xs, sm, md, lg, xl) +- Material Design components throughout + +### Component Parameters +Components accept parameters for data binding: +```razor +[Parameter] public List Tracks { get; set; } = []; +[Parameter] public TrackEntity Track { get; set; } = null!; +``` + +### State Management +ViewModels handle component state, pagination, and sorting logic, keeping components focused on presentation. + +When working with this project, maintain the separation between presentation (Razor components) and logic (ViewModels/Clients), and follow the established MudBlazor patterns for responsive UI design. \ No newline at end of file diff --git a/DeepDrftWeb/CLAUDE.md b/DeepDrftWeb/CLAUDE.md new file mode 100644 index 0000000..6f770f1 --- /dev/null +++ b/DeepDrftWeb/CLAUDE.md @@ -0,0 +1,145 @@ +# CLAUDE.md - DeepDrftWeb + +This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftWeb project. + +## Project Overview + +DeepDrftWeb is the main web application using **Blazor Server/WebAssembly hybrid** architecture with **MudBlazor** UI framework. It serves as the front-end interface for the DeepDrft music management system. + +## Architecture + +### Technology Stack +- **Blazor Hybrid**: Interactive Server + WebAssembly components +- **MudBlazor**: Material Design UI framework +- **Entity Framework Core**: SQLite database access +- **ASP.NET Core 9.0**: Web framework + +### Project Structure +``` +DeepDrftWeb/ +├── Components/ # Blazor components (.razor files) +│ ├── App.razor # Root application component +│ ├── Pages/ # Page components +│ └── _Imports.razor # Global using statements +├── Controllers/ # MVC API controllers +├── Data/ # Database layer +│ ├── DeepDrftContext.cs # EF DbContext +│ ├── Configurations/ # EF configurations +│ ├── Migrations/ # EF migrations +│ └── Repositories/ # Data access layer +├── Services/ # Business logic layer +└── Program.cs # Application entry point +``` + +## Key Patterns + +### Service Architecture +```csharp +// Three-layer pattern: Controller → Service → Repository +TrackController → TrackService → TrackRepository → DeepDrftContext +``` + +### Result Pattern +All service methods return `ResultContainer` or `Result` for consistent error handling: +```csharp +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); + } +} +``` + +### Paging Support +Uses `PagingParameters` and `PagedResult` from DeepDrftModels for consistent pagination: +```csharp +var parameters = new PagingParameters() +{ + Page = pageNumber, + PageSize = pageSize, + OrderBy = entity => entity.TrackName, + IsDescending = sortDescending +}; +``` + +## Development Commands + +### Running the Application +```bash +# Run web application +dotnet run --project DeepDrftWeb + +# Watch for changes during development +dotnet watch run --project DeepDrftWeb +``` + +### Entity Framework +```bash +# Add migration +dotnet ef migrations add MigrationName --project DeepDrftWeb + +# Update database +dotnet ef database update --project DeepDrftWeb + +# Drop database +dotnet ef database drop --project DeepDrftWeb +``` + +### Building +```bash +# Build project +dotnet build DeepDrftWeb + +# Clean build +dotnet clean DeepDrftWeb && dotnet build DeepDrftWeb +``` + +## Configuration + +### Database Connection +- **Connection String**: `appsettings.json` → `ConnectionStrings.DefaultConnection` +- **Database Location**: `../Database/deepdrft.db` (SQLite) +- **Context**: `DeepDrftContext` with `TrackEntity` DbSet + +### Service Registration +Key services registered in `Startup.ConfigureDomainServices()`: +- `DeepDrftContext` (EF DbContext) +- `TrackRepository` (Scoped) +- `TrackService` (Scoped) + +### HttpClient Setup +Configured for API communication with DeepDrftContent: +```csharp +builder.Services.AddHttpClient("DeepDrft.API", client => + client.BaseAddress = new Uri(Startup.GetKestrelUrl(builder))); +``` + +## Important Notes + +### Blazor Hybrid Architecture +- Server-side rendering with interactive components +- WebAssembly components from `DeepDrftWeb.Client` +- Shared assemblies for interactive modes + +### MudBlazor Integration +- UI framework providing Material Design components +- Registered via `builder.Services.AddMudServices()` + +### Repository Pattern +- Clean separation of concerns +- Async operations throughout +- CRUD operations for TrackEntity + +### URL Configuration +Dynamic URL resolution via `Startup.GetKestrelUrl()` supporting: +- `ASPNETCORE_URLS` environment variable +- `Kestrel:Endpoints` configuration +- Development defaults (https://localhost:5001) + +When working with this project, focus on maintaining the established patterns for service layer interaction, result handling, and Blazor component structure. \ No newline at end of file