Commit Graph

32 Commits

Author SHA1 Message Date
bvandeusen 20963847c2 docs(spec): add M3 session similarity + contextual_match_score design
Closes M3 — adds the `contextual_match_score` term to the scoring formula
via weighted-Jaccard similarity (tags 0.7, artists 0.3) over the user's
contextual_likes. Reads the current session vector from the most recent
open play_event (populated by sub-plan #2). Cold-start paths collapse to
zero contribution, preserving v1 behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-27 19:57:10 -04:00
bvandeusen 38beadf22e docs(plan): add M3 session vectors + contextual likes implementation plan
7 tasks: contextual_likes migration + sqlc, events.sql vector queries +
LikeTrack :execrows change, BuildSessionVector pure function, vector
capture in playevents.Writer, contextual_likes helpers + api handler
updates, subsonic handler updates, final verification.
2026-04-27 10:05:52 -04:00
bvandeusen 08eb1e3f8c docs(spec): add M3 session vectors + contextual likes design
Sub-plan #2 of 3 in M3 (Fable #341). Two write-path additions on top
of M2's events + likes infra:

1. play_started: compute session vector from prior 5 tracks in
   current play_session, write to play_events.session_vector_at_play.
2. like a track: if open play_event has populated vector, snapshot
   into contextual_likes with vector + session_id. Soft-delete on
   unlike (deleted_at column gates engine queries).

Includes new migration 0007_contextual_likes — the table was missing
from migration 0005 despite being mentioned in its comments. Adds
GIN index for sub-plan #3's similarity queries.

Backend-only slice; no UI changes.
2026-04-27 09:56:45 -04:00
bvandeusen b9937d6e3b docs(plan): add M3 weighted shuffle v1 implementation plan
7 tasks: pure score function, pure shuffle orchestrator, sqlc
LoadRadioCandidates query, DB-backed candidate loader,
RecommendationConfig + YAML, /api/radio handler rewrite, final
verification + branch finish.
2026-04-27 07:35:13 -04:00
bvandeusen f51b7c05ae docs(spec): add M3 weighted shuffle v1 design
Replaces the M2 stub /api/radio with real weighted-shuffle scoring:
LikeBoost + recency_decay - skip_ratio penalty + jitter, hard
suppression of last-hour plays. Wide candidate pool (whole library)
for v1; M4 adds similarity-based pool refinement. Pure scoring
function in internal/recommendation; live-DB candidate loader; HTTP
handler is a thin shim. No web changes — existing playRadio action
already calls /api/radio.

Sub-plan #1 of 3 in M3 (Fable #340). Session vectors and contextual
match score land in the next two sub-plans.
2026-04-27 01:35:51 -04:00
bvandeusen 1f08ee39bd fix(web): add likes/QueryClient mocks to route tests rendering LikeButton
Pages that render TrackRow/AlbumCard/ArtistRow/PlayerBar now indirectly
mount LikeButton, which calls useQueryClient(). Route tests need the
same mocks the component-level tests have.

- Added createLikedIdsQuery mock to 7 route test files
- Added useQueryClient mock to all affected route tests
- Added readable store import where needed
2026-04-26 17:18:39 -04:00
bvandeusen a3c05aeb34 docs(plan): add M2 likes implementation plan
9 tasks: schema + sqlc, native API, Subsonic star/unstar,
Subsonic getStarred/getStarred2, web likes.ts factory + mutations,
LikeButton component, wire LikeButton into existing components,
/library/liked page, final verification.
2026-04-26 15:52:42 -04:00
bvandeusen f91257a79e docs(spec): add M2 likes sub-plan design
Three new tables (general_likes, general_likes_albums,
general_likes_artists), seven native /api/likes/* endpoints, four
Subsonic handlers (star/unstar/getStarred/getStarred2), and web UI
heart buttons on TrackRow/AlbumCard/ArtistRow/PlayerBar plus a new
/library/liked page. Closes M2 (with the events foundation already
in main).

Liked state is computed client-side via O(1) Set lookups against a
single createLikedIdsQuery cache; server stays simple per request
(no joins added to entity reads). Optimistic updates with rollback.
2026-04-26 15:44:45 -04:00
bvandeusen 7df48ee9bc docs(plan): add M2 events sub-plan implementation plan
9 tasks: schema migration, events config, playsessions service,
playevents writer, /api/events handler, Subsonic scrobble integration,
web clientId + events dispatcher, layout wiring, final verification.
Tightly TDD-shaped with full code in every step.
2026-04-25 19:56:58 -04:00
bvandeusen f3b28db9d1 docs(spec): add M2 events sub-plan design
Specifies POST /api/events with start+end semantics, session service
(30-min rolling), play/skip classification (spec §6 boundaries),
sendBeacon + auto-close-on-next-start for abandoned plays, and
Subsonic /rest/scrobble integration that writes synthetic completed
plays so third-party clients feed the recommendation pipeline.

Schema migration ships the full M2 set (play_events, skip_events,
sessions) including M3-only nullable columns so M3 doesn't need a
follow-up migration. General likes deferred to a separate M2
sub-plan; this slice covers spec §13 step 5 only.
2026-04-25 19:39:16 -04:00
bvandeusen 8fd193e186 docs(plan): add web UI search implementation plan
12 tasks: server radio stub, web types, player-store enqueue/playRadio,
query helpers, TrackRow div+role refactor, AlbumCard +queue overlay,
SearchInput header component, SearchSkeleton, Shell wiring, /search
main page, three overflow pages, final verification.
2026-04-25 14:59:08 -04:00
bvandeusen 3588af83e5 docs(spec): add web UI search design
Specifies header search bar (debounced, URL-synced ?q=), /search page
with three sections of top-10 reusing library components, three
overflow routes (/search/artists, /search/albums, /search/tracks)
backed by createInfiniteQuery. Track click triggers playRadio with
seed via a new /api/radio stub that returns the seed alone (M4 fills
in real similarity-based selection later, response shape final). Adds
+queue button on TrackRow and AlbumCard via new enqueueTrack /
enqueueTracks player-store actions.
2026-04-25 14:49:01 -04:00
bvandeusen 7c19fe8a6a docs(plan): add web UI player implementation plan
8 TDD tasks: player rune store (2 tasks covering basic actions then
shuffle/repeat/audio-reporting), MediaSession glue, click-to-play
wiring in TrackRow + album page, PlayerBar component, Shell 3rd-row
integration, audio element wiring in root layout, and a final
verification + branch-finish step.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 08:57:52 -04:00
bvandeusen d6ea734152 docs(spec): add web UI player design
Queue-based playback on top of HTMLAudioElement: rune store + pure
action functions, single <audio> mounted in the root layout driven
via $effect, MediaSession metadata/action handlers, and a persistent
bottom bar with shuffle/repeat/volume. Non-goals: server-side listen
history (awaiting /api/events), cross-refresh persistence, keyboard
shortcuts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 08:50:58 -04:00
bvandeusen f9b02c4051 docs(plan): Task 13 — match the type-safety fixes applied in Task 12
page.params.id is string|undefined in SvelteKit types; use ?? ''.
TanStack Query's error is typed as Error; cast through unknown to ApiError.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 20:13:20 -04:00
bvandeusen 25d44a180c docs(plan): update Tasks 12/13 to unwrap TanStack Query's Readable store
TanStack Query 5's Svelte adapter returns a Readable<QueryObserverResult>
store, not a plain object. Pages need to destructure with $-subscription:
  const queryStore = $derived(createXQuery(id));
  const query = $derived($queryStore);

Applied to artist + album detail page templates. Task 11 already
landed with this fix (and readable-wrapped mocks in test-utils).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 20:01:46 -04:00
bvandeusen 4cd67405c9 docs(plan): update useDelayed task to match .svelte.test.ts convention
Rune-using test files need the .svelte. infix so vite-plugin-svelte
processes them. Also adds the flushSync() after $effect.root in the
'source already true' test so fake-timer advances fire the scheduled
timeout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 18:16:37 -04:00
bvandeusen ea17be9d45 docs(plan): add web UI library views implementation plan
14 TDD tasks: API types, formatDuration + covers helpers, useDelayed
rune, TanStack Query wrappers, 5 shared components (ArtistRow,
AlbumCard, TrackRow, LibrarySkeleton, ApiErrorBanner), 3 page routes
(/, /artists/:id, /albums/:id) with mocked-query integration tests,
and a final verification + branch-finish step.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:18:08 -04:00
bvandeusen 248f03495e docs(spec): add web UI library views design
Covers the three browse routes (/, /artists/:id, /albums/:id) on top
of the existing /api/artists, /api/artists/{id}, /api/albums/{id},
and /api/albums/{id}/cover endpoints. Uses TanStack Query's infinite
query for the artists list with Load-more pagination, reusable card
and row components, and a shared delayed-skeleton pattern for
cache-hit navigation feel.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:09:55 -04:00
bvandeusen fe410f14eb docs(plan): correct login test filename to avoid route walker collision
Renamed references from +page.test.ts to login.test.ts throughout,
matching the fix in 8896159. Keeps the plan accurate for re-runs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 06:10:29 -04:00
bvandeusen 12bf873f39 docs(plan): fix invalid toMatchObject<T> type-arg in auth plan
vitest's toMatchObject doesn't accept a type parameter. Removed the
annotation in Task 3 test code (and the unused ApiError import) so
re-runs of the plan don't reintroduce the type error fixed in 8a6a496.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 17:26:37 -04:00
bvandeusen 0b5c4a13bf docs(plan): add web UI auth implementation plan
12 TDD tasks: deps, api client, query client, auth store, 401
interceptor, Shell, placeholder pages, login page, root layout
wiring, and final verification + branch finish. Each task writes
the failing test first, then minimum implementation, then commits.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:47:23 -04:00
bvandeusen d53e7e2985 docs(spec): add web UI auth design
Covers the login flow, session store, fetch wrapper, persistent Shell,
and route guarding for the first frontend feature on top of the scaffold.
Commits to TanStack Query as the data layer going forward.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:40:07 -04:00
bvandeusen 8da51a1d13 docs: add Plan 3 web UI media endpoints implementation plan
Four-task TDD plan for /api/albums/{id}/cover and /api/tracks/{id}/stream:
scaffold media.go helpers (Task 1), cover handler (Task 2), stream handler
(Task 3), production Mount wiring + route-registration regression (Task 4).
Uses seedTrackWithFile helper to materialize real bytes on disk so Range /
If-Modified-Since tests hit http.ServeContent's real code path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 22:02:55 -04:00
bvandeusen 20c948a346 docs: clarify sidecar ordering and test helper extension in Plan 3 spec
Self-review fixups: make "first track" explicit (by disc/track order) and
replace the awkward "so existing tests continue to compile" phrasing with a
clearer description of why newLibraryRouter needs extending.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 21:52:07 -04:00
bvandeusen 7fcee05c1e docs: add Plan 3 web UI media endpoints spec
Covers /api/albums/{id}/cover and /api/tracks/{id}/stream — the byte-serving
endpoints Plan 2's cover_url / stream_url forward references point at.
Duplicates protocol-agnostic helpers locally per subsonic-is-legacy direction
rather than extracting a shared package.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 21:51:29 -04:00
bvandeusen 62e48642e2 docs(plan): add implementation plan for library reads + search
12 TDD-style tasks covering SQL additions, DTOs, conversion helpers,
per-endpoint handlers (tracks, albums, artist detail, artist list, search),
route wiring, and an end-to-end smoke + PR. Follows the approved design at
docs/superpowers/specs/2026-04-20-web-ui-library-reads-design.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 23:42:47 -04:00
bvandeusen 14aa9d7fba docs(spec): add design for library reads + search endpoints
Plan 2 of the web UI rollout. Covers GET /api/artists (paged, two sort
modes), artist/album/track detail, and unified search with enveloped
pagination and forward-reference stream/cover URLs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 23:33:51 -04:00
bvandeusen 9b0433ad9b docs: add web UI server auth foundation plan
10-task plan for the first implementation slice of the web UI
scaffold: sessions table, /api/auth/{login,logout}, /api/me, and
the RequireUser middleware (cookie + bearer). Stops short of the
library read endpoints and the SvelteKit project, which become
their own follow-up plans.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 19:30:24 -04:00
bvandeusen cb3df51f08 docs: add web UI scaffold design spec
First pass of the web UI design doc from the M1 close-out brainstorm.
Covers the stack (SvelteKit static + Go embed), auth model
(cookie + bearer from one endpoint), /api/* surface, shell layout
(sidebar + bottom player), first-cut feature scope, and how later
web UI work threads into M2–M5 alongside each backend milestone
instead of landing as a post-hoc M6.

Also ignores the local .superpowers/ brainstorming companion cache.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 19:18:04 -04:00
bvandeusen 419c0b6f4c docs: seed client spec on dev 2026-04-18 17:58:00 +00:00
bvandeusen 5861c146f7 docs: seed server spec on dev 2026-04-18 17:56:28 +00:00