# AIPaper-assisant - Architecture & Design Patterns

## 🏗️ System Architecture Overview

### High-Level Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│                    Claude Desktop (MCP Client)                  │
└─────────────────────────┬───────────────────────────────────────┘
                          │ MCP Protocol (JSON-RPC over stdio)
┌─────────────────────────┴───────────────────────────────────────┐
│                    MCP Server Core Layer                        │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                    server.ts                              │  │
│  │  • Tool registration & lifecycle                          │  │
│  │  • Request routing & validation                           │  │
│  │  • Error handling & logging                               │  │
│  │  • MCP protocol compliance                                │  │
│  └─────────────────────┬─────────────────────────────────────┘  │
└───────────────────────┼─────────────────────────────────────────┘
                        │
┌───────────────────────┴─────────────────────────────────────────┐
│                 Business Logic Layer                            │
│  ┌─────────────────┬─────────────────┬────────────────────────┐  │
│  │   Tool Layer    │  Service Layer  │    Data Layer         │  │
│  │                 │                 │                        │  │
│  │ • search_papers │ • RateLimiter   │ • Paper (model)       │  │
│  │ • download_paper│ • ErrorHandler  │ • PaperFactory        │  │
│  │ • get_status    │ • Validator     │ • SearchOptions       │  │
│  └─────┬───────────┴──────┬──────────┴──────────┬───────────┘  │
│        │                  │                      │              │
│  ┌─────┴──────────────────┴──────────────────────┴───────────┐  │
│  │              Platform Abstraction Layer                    │  │
│  │  ┌────────────────────────────────────────────────────┐    │  │
│  │  │              PaperSource (Abstract)               │    │  │
│  │  │  • Common interface definition                    │    │  │
│  │  │  • HTTP client configuration                      │    │  │
│  │  │  • Error handling patterns                        │    │  │
│  │  │  • Rate limiting integration                      │    │  │
│  │  └────────┬──────────────────────┬──────────────────┘    │  │
│  │           │                      │                        │  │
│  │  ┌────────┴──────┐  ┌───────────┴────────┐  ┌────────────┴────┐  │
│  │  │ArxivSearcher  │  │WebOfScienceSearcher│  │CrossrefSearcher │  │
│  │  │                │  │                    │  │                 │  │
│  │  │• arXiv API     │  │• WoS API          │  │• Crossref API   │  │
│  │  │• PDF download  │  │• Multi-topic      │  │• DOI metadata   │  │
│  │  │• Categories    │  │• Citations        │  │• Fallback       │  │
│  │  └────────────────┘  └────────────────────┘  └─────────────────┘  │
│  │  ┌────────────────┐  ┌────────────────────┐  ┌─────────────────┐  │
│  │  │SciHubSearcher  │  │SpringerSearcher    │  │ScopusSearcher   │  │
│  │  │                │  │                    │  │                 │  │
│  │  │• Mirror mgmt   │  │• Dual API         │  │• Elsevier DB    │  │
│  │  │• DOI-based     │  │• OpenAccess       │  │• Citations      │  │
│  │  │• Health check  │  │• Metadata         │  │• Analytics      │  │
│  │  └────────────────┘  └────────────────────┘  └─────────────────┘  │
│  └─────────────────────────────────────────────────────────────────────┘  │
└───────────────────────────────────────────────────────────────────────────┘
                        │
┌───────────────────────┴─────────────────────────────────────────┐
│                  External APIs & Services                       │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐  │
│  │  arXiv   │ │   WoS    │ │ Crossref │ │    Springer      │  │
│  │   API    │ │   API    │ │   API    │ │       API        │  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────────────┘  │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐  │
│  │  SciHub  │ │  Scopus  │ │   Wiley  │ │   ScienceDirect  │  │
│  │ Mirrors  │ │   API    │ │  TDM API │ │       API        │  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
```

### Key Architectural Principles

#### 1. Separation of Concerns
- **MCP Layer**: Pure protocol handling
- **Business Logic**: Tool implementations
- **Platform Layer**: External API integrations
- **Data Layer**: Models and transformations

#### 2. Dependency Inversion
- Abstract `PaperSource` base class
- Platform implementations depend on abstractions
- Easy to add new platforms without modifying core

#### 3. Interface Segregation
- Each platform implements only needed capabilities
- Capability system for feature discovery
- No forced implementation of unused methods

## 🎯 Design Patterns

### 1. Abstract Factory Pattern

**Implementation**: `PaperFactory` in `models/Paper.ts`

```typescript
class PaperFactory {
  static create(data: RawPaperData): Paper {
    // Validates and transforms raw data into consistent Paper object
    return {
      title: this.sanitizeTitle(data.title),
      authors: this.normalizeAuthors(data.authors),
      doi: this.validateDoi(data.doi),
      // ... standardized fields
    };
  }
}
```

**Benefits**:
- Consistent data format across platforms
- Centralized validation logic
- Easy to extend with new fields

### 2. Template Method Pattern

**Implementation**: `PaperSource` abstract class

```typescript
abstract class PaperSource {
  // Template method defining search algorithm
  async search(query: string, options?: SearchOptions): Promise<Paper[]> {
    await this.validateQuery(query);
    await this.rateLimiter.acquire();

    try {
      const rawResults = await this.performSearch(query, options);
      return this.transformResults(rawResults);
    } catch (error) {
      return this.handleSearchError(error);
    }
  }

