← back to Watches

BACKEND_API.md

639 lines

# Omega Watch Price History - Backend API Documentation

## Server Information

- **Port**: 7600
- **Base URL**: `http://45.61.58.125:7600`
- **API Base**: `http://45.61.58.125:7600/api`
- **WebSocket**: `ws://45.61.58.125:7600`

## Architecture Overview

### Key Features

1. **In-Memory Caching**: 5-minute TTL for expensive calculations
2. **WebSocket Support**: Real-time updates for watch data
3. **Data Export**: JSON and CSV formats
4. **Advanced Analytics**: Price predictions, trend analysis
5. **Watchlist Management**: User-specific watch collections
6. **Database Backup/Restore**: Automated backup system
7. **Performance Monitoring**: Request timing and slow query detection
8. **Schema Validation**: Ensures data integrity

### Technology Stack

- **Runtime**: Node.js (ES Modules)
- **Framework**: Express.js
- **Security**: Helmet.js
- **Compression**: gzip compression
- **Logging**: Morgan (combined format)
- **WebSocket**: ws library
- **Database**: JSON file storage with backup system

---

## API Endpoints

### Health & Monitoring

#### GET /api/health

Health check with detailed system metrics.

**Response:**
```json
{
  "status": "healthy",
  "timestamp": "2025-11-17T09:00:00.000Z",
  "uptime": 12345.67,
  "memory": {
    "rss": 123456789,
    "heapTotal": 98765432,
    "heapUsed": 87654321
  },
  "cache": {
    "keys": 5,
    "size": 41555,
    "oldestEntry": 1763370297358
  },
  "database": {
    "watches": 32,
    "collections": 9
  },
  "websocket": {
    "connections": 2
  }
}
```

#### GET /api/docs

API documentation (this information in JSON format).

---

### Watch Data

#### GET /api/watches

Get all watches with optional filtering and pagination.

**Query Parameters:**
- `series` (string): Filter by series name
- `minYear` (integer): Minimum year introduced
- `maxYear` (integer): Maximum year introduced
- `minPrice` (integer): Minimum current price
- `maxPrice` (integer): Maximum current price
- `page` (integer): Page number (default: 1)
- `limit` (integer): Items per page (default: 50)

**Example:**
```bash
GET /api/watches?series=Speedmaster&minYear=1960&limit=10
```

**Response:**
```json
{
  "total": 13,
  "page": 1,
  "limit": 10,
  "totalPages": 2,
  "watches": [...]
}
```

#### GET /api/watches/:id/history

Get price history for a specific watch.

**Parameters:**
- `id` (string): Watch ID

**Response:**
```json
{
  "watch": {
    "id": "speedmaster-moonwatch-1969",
    "model": "Speedmaster Professional Moonwatch ST 105.012",
    "series": "Speedmaster",
    "reference": "ST 105.012",
    "yearIntroduced": 1963,
    "specifications": {...}
  },
  "priceHistory": [...],
  "views": 42
}
```

#### GET /api/watches/trending

Get most viewed watches.

**Query Parameters:**
- `limit` (integer): Number of results (default: 10)

**Response:**
```json
{
  "trending": [...],
  "totalViews": 156
}
```

---

### Search & Analytics

#### GET /api/search

Advanced search with multiple filters.

**Query Parameters:**
- `q` (string): Search query (searches model, series, reference, description)
- `series` (string): Filter by series
- `movement` (string): Filter by movement type
- `minPrice` (integer): Minimum price
- `maxPrice` (integer): Maximum price
- `page` (integer): Page number
- `limit` (integer): Items per page (default: 20)

**Example:**
```bash
GET /api/search?q=moonwatch&series=Speedmaster&minPrice=5000
```

**Response:**
```json
{
  "query": "moonwatch",
  "total": 3,
  "page": 1,
  "limit": 20,
  "totalPages": 1,
  "results": [...]
}
```

#### GET /api/price-predictions/:id

Get price predictions using linear regression.

