Dökümanlar oluşturuldu
This commit is contained in:
626
doc/api-data-models.md
Normal file
626
doc/api-data-models.md
Normal file
@@ -0,0 +1,626 @@
|
||||
# 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
|
||||
```javascript
|
||||
const supabaseConfig = {
|
||||
url: process.env.VITE_SUPABASE_URL,
|
||||
anonKey: process.env.VITE_SUPABASE_ANON_KEY,
|
||||
};
|
||||
```
|
||||
|
||||
#### Authentication Endpoints
|
||||
|
||||
##### User Registration
|
||||
```http
|
||||
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
|
||||
```http
|
||||
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
|
||||
```http
|
||||
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
|
||||
```http
|
||||
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
|
||||
```http
|
||||
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
|
||||
```javascript
|
||||
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
|
||||
```http
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
// 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
|
||||
```typescript
|
||||
// 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.
|
||||
Reference in New Issue
Block a user