  // Abstract methods for subclasses
  protected abstract performSearch(query: string, options?: SearchOptions): Promise<any>;
  protected abstract transformResults(data: any): Promise<Paper[]>;
}
```

**Benefits**:
- Common behavior in base class
- Platform-specific logic in subclasses
- Consistent error handling

### 3. Strategy Pattern

**Implementation**: Platform selection in `server.ts`

```typescript
class SearchStrategy {
  private platforms: Map<string, PaperSource> = new Map();

  constructor() {
    this.platforms.set('arxiv', new ArxivSearcher());
    this.platforms.set('crossref', new CrossrefSearcher());
    // ... other platforms
  }

  async search(platform: string, query: string): Promise<Paper[]> {
    const searcher = this.platforms.get(platform);
    if (!searcher) throw new Error('Unknown platform');

    return searcher.search(query);
  }
}
```

**Benefits**:
- Runtime platform selection
- Easy to add new strategies
- Clean separation of algorithms

### 4. Decorator Pattern

**Implementation**: Capability enhancement in platforms

```typescript
// Base capability
interface PlatformCapabilities {
  search: boolean;
  download: boolean;
  citations: boolean;
}

// Enhanced with features
class EnhancedPlatform extends BasePlatform {
  getCapabilities(): PlatformCapabilities {
    return {
      ...super.getCapabilities(),
      advancedFilters: true,
      batchSearch: true,
      exportFormats: ['bibtex', 'ris']
    };
  }
}
```

### 5. Observer Pattern

**Implementation**: Event-driven status updates

```typescript
class PlatformStatusMonitor {
  private observers: StatusObserver[] = [];

  subscribe(observer: StatusObserver) {
    this.observers.push(observer);
  }

  notifyStatusChange(platform: string, status: PlatformStatus) {
    this.observers.forEach(observer => {
      observer.onStatusChange(platform, status);
    });
  }
}
```

### 6. Singleton Pattern

**Implementation**: Rate limiter instances

```typescript
class RateLimiterFactory {
  private static instances: Map<string, RateLimiter> = new Map();

  static getLimiter(platform: string): RateLimiter {
    if (!this.instances.has(platform)) {
      this.instances.set(platform, new RateLimiter(platform));
    }
    return this.instances.get(platform)!;
  }
}
```

## 🔧 Advanced Patterns

### 1. Circuit Breaker Pattern

**Implementation**: Platform health monitoring

```typescript
class CircuitBreaker {
  private failures = 0;
  private lastFailureTime = 0;
  private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';

  async execute<T>(operation: () => Promise<T>): Promise<T> {
    if (this.state === 'OPEN') {
      if (Date.now() - this.lastFailureTime > this.timeout) {
        this.state = 'HALF_OPEN';
      } else {
        throw new Error('Circuit breaker is OPEN');
      }
    }

    try {
      const result = await operation();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }
}
```

### 2. Retry Pattern

**Implementation**: Exponential backoff

```typescript
class RetryPolicy {
  async execute<T>(
    operation: () => Promise<T>,
    options: RetryOptions
  ): Promise<T> {
    let lastError: Error;

    for (let attempt = 0; attempt < options.maxAttempts; attempt++) {
      try {
        return await operation();
      } catch (error) {
        lastError = error as Error;

        if (attempt < options.maxAttempts - 1) {
          const delay = Math.min(
            options.baseDelay * Math.pow(2, attempt),
            options.maxDelay
          );
          await this.sleep(delay);
        }
      }
    }

    throw lastError!;
  }
}
```

### 3. Polymorphic Serialization

**Implementation**: Platform-specific data handling

```typescript
abstract class ResultSerializer {
  abstract serialize(data: any): string;
  abstract deserialize(data: string): any;
}

class JsonSerializer extends ResultSerializer {
  serialize(data: any): string {
    return JSON.stringify(data);
  }

