docs: close Phase 2.2/2.3 — move to COMPLETED.md, update DeepDrftPublic proxy CLAUDE.md

This commit is contained in:
daniel-c-harvey
2026-06-10 10:58:16 -04:00
parent d9b92e0703
commit 10256677ac
3 changed files with 18 additions and 22 deletions
+11
View File
@@ -6,6 +6,17 @@ Newest entries at the top. Group by phase/wave header (mirroring `PLAN.md` / `CM
---
## Phase 2.2 + 2.3 — Album/genre views and gallery search/filter
**Status:** Fully landed on 2026-06-10.
- **What:** Free-text search (`?q=`) across TrackName/Artist/Album via `EF.Functions.ILike` (Postgres, case-insensitive); album/genre exact-match filtering (`?album=`, `?genre=`); new `/albums` browsing page (grid of album cards with cover art and track counts, linking to filtered gallery); new `/genres` browsing page (genre list with counts, linking to filtered gallery); search bar with 400ms debounce and filter-pill dismiss on `TracksView`. Nav updated with Albums and Genres links.
- **Architecture:** Filter is threaded as a separate `TrackFilter` DTO alongside `PagingParameters<T>` (which is external and cannot carry a where-clause). Repository has new `GetPagedFilteredAsync`, `GetDistinctAlbumsAsync`, `GetDistinctGenresAsync` methods. `PersistentComponentState` restore on `TracksView` is skipped when filter params are active. `ClearFilter` preserves `SearchText` (only clears album/genre pill).
- **New types:** `TrackFilter`, `AlbumSummaryDto`, `GenreSummaryDto` in `DeepDrftModels/DTOs/`.
- **Tests:** `TrackFilterQueryTests` in `DeepDrftTests` — 4 in-memory cases plus 1 Postgres-gated `ILike` case (skip when `DEEPDRFT_TEST_PG` env var absent).
---
## Phase 4.1 — HTTP Range + CDN caching
**Status:** Fully landed on 2026-06-09 (implementation complete, all acceptance criteria met, merged to dev branch `p4-w1-range-streaming`).
+7 -3
View File
@@ -87,11 +87,15 @@ The middleware pipeline in `Program.cs` is ordered as follows:
`TrackProxyController` in `Controllers/` is the only HTTP controller. It is a thin proxy only — no domain logic, no data layer. The WASM client points both named HttpClients (`"DeepDrft.API"` and `"DeepDrft.Content"`) at the Blazor host's base address, so all browser requests route through this controller to DeepDrftAPI. Server-side SSR calls DeepDrftAPI directly (server-to-server) via the same named clients — no proxy hop on the server side.
The proxy forwards two public, unauthenticated routes:
The proxy forwards public, unauthenticated routes:
- `GET api/track/page` — paged metadata listing
- `GET api/track/{trackId}` — WAV audio streaming (handles `offset` param for seek-beyond-buffer)
- `GET api/track/{trackId}` — WAV audio streaming (handles `Range` header for seek-beyond-buffer)
- `GET api/track/albums` — distinct albums with counts
- `GET api/track/genres` — distinct genres with counts
- `GET api/track/random` — random track selection
- `GET api/track/meta/by-key/{entryKey}` — metadata lookup by vault entry key
Both actions use `HttpCompletionOption.ResponseHeadersRead` for streaming efficiency. Audio streaming registers the upstream response with `HttpContext.Response.RegisterForDispose()` so the stream is properly cleaned up after the response body is sent.
All actions use `HttpCompletionOption.ResponseHeadersRead` for streaming efficiency. Audio streaming registers the upstream response with `HttpContext.Response.RegisterForDispose()` so the stream is properly cleaned up after the response body is sent.
## Development commands
-19
View File
@@ -79,25 +79,6 @@ These were flagged during the audit but classified as feature work, not defect f
These follow from `CONTEXT.md §5`. Direction is strongly implied but no specific UI has been committed.
### 2.2 Album and genre views
- **What:** `TrackCard` already renders album/genre/release date; the data is there. Missing are gallery groupings (album view, genre view), filters, and the API-side support for filter expressions in `TrackService.GetPaged`.
- **Why it matters:** The track gallery is the only working content surface. Multiple views over the same library is how it earns the "gallery" name.
- **Shape:** Per `CONTEXT.md §6`, the convention is one source of truth, multiple views over it. New views should consume the same `TracksViewModel` / `PagedResult<TrackEntity>` and differ only at the rendering layer.
- `TrackService.GetPaged` extended to accept a filter expression (or a simple structured filter DTO).
- `PagingParameters<T>` extended with a `Where: Expression<Func<T, bool>>?` or a parallel `FilterParameters<T>` — pick one to avoid drift.
- New routes (`/albums`, `/genres`) consume the same VM with different grouping / filter inputs.
- **Prerequisite:** **2.1** for any view that prominently features cover art (album view especially is impoverished without it).
### 2.3 Search and filter on the gallery
- **What:** `TracksViewModel` exposes sort but no filter. `TrackService.GetPaged` accepts only sort. Simple text search across `TrackName` / `Artist` / `Album` is the obvious first cut.
- **Why it matters:** Once the library has more than ~30 entries, sort-only browsing is friction.
- **Shape:** Same extension to `GetPaged` as 2.2. UI is a debounced text input bound to the VM's filter property. EF Core translates `Contains` to SQLite `LIKE`.
- **Prerequisite:** Fold into 2.2 if both are being done — the same `GetPaged` extension serves both. Doing them separately doubles the API churn.
---
## Phase 3 — New content kinds