**Response:**
```json
{
  "model": "Speedmaster Professional Moonwatch ST 105.012",
  "currentPrice": 7200,
  "trend": "increasing",
  "averageAnnualChange": 12.45,
  "predictions": [
    {
      "year": 2025,
      "predictedPrice": 11691,
      "confidence": 34
    },
    {
      "year": 2026,
      "predictedPrice": 12588,
      "confidence": 34
    },
    {
      "year": 2027,
      "predictedPrice": 13484,
      "confidence": 34
    }
  ]
}
```

#### GET /api/statistics

Comprehensive market statistics and analytics.

**Response:**
```json
{
  "totalWatches": 32,
  "totalSeries": 9,
  "averageAppreciation": 12.45,
  "topPerformers": [...],
  "lastUpdated": "2025-11-17T09:00:00.000Z",
  "priceRanges": {
    "Under $5,000": 4,
    "$5,000 - $10,000": 15,
    "$10,000 - $25,000": 7,
    "$25,000 - $50,000": 3,
    "Over $50,000": 3
  },
  "movementTypes": {
    "Manual": 12,
    "Automatic": 20
  },
  "appreciationByDecade": {
    "1940s": 2363.77,
    "1950s": 62145.61,
    "1960s": 5884.14,
    ...
  }
}
```

#### GET /api/collections

Get all collections with detailed statistics.

**Response:**
```json
{
  "collections": [
    {
      "series": "Speedmaster",
      "count": 13,
      "watches": [...],
      "avgPrice": 52254,
      "avgYearIntroduced": 1992,
      "avgAppreciation": 24285.79
    },
    ...
  ],
  "totalCollections": 9
}
```

---

### Comparison & Management

#### POST /api/compare

Compare multiple watches side-by-side.

**Request Body:**
```json
{
  "watchIds": [
    "speedmaster-moonwatch-1969",
    "seamaster-300-1957"
  ]
}
```

**Response:**
```json
{
  "watches": [
    {
      "id": "speedmaster-moonwatch-1969",
      "model": "...",
      "series": "Speedmaster",
      "yearIntroduced": 1963,
      "priceHistory": [...],
      "specifications": {...},
      "currentPrice": 7200,
      "appreciation": 6692.45
    },
    ...
  ],
  "count": 2
}
```

#### POST /api/watchlist

Add or remove watches from user watchlist.

**Request Body:**
```json
{
  "userId": "user123",
  "watchId": "speedmaster-moonwatch-1969",
  "action": "add"
}
```

**Response:**
```json
{
  "userId": "user123",
  "watchlist": ["speedmaster-moonwatch-1969"],
  "count": 1
}
```

#### GET /api/watchlist/:userId

Get user's watchlist.

**Response:**
```json
{
  "userId": "user123",
  "watchlist": [...],
  "count": 3
}
```

---

### Data Export

#### GET /api/export/json

Export entire database as JSON.

**Headers:**
- `Content-Type: application/json`
- `Content-Disposition: attachment; filename=omega-watches.json`

#### GET /api/export/csv

Export watches as CSV.

**CSV Format:**
```csv
ID,Model,Series,Reference,Year Introduced,Current Price,Original Price,Appreciation %
speedmaster-moonwatch-1957,"Speedmaster Professional CK2915",Speedmaster,CK 2915-1,1957,200000,95,210426.32
```

---

### Admin Endpoints

#### GET /api/admin/backup

Create database backup.

**Response:**
```json
{
  "success": true,
  "backupPath": "/root/Projects/watches/data/backups/watches-backup-2025-11-17T09-00-00-000Z.json",
  "timestamp": "2025-11-17T09:00:00.000Z"
}
```

#### POST /api/admin/restore

Restore database from backup.

**Request Body:**
```json
{
  "backupFile": "watches-backup-2025-11-17T09-00-00-000Z.json"
}
```

#### POST /api/admin/clear-cache

Clear in-memory cache.

**Response:**
```json
{
  "success": true,
  "message": "Cache cleared"
}
```

---

## WebSocket API

### Connection

```javascript
const ws = new WebSocket('ws://45.61.58.125:7600');

ws.onopen = () => {
  console.log('Connected to Omega Watch WebSocket');
};
```