  deserialize(data: string): any {
    return JSON.parse(data);
  }
}

class XmlSerializer extends ResultSerializer {
  serialize(data: any): string {
    // XML-specific serialization
  }
}
```

## 🔄 Behavioral Patterns

### 1. Command Pattern

**Implementation**: Tool execution in MCP

```typescript
interface Command {
  execute(): Promise<any>;
  undo(): Promise<void>;
}

class SearchCommand implements Command {
  constructor(
    private searcher: PaperSource,
    private query: string
  ) {}

  async execute(): Promise<Paper[]> {
    return this.searcher.search(this.query);
  }

  async undo(): Promise<void> {
    // Log search for audit trail
  }
}
```

### 2. Chain of Responsibility

**Implementation**: Fallback mechanism

```typescript
abstract class SearchHandler {
  private nextHandler: SearchHandler | null = null;

  setNext(handler: SearchHandler): SearchHandler {
    this.nextHandler = handler;
    return handler;
  }

  async handle(query: string): Promise<Paper[]> {
    try {
      return await this.search(query);
    } catch (error) {
      if (this.nextHandler) {
        return this.nextHandler.handle(query);
      }
      throw error;
    }
  }

  protected abstract search(query: string): Promise<Paper[]>;
}

// Usage: Crossref -> arXiv -> Google Scholar
```

## 🎯 Architectural Decisions

### 1. Platform Abstraction

**Decision**: Abstract base class vs Interface

**Choice**: Abstract class with Template Method
**Reasons**:
- Common behavior can be shared
- Template method enforces algorithm structure
- Protected methods allow customization
- Easier to add new platforms

### 2. Error Handling Strategy

**Decision**: Typed errors vs Generic errors

**Choice**: Platform-specific error types
**Reasons**:
- Better error handling and recovery
- Platform-specific retry logic
- Clear error categorization
- Enhanced debugging capabilities

### 3. Rate Limiting Approach

**Decision**: Centralized vs Distributed

**Choice**: Centralized with per-platform configuration
**Reasons**:
- Consistent rate limiting behavior
- Easy to monitor and adjust
- Single point of control
- Platform-specific optimization

### 4. Data Modeling

**Decision**: Single unified model vs Platform-specific models

**Choice**: Unified model with factory pattern
**Reasons**:
- Consistent API for clients
- Easier to maintain and extend
- Clear data transformation logic
- Type safety across platforms

## 🔍 Anti-Patterns Avoided

### 1. God Object
- Each class has single responsibility
- Platform logic separated from core
- Clear boundaries between layers

### 2. Spaghetti Code
- Clear module structure
- Dependency injection
- Interface-based programming

### 3. Magic Numbers
- Configuration objects
- Named constants
- Environment-based settings

### 4. Hard Coding
- Platform URLs in config
- Rate limits as parameters
- Feature flags for capabilities

## 🚀 Scalability Patterns

### 1. Horizontal Scaling
- Stateless design
- Platform isolation
- No shared state between requests

### 2. Caching Strategy
- Platform capability caching
- Mirror health status
- Configurable TTL

### 3. Load Balancing
- Round-robin for mirrors
- Health check integration
- Automatic failover

### 4. Resource Pooling
- HTTP connection reuse
- Rate limiter pool
- Memory efficient streaming

## 📊 Performance Patterns

### 1. Lazy Loading
- Platform initialization on demand
- Configuration loading
- Resource allocation

### 2. Batch Operations
- Bulk search optimization
- Parallel downloads
- Concurrent API calls

### 3. Streaming
- Large result sets
- Memory efficiency
- Real-time updates

### 4. Indexing
- In-memory indexes
- Cache keys optimization
- Quick lookups

## 🔐 Security Patterns

### 1. Defense in Depth
- Input validation
- Output sanitization
- API key protection

### 2. Principle of Least Privilege
- Minimal required permissions
- Scope-based access
- Platform isolation

### 3. Secure Defaults
- Rate limiting enabled
- Error sanitization
- Timeout configurations

### 4. Audit Trail
- Request logging
- Error tracking
- Performance monitoring

## 🧪 Testing Patterns

### 1. Test Pyramid
- Unit tests (80%)
- Integration tests (15%)
- E2E tests (5%)

### 2. Mock Strategies
- Interface-based mocking
- Platform simulators
- Network stubbing

### 3. Test Data Management
- Fixture factories
- Platform-specific data
- Edge case coverage

### 4. Continuous Testing
- Pre-commit hooks
- CI/CD integration
- Performance benchmarks

---

*This architecture documentation serves as a comprehensive guide to the design patterns and architectural decisions in AIPaper-assisant. It provides a foundation for understanding the system's structure and making informed decisions about future enhancements.*