# Backend API 문서

## 시뮬레이션 API

### POST /api/simulation/run

오일 확산 시뮬레이션을 실행합니다.

#### 요청

```json
{
  "model": "OpenDrift",        // "KOSPS" | "POSEIDON" | "OpenDrift" | "앙상블"
  "lat": 34.7312,               // 사고 위도
  "lon": 127.6845,              // 사고 경도
  "duration_hours": 48,         // 예측 시간 (시간)
  "oil_type": "벙커C유",         // 유종
  "spill_amount": 100,          // 유출량 (kL)
  "spill_type": "연속"           // 유출 형태
}
```

#### 응답

```json
{
  "success": true,
  "model": "OpenDrift",
  "parameters": {
    "lat": 34.7312,
    "lon": 127.6845,
    "duration_hours": 48,
    "oil_type": "벙커C유",
    "spill_amount": 100,
    "spill_type": "연속"
  },
  "trajectory": [
    {
      "lat": 34.7312,
      "lon": 127.6845,
      "time": 0,
      "particle": 0
    },
    // ... more points
  ],
  "metadata": {
    "particle_count": 20,
    "time_steps": 49,
    "generated_at": "2026-02-16T16:45:00.000Z"
  }
}
```

#### 오류 응답

```json
{
  "error": "Missing required parameters",
  "required": ["model", "lat", "lon", "duration_hours"]
}
```

---

### GET /api/simulation/status/:jobId

시뮬레이션 작업 상태를 확인합니다 (향후 비동기 작업용).

#### 응답

```json
{
  "jobId": "abc123",
  "status": "completed",        // "pending" | "running" | "completed" | "failed"
  "progress": 100,              // 0-100
  "message": "Simulation completed"
}
```

---

## OpenDrift 통합 계획

### 1단계: 환경 설정

```bash
# Python 가상 환경 생성
python3 -m venv venv
source venv/bin/activate  # Linux/Mac
# venv\Scripts\activate   # Windows

# OpenDrift 설치
pip install opendrift

# 필요한 기상/해양 데이터 라이브러리
pip install netCDF4 xarray
```

### 2단계: 데이터 소스 연동

OpenDrift는 다음 데이터 소스가 필요합니다:

- **바람 데이터**: WindSpeed, WindDirection
  - 소스: ERA5, ECMWF, NCEP 등
  - 형식: NetCDF (CF-compliant)

- **해류 데이터**: CurrentSpeed, CurrentDirection
  - 소스: CMEMS, HYCOM, RTOFS 등
  - 형식: NetCDF

- **파고 데이터**: WaveHeight (선택)
  - 소스: WaveWatch III

### 3단계: TypeScript에서 Python 호출

```typescript
// backend/src/routes/simulation.ts
import { spawn } from 'child_process'

function runOpenDriftPython(params: SimulationRequest): Promise<ParticlePoint[]> {
  return new Promise((resolve, reject) => {
    const python = spawn('python3', [
      './src/utils/opendrift_runner.py',
      JSON.stringify(params)
    ])

    let stdout = ''
    let stderr = ''

    python.stdout.on('data', (data) => {
      stdout += data.toString()
    })

    python.stderr.on('data', (data) => {
      stderr += data.toString()
      console.error('OpenDrift stderr:', data.toString())
    })

    python.on('close', (code) => {
      if (code === 0) {
        const result = JSON.parse(stdout)
        resolve(result.trajectory)
      } else {
        reject(new Error(`OpenDrift failed with code ${code}: ${stderr}`))
      }
    })
  })
}
```

### 4단계: 비동기 작업 큐 (선택)

장시간 시뮬레이션의 경우 작업 큐 사용:

```bash
npm install bull redis
```

```typescript
import Queue from 'bull'

const simulationQueue = new Queue('simulation', {
  redis: { host: 'localhost', port: 6379 }
})

simulationQueue.process(async (job) => {
  const result = await runOpenDriftPython(job.data)
  return result
})
```

---

## 레이어 API

### GET /api/layers/tree/all

전체 레이어 트리 구조를 반환합니다.

#### 응답

```json
[
  {
    "id": "해도",
    "name": "해도",
    "type": "group",
    "children": [
      {
        "id": "기본해도",
        "name": "기본해도",
        "type": "layer",
        "wmsLayer": "khoa:base_chart"
      }
    ]
  }
]
```
