// ─── Types ──────────────────────────────────────────────────────────────────── export interface LoginResponse { status: string; message: string; data: { id: string; fullname: string; email: string; company: string; company_size: string; function: string; site: string; role: string; status: string; created_at: string; }; } export interface Room { id: string; title: string; created_at: string; updated_at: string | null; } export interface CreateRoomResponse { status: string; message: string; data: Room; } export interface RoomMessage { id: string; role: "user" | "assistant"; content: string; created_at: string; } export interface RoomDetail extends Room { messages: RoomMessage[]; } export type DocumentStatus = "pending" | "processing" | "completed" | "failed"; export interface ApiDocument { id: string; filename: string; status: DocumentStatus; file_size: number; file_type: string; created_at: string; } export interface UploadDocumentResponse { status: string; message: string; data: { id: string; filename: string; status: DocumentStatus }; } export interface ChatSource { document_id: string; filename: string; page_label: string | null; } // ─── Base Client ────────────────────────────────────────────────────────────── const BASE_URL = ((import.meta as unknown as { env: Record }).env.VITE_API_BASE_URL) ?? ""; async function request(path: string, options?: RequestInit): Promise { const res = await fetch(`${BASE_URL}${path}`, { headers: { "Content-Type": "application/json", ...options?.headers }, ...options, }); if (!res.ok) { const err = await res .json() .catch(() => ({ detail: `HTTP ${res.status}` })); throw new Error(err.detail ?? `HTTP ${res.status}`); } return res.json() as Promise; } // ─── Auth ───────────────────────────────────────────────────────────────────── export const login = (email: string, password: string) => request("/api/login", { method: "POST", body: JSON.stringify({ email, password }), }); // ─── Rooms ──────────────────────────────────────────────────────────────────── export const getRooms = (userId: string) => request(`/api/v1/rooms/${userId}`); export const getRoom = (roomId: string) => request(`/api/v1/room/${roomId}`); export const deleteRoom = (roomId: string, userId: string) => request<{ status: string; message: string }>( `/api/v1/room/${roomId}?user_id=${userId}`, { method: "DELETE" } ); export const createRoom = (userId: string, title?: string) => request("/api/v1/room/create", { method: "POST", body: JSON.stringify({ user_id: userId, title }), }); // ─── Documents ──────────────────────────────────────────────────────────────── export const getDocuments = (userId: string) => request(`/api/v1/documents/${userId}`); export const uploadDocument = async ( userId: string, file: File ): Promise => { const form = new FormData(); form.append("file", file); const res = await fetch( `${BASE_URL}/api/v1/document/upload?user_id=${userId}`, { method: "POST", body: form } ); if (!res.ok) { const err = await res .json() .catch(() => ({ detail: `HTTP ${res.status}` })); throw new Error(err.detail ?? `HTTP ${res.status}`); } return res.json() as Promise; }; export const processDocument = (userId: string, documentId: string) => request<{ status: string; message: string; data: { document_id: string; chunks_processed: number }; }>( `/api/v1/document/process?document_id=${documentId}&user_id=${userId}`, { method: "POST" } ); export const deleteDocument = (userId: string, documentId: string) => request<{ status: string; message: string }>( `/api/v1/document/delete?document_id=${documentId}&user_id=${userId}`, { method: "DELETE" } ); // ─── Chat ───────────────────────────────────────────────────────────────────── export const streamChat = ( userId: string, roomId: string, message: string ): Promise => fetch(`${BASE_URL}/api/v1/chat/stream`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: userId, room_id: roomId, message }), });