Files
muzick/frontend/src/types.ts
T
kami 9eba247a58
Typecheck / typecheck (backend) (push) Has been cancelled
Typecheck / typecheck (workers) (push) Has been cancelled
Typecheck / typecheck (backend) (pull_request) Has been cancelled
Typecheck / typecheck (workers) (pull_request) Has been cancelled
refactor(vibe): simplify durable session flow
2026-08-03 12:44:08 +04:00

124 lines
2.8 KiB
TypeScript

// 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 durable recommendation session. The sessionId comes from
// POST /api/v2/vibe/sessions and identifies its persisted 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;
}