Commit Graph

14 Commits

Author SHA1 Message Date
kami cd46ac397f fix: populate canonical_name and stop writing generated normalized_name
Three separate insert paths made a fresh Postgres volume unusable. The live
database only works because its volume predates the constraints.

  - scanner.service.resolveOrCreateArtist inserted only (name), but
    schema.sql declares canonical_name NOT NULL with no default. Every
    artist insert failed, and processFile swallows per-file errors, so a
    scan reported success with 0 tracks and a permanently empty library.
  - enrichment.service inserted explicitly into artists.normalized_name,
    which is GENERATED ALWAYS AS (normalize_artist(name)) STORED:
    "cannot insert a non-DEFAULT value into column" (428C9). All
    enrichment artist creation failed on a fresh volume.
  - db.service.createArtist omitted canonical_name, same failure.

canonical_name holds the raw tag name, not normalize_artist() output,
which truncates on `/` and a standalone `x` ("AC/DC" -> "AC"). That is the
convention createLocalArtist already used. The truncation bug in
artists.name is pre-existing and deliberately left untouched here.

Verified on a scratch postgres:16-alpine with the real schema: the old
statement reproduces the NOT NULL violation, the new path yields
artists/albums/tracks/track_artists rows.

REVIEW-2026-07-30.md finding 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 23:39:24 +04:00
kami d497588c87 fix claim_fusion MV duplicate-key failure on concurrent refresh
Typecheck / typecheck (backend) (push) Has been cancelled
Typecheck / typecheck (workers) (push) Has been cancelled
The MV SELECTed COALESCE(user_id, zero-uuid) but GROUPed BY raw user_id,
so a global enrichment claim (user_id NULL) and a default-user behavior
claim (user_id = zero-uuid) for the same edge produced two rows that
collide on idx_claim_fusion_pk, breaking REFRESH ... CONCURRENTLY.
Exposed by the #219 listener_behavior same_scene_as/alias_of writes.

New migration rebuilds the MV grouping by the COALESCE'd user_id so the
two fuse into one row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 13:38:12 +04:00
kami 7005756684 fix Redis active-plan race between /v2/vibe/next and /feedback (#221)
Per-user SET NX PX lock with Lua CAS release around the
getActivePlan->mutate->setActivePlan span so concurrent prefetch +
feedback requests serialize instead of losing one side's write.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 13:29:38 +04:00
kami c41316ee99 fix vibe engine audit findings: pg.Pool, plan replan, dead exclusions, legacy engine removal
Backend:
- app.ts: switch shared pg.Client to pg.Pool with per-transaction clients (#205)
- v2.routes.ts: replace plan instead of appending on replan, fixing self-duplication (#206)
- session-director: populate recentExclusions, per-candidate ranking, batch repetition checks (#209/#211/#213/#215 + minor)
- db.service.ts: claim-fusion watermark, legacy recommendation_batch engine removed (#216/#219/#232)
- app.ts: drop test enqueue-job endpoint (#234)

Frontend:
- AudioEngine/Vibe/usePlaybackStore: dedupe completed feedback, gate feedback to vibe sessions, End Vibe stops playback, Keep toast, shuffle played-set (#207/#236/#237/#238/#239/#240)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 13:22:06 +04:00
kami 9eb25311c8 update PLANS.md with ssrf and re-enrich sections 2026-07-15 11:38:09 +04:00
kami a7fce17d5b fix ssrf guard in image proxy (#111)
- add domain allowlist for known image hosts (coverartarchive.org,
  lastfm.freetls.fastly.net, i.scdn.co, images.genius.com, etc.)
- validate redirect targets against allowlist before following
- parse URL properly instead of prefix check (prevents file:// bypass)
- log blocked requests for visibility
2026-07-15 11:24:17 +04:00
kami f4af906e22 fix n+1 queries in comfortGenerator and deepDiveGenerator (#110)
both generators ran N sequential queries per artist/album.
rewritten with ROW_NUMBER() OVER (PARTITION BY ...) to get per-group
limits in a single round-trip, preserving existing semantics:
- comfortGenerator: up to 2 tracks per artist (was 20 queries → 1)
- deepDiveGenerator: up to 5 tracks per album (was 20 queries → 1)
2026-07-15 11:23:54 +04:00
kami 3bc9f2d303 muzick: nginx proxy Bearer auth, restart policies, env subst 2026-07-14 15:51:10 +04:00
kami 5bb2f00213 fix muzick backend: pin @fastify/cors@^9.0.1, fix redis hostname, rebuild stale image 2026-07-14 15:31:44 +04:00
kami 5ed8d9e723 add API auth (#150 #151): MUZICK_API_KEY + MUZICK_ADMIN_KEY via Bearer token 2026-07-14 15:03:06 +04:00
kami ef7fe9e712 merge muzick redis into shared infra stack, rotate secrets 2026-07-14 14:42:53 +04:00
kami 78c46b2dcb fix #108 systemd service (docker compose), fix #109 pin postgres:16-alpine 2026-07-14 01:37:22 +04:00
kami 42474c65fd fix AGENTS.md stack ref, add CORS plugin, add .env.example, remove dead index.ts 2026-07-14 01:36:25 +04:00
kami 737bf19fd1 initial state: muzick music player + recommendation engine 2026-07-14 01:35:52 +04:00