Files
imgPub/doc/api-data-models.md
2025-11-17 11:39:53 +03:00

12 KiB

API Documentation & Data Models

Overview

This document describes all API endpoints, request/response formats, and data models used throughout the imgPub application ecosystem.

External APIs

1. Supabase Authentication API

Configuration

const supabaseConfig = {
  url: process.env.VITE_SUPABASE_URL,
  anonKey: process.env.VITE_SUPABASE_ANON_KEY,
};

Authentication Endpoints

User Registration
POST /auth/v1/signup
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securePassword123",
  "options": {
    "data": {
      "username": "preferredUsername"
    }
  }
}

Response:
{
  "user": {
    "id": "uuid-string",
    "email": "user@example.com",
    "username": "preferredUsername",
    "created_at": "2024-01-01T00:00:00Z"
  },
  "session": {
    "access_token": "jwt-token",
    "refresh_token": "refresh-token",
    "expires_in": 3600
  }
}
User Login
POST /auth/v1/token?grant_type=password
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securePassword123"
}

Response:
{
  "access_token": "jwt-token",
  "refresh_token": "refresh-token",
  "expires_in": 3600,
  "user": {
    "id": "uuid-string",
    "email": "user@example.com",
    "username": "preferredUsername"
  }
}
Google OAuth
GET /auth/v1/authorize?provider=google
Redirect URI configured in Supabase dashboard

Response (after redirect):
{
  "access_token": "oauth-jwt-token",
  "refresh_token": "oauth-refresh-token",
  "expires_in": 3600,
  "user": {
    "id": "uuid-string",
    "email": "user@gmail.com",
    "username": "usergmail"
  }
}
Current User Info
GET /auth/v1/user
Authorization: Bearer {access_token}

Response:
{
  "id": "uuid-string",
  "email": "user@example.com",
  "username": "preferredUsername",
  "created_at": "2024-01-01T00:00:00Z",
  "last_sign_in_at": "2024-01-15T10:30:00Z"
}

2. Backend EPUB Generation API

Base URL

Development: http://localhost:4000
Production: https://api.imgpub.com

Generate EPUB Endpoint

POST /generate-epub
Content-Type: application/json
Authorization: Bearer {auth_token} (optional)

Request Body:
{
  "text": "Complete OCR text content with Turkish characters...",
  "meta": {
    "title": "Book Title",
    "author": "Author Name",
    "publisher": "Publisher Name",
    "description": "Book description",
    "isbn": "978-3-16-148410-0",
    "language": "tr",
    "coverImage": "base64-encoded-image-data"
  }
}

Response (200 OK):
{
  "success": true,
  "filename": "book-title.epub",
  "data": "base64-encoded-epub-content",
  "metadata": {
    "title": "Book Title",
    "author": "Author Name",
    "created_at": "2024-01-15T14:30:00Z",
    "file_size": 1024000
  }
}

Error Response (400 Bad Request):
{
  "success": false,
  "error": "Invalid metadata format",
  "details": "Title and author are required fields"
}

Error Response (500 Internal Server Error):
{
  "success": false,
  "error": "EPUB generation failed",
  "details": "Unable to process text content"
}

3. GLM-4.6 Translation API

Configuration

const translationConfig = {
  baseUrl: 'https://apiglm.example.com/v1',
  apiKey: process.env.VITE_GLM_API_KEY,
  model: 'glm-4.6',
  maxTokens: 4000,
  temperature: 0.3
};

Translation Endpoint

POST /chat/completions
Content-Type: application/json
Authorization: Bearer {glm_api_key}

Request Body:
{
  "model": "glm-4.6",
  "messages": [
    {
      "role": "system",
      "content": "You are a professional translator. Translate the following Turkish text to English while preserving meaning and context."
    },
    {
      "role": "user",
      "content": "Turkish text to translate..."
    }
  ],
  "max_tokens": 4000,
  "temperature": 0.3,
  "stream": false
}

