docs: reconcile PLAN.md and CONTEXT.md with post-split solution state
This commit is contained in:
+76
-50
@@ -2,61 +2,77 @@
|
||||
|
||||
Living orientation doc for what this repo is, how it is currently shaped, and where it appears headed. Sits alongside the root `CLAUDE.md` (operational guidance) — this file is the product/architecture view.
|
||||
|
||||
> **Drift notice.** The root `CLAUDE.md` and every folder-level `CLAUDE.md` currently in the tree describe the project as `.NET 9`. The most recent commit upgraded all projects to `.NET 10` (every `.csproj` now targets `net10.0`, packages pinned at `10.0.1`). Until those docs are refreshed, treat any framework-version claim in them as stale. The other staleness items are listed at the bottom of this file.
|
||||
> **Status.** The root `CLAUDE.md` is current — it reflects the post-split ten-project solution, `net10.0`, and the dual-app topology. This file (`CONTEXT.md`) was the lagging document and §2 / §4 / §7 below have been brought back into line with the root `CLAUDE.md` as of 2026-06-06. Folder-level `CLAUDE.md` files are still being swept (`DOC_PLAN.md`); treat framework-version and structural claims in any *folder* `CLAUDE.md` not yet rewritten as potentially stale until that sweep lands.
|
||||
|
||||
---
|
||||
|
||||
## 1. What this project is
|
||||
|
||||
DeepDrftHome is the home + listening surface for **DeepDrft**, a two-person electronic music collective based in Charleston, SC (per `DeepDrftWeb.Client/Pages/Home.razor`). The product is, at minimum:
|
||||
DeepDrftHome is the home + listening surface for **DeepDrft**, a two-person electronic music collective based in Charleston, SC (per `DeepDrftPublic.Client/Pages/Home.razor`). The product is, at minimum:
|
||||
|
||||
- A public-facing site (hero, about, "experience" features).
|
||||
- A public-facing site (hero, about, "experience" features) at `DeepDrftPublic`.
|
||||
- A **track gallery** that browses a library of WAV recordings, plays them in-browser with a persistent dock-style player, and supports seek (including seek beyond what's been streamed so far).
|
||||
- An admin CLI for adding tracks (Terminal.Gui or scripted), running locally against the same dual-database substrate the site uses.
|
||||
- A browser-based **CMS** (`DeepDrftManager`) for adding, editing, and deleting tracks — gated behind AuthBlocks login and the `Admin` role. This replaced the former `DeepDrftCli` Terminal.Gui admin tool, which has been retired.
|
||||
|
||||
The interesting engineering bet is the **dual-database split**: structured track metadata in SQLite via EF Core, and binary media + per-vault indexes in a hand-rolled `FileDatabase` that lives on disk. The split is enforced across two ASP.NET Core hosts so that the browser never reaches the database directly.
|
||||
The interesting engineering bet is the **dual-database split**: structured track metadata in PostgreSQL via EF Core, and binary media + per-vault indexes in a hand-rolled `FileDatabase` that lives on disk. The split is enforced through a dedicated authority host (`DeepDrftAPI`) so that the browser never reaches the database directly.
|
||||
|
||||
---
|
||||
|
||||
## 2. Solution shape (current)
|
||||
|
||||
Eight projects in `DeepDrftHome.sln`, plus an external `NetBlocks` referenced from `C:\lib\NetBlocks\`.
|
||||
Ten projects in `DeepDrftHome.sln`, plus an external `NetBlocks` referenced from `C:\lib\NetBlocks\`. The solution is split into **two independent Blazor applications** — the public site (`DeepDrftPublic`) and the CMS (`DeepDrftManager`) — both fronting a single dual-database authority host (`DeepDrftAPI`).
|
||||
|
||||
```
|
||||
DeepDrftWeb ASP.NET Core host. Blazor Web App (Server + WASM render modes).
|
||||
Owns the SQL-backed API (api/track/page), MudBlazor theme/host,
|
||||
TypeScript→JS audio interop sources under Interop/.
|
||||
DeepDrftWeb.Client Blazor WebAssembly assembly. All interactive UI lives here —
|
||||
pages, controls, player services, dark-mode/theme plumbing,
|
||||
HTTP clients for both backends.
|
||||
DeepDrftWeb.Services Class library. EF Core: DeepDrftContext, TrackConfiguration,
|
||||
Migrations, TrackRepository, TrackService. Sharable between
|
||||
the web host and the CLI (avoids duplicating data-access).
|
||||
── Public application ──────────────────────────────────────────────────────
|
||||
DeepDrftPublic ASP.NET Core host. Blazor Web App (Server + WASM render
|
||||
modes). Owns the browser-facing proxy controller for
|
||||
api/track/* (metadata listing + audio streaming),
|
||||
MudBlazor theme prerender, and TypeScript→JS audio interop
|
||||
sources under Interop/. The public listening surface.
|
||||
DeepDrftPublic.Client Blazor WebAssembly assembly. All interactive public UI —
|
||||
pages, the player stack, dark-mode plumbing, HTTP clients
|
||||
for the backend. Consumed by DeepDrftPublic.
|
||||
|
||||
DeepDrftContent ASP.NET Core host. Binary content API (api/track/{id}).
|
||||
ApiKey middleware, CORS, ForwardedHeaders. Returns audio bytes
|
||||
(with optional byte offset) and accepts PUT of AudioBinaryDto.
|
||||
DeepDrftContent.Services Class library. The FileDatabase implementation in full
|
||||
── CMS application ─────────────────────────────────────────────────────────
|
||||
DeepDrftManager ASP.NET Core host. Blazor Web App (InteractiveServer).
|
||||
Hosts all CMS Razor components/pages (Components/Pages/Cms/,
|
||||
Components/Pages/Tracks/, Components/Layout/CmsLayout.razor,
|
||||
Components/Shared/ — inlined from the former DeepDrftCms RCL).
|
||||
Gated by AuthBlocks login + hierarchical Admin role. All track
|
||||
operations proxy via ICmsTrackService / CmsTrackService.
|
||||
|
||||
── Dual-database authority ─────────────────────────────────────────────────
|
||||
DeepDrftAPI ASP.NET Core host. The single authority over both databases
|
||||
(SQL metadata + FileDatabase binary). AuthBlocks API host
|
||||
(registration, migration/seed, JWT endpoints). Seven track
|
||||
endpoints (stream, vault write, upload, delete, paged list,
|
||||
single metadata read, metadata update).
|
||||
DeepDrftData Class library. EF Core domain logic: DeepDrftContext,
|
||||
TrackConfiguration, Migrations, TrackRepository, TrackService,
|
||||
TrackManager. Consumed by DeepDrftAPI and tests.
|
||||
DeepDrftContent Class library. The FileDatabase implementation in full
|
||||
(Models, Services, Utils, Abstractions, Constants),
|
||||
WavOffsetService, AudioProcessor, TrackService (the content-side
|
||||
orchestrator that processes WAVs and stores them in a vault).
|
||||
WavOffsetService, AudioProcessor, content-side TrackService.
|
||||
Consumed by hosts and tests.
|
||||
|
||||
── Shared ──────────────────────────────────────────────────────────────────
|
||||
DeepDrftShared.Client Razor Class Library. Shared Blazor components consumed by
|
||||
BOTH DeepDrftPublic and DeepDrftManager (e.g. TrackCard,
|
||||
TracksGallery) for consistency across public and admin surfaces.
|
||||
DeepDrftModels Shared contracts: TrackEntity, TrackDto, PagingParameters<T>,
|
||||
PagedResult<T>. The only project all three layers reference.
|
||||
|
||||
DeepDrftCli Console app. Two modes: classic `add` / `list` / `help` and
|
||||
`gui` (Terminal.Gui). Consumes BOTH service libraries directly
|
||||
(it's a local admin tool, not a network client).
|
||||
|
||||
PagedResult<T>, plus waveform DTOs. Every project references this.
|
||||
DeepDrftTests NUnit. Covers the FileDatabase, MediaVault, IndexSystem,
|
||||
MediaVaultFactory, SimpleMediaTypeRegistry, utility code, and
|
||||
model behaviour. References DeepDrftContent.Services.
|
||||
MediaVaultFactory, SimpleMediaTypeRegistry, utility code, model
|
||||
behaviour, and the waveform loudness algorithm. References
|
||||
DeepDrftContent.
|
||||
|
||||
NetBlocks (external) Result patterns: Result, ResultContainer<T>, ApiResult<T>,
|
||||
ApiResultDto<T>. Referenced via absolute path.
|
||||
```
|
||||
|
||||
Two stray .sln files (`WebAPI.sln`, `WebUI.sln`, `CLI.sln`) exist at the root alongside `DeepDrftHome.sln`. `DeepDrftHome.sln` is the canonical solution; the others appear to be subsets.
|
||||
**Naming history (for readers of older docs/commits):** `DeepDrftWeb` → `DeepDrftPublic`, `DeepDrftWeb.Client` → `DeepDrftPublic.Client`, `DeepDrftWeb.Services` → `DeepDrftData`, `DeepDrftContent.Services` → `DeepDrftContent` (the host that previously owned the binary API is gone; its proxy duties moved into `DeepDrftPublic`, its authority duties into `DeepDrftAPI`). `DeepDrftCli` and the `DeepDrftCms` RCL have both been removed — the CLI retired in favour of the CMS, and the CMS RCL was inlined into `DeepDrftManager`.
|
||||
|
||||
**Subdomain topology (deployment):** `deepdrft.com` (public) and `manage.deepdrft.com` (CMS), behind nginx. CD infrastructure (Gitea workflows + installer scripts + systemd/nginx templates) has landed — see `COMPLETED.md` "Deployment Infrastructure."
|
||||
|
||||
---
|
||||
|
||||
@@ -147,17 +163,21 @@ In dev, the host serves the original `.ts` sources at `/Interop/...` for source-
|
||||
|
||||
Recent commits (newest first):
|
||||
|
||||
- `style simplification and publish upgrades for dotnet 10`
|
||||
- `Styles & Home Page Content Cleanup Mobile Menu System & Dark Mode Cookie Theme Draft`
|
||||
- `Theming Draft 2`
|
||||
- `2026 Deep DRFT Theme Draft 1 WIP`
|
||||
- `Spectrum Visualizer for player & Layout`
|
||||
- `docs: archive play-state icon normalization; update DeepDrftPublic.Client CLAUDE.md`
|
||||
- `Consolidate play/pause icon logic into PlaybackIcons mapper and PlayStateIcon component`
|
||||
- `Reflect real playback state on gallery cards and toggle pause/resume`
|
||||
- `WASM State Fixes`
|
||||
- `CMS Home autoredirect to /tracks`
|
||||
- `WaveformSeeker Improvements` / WaveformSeeker waves 1–3
|
||||
- (earlier: AudioPlayerBar responsive unification, CMS build-out, the two-app split, deployment infrastructure)
|
||||
|
||||
Three observations:
|
||||
Observations:
|
||||
|
||||
1. **The current arc is presentation, not capability.** The last five commits are framework upgrade, theming, content/layout cleanup, mobile menu, dark-mode persistence, and the spectrum visualiser. The playback substrate, streaming, and seek-beyond-buffer machinery landed earlier and is stable enough to support cosmetic iteration on top.
|
||||
2. **The "Track Gallery" is the only real page.** `/tracks` is the working surface; `/` is marketing copy. Nav (in `Pages.cs`) defines only `Home` + `Track Gallery`.
|
||||
3. **Content surface is narrow on purpose.** The DeepDrftContent API exposes exactly two routes: `GET api/track/{id}` (with optional `offset`) and `PUT api/track/{id}` (ApiKey). There is no listing endpoint there; listing lives on DeepDrftWeb because listings are SQL queries.
|
||||
1. **The big structural moves have landed.** Since the last revision of this doc, three large initiatives shipped: the **two-app split** (public/CMS separation with `DeepDrftAPI` as the dual-database authority), the **browser CMS** replacing the CLI (auth via AuthBlocks, stealth-routed `/cms/*`, full add/list/edit/delete parity), and **CD infrastructure** (Gitea workflows + host installer + systemd/nginx templates). The substrate is no longer the frontier — the product and presentation layers are.
|
||||
2. **The recent arc is player UX polish.** The latest wave of work is the WaveformSeeker (loudness-profile seekbar), AudioPlayerBar responsive unification, and play-state icon normalization (a single `PlaybackIcons` resolver + `PlayStateIcon` component, gallery cards reflecting real playback state with pause/resume). Presentation iteration on a stable streaming core.
|
||||
3. **The "Track Gallery" is still the only real public content page.** `/tracks` is the working listening surface; `/` is the (reskinned) marketing home. Nav (in `Layout/Pages.cs`) is still essentially `Home` + `Track Gallery`. The CMS adds admin surfaces under `/cms` but those are not public.
|
||||
4. **The metadata/streaming surface is consolidated on `DeepDrftAPI`.** It exposes seven track endpoints (stream, vault write, upload, delete, paged list, single-metadata read, metadata update) plus waveform endpoints. `DeepDrftPublic` is a thin browser-facing proxy in front of it; the browser never reaches `DeepDrftAPI` or the databases directly.
|
||||
5. **In flight (working tree, not yet committed):** an **embeddable iframe player** (`EmbedLayout.razor`, `FramePlayer.razor`, a new `ITrackDataService` seam) — a chrome-free single-track play surface for embedding off-site. Partial and not yet compiling; see `PLAN.md` "In-flight — Embeddable iframe player" for the open questions.
|
||||
|
||||
---
|
||||
|
||||
@@ -167,7 +187,7 @@ Captured here so the next round of planning has a starting point — none of thi
|
||||
|
||||
- **More vault types in active use.** `MediaVaultType.Image` exists end-to-end (tests cover it) but the production surface only registers a `tracks` vault of type `Audio`. The path to releases/albums probably runs through images first (cover art via `ImagePath`, which is currently a free-form URL string).
|
||||
- **More than one collection view.** The `TrackCard` already conditionally renders `ImagePath`, `Album`, `Genre`, `ReleaseDate` — the data shape supports album-grouped or genre-filtered views without schema work.
|
||||
- **Upload from the web side, not just the CLI.** The CLI is currently the only producer of tracks. A web-side upload would re-use `DeepDrftContent.Services.TrackService.AddTrackFromWavAsync` and pair it with a `TrackService.Create` on the SQL side. The `[ApiKeyAuthorize]` middleware on `PUT api/track/{id}` is already in place.
|
||||
- **Web upload — landed.** *(Historical note: this was a "likely direction" when the CLI was the only producer. It has since shipped.)* The CMS (`DeepDrftManager`) now produces tracks via `POST api/track/upload` on `DeepDrftAPI`, proxied through the auth-gated CMS surface. The CLI has been retired. The dual-write rollback gap (`PLAN.md §4.3`) still stands.
|
||||
- **Live/session content.** The home page advertises "Live Sessions" and "Video Content (coming soon)". No data model exists for these yet; they would likely need new vault types (`MediaVaultType.Media` is the obvious home for video) and new entity tables.
|
||||
- **Non-WAV formats.** Today the producer side is WAV-only (`AudioProcessor.ProcessWavFileAsync` validates RIFF/WAVE/PCM). `MimeTypeExtensions` already knows mp3/flac/aac/ogg/m4a — the gap is a processor per format and a decoder strategy in the JS player (currently WAV-specific).
|
||||
- **Search / filter on the gallery.** `TracksViewModel` exposes `SortBy` / `IsDescending` but no filter. `TrackService.GetPaged` accepts only sort, not filter. Adding filter would be a natural next step on the same pagination contract.
|
||||
@@ -187,14 +207,20 @@ Captured here so the next round of planning has a starting point — none of thi
|
||||
|
||||
## 7. Staleness in existing docs (for doc-keeper to address)
|
||||
|
||||
Captured so the next sweep of folder-level `CLAUDE.md` files can correct in one pass.
|
||||
Two layers of drift remain. The root `CLAUDE.md` and this `CONTEXT.md` are current; the lag is now in **folder-level `CLAUDE.md` files** and the in-tree `FileDatabase` README. `DOC_PLAN.md` holds the per-folder rewrite briefs, but note that `DOC_PLAN.md` itself was authored against the *pre-split* project names (2026-05-16) and is partly superseded — see the warning at the end of this section.
|
||||
|
||||
- Every folder `CLAUDE.md` says ".NET 9" / "ASP.NET Core 9.0"; reality is `net10.0` across the board.
|
||||
- `DeepDrftModels/CLAUDE.md` and `DeepDrftContent.Services/FileDatabase/README.md` reference `TrackEntity.MediaPath`; the field is `EntryKey` and the column is `entry_key`.
|
||||
- `DeepDrftContent/CLAUDE.md` describes a `FileDatabase/` tree inside `DeepDrftContent/`; that tree has moved entirely to `DeepDrftContent.Services/FileDatabase/`. The DeepDrftContent host now contains only `Controllers/`, `Middleware/`, `Models/` (settings POCOs), `environment/`, `Program.cs`, `Startup.cs`.
|
||||
- `DeepDrftContent/CLAUDE.md` documents only the PUT endpoint; the production API now also has `GET api/track/{id}?offset=` (unauthenticated read, with `WavOffsetService` for offset streaming).
|
||||
- `DeepDrftWeb/CLAUDE.md` describes EF Core, repositories, services, migrations as living inside `DeepDrftWeb/Data` and `DeepDrftWeb/Services`. They have all moved to `DeepDrftWeb.Services`. The only things still in `DeepDrftWeb` are `Controllers/TrackController.cs`, `Services/DarkModeService.cs`, `Startup.cs`, `Program.cs`, `Components/`, `Interop/`, `wwwroot/`.
|
||||
- `DeepDrftWeb.Client/CLAUDE.md` lists the `Pages/` directory as containing `Counter.razor` / `Weather.razor` (demo); those are gone. The real client structure is `Pages/Home.razor` + `Pages/TracksView.razor`, plus the `Controls/AudioPlayerBar/` cluster, `Controls/AudioPlayerProvider.razor`, `Services/AudioInteropService.cs` + `AudioPlayerService.cs` + `StreamingAudioPlayerService.cs` + `IPlayerService.cs` + dark-mode services, `Common/DarkModeSettings.cs` + `Common/DDIcons.cs`, and `Layout/Pages.cs` + `Layout/DeepDrftMenu.razor`.
|
||||
- The `DeepDrftWeb.Services` and `DeepDrftContent.Services` projects have **no** `CLAUDE.md` yet — they are where most of the domain logic actually lives, so this is the biggest gap.
|
||||
- `DeepDrftCli/CLAUDE.md` references `appsettings.json`; the CLI actually loads `environment/connections.json` into `CliSettings` (with `ConnectionString` and `VaultPath`). The "Available Commands" section is otherwise current, including the `gui` Terminal.Gui mode and interactive `add`.
|
||||
- `DeepDrftContent.Services/FileDatabase/README.md` (an in-tree dev README, not a CLAUDE.md) refers to `ImageDirectoryVault`; the type is `ImageVault`. It also describes `EntryKey` as removed in favour of strings, which is accurate, but its diagram still says "FileDatabase.csproj (.NET 9.0)" — the FileDatabase no longer has its own csproj at all (it's a subdirectory of `DeepDrftContent.Services`).
|
||||
**Project-rename drift (the big one).** The two-app split renamed or removed most projects. Any folder `CLAUDE.md` still using the old names is wrong at the structural level, not just the framework-version level:
|
||||
- `DeepDrftWeb` → `DeepDrftPublic`; `DeepDrftWeb.Client` → `DeepDrftPublic.Client`; `DeepDrftWeb.Services` → `DeepDrftData`.
|
||||
- `DeepDrftContent.Services` (class library) is now just `DeepDrftContent`; the old `DeepDrftContent` *host* is gone — binary-API duties split between the `DeepDrftPublic` proxy and the `DeepDrftAPI` authority.
|
||||
- `DeepDrftCli` and the `DeepDrftCms` RCL are **deleted**. Any `CLAUDE.md` for them should be removed, not rewritten.
|
||||
|
||||
**Known content drift to correct in the sweep:**
|
||||
- Framework version: any folder `CLAUDE.md` still saying ".NET 9" / "ASP.NET Core 9.0" — reality is `net10.0` across the board.
|
||||
- `TrackEntity.MediaPath` references (notably the `FileDatabase/README.md`) — the field is `EntryKey`, column `entry_key`.
|
||||
- The `FileDatabase/README.md` refers to `ImageDirectoryVault` (the type is `ImageVault`) and a "FileDatabase.csproj (.NET 9.0)" that no longer exists (FileDatabase is a subdirectory of `DeepDrftContent`).
|
||||
- `DeepDrftData` and `DeepDrftContent` are where most domain logic lives and are the highest-value targets for accurate `CLAUDE.md` coverage.
|
||||
|
||||
**Already corrected (no longer stale):**
|
||||
- `DeepDrftPublic.Client/CLAUDE.md` was rewritten in commit `9110b4b` and reflects the current player stack, `PlaybackIcons`/`PlayStateIcon`, and the post-split structure.
|
||||
|
||||
> **`DOC_PLAN.md` caveat.** `DOC_PLAN.md` predates the two-app split — its per-folder briefs reference `DeepDrftWeb*`, `DeepDrftCli`, and a SQLite backend (now PostgreSQL). Treat its *intent* (lead-with-truth, cross-reference root, no docs for build output) as still valid, but its *project list and per-folder details* need reconciling against the current ten-project solution before doc-keeper executes against it. Flag to Daniel whether to refresh `DOC_PLAN.md` first or let doc-keeper work from the root `CLAUDE.md` directly.
|
||||
|
||||
Reference in New Issue
Block a user