565 lines
10 KiB
Markdown
565 lines
10 KiB
Markdown
# API 레퍼런스
|
|
|
|
> Base URL: `http://localhost:8000/api/v1`
|
|
> 인증: `Authorization: Bearer <access_token>`
|
|
|
|
---
|
|
|
|
## 인증 (Auth)
|
|
|
|
### POST `/auth/register`
|
|
|
|
회원가입 후 토큰을 발급한다.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "securepassword",
|
|
"full_name": "홍길동"
|
|
}
|
|
```
|
|
|
|
**Response (201):**
|
|
```json
|
|
{
|
|
"access_token": "eyJ...",
|
|
"refresh_token": "eyJ...",
|
|
"token_type": "bearer"
|
|
}
|
|
```
|
|
|
|
**에러:**
|
|
- `409` — 이미 등록된 이메일
|
|
|
|
---
|
|
|
|
### POST `/auth/login`
|
|
|
|
이메일/비밀번호로 로그인한다.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "securepassword"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"access_token": "eyJ...",
|
|
"refresh_token": "eyJ...",
|
|
"token_type": "bearer"
|
|
}
|
|
```
|
|
|
|
**에러:**
|
|
- `401` — 잘못된 이메일/비밀번호 또는 비활성 계정
|
|
|
|
---
|
|
|
|
### POST `/auth/refresh`
|
|
|
|
리프레시 토큰으로 새 토큰 쌍을 발급한다. 기존 리프레시 토큰은 폐기된다.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"refresh_token": "eyJ..."
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"access_token": "eyJ...(new)",
|
|
"refresh_token": "eyJ...(new)",
|
|
"token_type": "bearer"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### POST `/auth/logout`
|
|
|
|
현재 사용자의 모든 리프레시 토큰을 폐기한다.
|
|
|
|
**Headers:** `Authorization: Bearer <access_token>`
|
|
|
|
**Response:** `204 No Content`
|
|
|
|
---
|
|
|
|
## 사용자 (Users)
|
|
|
|
### GET `/users/me`
|
|
|
|
현재 로그인한 사용자의 정보를 조회한다.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"email": "user@example.com",
|
|
"role": "user",
|
|
"is_active": true,
|
|
"is_verified": false,
|
|
"full_name": "홍길동",
|
|
"phone": "010-1234-5678",
|
|
"organization": "ACME Corp",
|
|
"avatar_url": "",
|
|
"created_at": "2025-01-01T00:00:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PATCH `/users/me`
|
|
|
|
자신의 프로필 정보를 수정한다. `role`과 `is_active`는 변경할 수 없다.
|
|
|
|
**Request Body (partial):**
|
|
```json
|
|
{
|
|
"full_name": "김철수",
|
|
"phone": "010-9999-8888"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/users`
|
|
|
|
사용자 목록을 페이징 조회한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
**Query Parameters:**
|
|
| 파라미터 | 타입 | 기본값 | 설명 |
|
|
|---------|------|--------|------|
|
|
| page | int | 1 | 페이지 번호 |
|
|
| size | int | 20 | 페이지 크기 (max 100) |
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"items": [{ ... }],
|
|
"total": 150,
|
|
"page": 1,
|
|
"size": 20,
|
|
"pages": 8
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/users/{user_id}`
|
|
|
|
특정 사용자를 조회한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
---
|
|
|
|
### POST `/users`
|
|
|
|
사용자를 생성한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email": "new@example.com",
|
|
"password": "password123",
|
|
"role": "manager",
|
|
"full_name": "박매니저",
|
|
"phone": "010-1111-2222",
|
|
"organization": "Dev Team"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### PATCH `/users/{user_id}`
|
|
|
|
사용자 정보를 수정한다. 관리자는 역할과 활성 상태도 변경할 수 있다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
---
|
|
|
|
### DELETE `/users/{user_id}`
|
|
|
|
사용자를 소프트 삭제한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
**Response:** `204 No Content`
|
|
|
|
---
|
|
|
|
## 디바이스 (Devices)
|
|
|
|
### GET `/devices`
|
|
|
|
디바이스 목록을 페이징 조회한다.
|
|
|
|
**Query Parameters:**
|
|
| 파라미터 | 타입 | 기본값 | 설명 |
|
|
|---------|------|--------|------|
|
|
| page | int | 1 | 페이지 번호 |
|
|
| size | int | 20 | 페이지 크기 (max 100) |
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"device_uid": "sensor-temp-001",
|
|
"name": "1층 온도센서",
|
|
"device_type": "temperature",
|
|
"status": "online",
|
|
"firmware_version": "1.2.0",
|
|
"ip_address": "192.168.1.100",
|
|
"group_id": 1,
|
|
"owner_id": 2,
|
|
"last_seen_at": "2025-01-15T12:00:00",
|
|
"created_at": "2025-01-01T00:00:00"
|
|
}
|
|
],
|
|
"total": 50,
|
|
"page": 1,
|
|
"size": 20,
|
|
"pages": 3
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/devices/{device_id}`
|
|
|
|
특정 디바이스 상세를 조회한다.
|
|
|
|
---
|
|
|
|
### POST `/devices`
|
|
|
|
디바이스를 등록한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN, MANAGER
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"device_uid": "sensor-temp-001",
|
|
"name": "1층 온도센서",
|
|
"device_type": "temperature",
|
|
"group_id": 1,
|
|
"owner_id": 2,
|
|
"firmware_version": "1.0.0"
|
|
}
|
|
```
|
|
|
|
**에러:**
|
|
- `409` — 이미 등록된 device_uid
|
|
|
|
---
|
|
|
|
### PATCH `/devices/{device_id}`
|
|
|
|
디바이스 정보를 수정한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN, MANAGER
|
|
|
|
**Request Body (partial):**
|
|
```json
|
|
{
|
|
"name": "수정된 센서명",
|
|
"status": "maintenance"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### DELETE `/devices/{device_id}`
|
|
|
|
디바이스를 소프트 삭제한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN
|
|
|
|
**Response:** `204 No Content`
|
|
|
|
---
|
|
|
|
## 모니터링 (Monitoring)
|
|
|
|
### GET `/monitoring/health`
|
|
|
|
시스템 상태를 상세 조회한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN, MANAGER
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"mariadb": "connected",
|
|
"mongodb": "connected",
|
|
"redis": "connected",
|
|
"mqtt": "connected",
|
|
"active_devices": 42,
|
|
"active_alerts": 3
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/monitoring/alerts`
|
|
|
|
미확인 알림 목록을 조회한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN, MANAGER
|
|
|
|
**Query Parameters:**
|
|
| 파라미터 | 타입 | 기본값 | 설명 |
|
|
|---------|------|--------|------|
|
|
| skip | int | 0 | 건너뛸 수 |
|
|
| limit | int | 50 | 최대 개수 (max 200) |
|
|
|
|
**Response (200):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 1,
|
|
"rule_id": 3,
|
|
"device_id": 5,
|
|
"severity": "warning",
|
|
"message": "Temperature exceeded threshold",
|
|
"is_acknowledged": false,
|
|
"acknowledged_by": null,
|
|
"acknowledged_at": null,
|
|
"created_at": "2025-01-15T10:30:00"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### POST `/monitoring/alerts/{alert_id}/acknowledge`
|
|
|
|
알림을 확인 처리한다.
|
|
|
|
---
|
|
|
|
### GET `/monitoring/alert-rules`
|
|
|
|
알림 규칙 목록을 조회한다.
|
|
|
|
---
|
|
|
|
### POST `/monitoring/alert-rules`
|
|
|
|
알림 규칙을 생성한다.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "고온 경고",
|
|
"description": "온도가 40도를 초과하면 알림",
|
|
"metric": "temperature",
|
|
"condition": "gt",
|
|
"threshold": 40.0,
|
|
"severity": "warning",
|
|
"device_group_id": 1
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 분석 (Analytics)
|
|
|
|
### GET `/analytics/telemetry/{device_id}`
|
|
|
|
특정 디바이스의 텔레메트리 데이터를 시간 간격별로 집계한다.
|
|
|
|
**권한:** SUPERADMIN, ADMIN, MANAGER
|
|
|
|
**Query Parameters:**
|
|
| 파라미터 | 타입 | 필수 | 설명 |
|
|
|---------|------|------|------|
|
|
| start | datetime | O | 시작 시각 (ISO 8601) |
|
|
| end | datetime | O | 종료 시각 (ISO 8601) |
|
|
| interval | string | X | 집계 간격 (기본값: `1h`) |
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"device_id": "sensor-temp-001",
|
|
"records": [
|
|
{"timestamp": "2025-01-15T10:00:00", "temperature": 23.5, "humidity": 45.2},
|
|
{"timestamp": "2025-01-15T11:00:00", "temperature": 24.1, "humidity": 44.8}
|
|
],
|
|
"count": 2
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### POST `/analytics/reports/{device_id}`
|
|
|
|
디바이스 종합 리포트를 생성한다 (상태 분석 + 추세 분석).
|
|
|
|
**Query Parameters:** `start`, `end` (ISO 8601)
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"report_id": "65a1b2c3...",
|
|
"device_id": "sensor-temp-001",
|
|
"status": {
|
|
"total_events": 150,
|
|
"status_counts": {"online": 140, "offline": 10},
|
|
"uptime_ratio": 0.9333
|
|
},
|
|
"trends": {
|
|
"count": 720,
|
|
"mean": 23.5,
|
|
"std": 1.2,
|
|
"min": 20.1,
|
|
"max": 28.3,
|
|
"slope": 0.0023,
|
|
"trend": "stable"
|
|
},
|
|
"created_at": "2025-01-15T12:00:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/analytics/status/{device_id}`
|
|
|
|
디바이스 상태 변경 이력을 분석한다.
|
|
|
|
---
|
|
|
|
### GET `/analytics/trends/{device_id}`
|
|
|
|
텔레메트리 데이터의 추세를 분석한다 (선형 회귀).
|
|
|
|
---
|
|
|
|
### GET `/analytics/results`
|
|
|
|
저장된 분석 결과를 조회한다.
|
|
|
|
**Query Parameters:**
|
|
| 파라미터 | 타입 | 필수 | 설명 |
|
|
|---------|------|------|------|
|
|
| analysis_type | string | O | 분석 유형 |
|
|
| device_id | string | X | 디바이스 ID |
|
|
| skip | int | X | 건너뛸 수 (기본 0) |
|
|
| limit | int | X | 최대 개수 (기본 20) |
|
|
|
|
---
|
|
|
|
## 시스템 (System)
|
|
|
|
### GET `/system/health`
|
|
|
|
서비스 헬스체크. 인증 불필요.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"service": "core-api",
|
|
"version": "0.1.0"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### GET `/system/info`
|
|
|
|
시스템 설정 정보를 조회한다.
|
|
|
|
**권한:** SUPERADMIN
|
|
|
|
---
|
|
|
|
## 공통 에러 응답
|
|
|
|
모든 에러는 다음 형식으로 반환된다:
|
|
|
|
```json
|
|
{
|
|
"detail": "에러 메시지"
|
|
}
|
|
```
|
|
|
|
| 상태 코드 | 설명 |
|
|
|----------|------|
|
|
| 401 | 인증 실패 (토큰 없음/만료/유효하지 않음) |
|
|
| 403 | 권한 부족 |
|
|
| 404 | 리소스를 찾을 수 없음 |
|
|
| 409 | 리소스 충돌 (중복) |
|
|
| 422 | 요청 데이터 검증 실패 |
|
|
| 429 | 요청 속도 제한 초과 |
|
|
| 500 | 서버 내부 오류 |
|
|
|
|
---
|
|
|
|
## Socket.IO 이벤트
|
|
|
|
> 연결: `io("http://localhost:8000", { path: "/socket.io/" })`
|
|
|
|
### 네임스페이스: `/monitoring`
|
|
|
|
| 이벤트 | 방향 | 데이터 | 설명 |
|
|
|--------|------|--------|------|
|
|
| `subscribe_device` | Client → Server | `{ device_uid }` | 디바이스 모니터링 구독 |
|
|
| `unsubscribe_device` | Client → Server | `{ device_uid }` | 구독 해제 |
|
|
| `telemetry` | Server → Client | `{ device_uid, data }` | 실시간 텔레메트리 |
|
|
| `device_status` | Server → Client | `{ device_uid, status }` | 상태 변경 |
|
|
|
|
### 네임스페이스: `/device`
|
|
|
|
| 이벤트 | 방향 | 데이터 | 설명 |
|
|
|--------|------|--------|------|
|
|
| `send_command` | Client → Server | `{ device_uid, command }` | 디바이스 명령 전송 |
|
|
| `device_response` | Server → Client | `{ device_uid, data }` | 명령 응답 |
|
|
|
|
### 네임스페이스: `/notification`
|
|
|
|
| 이벤트 | 방향 | 데이터 | 설명 |
|
|
|--------|------|--------|------|
|
|
| `join_user_room` | Client → Server | `{ user_id }` | 알림 수신 등록 |
|
|
| `notification` | Server → Client | `{ title, message, type }` | 알림 푸시 |
|
|
|
|
---
|
|
|
|
## MQTT 토픽
|
|
|
|
> 브로커: `mqtt://localhost:1883`
|
|
|
|
### Device → Server
|
|
|
|
| 토픽 | 페이로드 | 처리 |
|
|
|------|---------|------|
|
|
| `devices/{uid}/telemetry` | `{ temperature: 23.5, ... }` | MongoDB 저장 + Socket.IO 브로드캐스트 |
|
|
| `devices/{uid}/status` | `{ status: "online" }` | MongoDB 로그 + Socket.IO 전송 |
|
|
| `devices/{uid}/log` | `{ event_type: "...", ... }` | MongoDB 저장 |
|
|
| `devices/{uid}/response` | `{ command_id: "...", ... }` | Socket.IO 전송 |
|
|
|
|
### Server → Device
|
|
|
|
| 토픽 | 페이로드 | 용도 |
|
|
|------|---------|------|
|
|
| `devices/{uid}/command` | `{ action: "restart" }` | 원격 명령 |
|
|
| `devices/{uid}/config` | `{ interval: 30 }` | 설정 변경 |
|
|
| `devices/{uid}/ota` | `{ url: "...", action: "update" }` | 펌웨어 업데이트 |
|