Response (200 OK):
{
  "id": "chatcmpl-translation-id",
  "object": "chat.completion",
  "created": 1705315200,
  "model": "glm-4.6",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Translated English text..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1500,
    "completion_tokens": 1800,
    "total_tokens": 3300
  }
}

Error Response (401 Unauthorized):
{
  "error": {
    "message": "Invalid API key",
    "type": "invalid_request_error"
  }
}

Error Response (429 Rate Limited):
{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_error",
    "retry_after": 60
  }
}

Internal Data Models

Application State Model (Zustand Store)

Complete State Structure

interface AppState {
  // File Management
  uploadedImages: UploadedImage[];
  cropConfig: CropConfiguration;
  croppedImages: CroppedImage[];
  coverImageId: string | null;
  coverCropConfig: CropConfiguration;
  croppedCoverImage: CroppedImage | null;

  // Text Processing
  ocrText: string;
  bookTitle: string;
  bookMetadata: BookMetadata | null;
  translatedText: string;
  translationStatus: TranslationStatus;
  translationError: string | null;
  translationProgress: number;

  // Generated Content
  generatedEpub: EpubData | null;

  // Authentication
  authToken: string | null;
  currentUser: User | null;

  // Error Handling
  error: string | null;

  // Actions
  // ... (actions omitted for brevity)
}

Data Type Definitions

interface UploadedImage {
  id: string;
  file: File;
  url: string; // Blob URL for preview
  name: string;
  size: number;
  type: string;
  uploadedAt: Date;
}

interface CropConfiguration {
  x: number;
  y: number;
  zoom: number;
  width: number;
  height: number;
  top: number;
  bottom: number;
  left: number;
  right: number;
  cropAreaX: number;
  cropAreaY: number;
  imageWidth: number;
  imageHeight: number;
  referenceImageId: string | null;
  selection: CropSelection | null;
}

interface CropSelection {
  x: number;
  y: number;
  width: number;
  height: number;
}

interface CroppedImage {
  id: string;
  originalImageId: string;
  blob: Blob;
  url: string; // Blob URL for display
  cropConfig: CropConfiguration;
  processedAt: Date;
}

interface BookMetadata {
  title: string;
  author: string;
  publisher?: string;
  description?: string;
  isbn?: string;
  language: string;
  publishedDate?: string;
  tags?: string[];
  coverImageData?: string; // Base64
}

type TranslationStatus = 'idle' | 'processing' | 'completed' | 'error';

interface User {
  id: string;
  email: string;
  username: string;
  createdAt: string;
  lastSignInAt?: string;
  profileImageUrl?: string;
}

interface EpubData {
  filename: string;
  blob: Blob;
  url: string; // Download URL
  metadata: BookMetadata;
  createdAt: Date;
  fileSize: number;
}

Component Props Models

Upload Step Component

interface UploadStepProps {
  onFilesUploaded: (files: File[]) => void;
  maxFiles: number;
  acceptedFileTypes: string[];
  maxFileSize: number;
}

interface ImagePreviewProps {
  images: UploadedImage[];
  onRemoveImage: (imageId: string) => void;
  onCropImage: (imageId: string) => void;
}

Crop Step Component

interface CropStepProps {
  images: UploadedImage[];
  cropConfig: CropConfiguration;
  onCropConfigChange: (config: CropConfiguration) => void;
  referenceImageId: string;
  onReferenceChange: (imageId: string) => void;
}

interface CropControlsProps {
  cropConfig: CropConfiguration;
  onConfigChange: (config: CropConfiguration) => void;
  imageDimensions: { width: number; height: number };
}

OCR Step Component

interface OcrStepProps {
  images: CroppedImage[];
  onOcrComplete: (text: string) => void;
  onProgressUpdate: (progress: number) => void;
}

interface OcrProgressProps {
  currentImage: number;
  totalImages: number;
  currentProgress: number;
  extractedText: string;
}

API Client Models

Request Models

interface GenerateEpubRequest {
  text: string;
  meta: BookMetadata;
}

interface TranslationRequest {
  text: string;
  sourceLanguage: string;
  targetLanguage: string;
  maxTokens?: number;
}

