feat(api): My Wave sessions with a Go fallback and wave metrics (M4)
- /wave/options, POST /wave/sessions (activity, mood, seed), /next with reactions, PATCH to switch the context on the fly, DELETE - the recommender is called with an 800 ms budget; on failure the api serves a fallback wave of likes, favourite artists and random available tracks with the same dislike / recent / served filters - every served track is an impression with its source and model; wave events (context_type wave) set its outcome, reactions win - library status shows the analysis queue and 7-day wave metrics: listen-through, early skip and like rate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ef29b85320
commit
3908814cda
13 files changed
+1811
-162
No files matched your search
+215
-1
@@ -17,6 +17,7 @@ tags:
|
||||
- name: search
|
||||
- name: playback
|
||||
- name: collection
|
||||
- name: wave
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
@@ -974,6 +975,93 @@ paths:
|
||||
description: Снято
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
/api/v1/wave/options:
|
||||
get:
|
||||
operationId: getWaveOptions
|
||||
tags: [wave]
|
||||
summary: Занятия и настроения (ключи для i18n и иконки)
|
||||
responses:
|
||||
"200":
|
||||
description: Варианты
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveOptions"
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
/api/v1/wave/sessions:
|
||||
post:
|
||||
operationId: startWave
|
||||
tags: [wave]
|
||||
summary: Начать «Мою волну»
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveStart"
|
||||
responses:
|
||||
"201":
|
||||
description: Сессия и первая пачка
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveBatch"
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
/api/v1/wave/sessions/{id}:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/EntityId"
|
||||
patch:
|
||||
operationId: updateWave
|
||||
tags: [wave]
|
||||
summary: Сменить занятие / настроение на лету — пачка пересобирается
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveContext"
|
||||
responses:
|
||||
"200":
|
||||
description: Новая пачка
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveBatch"
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
delete:
|
||||
operationId: endWave
|
||||
tags: [wave]
|
||||
summary: Завершить сессию волны
|
||||
responses:
|
||||
"204":
|
||||
description: Завершена
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
/api/v1/wave/sessions/{id}/next:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/EntityId"
|
||||
post:
|
||||
operationId: nextWave
|
||||
tags: [wave]
|
||||
summary: Следующая пачка с учётом реакций на выданные треки
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveNext"
|
||||
responses:
|
||||
"200":
|
||||
description: Пачка
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/WaveBatch"
|
||||
default:
|
||||
$ref: "#/components/responses/Problem"
|
||||
components:
|
||||
parameters:
|
||||
SourceId:
|
||||
@@ -1566,8 +1654,12 @@ components:
|
||||
nullable: true
|
||||
LibraryStatus:
|
||||
type: object
|
||||
required: [artists, albums, tracks, files, missing_files, file_errors, sources]
|
||||
required: [artists, albums, tracks, files, missing_files, file_errors, sources, analysis, wave]
|
||||
properties:
|
||||
analysis:
|
||||
$ref: "#/components/schemas/AnalysisStatus"
|
||||
wave:
|
||||
$ref: "#/components/schemas/WaveMetrics"
|
||||
artists:
|
||||
type: integer
|
||||
albums:
|
||||
@@ -2022,6 +2114,128 @@ components:
|
||||
properties:
|
||||
reaction:
|
||||
$ref: "#/components/schemas/Reaction"
|
||||
WaveOption:
|
||||
type: object
|
||||
required: [key, icon]
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
example: running
|
||||
icon:
|
||||
type: string
|
||||
description: Имя иконки Material Symbols
|
||||
WaveOptions:
|
||||
type: object
|
||||
required: [activities, moods]
|
||||
properties:
|
||||
activities:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/WaveOption"
|
||||
moods:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/WaveOption"
|
||||
WaveContext:
|
||||
type: object
|
||||
properties:
|
||||
activity:
|
||||
type: string
|
||||
nullable: true
|
||||
mood:
|
||||
type: string
|
||||
nullable: true
|
||||
WaveStart:
|
||||
type: object
|
||||
properties:
|
||||
activity:
|
||||
type: string
|
||||
nullable: true
|
||||
mood:
|
||||
type: string
|
||||
nullable: true
|
||||
seed:
|
||||
type: object
|
||||
required: [type, id]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: [track, album, artist]
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
WaveFeedback:
|
||||
type: object
|
||||
required: [track_id, outcome]
|
||||
properties:
|
||||
track_id:
|
||||
type: string
|
||||
format: uuid
|
||||
outcome:
|
||||
type: string
|
||||
enum: [complete, skip, skip_early, like, dislike]
|
||||
WaveNext:
|
||||
type: object
|
||||
properties:
|
||||
feedback:
|
||||
type: array
|
||||
maxItems: 50
|
||||
items:
|
||||
$ref: "#/components/schemas/WaveFeedback"
|
||||
WaveBatch:
|
||||
type: object
|
||||
required: [session_id, activity, mood, tracks, fallback]
|
||||
properties:
|
||||
session_id:
|
||||
type: string
|
||||
format: uuid
|
||||
activity:
|
||||
type: string
|
||||
nullable: true
|
||||
mood:
|
||||
type: string
|
||||
nullable: true
|
||||
tracks:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Track"
|
||||
fallback:
|
||||
type: boolean
|
||||
description: Рекомендатель недоступен — пачка собрана упрощённо (лайки, любимые исполнители)
|
||||
AnalysisStatus:
|
||||
type: object
|
||||
required: [queued, running, done, failed, analyzer_ver]
|
||||
properties:
|
||||
queued:
|
||||
type: integer
|
||||
running:
|
||||
type: integer
|
||||
done:
|
||||
type: integer
|
||||
failed:
|
||||
type: integer
|
||||
analyzer_ver:
|
||||
type: string
|
||||
nullable: true
|
||||
WaveMetrics:
|
||||
type: object
|
||||
required: [served, listen_through_rate, early_skip_rate, like_rate, sessions]
|
||||
description: Метрики волны за 7 дней
|
||||
properties:
|
||||
served:
|
||||
type: integer
|
||||
listen_through_rate:
|
||||
type: number
|
||||
nullable: true
|
||||
early_skip_rate:
|
||||
type: number
|
||||
nullable: true
|
||||
like_rate:
|
||||
type: number
|
||||
nullable: true
|
||||
description: Лайков на 100 треков
|
||||
sessions:
|
||||
type: integer
|
||||
Session:
|
||||
type: object
|
||||
required: [id, device_name, client_type, created_at, last_used_at, current]
|
||||
|
||||
Reference in new issue
Block a user