Add FastAPI backend and React frontend subprojects
Backend: - FastAPI app with 17 REST endpoints covering dashboard, monitoring, media index, file browser, and jobs - Reuses existing clients/domain/services unchanged - pydantic-settings config, dependency injection, CORS setup - Auto-generated OpenAPI docs at /docs Frontend: - Vite + React + TypeScript SPA - @tanstack/react-query for data fetching with polling - ag-grid-react for media table and file browser - recharts for monitoring charts - Tailwind CSS styling - 4 pages: Dashboard, Monitoring, Media, File Browser - Typed API client matching all backend endpoints Also: - docs/MIGRATION_PLAN.md with full architecture plan - Updated .gitignore for both subprojects - Streamlit app preserved for now (can coexist)
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Shared TypeScript interfaces matching backend API responses.
|
||||
*/
|
||||
|
||||
export interface MediaCounts {
|
||||
movies: number;
|
||||
series: number;
|
||||
episodes: number;
|
||||
}
|
||||
|
||||
export interface LibraryCount {
|
||||
library: string;
|
||||
type: string;
|
||||
movies: number;
|
||||
series: number;
|
||||
episodes: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface NowPlayingSession {
|
||||
user: string;
|
||||
title: string;
|
||||
type: string;
|
||||
state: string;
|
||||
transcoding: string;
|
||||
transcoding_type: string;
|
||||
device: string;
|
||||
session_id: string;
|
||||
}
|
||||
|
||||
export interface MonitoringStatus {
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface MonitoringSample {
|
||||
ts: number;
|
||||
cpu_pct: number;
|
||||
iowait_pct?: number;
|
||||
mem_pct: number;
|
||||
net_rx_bytes_per_sec: number;
|
||||
net_tx_bytes_per_sec: number;
|
||||
disk_read_bps: number;
|
||||
disk_write_bps: number;
|
||||
}
|
||||
|
||||
export interface MonitoringMetrics {
|
||||
samples: MonitoringSample[];
|
||||
total_samples: number;
|
||||
filtered_samples: number;
|
||||
cutoff_ts: number;
|
||||
}
|
||||
|
||||
export interface DiskSpace {
|
||||
filesystem: string;
|
||||
size: number;
|
||||
used: number;
|
||||
available: number;
|
||||
used_pct: string;
|
||||
mount: string;
|
||||
}
|
||||
|
||||
export interface MediaIndexStatus {
|
||||
exists: boolean;
|
||||
item_count: number;
|
||||
updated_at: number | null;
|
||||
updated_at_label: string;
|
||||
build_duration_seconds: number | null;
|
||||
}
|
||||
|
||||
export interface MediaItem {
|
||||
id: string;
|
||||
title: string;
|
||||
series: string;
|
||||
season: string;
|
||||
episode: number | null;
|
||||
type: string;
|
||||
year: number | null;
|
||||
runtime_min: number | null;
|
||||
size: string;
|
||||
bitrate: string;
|
||||
hdr: string;
|
||||
video: string;
|
||||
resolution: string;
|
||||
date_added: string;
|
||||
library: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface MediaQueryResponse {
|
||||
items: MediaItem[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface FileEntry {
|
||||
type: string;
|
||||
size: number;
|
||||
mtime: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface DirectoryListing {
|
||||
path: string;
|
||||
entries: FileEntry[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface JobTemplate {
|
||||
key: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface JobResult {
|
||||
job_key: string;
|
||||
path: string;
|
||||
exit_status: number;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
export interface ResolvedPath {
|
||||
original: string;
|
||||
resolved: string;
|
||||
}
|
||||
Reference in New Issue
Block a user