interface AuthRequest {
  email: string;
  password: string;
  username?: string;
}

Response Models

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: string;
  details?: string;
}

interface GenerateEpubResponse {
  filename: string;
  data: string; // Base64 encoded
  metadata: {
    title: string;
    author: string;
    created_at: string;
    file_size: number;
  };
}

interface TranslationResponse {
  translatedText: string;
  usage: {
    promptTokens: number;
    completionTokens: number;
    totalTokens: number;
  };
}

interface AuthResponse {
  user: User;
  session: Session;
}

interface Session {
  accessToken: string;
  refreshToken: string;
  expiresAt: number;
}

Error Models

Application Errors

interface ApplicationError {
  code: string;
  message: string;
  details?: any;
  timestamp: Date;
  context?: string;
}

type ErrorCode =
  | 'FILE_TOO_LARGE'
  | 'INVALID_FILE_TYPE'
  | 'OCR_PROCESSING_FAILED'
  | 'TRANSLATION_FAILED'
  | 'EPUB_GENERATION_FAILED'
  | 'AUTHENTICATION_ERROR'
  | 'NETWORK_ERROR'
  | 'UNKNOWN_ERROR';

interface ErrorState {
  code: ErrorCode;
  message: string;
  details?: any;
  retryable: boolean;
  userAction?: string;
}

Configuration Models

Application Configuration

interface AppConfig {
  api: {
    baseUrl: string;
    timeout: number;
    retries: number;
  };
  ocr: {
    languages: string[];
    workerPath: string;
    corePath: string;
    langPath: string;
  };
  translation: {
    maxTextLength: number;
    chunkSize: number;
    timeout: number;
  };
  upload: {
    maxFileSize: number;
    maxFiles: number;
    allowedTypes: string[];
  };
  epub: {
    defaultLanguage: string;
    supportedFormats: string[];
  };
}

Environment Configuration

interface EnvConfig {
  VITE_API_BASE_URL: string;
  VITE_SUPABASE_URL: string;
  VITE_SUPABASE_ANON_KEY: string;
  VITE_GLM_API_KEY: string;
  VITE_APP_NAME: string;
  VITE_APP_VERSION: string;
}

Data Flow Examples

File Upload Flow

// File Upload Sequence
const handleFileUpload = async (files: FileList): Promise<void> => {
  try {
    // 1. Validate files
    const validFiles = validateFiles(files);

    // 2. Convert to UploadedImage model
    const uploadedImages: UploadedImage[] = await Promise.all(
      Array.from(validFiles).map(async (file) => ({
        id: generateId(),
        file,
        url: URL.createObjectURL(file),
        name: file.name,
        size: file.size,
        type: file.type,
        uploadedAt: new Date()
      }))
    );

    // 3. Update state
    useAppStore.getState().setUploadedImages(uploadedImages);

    // 4. Navigate to next step
    navigate('/crop');

  } catch (error) {
    // 5. Handle error
    useAppStore.getState().setError(error.message);
  }
};

EPUB Generation Flow

// EPUB Generation Sequence
const generateEpub = async (): Promise<void> => {
  try {
    // 1. Prepare request data
    const requestData: GenerateEpubRequest = {
      text: finalText,
      meta: bookMetadata
    };

    // 2. API call
    const response = await epubService.generate(requestData);

    // 3. Process response
    const epubData: EpubData = {
      filename: response.filename,
      blob: base64ToBlob(response.data),
      url: '', // Will be created
      metadata: response.metadata,
      createdAt: new Date(),
      fileSize: response.metadata.file_size
    };

    // 4. Create download URL
    epubData.url = URL.createObjectURL(epubData.blob);

    // 5. Update state
    useAppStore.getState().setGeneratedEpub(epubData);

    // 6. Navigate to download step
    navigate('/download');

  } catch (error) {
    useAppStore.getState().setError('EPUB generation failed');
  }
};

This comprehensive API and data model documentation provides complete information for understanding all data structures, API endpoints, and integration patterns within the imgPub application.