1
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
export const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://127.0.0.1:8000";
|
||||
|
||||
export type Subject = { id: number; name: string; slug: string; created_at: string };
|
||||
export type Week = { id: number; subject_id: number; number: number; title?: string | null; created_at: string };
|
||||
export type Source = {
|
||||
id: number;
|
||||
week_id: number;
|
||||
original_name: string;
|
||||
stored_path: string;
|
||||
source_type: string;
|
||||
status: string;
|
||||
file_size?: number | null;
|
||||
sha256?: string | null;
|
||||
mime_type?: string | null;
|
||||
processor?: string | null;
|
||||
page_ranges?: string | null;
|
||||
processed_at?: string | null;
|
||||
document_id?: number | null;
|
||||
document_title?: string | null;
|
||||
document_markdown_path?: string | null;
|
||||
document_created_at?: string | null;
|
||||
created_at: string;
|
||||
};
|
||||
export type Job = { id: number; status: string; message: string; source_id?: number | null; document_id?: number | null; created_at: string; updated_at: string };
|
||||
export type DocumentItem = {
|
||||
id: number;
|
||||
source_id: number;
|
||||
title: string;
|
||||
markdown_path: string;
|
||||
source_original_name?: string | null;
|
||||
source_type?: string | null;
|
||||
source_status?: string | null;
|
||||
source_processor?: string | null;
|
||||
source_page_ranges?: string | null;
|
||||
created_at: string;
|
||||
};
|
||||
export type SettingsStatus = { mistral_configured: boolean; deepgram_configured: boolean; data_dir: string; database_path: string };
|
||||
|
||||
async function parseResponse<T>(response: Response): Promise<T> {
|
||||
if (!response.ok) {
|
||||
const detail = await response.json().catch(() => null);
|
||||
throw new Error(detail?.detail || `Error ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
async health() {
|
||||
return parseResponse<{ status: string }>(await fetch(`${API_URL}/health`, { cache: "no-store" }));
|
||||
},
|
||||
async settings() {
|
||||
return parseResponse<SettingsStatus>(await fetch(`${API_URL}/settings/status`, { cache: "no-store" }));
|
||||
},
|
||||
async subjects() {
|
||||
return parseResponse<Subject[]>(await fetch(`${API_URL}/subjects`, { cache: "no-store" }));
|
||||
},
|
||||
async subject(id: number) {
|
||||
return parseResponse<Subject>(await fetch(`${API_URL}/subjects/${id}`, { cache: "no-store" }));
|
||||
},
|
||||
async createSubject(name: string) {
|
||||
return parseResponse<Subject>(await fetch(`${API_URL}/subjects`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ name }),
|
||||
}));
|
||||
},
|
||||
async weeks(subjectId: number) {
|
||||
return parseResponse<Week[]>(await fetch(`${API_URL}/subjects/${subjectId}/weeks`, { cache: "no-store" }));
|
||||
},
|
||||
async week(subjectId: number, weekNumber: number) {
|
||||
return parseResponse<Week>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${weekNumber}`, { cache: "no-store" }));
|
||||
},
|
||||
async createWeek(subjectId: number, number: number, title: string) {
|
||||
return parseResponse<Week>(await fetch(`${API_URL}/subjects/${subjectId}/weeks`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ number, title: title || null }),
|
||||
}));
|
||||
},
|
||||
async updateWeek(subjectId: number, currentNumber: number, number: number, title: string) {
|
||||
return parseResponse<Week>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${currentNumber}`, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ number, title: title || null }),
|
||||
}));
|
||||
},
|
||||
async sources(subjectId: number, weekNumber: number) {
|
||||
return parseResponse<Source[]>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/sources`, { cache: "no-store" }));
|
||||
},
|
||||
async jobs(subjectId: number, weekNumber: number) {
|
||||
return parseResponse<Job[]>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/jobs`, { cache: "no-store" }));
|
||||
},
|
||||
async documents(subjectId: number, weekNumber: number) {
|
||||
return parseResponse<DocumentItem[]>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/documents`, { cache: "no-store" }));
|
||||
},
|
||||
async deleteSource(sourceId: number) {
|
||||
return parseResponse<{ status: string }>(await fetch(`${API_URL}/sources/${sourceId}`, { method: "DELETE" }));
|
||||
},
|
||||
async deleteDocument(documentId: number) {
|
||||
return parseResponse<{ status: string }>(await fetch(`${API_URL}/documents/${documentId}`, { method: "DELETE" }));
|
||||
},
|
||||
async reprocessSource(sourceId: number, useOcr: boolean, pageRanges?: string) {
|
||||
const params = new URLSearchParams({ use_ocr: String(useOcr) });
|
||||
if (pageRanges?.trim()) params.set("page_ranges", pageRanges.trim());
|
||||
return parseResponse<{ source: Source; job: Job }>(await fetch(`${API_URL}/sources/${sourceId}/reprocess?${params.toString()}`, { method: "POST" }));
|
||||
},
|
||||
async upload(subjectId: number, weekNumber: number, file: File, useOcr: boolean, pageRanges?: string) {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
const params = new URLSearchParams({ use_ocr: String(useOcr) });
|
||||
if (pageRanges?.trim()) params.set("page_ranges", pageRanges.trim());
|
||||
return parseResponse<{ source: Source; job: Job }>(await fetch(`${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/files?${params.toString()}`, {
|
||||
method: "POST",
|
||||
body: form,
|
||||
}));
|
||||
},
|
||||
async markdown(documentId: number) {
|
||||
const response = await fetch(`${API_URL}/documents/${documentId}/markdown`, { cache: "no-store" });
|
||||
if (!response.ok) throw new Error(`Error ${response.status}`);
|
||||
return response.text();
|
||||
},
|
||||
async document(documentId: number) {
|
||||
return parseResponse<DocumentItem>(await fetch(`${API_URL}/documents/${documentId}`, { cache: "no-store" }));
|
||||
},
|
||||
async saveMarkdown(documentId: number, content: string) {
|
||||
return parseResponse<DocumentItem>(await fetch(`${API_URL}/documents/${documentId}/markdown`, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ content }),
|
||||
}));
|
||||
},
|
||||
downloadDocumentUrl(documentId: number) {
|
||||
return `${API_URL}/documents/${documentId}/download`;
|
||||
},
|
||||
exportWeekUrl(subjectId: number, weekNumber: number) {
|
||||
return `${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/export`;
|
||||
},
|
||||
exportWeekZipUrl(subjectId: number, weekNumber: number) {
|
||||
return `${API_URL}/subjects/${subjectId}/weeks/${weekNumber}/export.zip`;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user