> For the complete documentation index, see [llms.txt](https://kopens.gitbook.io/plantpulse-platform/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kopens.gitbook.io/plantpulse-platform/developer/api-manual/site-service.md).

# 5. Site 서비스

`client.site()` 으로 접근합니다. 사이트(공장)는 자산 계층의 **최상위 노드**이며, 모든 OPC·Asset·Tag·Order는 사이트에 소속됩니다.

> **ID 규칙**: `SITE_` 접두사 필수. 자세한 내용은 [도메인 ID 규칙](/plantpulse-platform/developer/api-manual/id-rules.md#22-site-id) 참고.

## 5.1 메서드 일람

| 메서드                              | 반환 타입                      | HTTP   | 엔드포인트                      |
| -------------------------------- | -------------------------- | ------ | -------------------------- |
| `create(SiteRequestV5)`          | `SiteResponseV5` 또는 `null` | POST   | `/api/v5/site`             |
| `update(site_id, SiteRequestV5)` | `SiteResponseV5` 또는 `null` | PUT    | `/api/v5/site/{id}`        |
| `delete(site_id)`                | `boolean`                  | DELETE | `/api/v5/site/{id}`        |
| `get(site_id)`                   | `SiteResponseV5` 또는 `null` | GET    | `/api/v5/site/{id}`        |
| `list()`                         | `List<SiteResponseV5>`     | GET    | `/api/v5/site`             |
| `exists(site_id)`                | `boolean`                  | GET    | `/api/v5/site/{id}/exists` |

## 5.2 SiteRequestV5 (요청 DTO)

| 필드            | 타입     | 필수 | 설명             |
| ------------- | ------ | -- | -------------- |
| `site_id`     | String | ✅  | `SITE_` 로 시작   |
| `site_name`   | String | ✅  | 사이트명           |
| `description` | String | -  | 설명             |
| `lat` / `lng` | String | -  | 위경도 (지도용)      |
| `company_id`  | String | -  | 회사 ID (멀티 테넌시) |

## 5.3 SiteResponseV5 (응답 DTO)

위 요청 필드 + 다음 추가 필드:

| 필드                            | 타입     | 설명          |
| ----------------------------- | ------ | ----------- |
| `insert_date` / `update_date` | String | 등록/수정 시각    |
| `total_area_count`            | int    | 사이트의 Area 수 |
| `total_line_count`            | int    | Line 수      |
| `total_equipment_count`       | int    | Equipment 수 |
| `total_tag_count`             | int    | Tag 수       |

## 5.4 사용 예시

### 사이트 생성

```java
import plantpulse.api.v5.dto.request.SiteRequestV5;
import plantpulse.api.v5.dto.response.SiteResponseV5;

SiteRequestV5 req = new SiteRequestV5();
req.setSite_id("SITE_DJ");
req.setSite_name("대전 1공장");
req.setDescription("주력 생산 공장");
req.setLat("36.3504");
req.setLng("127.3845");

SiteResponseV5 created = client.site().create(req);
if (created != null) {
    System.out.println("등록 완료: " + created.getSite_id());
}
```

### 단건 조회

```java
SiteResponseV5 site = client.site().get("SITE_DJ");
if (site != null) {
    System.out.println(site.getSite_name());
    System.out.println("Area 수: " + site.getTotal_area_count());
    System.out.println("Line 수: " + site.getTotal_line_count());
    System.out.println("Equipment 수: " + site.getTotal_equipment_count());
    System.out.println("Tag 수: " + site.getTotal_tag_count());
}
```

### 전체 목록

```java
import java.util.List;

List<SiteResponseV5> sites = client.site().list();
for (SiteResponseV5 s : sites) {
    System.out.println(s.getSite_id() + " — " + s.getSite_name());
}
```

### 사이트 수정

```java
SiteRequestV5 update = new SiteRequestV5();
update.setSite_id("SITE_DJ");                // 동일하게 채워서 보내야 합니다
update.setSite_name("대전 1공장 (확장)");
update.setDescription("2026년 라인 증설 완료");

SiteResponseV5 updated = client.site().update("SITE_DJ", update);
```

### 존재 여부 확인

```java
if (client.site().exists("SITE_DJ")) {
    // ...
}
```

### 사이트 삭제

> ⚠️ 사이트 삭제 전에 그 사이트에 속한 모든 Asset·OPC·Tag·Order를 먼저 삭제해야 합니다. 그렇지 않으면 `E1200` (CONFLICT) 응답을 받고 `false` 가 반환됩니다.

```java
boolean ok = client.site().delete("SITE_OLD");
if (!ok) {
    System.err.println("삭제 실패 — 하위 리소스 존재 가능");
}
```

## 5.5 활용 시나리오

### 시나리오 — 사이트별 KPI 대시보드

```java
for (SiteResponseV5 site : client.site().list()) {
    String siteId = site.getSite_id();

    // 사이트별 자산 통계는 SiteResponseV5에 이미 포함됨
    int eqCount  = site.getTotal_equipment_count();
    int tagCount = site.getTotal_tag_count();

    // 사이트별 OPC 수
    long opcCount = client.opc().countBySite(siteId);

    System.out.printf("%s — Equipment %d, Tag %d, OPC %d%n",
        site.getSite_name(), eqCount, tagCount, opcCount);
}
```

## 다음 단계

* [Asset 서비스](/plantpulse-platform/developer/api-manual/asset-service.md) — Area/Line/Equipment 트리 구축
* [OPC 서비스](/plantpulse-platform/developer/api-manual/opc-service.md) — 데이터 수집 채널 등록
