feat: taste onboarding for new listeners (M6)
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m2s
ci / db / db (push) Failing after 1m29s
ci / ts / ts (packages + web) (push) Successful in 49s
ci / api / api (push) Successful in 1m25s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 48s
ci / recommender / recommender (push) Successful in 21s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m2s
ci / db / db (push) Failing after 1m29s
ci / ts / ts (packages + web) (push) Successful in 49s
ci / api / api (push) Successful in 1m25s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 48s
ci / recommender / recommender (push) Successful in 21s
- GET /onboarding offers the library's top artists (with album covers) and genres and says whether to show it (not done and < 10 plays); PUT /me/onboarding stores the choice or a skip (migration 00009). - The recommender seeds the taste from it while the user has fewer than 30 scored tracks: chosen artists' tracks +1, chosen genres +0.5. - Web: onboarding replaces the wave on the home page until done or skipped; artist grid with covers, genre chips, at least 3 artists. - e2e journey and the recommender DB test cover it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ff0aafdb1e
commit
fb07f962eb
14 files changed
+1137
-238
No files matched your search
@@ -3,6 +3,7 @@
|
||||
Локально: TEST_DATABASE_URL=postgresql://… uv run pytest tests/test_db_integration.py
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import uuid
|
||||
@@ -139,3 +140,22 @@ def test_training_and_wave_queries(world: dict[str, Any]) -> None:
|
||||
assert active is not None and active[0] == 1
|
||||
picks = build_batch(index, profile, Session(), [], n=5, rng=np.random.default_rng(0))
|
||||
assert len(picks) == 5
|
||||
|
||||
|
||||
def test_onboarding_seeds_taste(world: dict[str, Any]) -> None:
|
||||
user = uid()
|
||||
with psycopg.connect(DSN, autocommit=True) as conn:
|
||||
conn.execute(
|
||||
"INSERT INTO users (id, username, password_hash) VALUES (%s, %s, 'x')", (user, f"new-{user[:6]}")
|
||||
)
|
||||
artist = conn.execute(
|
||||
"SELECT artist_id::text FROM track_artists WHERE track_id = %s", (world["tracks"][0],)
|
||||
).fetchone()
|
||||
assert artist is not None
|
||||
conn.execute(
|
||||
"INSERT INTO user_profiles_rec (user_id, onboarding) VALUES (%s, %s)",
|
||||
(user, json.dumps({"artist_ids": [artist[0]], "genres": []})),
|
||||
)
|
||||
profile = load_profile(conn, user)
|
||||
assert len(profile.scores) >= 10, "chosen artist's tracks become the initial taste"
|
||||
assert not profile.played
|
||||
Reference in new issue
Block a user