# Health Check API Integration

This document describes the integration between the MaplePress frontend and the Health Check API endpoint.

## Table of Contents

- [Overview](#overview)
- [Backend API Specification](#backend-api-specification)
- [Frontend Implementation](#frontend-implementation)
- [Service Methods](#service-methods)
- [Usage Examples](#usage-examples)
- [Use Cases](#use-cases)
- [Error Handling](#error-handling)
- [Testing](#testing)
- [Troubleshooting](#troubleshooting)

---

## Overview

The Health Check API is a simple, unauthenticated endpoint that verifies the MaplePress backend service is running and operational. It's commonly used for:

- **Monitoring**: Service availability checks
- **Load Balancers**: Health probe endpoints
- **Startup Verification**: Ensuring backend is ready before initializing frontend
- **API Connectivity**: Testing network connectivity to backend

### Key Features

- ✅ **No Authentication Required**: Public endpoint
- ✅ **Simple Response**: Returns `{ "status": "healthy" }`
- ✅ **Fast Response**: Lightweight check with minimal processing
- ✅ **Always Available**: Does not depend on database or external services

---

## Backend API Specification

### Endpoint

```
GET /health
```

### Authentication

**None required** - This is a public endpoint.

### Request Headers

No headers required.

### Request Parameters

None.

### Response (200 OK)

```json
{
  "status": "healthy"
}
```

### Response Fields

| Field | Type | Description |
|-------|------|-------------|
| status | string | Health status - always "healthy" when service is running |

### Error Responses

- `503 Service Unavailable`: Backend service is down or unreachable
- Network errors: Connection refused, timeout, etc.

### Backend Implementation

**Handler File**: `cloud/maplepress-backend/internal/interface/http/handler/healthcheck/healthcheck_handler.go`

```go
func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) {
    response := map[string]string{
        "status": "healthy",
    }
    httpresponse.OK(w, response)
}
```

---

## Frontend Implementation

### Service File

**Location**: `src/services/API/HealthService.js`

### Dependencies

```javascript
import ApiClient from "./ApiClient";
```

### Architecture

The HealthService follows the same three-layer architecture as other API services:

```
┌─────────────────────────────────────┐
│     React Components (UI)           │
│  - Dashboard, Status Indicators     │
└─────────────┬───────────────────────┘
              │
              ↓
┌─────────────────────────────────────┐
│     HealthService (API Layer)       │
│  - checkHealth()                    │
│  - isHealthy()                      │
│  - waitUntilHealthy()               │
│  - getDetailedStatus()              │
└─────────────┬───────────────────────┘
              │
              ↓
┌─────────────────────────────────────┐
│     ApiClient (HTTP Layer)          │
│  - GET /health                      │
└─────────────┬───────────────────────┘
              │
              ↓
┌─────────────────────────────────────┐
│     Backend API                     │
│  GET /health → { status: "healthy" }│
└─────────────────────────────────────┘
```

---

## Service Methods

### 1. `checkHealth()`

Check if the backend service is healthy.

**Signature**:
```javascript
async function checkHealth(): Promise<Object>
```

**Returns**:
```javascript
{
  status: "healthy"
}
```

**Throws**: `Error` if service is unreachable or unhealthy

**Example**:
```javascript
import HealthService from './services/API/HealthService';

try {
  const health = await HealthService.checkHealth();
  if (health.status === 'healthy') {
    console.log('✅ Backend is healthy');
  }
} catch (error) {
  console.error('❌ Backend is down:', error.message);
}
```

---

### 2. `isHealthy()`

Simple boolean check for backend health.

**Signature**:
```javascript
async function isHealthy(): Promise<boolean>
```

**Returns**: `true` if backend is healthy, `false` otherwise

**Example**:
```javascript
const healthy = await HealthService.isHealthy();

if (healthy) {
  console.log('✅ Backend is ready');
} else {
  console.error('❌ Backend is not available');
}
```

**Use Case**: Quick status checks, conditional rendering

---

### 3. `waitUntilHealthy()`

Wait for the backend to become healthy (with retries).

**Signature**:
```javascript
async function waitUntilHealthy(options?: Object): Promise<boolean>
```

**Parameters**:
```javascript
{
  maxAttempts: number,    // Maximum retry attempts (default: 30)
  retryDelayMs: number    // Delay between attempts in ms (default: 1000)
}
```

**Returns**: `true` if backend became healthy, `false` if timeout

**Example**:
```javascript
// Wait up to 10 seconds (10 attempts x 1 second)
const ready = await HealthService.waitUntilHealthy({
  maxAttempts: 10,
  retryDelayMs: 1000
});

if (ready) {
  console.log('✅ Backend is ready!');
  // Proceed with app initialization
} else {
  console.error('❌ Backend did not become ready in time');
  // Show error message to user
}
```

**Use Case**: Application startup, waiting for backend deployment

---

### 4. `getDetailedStatus()`

Get detailed health status with timing information.

**Signature**:
```javascript
async function getDetailedStatus(): Promise<Object>
```

**Returns**:
```javascript
{
  healthy: boolean,        // Whether backend is healthy
  status: string,          // "healthy" or "unhealthy"
  responseTimeMs: number,  // Response time in milliseconds
  timestamp: Date,         // When check was performed
  error?: string           // Error message if unhealthy
}
```

**Example**:
```javascript
const status = await HealthService.getDetailedStatus();

console.log(`Backend Status: ${status.status}`);
console.log(`Response Time: ${status.responseTimeMs}ms`);
console.log(`Checked At: ${status.timestamp.toISOString()}`);

if (!status.healthy) {
  console.error(`Error: ${status.error}`);
}
```

**Use Case**: Monitoring dashboards, performance tracking, diagnostics

---

## Usage Examples

### Example 1: Application Startup Check

Check backend health before initializing the app:

```javascript
// In App.jsx or main.jsx
import { useEffect, useState } from 'react';
import HealthService from './services/API/HealthService';

function App() {
  const [backendReady, setBackendReady] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function checkBackend() {
      try {
        const healthy = await HealthService.isHealthy();
        setBackendReady(healthy);

        if (!healthy) {
          setError('Backend service is not available');
        }
      } catch (err) {
        setError(err.message);
      }
    }

    checkBackend();
  }, []);

  if (error) {
    return <div className="error">Backend Error: {error}</div>;
  }

  if (!backendReady) {
    return <div className="loading">Connecting to backend...</div>;
  }

  return <div>App content...</div>;
}
```

---

### Example 2: Status Indicator Component

Show real-time backend status:

```javascript
import { useEffect, useState } from 'react';
import HealthService from '../services/API/HealthService';

function BackendStatusIndicator() {
  const [status, setStatus] = useState(null);

  useEffect(() => {
    // Check status every 30 seconds
    const checkStatus = async () => {
      const detail = await HealthService.getDetailedStatus();
      setStatus(detail);
    };

    checkStatus();
    const interval = setInterval(checkStatus, 30000);

    return () => clearInterval(interval);
  }, []);

  if (!status) {
    return <span>Checking...</span>;
  }

  return (
    <div className={`status-indicator ${status.healthy ? 'healthy' : 'unhealthy'}`}>
      <span className="status-dot"></span>
      <span className="status-text">
        Backend: {status.status} ({status.responseTimeMs}ms)
      </span>
    </div>
  );
}
```

---

### Example 3: Deployment Health Check

Wait for backend after deployment:

```javascript
import HealthService from './services/API/HealthService';

async function waitForBackend() {
  console.log('Waiting for backend to become ready...');

  const ready = await HealthService.waitUntilHealthy({
    maxAttempts: 60,      // Wait up to 1 minute
    retryDelayMs: 1000    // Check every second
  });

  if (ready) {
    console.log('✅ Backend is ready!');
    return true;
  } else {
    console.error('❌ Backend deployment timeout');
    return false;
  }
}

// Usage in deployment script
if (await waitForBackend()) {
  // Proceed with app initialization
} else {
  // Show deployment error message
}
```

---

### Example 4: Error Recovery

Retry failed API calls after backend recovers:

```javascript
import HealthService from './services/API/HealthService';
import SiteService from './services/API/SiteService';

async function fetchSitesWithRetry() {
  try {
    // Try to fetch sites
    const sites = await SiteService.listSites();
    return sites;
  } catch (error) {
    console.error('Failed to fetch sites:', error);

    // Check if backend is healthy
    const healthy = await HealthService.isHealthy();

    if (!healthy) {
      console.log('Backend is down, waiting for recovery...');

      // Wait for backend to recover
      const recovered = await HealthService.waitUntilHealthy({
        maxAttempts: 10,
        retryDelayMs: 2000
      });

      if (recovered) {
        console.log('Backend recovered, retrying...');
        return await SiteService.listSites();
      }
    }

    throw error;
  }
}
```

---

## Use Cases

### 1. **Monitoring & Observability**

- Service uptime monitoring
- Response time tracking
- Health dashboard indicators
- Alerting on service degradation

### 2. **Load Balancer Integration**

- Health probe endpoint for AWS/Azure/GCP load balancers
- Kubernetes liveness/readiness probes
- Docker healthcheck configuration

### 3. **Application Lifecycle**

- Startup health verification
- Graceful degradation on backend issues
- Post-deployment verification
- Environment validation (dev/staging/prod)

### 4. **User Experience**

- Show connection status to users
- Prevent API calls when backend is down
- Display maintenance mode messages
- Automatic retry on recovery

### 5. **Development & Testing**

- Verify backend is running before tests
- E2E test prerequisites
- Local development environment checks
- CI/CD pipeline health gates

---

## Error Handling

### Network Errors

```javascript
try {
  await HealthService.checkHealth();
} catch (error) {
  if (error.message.includes('network') || error.message.includes('fetch')) {
    // Network connectivity issue
    console.error('Cannot reach backend - check network');
  }
}
```

### Service Unavailable

```javascript
try {
  await HealthService.checkHealth();
} catch (error) {
  if (error.message.includes('503') || error.message.includes('unavailable')) {
    // Backend is down or restarting
    console.error('Backend service is unavailable');
  }
}
```

### Timeout Handling

```javascript
// With timeout wrapper
async function checkHealthWithTimeout(timeoutMs = 5000) {
  const timeoutPromise = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Health check timeout')), timeoutMs)
  );

  try {
    return await Promise.race([
      HealthService.checkHealth(),
      timeoutPromise
    ]);
  } catch (error) {
    console.error('Health check failed or timed out:', error.message);
    return { status: 'unhealthy' };
  }
}
```

---

## Testing

### Manual Testing

1. **Start the backend**:
   ```bash
   cd cloud/maplepress-backend
   task dev
   ```

2. **Test with curl**:
   ```bash
   curl -X GET http://localhost:8000/health
   ```

   Expected response:
   ```json
   { "status": "healthy" }
   ```

3. **Test from frontend**:
   ```javascript
   // In browser console
   import HealthService from './services/API/HealthService.js';

   const health = await HealthService.checkHealth();
   console.log(health); // { status: "healthy" }
   ```

### Automated Testing

```javascript
// Example test (using Jest or Vitest)
import HealthService from '../services/API/HealthService';

describe('HealthService', () => {
  it('should return healthy status when backend is up', async () => {
    const health = await HealthService.checkHealth();
    expect(health.status).toBe('healthy');
  });

  it('should return true for isHealthy()', async () => {
    const healthy = await HealthService.isHealthy();
    expect(healthy).toBe(true);
  });

  it('should include response time in detailed status', async () => {
    const status = await HealthService.getDetailedStatus();
    expect(status).toHaveProperty('responseTimeMs');
    expect(status.responseTimeMs).toBeGreaterThan(0);
  });
});
```

---

## Troubleshooting

### Issue: "Unable to connect to backend service"

**Symptoms**: Network or fetch errors

**Solutions**:
1. Verify backend is running: `curl http://localhost:8000/health`
2. Check `VITE_API_BASE_URL` in `.env` file
3. Verify no CORS issues in browser console
4. Check firewall/network settings

### Issue: "Backend service is temporarily unavailable"

**Symptoms**: 503 status code

**Solutions**:
1. Backend may be starting up - wait a few seconds
2. Check backend logs: `docker logs mapleopentech_backend`
3. Verify backend services (Cassandra, Redis) are running
4. Restart backend: `task end && task dev`

### Issue: Health check timeout

**Symptoms**: Slow or no response

**Solutions**:
1. Check backend server load
2. Verify network latency
3. Check if backend is overloaded
4. Consider increasing timeout in `waitUntilHealthy()`

### Issue: Always returns unhealthy

**Symptoms**: `isHealthy()` always returns false

**Solutions**:
1. Check browser console for errors
2. Verify API base URL is correct
3. Check CORS configuration
4. Test endpoint directly with curl

---

## Best Practices

### 1. **Use During Initialization**

Always check backend health during app startup:

```javascript
useEffect(() => {
  HealthService.isHealthy().then(healthy => {
    if (!healthy) {
      showBackendError();
    }
  });
}, []);
```

### 2. **Periodic Health Checks**

For long-running apps, check periodically:

```javascript
// Every 5 minutes
setInterval(async () => {
  const healthy = await HealthService.isHealthy();
  updateStatusIndicator(healthy);
}, 300000);
```

### 3. **Handle Failures Gracefully**

Don't throw errors to users - handle them gracefully:

```javascript
const healthy = await HealthService.isHealthy().catch(() => false);
if (!healthy) {
  showOfflineMode();
}
```

### 4. **Log Response Times**

Monitor performance over time:

```javascript
const status = await HealthService.getDetailedStatus();
analytics.track('backend_health', {
  responseTime: status.responseTimeMs,
  healthy: status.healthy
});
```

---

## Integration with Other Services

The HealthService can be combined with other services for robust error handling:

```javascript
import HealthService from './services/API/HealthService';
import AuthManager from './services/Manager/AuthManager';

async function safeLogin(email, password) {
  // Check backend health first
  const healthy = await HealthService.isHealthy();

  if (!healthy) {
    throw new Error('Backend is currently unavailable. Please try again later.');
  }

  // Proceed with login
  return await AuthManager.login({ email, password });
}
```

---

## Summary

The Health Check API provides a simple, reliable way to verify backend availability:

- ✅ **Simple Integration**: One GET request, no auth required
- ✅ **Multiple Helper Methods**: `checkHealth()`, `isHealthy()`, `waitUntilHealthy()`, `getDetailedStatus()`
- ✅ **Error Handling**: Comprehensive error detection and user-friendly messages
- ✅ **Flexible Usage**: Startup checks, monitoring, status indicators, deployment verification
- ✅ **Production Ready**: Tested against backend implementation

For questions or issues, refer to the [Troubleshooting](#troubleshooting) section or check the main [README](../../README.md).

---

**Last Updated**: October 30, 2024
**Frontend Version**: 0.0.0
**Backend API Version**: 1.0.0
