Merge branch 'p4-w3-rename-public' into dev

This commit is contained in:
Daniel Harvey
2026-05-20 09:48:12 -04:00
83 changed files with 116 additions and 116 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ public static class CmsStartup
// CMS-specific services registered here as implementation waves land.
//
// Note: ITrackService (and its dependencies: TrackRepository, DeepDrftContext) is registered
// by DeepDrftWeb.Startup.ConfigureDomainServices, not here. The CMS RCL runs inside the
// DeepDrftWeb host, which wires those up before this method is called. A standalone CMS
// by DeepDrftPublic.Startup.ConfigureDomainServices, not here. The CMS RCL runs inside the
// DeepDrftPublic host, which wires those up before this method is called. A standalone CMS
// host would need to register ITrackService separately.
return services;
}
@@ -121,7 +121,7 @@ public class TrackController : ControllerBase
}
// POST api/track/upload: raw WAV in (multipart/form-data) + metadata → unpersisted TrackEntity out.
// Used by the CMS upload flow on DeepDrftWeb; that host proxies the upload here so it never
// Used by the CMS upload flow on DeepDrftPublic; that host proxies the upload here so it never
// touches the vault disk path directly (Option B in CMS-PLAN §5).
//
// RequestSizeLimit/MultipartBodyLengthLimit set to 1 GB: WAV uploads can be tens to hundreds
+3 -3
View File
@@ -8,13 +8,13 @@ public class DeepDrftContextFactory : IDesignTimeDbContextFactory<DeepDrftContex
public DeepDrftContext CreateDbContext(string[] args)
{
// Load the real connection string from environment/connections.json — the same
// file DeepDrftWeb's Program.cs loads via CredentialTools. When EF tools run with
// --startup-project DeepDrftWeb, the working directory resolves there, so this
// file DeepDrftPublic's Program.cs loads via CredentialTools. When EF tools run with
// --startup-project DeepDrftPublic, the working directory resolves there, so this
// relative path works without any env var configuration.
const string relPath = "environment/connections.json";
if (!File.Exists(relPath))
throw new FileNotFoundException(
$"'{relPath}' not found. Run EF commands with --startup-project DeepDrftWeb " +
$"'{relPath}' not found. Run EF commands with --startup-project DeepDrftPublic " +
$"from the solution root (current dir: {Directory.GetCurrentDirectory()}).", relPath);
using var doc = System.Text.Json.JsonDocument.Parse(File.ReadAllText(relPath));
+2 -2
View File
@@ -1,8 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftWeb", "DeepDrftWeb\DeepDrftWeb.csproj", "{7E629215-7EF7-465D-B7F2-2CED53C4BFEC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftPublic", "DeepDrftPublic\DeepDrftPublic.csproj", "{7E629215-7EF7-465D-B7F2-2CED53C4BFEC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftWeb.Client", "DeepDrftWeb.Client\DeepDrftWeb.Client.csproj", "{E76D21B4-308B-487B-B8D6-59D6AE49F1F7}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftPublic.Client", "DeepDrftPublic.Client\DeepDrftPublic.Client.csproj", "{E76D21B4-308B-487B-B8D6-59D6AE49F1F7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeepDrftModels", "DeepDrftModels\DeepDrftModels.csproj", "{10CE5160-16C3-4CB1-9E2E-52467BA80B4B}"
EndProject
+1 -1
View File
@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<!-- EF Core kept in sync with DeepDrftData / DeepDrftWeb so the same DbContext registration compiles. -->
<!-- EF Core kept in sync with DeepDrftData / DeepDrftPublic so the same DbContext registration compiles. -->
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.7" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
+2 -2
View File
@@ -120,7 +120,7 @@ builder.Services.Configure<ForwardedHeadersOptions>(options =>
});
// Controllers: discovers CMS mutation controllers (CmsUploadController, CmsEditController,
// CmsDeleteController) and the AuthBlocks surface. Matches DeepDrftWeb precedent.
// CmsDeleteController) and the AuthBlocks surface. Matches DeepDrftPublic precedent.
builder.Services.AddControllers();
// InteractiveServer only — no WASM render mode on the CMS host.
@@ -179,7 +179,7 @@ app.MapRazorComponents<App>()
app.Run();
// Local helper — mirrors DeepDrftWeb.Startup.GetKestrelUrl. Kept inline because this host's
// Local helper — mirrors DeepDrftPublic.Startup.GetKestrelUrl. Kept inline because this host's
// only consumer is right here; promoting to a shared library would be premature.
static string GetKestrelUrl(WebApplicationBuilder builder)
{
@@ -1,6 +1,6 @@
# CLAUDE.md - DeepDrftWeb.Client
# CLAUDE.md - DeepDrftPublic.Client
Guidance for working in the DeepDrftWeb.Client project (the Blazor WebAssembly assembly).
Guidance for working in the DeepDrftPublic.Client project (the Blazor WebAssembly assembly).
See the root `CLAUDE.md` for full architecture overview. This file covers what is specific to this project.
@@ -76,7 +76,7 @@ Both are configured with JSON serializer settings (case-insensitive property mat
- `DarkModeSettings` (`Common/`): `[PersistentState]`-annotated class with `IsDarkMode` property. Registered scoped in `Startup.ConfigureDomainServices`. Single source of truth in the client.
- `DarkModeServiceBase`: Holds the cookie name constant (`"darkMode"`).
- `DarkModeCookieService`: Reads/writes the cookie via JS (`document.cookie` interop). Calls `DarkModeSettings.IsDarkMode = value` when the cookie changes or user toggles the button.
- Server-side `DarkModeService` (in `DeepDrftWeb`, **not here**): Reads the cookie during prerender, seeds the `DarkModeSettings` instance, rounds it through `PersistentComponentState` to the client.
- Server-side `DarkModeService` (in `DeepDrftPublic`, **not here**): Reads the cookie during prerender, seeds the `DarkModeSettings` instance, rounds it through `PersistentComponentState` to the client.
- `MainLayout.razor`: Wraps entire layout in `CascadingValue` of `DarkModeSettings`, so all children see the current dark-mode state. The dark-mode toggle button (hand-rolled lit/unlit gas-lamp icon from `DDIcons.cs`) calls `DarkModeCookieService.ToggleDarkModeAsync()`.
The flow ensures the first paint uses the correct theme (no flash), and toggling the button persists the setting to a 365-day cookie.
@@ -91,20 +91,20 @@ Component state lives in ViewModels (registered scoped in DI). Components render
## Theming convention
- Bespoke `PaletteLight` / `PaletteDark` defined inline in `MainLayout.razor` (MudBlazor theme objects).
- CSS classes prefixed `deepdrft-` live in `DeepDrftWeb/wwwroot/styles/deepdrft-styles.css` (shared across server and client).
- CSS classes prefixed `deepdrft-` live in `DeepDrftPublic/wwwroot/styles/deepdrft-styles.css` (shared across server and client).
- Custom SVG icons: `Common/DDIcons.cs` (hand-rolled gas-lamp, etc.).
## Development commands
```bash
# The client runs as part of the DeepDrftWeb host:
dotnet run --project DeepDrftWeb
# The client runs as part of the DeepDrftPublic host:
dotnet run --project DeepDrftPublic
# Watch during development (rebuilds WASM as you change .cs/.razor/.ts files):
dotnet watch run --project DeepDrftWeb
dotnet watch run --project DeepDrftPublic
# Build just the client (for verification):
dotnet build DeepDrftWeb.Client
dotnet build DeepDrftPublic.Client
# Run client-specific tests (if any; currently none exist):
dotnet test DeepDrftTests/
@@ -113,7 +113,7 @@ dotnet test DeepDrftTests/
## Configuration
- `Program.cs`: Entry point. Calls `Startup.ConfigureApiHttpClient` (registers named clients), `ConfigureContentServices` (same), `ConfigureDomainServices` (registers services like `TracksViewModel`, `DarkModeSettings`, `AudioPlayerService`).
- Both `Startup` methods are static and called from **both** the server `DeepDrftWeb/Program.cs` and the client `Program.cs`, ensuring prerender and runtime DI are identical.
- Both `Startup` methods are static and called from **both** the server `DeepDrftPublic/Program.cs` and the client `Program.cs`, ensuring prerender and runtime DI are identical.
- No `appsettings.json` in the WASM assembly — config comes from the server `appsettings.json` via HTTP or is hardcoded.
## Important patterns
@@ -5,7 +5,7 @@ using System.Text.Json;
using System.Web;
using Microsoft.AspNetCore.Http;
namespace DeepDrftWeb.Client.Clients;
namespace DeepDrftPublic.Client.Clients;
public class TrackClient
{
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using NetBlocks.Models;
namespace DeepDrftWeb.Client.Clients;
namespace DeepDrftPublic.Client.Clients;
public class TrackMediaResponse : IDisposable
{
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components;
namespace DeepDrftWeb.Client.Common;
namespace DeepDrftPublic.Client.Common;
public class DarkModeSettings()
{
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
namespace DeepDrftWeb.Client.Controls;
namespace DeepDrftPublic.Client.Controls;
public partial class AppNavLink : ComponentBase
{
@@ -1,9 +1,9 @@
using DeepDrftWeb.Client.Services;
using DeepDrftPublic.Client.Services;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using MudBlazor.Services;
namespace DeepDrftWeb.Client.Controls.AudioPlayerBar;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
{
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace DeepDrftWeb.Client.Controls.AudioPlayerBar;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
public partial class PlayerControls : ComponentBase
{
@@ -1,4 +1,4 @@
@namespace DeepDrftWeb.Client.Controls.AudioPlayerBar
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
<div class="spectrum-container @(IsVisible ? "" : "hidden")">
<div class="spectrum-bars">
@@ -1,7 +1,7 @@
using DeepDrftWeb.Client.Services;
using DeepDrftPublic.Client.Services;
using Microsoft.AspNetCore.Components;
namespace DeepDrftWeb.Client.Controls.AudioPlayerBar;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
public partial class SpectrumVisualizer : ComponentBase, IAsyncDisposable
{
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components;
namespace DeepDrftWeb.Client.Controls.AudioPlayerBar;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
public partial class TimestampLabel : ComponentBase
{
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace DeepDrftWeb.Client.Controls.AudioPlayerBar;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
public partial class VolumeControls : ComponentBase
{
@@ -1,9 +1,9 @@
using DeepDrftWeb.Client.Services;
using DeepDrftWeb.Client.Clients;
using DeepDrftPublic.Client.Services;
using DeepDrftPublic.Client.Clients;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
namespace DeepDrftWeb.Client.Controls;
namespace DeepDrftPublic.Client.Controls;
public partial class AudioPlayerProvider : ComponentBase, IAsyncDisposable
{
@@ -1,5 +1,5 @@
@using DeepDrftWeb.Client.Common
@using DeepDrftWeb.Client.Services
@using DeepDrftPublic.Client.Common
@using DeepDrftPublic.Client.Services
@implements IAsyncDisposable
<nav class="@NavClass">
@@ -1,7 +1,7 @@
@using DeepDrftWeb.Client.Controls
@using DeepDrftWeb.Client.Controls.AudioPlayerBar
@using DeepDrftWeb.Client.Services
@using DeepDrftWeb.Client.Common
@using DeepDrftPublic.Client.Controls
@using DeepDrftPublic.Client.Controls.AudioPlayerBar
@using DeepDrftPublic.Client.Services
@using DeepDrftPublic.Client.Common
@using DeepDrftShared.Client.Common
@using Microsoft.AspNetCore.Components
@inherits LayoutComponentBase
@@ -0,0 +1,5 @@
@using DeepDrftPublic.Client.Controls
@@ -1,6 +1,6 @@
using MudBlazor;
namespace DeepDrftWeb.Client.Layout;
namespace DeepDrftPublic.Client.Layout;
public class PageRoute
{
@@ -1,6 +1,6 @@
@page "/"
@rendermode InteractiveAuto
@using DeepDrftWeb.Client.Services
@using DeepDrftPublic.Client.Services
<PageTitle>Deep DRFT - Electronic Music Collective</PageTitle>
@@ -1,10 +1,10 @@
using DeepDrftModels.Entities;
using DeepDrftWeb.Client.Services;
using DeepDrftWeb.Client.ViewModels;
using DeepDrftPublic.Client.Services;
using DeepDrftPublic.Client.ViewModels;
using Microsoft.AspNetCore.Components;
using Models.Common;
namespace DeepDrftWeb.Client.Pages;
namespace DeepDrftPublic.Client.Pages;
public partial class TracksView : ComponentBase
{
@@ -1,4 +1,4 @@
using DeepDrftWeb.Client;
using DeepDrftPublic.Client;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
@@ -1,6 +1,6 @@
using Microsoft.JSInterop;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public class AudioInteropService : IAsyncDisposable
{
@@ -1,10 +1,10 @@
using DeepDrftModels.Entities;
using DeepDrftWeb.Client.Clients;
using DeepDrftPublic.Client.Clients;
using Microsoft.AspNetCore.Components;
using NetBlocks.Models;
using System.Buffers;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public abstract class AudioPlayerService : IPlayerService, IAsyncDisposable
{
@@ -1,7 +1,7 @@
using DeepDrftWeb.Client.Common;
using DeepDrftPublic.Client.Common;
using Microsoft.JSInterop;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public class DarkModeCookieService(DarkModeSettings darkModeSetting, IJSRuntime js) : DarkModeServiceBase
{
@@ -1,4 +1,4 @@
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public abstract class DarkModeServiceBase
{
@@ -2,7 +2,7 @@ using DeepDrftModels.Entities;
using Microsoft.AspNetCore.Components;
using NetBlocks.Models;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public interface IPlayerService
{
@@ -1,9 +1,9 @@
using DeepDrftModels.Entities;
using DeepDrftWeb.Client.Clients;
using DeepDrftPublic.Client.Clients;
using System.Buffers;
using Microsoft.Extensions.Logging;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerService
{
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
namespace DeepDrftWeb.Client.Services;
namespace DeepDrftPublic.Client.Services;
public static class StreamingErrorHandler
{
@@ -1,10 +1,10 @@
using DeepDrftWeb.Client.Clients;
using DeepDrftWeb.Client.Common;
using DeepDrftWeb.Client.Services;
using DeepDrftWeb.Client.ViewModels;
using DeepDrftPublic.Client.Clients;
using DeepDrftPublic.Client.Common;
using DeepDrftPublic.Client.Services;
using DeepDrftPublic.Client.ViewModels;
using Microsoft.AspNetCore.Http;
namespace DeepDrftWeb.Client;
namespace DeepDrftPublic.Client;
public static class Startup
{
@@ -1,8 +1,8 @@
using DeepDrftModels.Entities;
using DeepDrftWeb.Client.Clients;
using DeepDrftPublic.Client.Clients;
using Models.Common;
namespace DeepDrftWeb.Client.ViewModels;
namespace DeepDrftPublic.Client.ViewModels;
public class TracksViewModel
{
@@ -9,7 +9,7 @@
@using MudBlazor
@using MudBlazor.Services
@using MudBlazor.ThemeManager
@using DeepDrftWeb.Client.Common
@using DeepDrftPublic.Client.Common
@using DeepDrftShared.Client.Common
@using DeepDrftShared.Client.Components
@layout DeepDrftWeb.Client.Layout.MainLayout
@layout DeepDrftPublic.Client.Layout.MainLayout

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@@ -1,12 +1,12 @@
# CLAUDE.md - DeepDrftWeb
# CLAUDE.md - DeepDrftPublic
Guidance for working in the DeepDrftWeb project (the Blazor Web App host).
Guidance for working in the DeepDrftPublic project (the Blazor Web App host).
See the root `CLAUDE.md` for full architecture overview. This file covers what is specific to this project.
## 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 `DeepDrftWeb.Services`.**
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`.**
## What lives here now (only)
@@ -20,7 +20,7 @@ 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 `DeepDrftWeb.Services`. Do not add new repositories or EF code to this project.
- `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`.
## Blazor Web App render modes
@@ -28,14 +28,14 @@ The Blazor Web App host. Owns HTTP surface (one controller + render-mode wiring)
Hybrid Blazor with `AddInteractiveServerComponents()` + `AddInteractiveWebAssemblyComponents()`.
- Root component is `<Routes @rendermode="InteractiveAuto" />` from `Components/App.razor`.
- WASM render-mode loads `DeepDrftWeb.Client._Imports` as an additional assembly.
- **New routable pages go in `DeepDrftWeb.Client/Pages`, not here** — the client project owns the interactive UI.
- WASM render-mode loads `DeepDrftPublic.Client._Imports` as an additional assembly.
- **New routable pages go in `DeepDrftPublic.Client/Pages`, not here** — the client project owns the interactive UI.
Server-side prerender happens before WASM kicks in. Dark mode, CORS, forwarded headers, and MudBlazor setup must all tolerate this split.
## Dark-mode prerender bridge
`DarkModeService` in this project reads the `darkMode` cookie via `IHttpContextAccessor` in `App.razor`'s `OnInitialized` and seeds `DarkModeSettings.IsDarkMode`. This setting is registered in `DeepDrftWeb.Client.Startup.ConfigureDomainServices`. The setting carries over to WASM via `PersistentComponentState` in `MainLayout.razor`.
`DarkModeService` in this project reads the `darkMode` cookie via `IHttpContextAccessor` in `App.razor`'s `OnInitialized` and seeds `DarkModeSettings.IsDarkMode`. This setting is registered in `DeepDrftPublic.Client.Startup.ConfigureDomainServices`. The setting carries over to WASM via `PersistentComponentState` in `MainLayout.razor`.
The flow ensures the first paint uses the correct theme (no flash).
@@ -49,11 +49,11 @@ Audio interop is TypeScript, not raw JS:
- `tsconfig.json` configured for ES module interop and must **not** be copied to output.
- In development, raw `.ts` is served from `/Interop/` for source-map debugging.
Blazor calls TypeScript via `AudioInteropService.ts` (a JS interop wrapper in `DeepDrftWeb.Client`), which manages `DotNetObjectReference` lifetimes for progress, end-of-playback, and spectrum callbacks.
Blazor calls TypeScript via `AudioInteropService.ts` (a JS interop wrapper in `DeepDrftPublic.Client`), which manages `DotNetObjectReference` lifetimes for progress, end-of-playback, and spectrum callbacks.
## HTTP client wiring
Mostly in `DeepDrftWeb.Client.Startup`:
Mostly 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`).
@@ -73,7 +73,7 @@ Server-side `Program.cs` adds:
## The one controller
`TrackController` is thin — it just deserializes query parameters, calls `DeepDrftWeb.Services.TrackService.GetPaged`, and wraps the result:
`TrackController` is thin — it just deserializes query parameters, calls `DeepDrftData.TrackService.GetPaged`, and wraps the result:
```csharp
[HttpGet("api/track/page")]
@@ -84,22 +84,22 @@ public async Task<ActionResult<ApiResultDto<PagedResult<TrackEntity>>>> GetPage(
[FromQuery] bool sortDescending = false)
```
If you're adding new SQL endpoints, this is the file. If you're adding new logic, that goes in `DeepDrftWeb.Services/TrackService.cs`.
If you're adding new SQL endpoints, this is the file. If you're adding new logic, that goes in `DeepDrftData/TrackService.cs`.
## Development commands
```bash
# Run the web host (includes WASM from DeepDrftWeb.Client)
dotnet run --project DeepDrftWeb
# Run the web host (includes WASM from DeepDrftPublic.Client)
dotnet run --project DeepDrftPublic
# Watch during development
dotnet watch run --project DeepDrftWeb
dotnet watch run --project DeepDrftPublic
# Build
dotnet build DeepDrftWeb
dotnet build DeepDrftPublic
# Add migration (run from solution root; creates in DeepDrftWeb.Services)
dotnet ef migrations add MigrationName --project DeepDrftWeb.Services --startup-project DeepDrftWeb
# Add migration (run from solution root; creates in DeepDrftData)
dotnet ef migrations add MigrationName --project DeepDrftData --startup-project DeepDrftPublic
```
## Configuration
@@ -113,6 +113,6 @@ dotnet ef migrations add MigrationName --project DeepDrftWeb.Services --startup-
## 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 `DeepDrftWeb.Services` for the contract.
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 `DeepDrftWeb.Services`.
When working with this project, focus on the host surface (controllers, middleware, config) and prerender coordination. New domain logic goes in `DeepDrftData`.
@@ -1,4 +1,4 @@
@using DeepDrftWeb.Services
@using DeepDrftPublic.Services
@using DeepDrftShared.Client.Components
<!DOCTYPE html>
<html lang="en">
@@ -10,7 +10,7 @@
<DeepDrftFontLinks />
<link href="_@Assets["content/MudBlazor.ThemeManager/MudBlazorThemeManager.css"]" rel="stylesheet" />
<link href=@Assets["_content/MudBlazor/MudBlazor.min.css"] rel="stylesheet" />
<link rel="stylesheet" href="@Assets["DeepDrftWeb.styles.css"]"/>
<link rel="stylesheet" href="@Assets["DeepDrftPublic.styles.css"]"/>
<link rel="stylesheet" href="@Assets["_content/DeepDrftShared.Client/styles/deepdrft-tokens.css"]" />
<link rel="stylesheet" href="styles/deepdrft-styles.css" />
<ImportMap />
@@ -1,7 +1,7 @@
<Router AppAssembly="typeof(App).Assembly"
AdditionalAssemblies="new[] { typeof(DeepDrftWeb.Client._Imports).Assembly }">
AdditionalAssemblies="new[] { typeof(DeepDrftPublic.Client._Imports).Assembly }">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(DeepDrftWeb.Client.Layout.MainLayout)" />
<RouteView RouteData="routeData" DefaultLayout="typeof(DeepDrftPublic.Client.Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
<NotFound>
@@ -8,6 +8,6 @@
@using Microsoft.JSInterop
@using MudBlazor
@using MudBlazor.Services
@using DeepDrftWeb
@using DeepDrftWeb.Client
@using DeepDrftWeb.Components
@using DeepDrftPublic
@using DeepDrftPublic.Client
@using DeepDrftPublic.Components
@@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Models.Common;
using NetBlocks.Models;
namespace DeepDrftWeb.Controllers;
namespace DeepDrftPublic.Controllers;
[ApiController]
[Route("api/[controller]")]
@@ -21,7 +21,7 @@
<!-- Npgsql 10.0.1 requires Microsoft.EntityFrameworkCore >= 10.0.4; keep in sync -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<ProjectReference Include="..\DeepDrftModels\DeepDrftModels.csproj" />
<ProjectReference Include="..\DeepDrftWeb.Client\DeepDrftWeb.Client.csproj" />
<ProjectReference Include="..\DeepDrftPublic.Client\DeepDrftPublic.Client.csproj" />
<ProjectReference Include="..\DeepDrftData\DeepDrftData.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.7" />
</ItemGroup>
@@ -1,6 +1,6 @@
using DeepDrftWeb;
using DeepDrftPublic;
using MudBlazor.Services;
using DeepDrftWeb.Components;
using DeepDrftPublic.Components;
using Microsoft.AspNetCore.HttpOverrides;
using NetBlocks.Utilities.Environment;
@@ -10,7 +10,7 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMudServices();
// Required credential files — must exist before the app will start.
// In dev: create the files under DeepDrftWeb/environment/ (gitignored).
// In dev: create the files under DeepDrftPublic/environment/ (gitignored).
// In prod: systemd CREDENTIALS_DIRECTORY points to encrypted credential blobs.
// - environment/connections.json: { "ConnectionStrings": { "DefaultConnection": "..." } }
// AuthBlocks and the DeepDrftContent API key now live on DeepDrftManager;
@@ -20,9 +20,9 @@ builder.Configuration.AddJsonFile(connectionsPath, optional: false, reloadOnChan
var contentApiUrl = builder.Configuration["ApiUrls:ContentApi"] ?? throw new Exception("Content API URL is not configured");
DeepDrftWeb.Client.Startup.ConfigureApiHttpClient(builder.Services, builder.GetKestrelUrl());
DeepDrftWeb.Client.Startup.ConfigureDomainServices(builder.Services);
DeepDrftWeb.Client.Startup.ConfigureContentServices(builder.Services, contentApiUrl);
DeepDrftPublic.Client.Startup.ConfigureApiHttpClient(builder.Services, builder.GetKestrelUrl());
DeepDrftPublic.Client.Startup.ConfigureDomainServices(builder.Services);
DeepDrftPublic.Client.Startup.ConfigureContentServices(builder.Services, contentApiUrl);
Startup.ConfigureDomainServices(builder);
@@ -114,7 +114,7 @@ app.MapControllers();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(DeepDrftWeb.Client._Imports).Assembly);
.AddAdditionalAssemblies(typeof(DeepDrftPublic.Client._Imports).Assembly);
app.Run();
@@ -1,7 +1,7 @@
using DeepDrftWeb.Client.Common;
using DeepDrftWeb.Client.Services;
using DeepDrftPublic.Client.Common;
using DeepDrftPublic.Client.Services;
namespace DeepDrftWeb.Services;
namespace DeepDrftPublic.Services;
public class DarkModeService(DarkModeSettings darkModeSettings, IHttpContextAccessor httpAccessor) : DarkModeServiceBase
{
@@ -1,10 +1,10 @@
using DeepDrftData;
using DeepDrftData.Data;
using DeepDrftData.Repositories;
using DeepDrftWeb.Services; // DarkModeService namespace (within this host project)
using DeepDrftPublic.Services; // DarkModeService namespace (within this host project)
using Microsoft.EntityFrameworkCore;
namespace DeepDrftWeb;
namespace DeepDrftPublic;
public static class Startup
{
@@ -15,7 +15,7 @@ public static class Startup
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
// Add Server Prerendering Theming Support
// DarkModeSettings is registered in DeepDrftWeb.Client.Startup.ConfigureDomainServices
// DarkModeSettings is registered in DeepDrftPublic.Client.Startup.ConfigureDomainServices
builder.Services
.AddHttpContextAccessor()
.AddScoped<DarkModeService>();

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

@@ -1,7 +1,7 @@
/* DeepDrft design tokens — shared palette layer.
Consumed by both DeepDrftWeb (public site, light + dark) and the CMS host
Consumed by both DeepDrftPublic (public site, light + dark) and the CMS host
(light only). Page-specific styling lives in the consuming host's own
stylesheet (e.g. DeepDrftWeb/wwwroot/styles/deepdrft-styles.css). */
stylesheet (e.g. DeepDrftPublic/wwwroot/styles/deepdrft-styles.css). */
/* Light theme - wireframe palette (navy / green / warm off-white) */
:root {
-5
View File
@@ -1,5 +0,0 @@
@using DeepDrftWeb.Client.Controls
+2 -2
View File
@@ -3,8 +3,8 @@ eval $(ssh-agent -s)
ssh-add /c/.ssh/deepdrft_dch6_ed25519
CONTENT_PROJ="DeepDrftContent"
WEB_PROJ="DeepDrftWeb"
WEB_SERVICES_PROJ="DeepDrftWeb.Services"
WEB_PROJ="DeepDrftPublic"
WEB_SERVICES_PROJ="DeepDrftData"
CONTENT_APP="deepdrft-content.tar.gz"
WEB_APP="deepdrft-web.tar.gz"