// Database types for Supabase tables export interface Book { id: string; title: string; description: string | null; status: 'Planning' | 'Draft' | 'In Progress' | 'Completed' | 'Published'; word_count: number; created_at: string; updated_at: string; user_id: string; // Metadata author: string | null; cover_image_url: string | null; genre: string | null; target_word_count: number | null; template_id: string | null; // Settings (stored as JSONB) settings: Record; } export interface GeneratedImage { id: string; user_id: string; book_id: string | null; prompt: string; revised_prompt: string | null; image_url: string; model: string; size: string; quality: string; style: string; cost_usd: number; metadata: Record; created_at: string; updated_at: string; } export interface BookTemplate { id: string; name: string; description: string | null; is_default: boolean; is_system: boolean; structure: TemplateStructure; created_by: string | null; created_at: string; updated_at: string; metadata: Record; } export interface TemplateStructure { files: TemplateFile[]; folders: TemplateFolder[]; } export interface TemplateFile { name: string; type: 'file'; content: string; file_extension: string; mime_type: string; sort_order: number; } export interface TemplateFolder { name: string; type: 'folder'; expanded: boolean; sort_order: number; children?: (TemplateFile | TemplateFolder)[]; } export interface FileSystemItem { id: string; book_id: string; parent_id: string | null; // Basic properties name: string; type: 'file' | 'folder'; // File-specific properties content: string | null; file_extension: string | null; mime_type: string | null; file_size: number | null; file_url: string | null; // Folder-specific properties expanded: boolean; // Ordering and organization sort_order: number; // Timestamps created_at: string; updated_at: string; // Metadata (stored as JSONB) metadata: Record; } // Extended interface for UI purposes (matches current FileItem interface) export interface FileItem { // Convert database IDs to numbers for compatibility with existing UI id: number; parent_id?: number | null; // Basic properties name: string; type: 'file' | 'folder'; // File-specific properties content?: string; file_extension?: string | null; mime_type?: string | null; file_size?: number | null; file_url?: string | null; // Folder-specific properties expanded?: boolean; // Ordering and organization sort_order?: number; // For nested structure in UI children?: FileItem[]; } // For API requests export interface CreateBookRequest { title: string; description?: string; author?: string; genre?: string; genres?: string[]; target_word_count?: number; template_id?: string; } export interface UpdateBookRequest { title?: string; description?: string; author?: string; status?: Book['status']; genre?: string; target_word_count?: number; cover_image_url?: string; settings?: Record; } export interface CreateFileSystemItemRequest { book_id: string; parent_id?: string | null; name: string; type: 'file' | 'folder'; content?: string; file_extension?: string; mime_type?: string; sort_order?: number; } export interface UpdateFileSystemItemRequest { name?: string; content?: string; expanded?: boolean; sort_order?: number; parent_id?: string | null; } // Response types export interface BookWithStats extends Book { file_count?: number; folder_count?: number; last_modified_file?: string; } // For the file tree view export interface FileTreeItem extends FileSystemItem { depth: number; path: number[]; children?: FileTreeItem[]; } // Utility types for common operations export type BookStatus = Book['status']; export type FileType = FileSystemItem['type']; // Common mime types for validation export const SUPPORTED_MIME_TYPES = { // Text files 'text/plain': ['.txt'], 'text/markdown': ['.md', '.markdown'], 'text/html': ['.html', '.htm'], 'application/json': ['.json'], // Documents 'application/pdf': ['.pdf'], 'application/msword': ['.doc'], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], // Images 'image/jpeg': ['.jpg', '.jpeg'], 'image/png': ['.png'], 'image/gif': ['.gif'], 'image/svg+xml': ['.svg'], 'image/webp': ['.webp'], // Audio 'audio/mpeg': ['.mp3'], 'audio/wav': ['.wav'], 'audio/ogg': ['.ogg'], // Video 'video/mp4': ['.mp4'], 'video/webm': ['.webm'], 'video/ogg': ['.ogv'], } as const; // Helper function to get mime type from file extension export function getMimeTypeFromExtension(extension: string): string | null { const ext = extension.toLowerCase().startsWith('.') ? extension : `.${extension}`; for (const [mimeType, extensions] of Object.entries(SUPPORTED_MIME_TYPES)) { if ((extensions as readonly string[]).includes(ext)) { return mimeType; } } return null; } // Helper function to check if a file type is supported export function isSupportedFileType(extension: string): boolean { return getMimeTypeFromExtension(extension) !== null; } // Default file extensions for new files export const DEFAULT_FILE_EXTENSIONS = { markdown: 'md', text: 'txt', html: 'html', json: 'json', } as const; // Chat-related interfaces export interface Chat { id: string; book_id: string; user_id: string; title: string; created_at: string; updated_at: string; // Chat metadata model: string; total_messages: number; last_message_at: string; } export interface Message { id: string; chat_id: string; type: 'user' | 'ai'; content: string; created_at: string; // Message ordering sequence_number: number; // Optional metadata for AI messages model?: string | null; tool_results?: Record | null; context_info?: Record | null; } // UI-compatible message interface (for compatibility with existing code) export interface MessageUI { id: number | string; type: 'user' | 'ai'; content: string; timestamp?: Date; // Optional metadata model?: string; tool_results?: Record; context_info?: Record; }