### Subscribe to Watch Updates

```javascript
ws.send(JSON.stringify({
  type: 'subscribe',
  watchId: 'speedmaster-moonwatch-1969'
}));
```

### Receive Updates

```javascript
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  if (data.type === 'subscribed') {
    console.log('Subscribed to watch:', data.watchId);
  }

  if (data.type === 'update') {
    console.log('Watch updated:', data.watchId, data.data);
  }
};
```

---

## Caching Strategy

The server implements an intelligent in-memory cache:

- **TTL**: 5 minutes
- **Cached Operations**:
  - All watch data
  - Statistics calculations
  - Collection aggregations
  - Top performers
  - Price range distributions
  - Movement type distributions

Cache can be cleared via `/api/admin/clear-cache`.

---

## Performance Metrics

Based on test results:

| Endpoint | Average Response Time |
|----------|----------------------|
| Health Check | < 100ms |
| Statistics | < 500ms (11ms cached) |
| Collections | < 500ms (11ms cached) |
| Search | < 300ms (10ms) |
| Watch History | < 200ms |

---

## Error Handling

All endpoints return appropriate HTTP status codes:

- **200**: Success
- **400**: Bad Request (invalid parameters)
- **404**: Not Found (watch doesn't exist)
- **500**: Internal Server Error

**Error Response Format:**
```json
{
  "error": "Error message",
  "details": "Additional details (optional)"
}
```

---

## Data Validation

The backend includes comprehensive data validation:

- Schema validation against `/schema/watch-schema.json`
- Required field checks
- Data type validation
- Range validation (years, prices)
- Chronological ordering of price history

Run validation:
```bash
node utils/validator.js data/watches.json
```

---

## Database Migrations

Migration system for schema changes:

### Create Migration
```bash
node utils/migrations.js create add_rating_field
```

### Run Migrations
```bash
node utils/migrations.js run
```

Migrations are stored in `/migrations/` directory.

---

## Testing

Comprehensive test suite included:

```bash
./test/api-tests.sh
```

Tests:
- All endpoints (28 tests)
- Performance benchmarks
- Cache verification
- Error handling
- 100% pass rate

---

## Security

Security measures implemented:

1. **Helmet.js**: HTTP security headers
2. **CORS**: Cross-origin resource sharing
3. **Compression**: gzip compression
4. **Request Logging**: Morgan combined format
5. **Input Validation**: Query parameter sanitization
6. **Error Handling**: Safe error messages

---

## Deployment

Service runs on PM2:

```bash
# Start
pm2 start server.js --name omega-watches

# Stop
pm2 stop omega-watches

# Restart
pm2 restart omega-watches

# Logs
pm2 logs omega-watches
```

---

## Development

### Install Dependencies
```bash
npm install
```

### Start Server
```bash
npm start
```

### Run Tests
```bash
./test/api-tests.sh
```

### Validate Data
```bash
node utils/validator.js data/watches.json
```

---

## Rate Limiting

Currently no rate limiting implemented. For production:

1. Add `express-rate-limit` package
2. Configure per-IP limits
3. Separate limits for read/write operations

---

## Future Enhancements

Potential improvements:

1. **Database**: PostgreSQL or MongoDB for scalability
2. **Authentication**: JWT-based user authentication
3. **Rate Limiting**: API rate limiting per user/IP
4. **GraphQL**: GraphQL endpoint alongside REST
5. **Redis**: Redis for distributed caching
6. **Elasticsearch**: Full-text search with Elasticsearch
7. **Notifications**: Email/SMS for price alerts
8. **API Versioning**: Support multiple API versions
9. **Swagger UI**: Interactive API documentation
10. **Monitoring**: Prometheus/Grafana metrics

---

## Support

For issues or questions:

- Check API documentation: `GET /api/docs`
- Review logs: `pm2 logs omega-watches`
- Run health check: `GET /api/health`
- Run test suite: `./test/api-tests.sh`

---

**Last Updated**: November 17, 2025
**Version**: 2.0.0
**Maintainer**: Backend Architecture Team