export type TrackAvailability = 'server' | 'downloading' | 'error' | 'missing'; export interface Track { id: string; title: string; artistId: string; artistName: string; albumId: string; albumTitle: string; albumArtUrl?: string; durationMs: number; trackNumber?: number; discNumber?: number; year?: number; genre?: string; availability: TrackAvailability; fileSize?: number; format?: string; bitrate?: number; liked: boolean; } export interface Album { id: string; title: string; artistId: string; artistName: string; artUrl?: string; year?: number; trackCount: number; totalDurationMs: number; genre?: string; } export interface Artist { id: string; name: string; artUrl?: string; albumCount: number; trackCount: number; } export interface Playlist { id: string; name: string; description?: string; ownerId: string; trackCount: number; totalDurationMs: number; artUrl?: string; isPublic: boolean; createdAt: string; updatedAt: string; } export interface PlaylistTrack extends Track { position: number; addedAt: string; } export interface DownloadJob { id: string; url: string; title?: string; artist?: string; album?: string; status: 'queued' | 'downloading' | 'processing' | 'done' | 'error'; progress: number; errorMessage?: string; trackId?: string; createdAt: string; updatedAt: string; } export interface UploadResponse { track_id: string; title: string; already_exists: boolean; } export interface StorageStats { totalBytes: number; usedBytes: number; trackCount: number; albumCount: number; artistCount: number; } export interface User { id: string; username: string; email?: string; role: 'admin' | 'user'; createdAt: string; lastActiveAt?: string; } export interface AuthTokens { accessToken: string; refreshToken: string; expiresIn: number; } export interface LoginRequest { username: string; password: string; } export interface LoginResponse { user: User; tokens: AuthTokens; } export interface PaginatedResponse { items: T[]; total: number; page: number; pageSize: number; hasMore: boolean; } export interface LibraryFilters { search?: string; genre?: string; artistId?: string; albumId?: string; liked?: boolean; page?: number; pageSize?: number; sortBy?: 'title' | 'artist' | 'album' | 'year' | 'dateAdded'; sortOrder?: 'asc' | 'desc'; } export interface ApiError { status: number; message: string; code?: string; }