docs: update CLAUDE.md files for DeepDrftPublic simplification

This commit is contained in:
Daniel Harvey
2026-05-25 17:33:32 -04:00
parent 068205a84e
commit 708836a169
4 changed files with 35 additions and 55 deletions
+6 -6
View File
@@ -8,12 +8,12 @@ DeepDrftHome is a **net10.0** solution consisting of ten projects implementing a
### Core Projects
- **DeepDrftPublic**: ASP.NET Core host. Blazor Web App with Server + WASM render modes. Owns the SQL-backed `api/track/page` endpoint, MudBlazor theme prerender, and TypeScript→JS audio interop. Public-facing site for listeners.
- **DeepDrftPublic**: ASP.NET Core host. Blazor Web App with Server + WASM render modes. Pure Blazor host with no data layer; fetches track metadata from DeepDrftAPI via HTTP. Owns MudBlazor theme prerender and TypeScript→JS audio interop. Public-facing site for listeners.
- **DeepDrftPublic.Client**: Blazor WebAssembly assembly. All interactive UI (pages, player stack, dark-mode plumbing, HTTP clients for both backends). Consumed by the public site.
- **DeepDrftManager**: ASP.NET Core host. Blazor Web App with server-rendered `InteractiveServer` render mode. Hosts all CMS Razor components and pages under `Components/Pages/Cms/`, `Components/Pages/Tracks/`, `Components/Layout/CmsLayout.razor`, and `Components/Shared/` (all inlined from the former `DeepDrftCms` RCL). Gated by AuthBlocks login and hierarchical `Admin` role authorization. All track operations (upload, metadata read/write, delete) are HTTP proxies via `ICmsTrackService` / `CmsTrackService` injected directly into Blazor components; no in-process data layer.
- **DeepDrftShared.Client**: Razor Class Library. Shared Blazor components consumed by both `DeepDrftPublic` and `DeepDrftManager` for consistency across public and admin surfaces.
- **DeepDrftData**: Class library. EF Core domain logic: `DeepDrftContext`, `TrackConfiguration`, `Migrations`, `TrackRepository`, `TrackService`, `TrackManager`. Consumed by `DeepDrftAPI`, `DeepDrftPublic`, and tests.
- **DeepDrftAPI**: ASP.NET Core host. Dual-database authority (SQL metadata + FileDatabase binary). AuthBlocks API host (owns registration, migration/seed, JWT endpoints). Seven track endpoints: `GET api/track/{id}` unauthenticated streaming; `PUT api/track/{id}` vault write (ApiKey); `POST api/track/upload` upload + SQL persist (ApiKey); `DELETE api/track/{id:long}` SQL delete + vault remove (ApiKey); `GET api/track/page` paged metadata list (ApiKey); `GET api/track/meta/{id:long}` single metadata (ApiKey); `PUT api/track/meta/{id:long}` metadata update (ApiKey).
- **DeepDrftData**: Class library. EF Core domain logic: `DeepDrftContext`, `TrackConfiguration`, `Migrations`, `TrackRepository`, `TrackService`, `TrackManager`. Consumed by `DeepDrftAPI` and tests.
- **DeepDrftAPI**: ASP.NET Core host. Dual-database authority (SQL metadata + FileDatabase binary). AuthBlocks API host (owns registration, migration/seed, JWT endpoints). Seven track endpoints: `GET api/track/{id}` unauthenticated streaming; `PUT api/track/{id}` vault write (ApiKey); `POST api/track/upload` upload + SQL persist (ApiKey); `DELETE api/track/{id:long}` SQL delete + vault remove (ApiKey); `GET api/track/page` paged metadata list (unauthenticated); `GET api/track/meta/{id:long}` single metadata (ApiKey); `PUT api/track/meta/{id:long}` metadata update (ApiKey).
- **DeepDrftContent**: Class library. The FileDatabase implementation in full (Models, Services, Utils, Abstractions, Constants), `WavOffsetService`, `AudioProcessor`, content-side `TrackService`. Consumed by hosts and tests.
- **DeepDrftModels**: Shared contracts. `TrackEntity`, `TrackDto`, `PagingParameters<T>`, `PagedResult<T>`. Every project references this.
- **DeepDrftTests**: NUnit test suite. Comprehensive FileDatabase tests (vault creation, media storage, indexing, factory patterns, utilities). Integration-focused with temp-directory test isolation.
@@ -26,8 +26,8 @@ External: **NetBlocks** (absolute path `C:\lib\NetBlocks\`). Provides `Result`,
```
DeepDrftPublic.Client (WASM)
├── HttpClient "DeepDrft.API" ──► DeepDrftPublic host ──► EF Core / SQLite (metadata)
└── HttpClient "DeepDrft.Content" ──► DeepDrftContent ──► FileDatabase / disk (binary)
├── HttpClient "DeepDrft.API" ──► DeepDrftAPI ──► EF Core / SQLite (metadata)
└── HttpClient "DeepDrft.Content" ──► DeepDrftAPI ──► FileDatabase / disk (binary)
```
1. **SQL Database (SQLite)**: Metadata and track info via Entity Framework
@@ -120,7 +120,7 @@ dotnet ef database update --project DeepDrftData --startup-project DeepDrftPubli
All projects load secrets via `CredentialTools.ResolvePathOrThrow()` from gitignored `environment/` files:
- `DeepDrftPublic/appsettings.json`: Logging and URL config. Secrets loaded from `environment/connections.json` (SQL connection string).
- `DeepDrftPublic/appsettings.json`: Logging and URL config (DeepDrftAPI base URL). No secrets file dependency.
- `DeepDrftManager/appsettings.json`: Logging and URL config. Secrets loaded from `environment/api.json` (DeepDrftAPI base URL and API key).
- `DeepDrftAPI/appsettings.json`: Logging and hosting config. Secrets loaded from `environment/filedatabase.json` (FileDatabase vault path), `environment/apikey.json` (API key), `environment/connections.json` (SQL and Auth connection strings), `environment/authblocks.json` (AuthBlocks JWT/email/admin creds).
+10 -15
View File
@@ -6,11 +6,11 @@ See the root `CLAUDE.md` for full architecture overview. This file covers what i
## One-line purpose
SQL-side domain logic for tracks. EF Core context, configurations, migrations, repository, manager, design-time factory. Consumed by `DeepDrftContent` (the dual-database authority), `DeepDrftPublic` (the public API), and `DeepDrftCli` (the admin CLI).
SQL-side domain logic for tracks. EF Core context, configurations, migrations, repository, manager, design-time factory. Consumed by `DeepDrftAPI` (the dual-database authority) and tests.
## Why this project exists
Separating domain logic from hosts so multiple consumers (CLI, public API, content API) can reuse `TrackManager` / `TrackRepository` / `DeepDrftContext` without referencing the ASP.NET hosts directly. The CLI is a local admin tool; the APIs proxy these services over HTTP.
Separating domain logic from hosts so DeepDrftAPI can reuse `TrackManager` / `TrackRepository` / `DeepDrftContext` without embedding them directly in the host. Tests also consume this library.
**New SQL-side domain code goes here, not in the host projects.**
@@ -131,16 +131,14 @@ Migrations live in the `DeepDrftData.Migrations` namespace. Migration files are
## Connection string
- **DeepDrftPublic**: `appsettings.json``ConnectionStrings:DefaultConnection`
- **DeepDrftContent**: `environment/connections.json``ConnectionStrings:DefaultConnection`
- **DeepDrftCli**: `environment/connections.json``CliSettings:ConnectionString`
- All point at the same database (PostgreSQL in production, SQLite for local development).
- **DeepDrftAPI**: `environment/connections.json``ConnectionStrings:DefaultConnection`
- Points at the same database (PostgreSQL in production, SQLite for local development).
The design-time factory hard-codes the local path for `dotnet ef` commands.
## Service registration
In `DeepDrftContent/Program.cs`, `DeepDrftPublic/Program.cs`, and `DeepDrftCli/Program.cs`:
In `DeepDrftAPI/Program.cs`:
```csharp
services.AddDbContext<DeepDrftContext>(options =>
@@ -150,7 +148,7 @@ services.AddScoped<TrackManager>();
services.AddScoped<ITrackService>(sp => sp.GetRequiredService<TrackManager>());
```
This pattern allows callers to depend on `ITrackService` (the public interface) without knowing about `TrackManager` (the implementation). `DeepDrftContent` also registers `UnifiedTrackService` for dual-database orchestration.
This pattern allows callers to depend on `ITrackService` (the public interface) without knowing about `TrackManager` (the implementation).
## Important patterns
@@ -166,16 +164,13 @@ This pattern allows callers to depend on `ITrackService` (the public interface)
dotnet build DeepDrftData
# Add migration (from solution root)
dotnet ef migrations add MigrationName --project DeepDrftData --startup-project DeepDrftPublic
dotnet ef migrations add MigrationName --project DeepDrftData --startup-project DeepDrftAPI
# Apply migration
dotnet ef database update --project DeepDrftData --startup-project DeepDrftPublic
dotnet ef database update --project DeepDrftData --startup-project DeepDrftAPI
# Run from CLI (which consumes this service)
dotnet run --project DeepDrftCli -- list
# Run from Content API (dual-database host)
dotnet run --project DeepDrftContent
# Run API (dual-database host consuming this service)
dotnet run --project DeepDrftAPI
```
## What does NOT live here
+5 -5
View File
@@ -25,8 +25,8 @@ All interactive UI for the site. Blazor WebAssembly. Pages, controls, the stream
- `StreamingAudioPlayerService`: Production implementation. Chunked stream from `TrackMediaClient`, adaptive 1664 KB buffer, early-playback, **seek-beyond-buffer** via offset request to the content API.
- `AudioInteropService`: JS interop wrapper over `window.DeepDrftAudio`. Manages `DotNetObjectReference` lifetimes for progress, end-of-playback, spectrum callbacks.
- Dark-mode services: `DarkModeServiceBase` (cookie name constant), `DarkModeCookieService` (JS cookie read/write).
- `Clients/`: HTTP API clients.
- `TrackClient`: SQL metadata API. Uses named `IHttpClientFactory` client `"DeepDrft.API"`. Async methods like `GetPageAsync(pageNumber, pageSize, sortColumn, sortDescending)``ApiResult<PagedResult<TrackEntity>>`.
- `Clients/`: HTTP API clients (both target DeepDrftAPI).
- `TrackClient`: SQL metadata API. Uses named `IHttpClientFactory` client `"DeepDrft.API"`. Sends `page` param (not `pageNumber`). Deserializes response as bare `PagedResult<TrackDto>` (not wrapped in ApiResultDto envelope).
- `TrackMediaClient`: Content API. Uses named `IHttpClientFactory` client `"DeepDrft.Content"`. Methods like `GetAudioStreamAsync(trackId, offset)``Stream`.
- `ViewModels/`: Component state.
- `TracksViewModel`: Scoped. Holds current page, page size, sort column, descending flag. `SetPage(pageNumber)` calls `TrackClient.GetPageAsync` and updates. Registered in `Startup.ConfigureDomainServices`.
@@ -40,10 +40,10 @@ All interactive UI for the site. Blazor WebAssembly. Pages, controls, the stream
Both clients are configured in `Startup.cs` (static methods called from **both** server and WASM `Program.cs`):
- `TrackClient` uses `"DeepDrft.API"` (base address from `appsettings.json` `ApiUrls:SqlApi`). Fetches paginated metadata.
- `TrackMediaClient` uses `"DeepDrft.Content"` (base address from `appsettings.json` `ApiUrls:ContentApi`). Streams audio bytes, optionally with offset.
- `TrackClient` uses `"DeepDrft.API"` (base address from `appsettings.json` `ApiUrls:SqlApi`, points to DeepDrftAPI). Fetches paginated metadata.
- `TrackMediaClient` uses `"DeepDrft.Content"` (base address from `appsettings.json` `ApiUrls:ContentApi`, points to DeepDrftAPI). Streams audio bytes, optionally with offset.
Both are configured with JSON serializer settings (case-insensitive property matching). The dual-client pattern keeps concerns separated: one for structured data, one for binary streaming.
Both are configured with JSON serializer settings (case-insensitive property matching). The dual-client pattern keeps concerns separated: one for structured data, one for binary streaming. Both target DeepDrftAPI (they may share the same host URL in production).
## Audio player stack (deepest part of the codebase)
+14 -29
View File
@@ -6,12 +6,11 @@ See the root `CLAUDE.md` for full architecture overview. This file covers what i
## One-line purpose
The Blazor Web App host. Owns HTTP surface (one controller + render-mode wiring), MudBlazor theme prerender, TypeScript→JS audio interop, and the SQL-side `api/track/page` endpoint. **Domain logic lives in `DeepDrftData`.**
The Blazor Web App host. Pure HTTP render surface (render-mode wiring, no controllers), MudBlazor theme prerender, TypeScript→JS audio interop. Fetches track metadata from DeepDrftAPI via HTTP.
## What lives here now (only)
- `Program.cs`, `Startup.cs`: HTTP host config, DI wiring, port binding.
- `Controllers/TrackController.cs`: Single controller. `GET api/track/page?pageNumber&pageSize&sortColumn&sortDescending` → service call → `ApiResultDto<PagedResult<TrackEntity>>`.
- `Services/DarkModeService.cs`: Server-side dark-mode prerender (reads `darkMode` cookie, seeds `DarkModeSettings.IsDarkMode` via `IHttpContextAccessor`, carries to WASM via `PersistentComponentState`).
- `Components/App.razor`: Root component with `@rendermode="InteractiveAuto"`. Calls `DarkModeService.InitializeAsync()` in `OnInitialized`.
- `Components/Pages/Error.razor`: Error fallback.
@@ -20,8 +19,12 @@ The Blazor Web App host. Owns HTTP surface (one controller + render-mode wiring)
## What does NOT live here anymore
- `DeepDrftContext`, `TrackRepository`, `TrackService`, `Configurations/`, `Migrations/` — all moved to `DeepDrftData`. Do not add new repositories or EF code to this project.
- Any FileDatabase code — that lives in `DeepDrftContent.Services`.
- `TrackController` — deleted; track metadata now comes from DeepDrftAPI via HTTP.
- `TrackDirectDataService` — deleted; no in-process data adapter.
- `DeepDrftContext`, `TrackRepository`, `TrackService`, `Configurations/`, `Migrations/` — all in `DeepDrftData` (consumed only by DeepDrftAPI).
- Any FileDatabase code — that lives in `DeepDrftContent`.
- EF Core registration, SQL connection string — DeepDrftPublic has no data layer.
- `environment/connections.json` dependency — removed.
## Blazor Web App render modes
@@ -53,10 +56,10 @@ Blazor calls TypeScript via `AudioInteropService.ts` (a JS interop wrapper in `D
## HTTP client wiring
Mostly in `DeepDrftPublic.Client.Startup`:
Configured in `DeepDrftPublic.Client.Startup`:
- Named clients `"DeepDrft.API"` (SQL metadata) and `"DeepDrft.Content"` (binary audio).
- Base addresses passed in from `appsettings.json` (`ApiUrls:ContentApi`, `ApiUrls:SqlApi`).
- Both clients point to DeepDrftAPI. Base addresses passed in from `appsettings.json` (`ApiUrls:ContentApi`, `ApiUrls:SqlApi`).
- `Startup.ConfigureApiHttpClient` and `Startup.ConfigureContentServices` are static methods called from **both** the server `Program.cs` and the WASM `Program.cs` so prerender and runtime see the same DI.
Server-side `Program.cs` adds:
@@ -71,20 +74,9 @@ Server-side `Program.cs` adds:
`UseForwardedHeaders()` runs first in the pipeline. HTTPS redirect is conditionally disabled via `ForwardedHeaders:DisableHttpsRedirection` so the app can sit behind nginx without forcing HTTPS at the host level.
## The one controller
## No controllers
`TrackController` is thin — it just deserializes query parameters, calls `DeepDrftData.TrackService.GetPaged`, and wraps the result:
```csharp
[HttpGet("api/track/page")]
public async Task<ActionResult<ApiResultDto<PagedResult<TrackEntity>>>> GetPage(
[FromQuery] int pageNumber = 1,
[FromQuery] int pageSize = 20,
[FromQuery] string? sortColumn = null,
[FromQuery] bool sortDescending = false)
```
If you're adding new SQL endpoints, this is the file. If you're adding new logic, that goes in `DeepDrftData/TrackService.cs`.
DeepDrftPublic has no HTTP controllers. It is a pure Blazor render host. Track metadata endpoints are served by DeepDrftAPI (see `DeepDrftAPI/CLAUDE.md` for endpoint details).
## Development commands
@@ -97,22 +89,15 @@ dotnet watch run --project DeepDrftPublic
# Build
dotnet build DeepDrftPublic
# Add migration (run from solution root; creates in DeepDrftData)
dotnet ef migrations add MigrationName --project DeepDrftData --startup-project DeepDrftPublic
```
## Configuration
- `appsettings.json`: `ApiUrls:*` (backend base addresses), `Logging:*`, `AllowedHosts`, `ForwardedHeaders`. Port binding via `Kestrel:Endpoints` or `ASPNETCORE_URLS`.
- `environment/apikey.json`: DeepDrftContent API key. Loaded via CredentialTools (not in repo).
- `environment/connections.json`: SQL `DefaultConnection` and Auth connection strings. Loaded via CredentialTools (not in repo).
- `environment/authblocks.json`: AuthBlocks settings. Loaded via CredentialTools (not in repo).
- `appsettings.json`: `ApiUrls:*` (DeepDrftAPI base addresses), `Logging:*`, `AllowedHosts`, `ForwardedHeaders`. Port binding via `Kestrel:Endpoints` or `ASPNETCORE_URLS`.
- No secrets files — DeepDrftPublic has no data layer or API credentials.
- MudBlazor theme (`MainLayout.razor` in client): bespoke light ("Charleston in the Day") and dark ("Lowcountry Summer Nights") palettes.
- No `wwwroot/` changes during normal development — TS → JS compilation is automatic.
## Important patterns
All service calls in the controller return `ResultContainer<T>` or `Result`. The controller doesn't catch — it checks `Success` and returns 200/4xx/5xx accordingly. See `DeepDrftData` for the contract.
When working with this project, focus on the host surface (controllers, middleware, config) and prerender coordination. New domain logic goes in `DeepDrftData`.
This project is a render host only. All data operations go through HTTP to DeepDrftAPI. When working with this project, focus on the render surface (components, middleware, config) and prerender coordination. New domain logic belongs in `DeepDrftData` / `DeepDrftAPI`.