initial state: muzick music player + recommendation engine
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
// Shared TypeScript types mirroring the backend (backend/src/services/db.service.ts).
|
||||
// Single-user app: the backend defaults the user when no `x-user-id` header is sent,
|
||||
// so the frontend currently omits the header. Add it here later for multi-user.
|
||||
|
||||
export type TrackState =
|
||||
| 'LIBRARY'
|
||||
| 'RECOMMENDED'
|
||||
| 'HIDDEN'
|
||||
| 'MISSING'
|
||||
| 'DELETED';
|
||||
|
||||
export type SourceType = 'MANUAL' | 'RECOMMENDATION';
|
||||
|
||||
export interface TrackArtist {
|
||||
id: string;
|
||||
name: string;
|
||||
role: 'main' | 'featured';
|
||||
}
|
||||
|
||||
export interface Track {
|
||||
id: string;
|
||||
path: string;
|
||||
hash: string;
|
||||
title: string;
|
||||
artist: string;
|
||||
album_id: string;
|
||||
duration: number;
|
||||
state: TrackState | string;
|
||||
play_count: number;
|
||||
skip_count: number;
|
||||
dislike_count: number;
|
||||
last_played_at?: string | null;
|
||||
mtime?: number | null;
|
||||
source_type: SourceType | string;
|
||||
artists?: TrackArtist[];
|
||||
artwork_id?: string | null; // album cover art
|
||||
}
|
||||
|
||||
export interface Artist {
|
||||
id: string;
|
||||
name: string;
|
||||
mbid?: string | null;
|
||||
discogs_id?: string | null;
|
||||
image_path?: string | null;
|
||||
}
|
||||
|
||||
export interface Album {
|
||||
id: string;
|
||||
artist_id: string;
|
||||
title: string;
|
||||
year?: number | null;
|
||||
artwork_id?: string | null;
|
||||
artist_name?: string | null;
|
||||
}
|
||||
|
||||
export interface ArtistWithAlbums extends Artist {
|
||||
albums: Album[];
|
||||
}
|
||||
|
||||
export interface AlbumWithTracks extends Album {
|
||||
tracks: Track[];
|
||||
}
|
||||
|
||||
// Genres are listed via GET /api/genres (with track_count), fetched individually
|
||||
// via GET /api/genres/:id, and their tracks via GET /api/genres/:id/tracks.
|
||||
export interface Genre {
|
||||
id: string;
|
||||
name: string;
|
||||
parent_id?: string | null;
|
||||
track_count?: number;
|
||||
}
|
||||
|
||||
export interface HealthResponse {
|
||||
postgres: 'ok' | 'error' | 'unknown';
|
||||
redis: 'ok' | 'error' | 'unknown';
|
||||
}
|
||||
|
||||
// Active v2 recommendation session. The sessionId comes from
|
||||
// POST /api/v2/vibe/start and identifies the Redis-stored plan.
|
||||
export interface VibeSession {
|
||||
sessionId: string;
|
||||
seedTrackId: string | null;
|
||||
}
|
||||
|
||||
// A row from GET /api/history: a Track plus playback metadata.
|
||||
export interface HistoryEntry extends Track {
|
||||
history_id: string;
|
||||
batch_id: string | null;
|
||||
played_at: string;
|
||||
completed: boolean;
|
||||
}
|
||||
|
||||
export interface DislikeEntry {
|
||||
track_id: string;
|
||||
disliked_at: string;
|
||||
warned_at: string | null;
|
||||
deleted_at: string | null;
|
||||
grace_hours: number;
|
||||
state: 'HIDDEN' | 'WARNED' | 'DELETED' | string;
|
||||
track_title: string;
|
||||
track_artist: string;
|
||||
track_path: string;
|
||||
}
|
||||
|
||||
export const FEEDBACK_ACTIONS = [
|
||||
'promoted',
|
||||
'disliked',
|
||||
'skipped',
|
||||
'deleted_permanent',
|
||||
] as const;
|
||||
|
||||
export type FeedbackAction = (typeof FEEDBACK_ACTIONS)[number];
|
||||
|
||||
// Typesense-style search response surfaced by GET /api/search?q=.
|
||||
export interface SearchHit<T> {
|
||||
document: T;
|
||||
}
|
||||
|
||||
export interface SearchResponse {
|
||||
found?: number;
|
||||
hits?: SearchHit<Track>[];
|
||||
[key: string]: unknown;
|
||||
}
|
||||
Reference in New Issue
Block a user