Files
python-api/docs/API_REFERENCE.md
2026-03-01 07:44:19 +09:00

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" }` | 펌웨어 업데이트 |